diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-10-20 20:48:48 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-10-20 20:48:48 +0400 |
commit | 55015daa43f0ab45341e316abcf11f23c87b5ebe (patch) | |
tree | 3156892b6d807d9ba513d444adb870b0ae358e7a | |
parent | 1fe70c07a008185c4e5925aff2c214c93ff396b7 (diff) | |
parent | a9e2e2279780ec2fb58e6820b9cad95ba03f4cad (diff) |
Merged changes in the trunk up to revision 51448.
Conflicts resolved:
source/blender/blenkernel/CMakeLists.txt
source/blender/blenloader/intern/readfile.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/makesrna/intern/rna_main_api.c
1248 files changed, 36981 insertions, 20236 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f0ef41fe59..058da2d40b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,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) @@ -733,23 +734,14 @@ if(UNIX AND NOT APPLE) 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_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR) 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 @@ -787,8 +779,6 @@ if(UNIX AND NOT APPLE) 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 @@ -956,8 +946,6 @@ elseif(WIN32) else() message(STATUS "OSL not found") endif() - - include_directories(${OSL_INCLUDES}) endif() if(MSVC) @@ -1608,7 +1596,7 @@ elseif(APPLE) if(WITH_OPENIMAGEIO) set(OPENIMAGEIO ${LIBDIR}/openimageio) set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) - set(OPENIMAGEIO_LIBRARIES -force_load ${OPENIMAGEIO}/lib/libOpenImageIO.a ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES}) + set(OPENIMAGEIO_LIBRARIES ${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() @@ -1639,23 +1627,14 @@ elseif(APPLE) 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_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR) 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 @@ -1692,8 +1671,6 @@ elseif(APPLE) else() message(STATUS "OSL not found") endif() - - include_directories(${OSL_INCLUDES}) endif() set(EXETYPE MACOSX_BUNDLE) @@ -1880,12 +1857,16 @@ if(CMAKE_COMPILER_IS_GNUCC) ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings) 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) + # gcc 4.2 gives annoying warnings on every file with this + if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER "4.2") + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized) + endif() + # 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) @@ -1897,11 +1878,15 @@ if(CMAKE_COMPILER_IS_GNUCC) 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) + # gcc 4.2 gives annoying warnings on every file with this + if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER "4.2") + ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized) + endif() + # causes too many warnings if(NOT APPLE) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef) @@ -2014,9 +1999,10 @@ if(WITH_PYTHON) endif() endif() - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS} ${C_WARNINGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ${CXX_WARNINGS}") +# Include warnings first, so its possible to disable them with user defined flags +# eg: -Wno-uninitialized +set(CMAKE_C_FLAGS "${C_WARNINGS} ${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS}") +set(CMAKE_CXX_FLAGS "${CXX_WARNINGS} ${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS}") #------------------------------------------------------------------------------- # Global Defines @@ -2123,6 +2109,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) diff --git a/GNUmakefile b/GNUmakefile index 90d76dfe432..f8207787cbe 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -163,20 +163,27 @@ help: @echo " * package_archive - build an archive package" @echo "" @echo "Testing Targets (not associated with building blender)" - @echo " * test - run ctest, currently tests import/export, operator execution and that python modules load" - @echo " * test_cmake - runs our own cmake file checker which detects errors in the cmake file list definitions" - @echo " * test_pep8 - checks all python script are pep8 which are tagged to use the stricter formatting" - @echo " * test_deprecated - checks for deprecation tags in our code which may need to be removed" - @echo " * test_style - checks C/C++ conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" + @echo " * test - run ctest, currently tests import/export, operator execution and that python modules load" + @echo " * test_cmake - runs our own cmake file checker which detects errors in the cmake file list definitions" + @echo " * test_pep8 - checks all python script are pep8 which are tagged to use the stricter formatting" + @echo " * test_deprecated - checks for deprecation tags in our code which may need to be removed" + @echo " * test_style_c - checks C/C++ conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" + @echo " * test_style_c_qtc - same as test_style but outputs QtCreator tasks format" + @echo " * test_style_osl - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" + @echo " * test_style_osl_qtc - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" @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 " * 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 (OSL only)" + @echo " * check_spelling_osl - check for spelling errors (C/C++ only)" + @echo " * check_spelling_py - check for spelling errors (Python only)" + @echo "" + @echo "Utilities (not associated with building blender)" + @echo " * tbz - create a compressed svn export 'blender_archive.tar.bz2'" @echo "" @echo "Documentation Targets (not associated with building blender)" @echo " * doc_py - generate sphinx python api docs" @@ -207,31 +214,51 @@ test: # run pep8 check check on scripts we distribute. test_pep8: - python3.2 source/tests/pep8.py > test_pep8.log 2>&1 + python3 source/tests/pep8.py > test_pep8.log 2>&1 @echo "written: test_pep8.log" # run some checks on our cmakefiles. test_cmake: - python3.2 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1 + python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1 @echo "written: test_cmake_consistency.log" # run deprecation tests, see if we have anything to remove. test_deprecated: - python3.2 source/tests/check_deprecated.py + python3 source/tests/check_deprecated.py + +test_style_c: + # run our own checks on C/C++ style + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check + +test_style_c_qtc: + # run our own checks on C/C++ style + USE_QTC_TASK=1 \ + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check > \ + test_style.tasks + @echo "written: test_style.tasks" + -test_style: +test_style_osl: # run our own checks on C/C++ style - PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/osl + + +test_style_osl_qtc: + # run our own checks on C/C++ style + USE_QTC_TASK=1 \ + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/osl > \ + test_style.tasks + @echo "written: test_style.tasks" # ----------------------------------------------------------------------------- # Project Files # project_qtcreator: - python3.2 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR) + python3 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR) project_netbeans: - python3.2 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR) + python3 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR) project_eclipse: cmake -G"Eclipse CDT4 - Unix Makefiles" -H$(BLENDER_DIR) -B$(BUILD_DIR) @@ -243,29 +270,43 @@ project_eclipse: check_cppcheck: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py + cd $(BUILD_DIR) ; python3 $(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 + cd $(BUILD_DIR) ; python3 $(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 + cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py check_sparse: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py + cd $(BUILD_DIR) ; python3 $(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 + cd $(BUILD_DIR) ; python3 $(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 + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts check_spelling_c: - cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source + +check_spelling_osl: + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/osl + +# ----------------------------------------------------------------------------- +# Utilities +# + +tbz: + svn export . blender_archive + tar cjf blender_archive.tar.bz2 blender_archive/ + rm -rf blender_archive/ + @echo "blender_archive.tar.bz2 written" + # ----------------------------------------------------------------------------- # Documentation @@ -286,7 +327,7 @@ doc_dna: @echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'" doc_man: - python3.2 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender + python3 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender clean: diff --git a/SConstruct b/SConstruct index 7676b44f759..7b92a0cb25c 100644 --- a/SConstruct +++ b/SConstruct @@ -366,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'] diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index 066c133d335..1bd47303b2f 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -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)) diff --git a/build_files/buildbot/master_unpack.py b/build_files/buildbot/master_unpack.py index f67bd294496..ecacf3bff6f 100644 --- a/build_files/buildbot/master_unpack.py +++ b/build_files/buildbot/master_unpack.py @@ -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 diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index 654efd72876..eafb25ac7b0 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -50,9 +50,9 @@ 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 diff --git a/build_files/cmake/clang_array_check.py b/build_files/cmake/clang_array_check.py index df45648f975..3070c27f769 100644 --- a/build_files/cmake/clang_array_check.py +++ b/build_files/cmake/clang_array_check.py @@ -19,12 +19,15 @@ Invocation: """ +# 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}, + "glColor3bv": {0: 3}, + "glColor4bv": {0: 4}, "glColor3ubv": {0: 3}, "glColor4ubv": {0: 4}, @@ -32,11 +35,11 @@ defs_precalc = { "glColor4usv": {0: 3}, "glColor4usv": {0: 4}, - "glColor3fv": {0: 3}, - "glColor4fv": {0: 4}, + "glColor3fv": {0: 3}, + "glColor4fv": {0: 4}, - "glColor3dv": {0: 3}, - "glColor4dv": {0: 4}, + "glColor3dv": {0: 3}, + "glColor4dv": {0: 4}, "glVertex2fv": {0: 2}, "glVertex3fv": {0: 3}, @@ -52,12 +55,12 @@ defs_precalc = { "glRasterPos4dv": {0: 4}, "glRasterPos2fv": {0: 2}, - "glRasterPos3fv": {0: 3}, + "glRasterPos3fv": {0: 3}, "glRasterPos4fv": {0: 4}, "glRasterPos2sv": {0: 2}, - "glRasterPos3sv": {0: 3}, - "glRasterPos4sv": {0: 4}, + "glRasterPos3sv": {0: 3}, + "glRasterPos4sv": {0: 4}, "glTexCoord2fv": {0: 2}, "glTexCoord3fv": {0: 3}, @@ -112,10 +115,11 @@ args = sys.argv[2:] # print(args) tu = index.parse(sys.argv[1], args) -print 'Translation unit:', tu.spelling +print('Translation unit: %s' % tu.spelling) # ----------------------------------------------------------------------------- + def function_parm_wash_tokens(parm): # print(parm.kind) assert parm.kind in (CursorKind.PARM_DECL, @@ -174,22 +178,21 @@ def parm_size(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 == "]")): + 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 node.spelling == "BM_vert_create" or 1: + 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] @@ -211,11 +214,19 @@ def function_get_arg_sizes(node): # ----------------------------------------------------------------------------- _defs = {} + def lookup_function_size_def(func_id): - return _defs.get(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 @@ -224,7 +235,13 @@ def file_check_arg_sizes(tu): Loop over args and validate sizes for args we KNOW the size of. """ assert node.kind == CursorKind.CALL_EXPR - # print("---", " <~> ".join([" ".join([t.spelling for t in C.get_tokens()]) for C in node.get_children()])) + + 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. @@ -283,36 +300,32 @@ def file_check_arg_sizes(tu): if size != -1 and size != 0: # nice print! - ''' - print("".join([t.spelling for t in func.get_tokens()]), - i, - " ".join([t.spelling for t in dec.get_tokens()])) - ''' + 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: + 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 - )) - + 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) @@ -322,7 +335,10 @@ def file_check_arg_sizes(tu): def recursive_arg_sizes(node, ): # print(node.kind, node.spelling) if node.kind == CursorKind.FUNCTION_DECL: - args_sizes = function_get_arg_sizes(node) + 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 diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index 32d20489e6a..83ea761e2d1 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -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() diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py index ff15a130ee0..941407170ff 100644 --- a/build_files/cmake/cmake_static_check_clang_array.py +++ b/build_files/cmake/cmake_static_check_clang_array.py @@ -30,6 +30,7 @@ import os CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "python2" @@ -51,7 +52,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py index c340ca5c458..c458e8ede11 100644 --- a/build_files/cmake/cmake_static_check_cppcheck.py +++ b/build_files/cmake/cmake_static_check_cppcheck.py @@ -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)) diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py index 779945b030a..5681d2ae5ed 100644 --- a/build_files/cmake/cmake_static_check_smatch.py +++ b/build_files/cmake/cmake_static_check_smatch.py @@ -25,6 +25,7 @@ CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "smatch" @@ -49,7 +50,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py index db1b14e7acb..4f4eb838dd5 100644 --- a/build_files/cmake/cmake_static_check_sparse.py +++ b/build_files/cmake/cmake_static_check_sparse.py @@ -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)) diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py index f538fa612d0..7be28c01af8 100644 --- a/build_files/cmake/cmake_static_check_splint.py +++ b/build_files/cmake/cmake_static_check_splint.py @@ -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)) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index ae07743191b..de3cfd166b7 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -10,6 +10,7 @@ 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) diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index a80ae623eb9..b154d578144 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -112,7 +112,7 @@ def is_glsl(filename): def is_c(filename): ext = splitext(filename)[1] - return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl")) + return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"}) def is_c_any(filename): @@ -133,12 +133,20 @@ def cmake_advanced_info(): """ Extracr includes and defines from cmake. """ + make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM") + make_exe_basename = os.path.basename(make_exe) + def create_eclipse_project(): print("CMAKE_DIR %r" % CMAKE_DIR) if sys.platform == "win32": cmd = 'cmake "%s" -G"Eclipse CDT4 - MinGW Makefiles"' % CMAKE_DIR else: - cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR + if make_exe_basename.startswith("make"): + cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR + elif make_exe_basename.startswith("ninja"): + cmd = 'cmake "%s" -G"Eclipse CDT4 - Ninja"' % CMAKE_DIR + else: + raise Exception("Unknown make program %r" % make_exe) os.system(cmd) diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py index ed17ec5bac4..10bc36ba1a8 100644 --- a/build_files/cmake/project_source_info.py +++ b/build_files/cmake/project_source_info.py @@ -48,7 +48,7 @@ def is_c_header(filename): def is_c(filename): ext = os.path.splitext(filename)[1] - return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl")) + return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"}) def is_c_any(filename): @@ -82,10 +82,20 @@ def makefile_log(): import subprocess import time - print("running make with --dry-run ...") - process = subprocess.Popen(["make", "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"], - stdout=subprocess.PIPE, - ) + # support both make and ninja + make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM") + make_exe_basename = os.path.basename(make_exe) + + if make_exe_basename.startswith("make"): + print("running 'make' with --dry-run ...") + process = subprocess.Popen([make_exe, "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"], + stdout=subprocess.PIPE, + ) + elif make_exe_basename.startswith("ninja"): + print("running 'ninja' with -t commands ...") + process = subprocess.Popen([make_exe, "-t", "commands"], + stdout=subprocess.PIPE, + ) while process.poll(): time.sleep(1) @@ -145,6 +155,12 @@ def build_info(use_c=True, use_cxx=True, ignore_prefix_list=None): source.append((c, inc_dirs, defs)) + # make relative includes absolute + # not totally essential but useful + for i, f in enumerate(inc_dirs): + if not os.path.isabs(f): + inc_dirs[i] = os.path.abspath(os.path.join(CMAKE_DIR, f)) + # safety check that our includes are ok for f in inc_dirs: if not os.path.exists(f): diff --git a/doc/guides/interface_API.txt b/doc/guides/interface_API.txt index 5f601dd3ebc..5f0fbc85ff8 100644 --- a/doc/guides/interface_API.txt +++ b/doc/guides/interface_API.txt @@ -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; } diff --git a/doc/python_api/examples/bpy.types.Operator.4.py b/doc/python_api/examples/bpy.types.Operator.4.py index 861496c6d18..885ed857842 100644 --- a/doc/python_api/examples/bpy.types.Operator.4.py +++ b/doc/python_api/examples/bpy.types.Operator.4.py @@ -26,8 +26,8 @@ class CustomDrawOperator(bpy.types.Operator): return {'FINISHED'} def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {'RUNNING_MODAL'} + wm = context.window_manager + return wm.invoke_props_dialog(self) def draw(self, context): layout = self.layout diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index e123768431b..4a0abcb62c3 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -40,15 +40,17 @@ class ModalOperator(bpy.types.Operator): elif event.type == 'LEFTMOUSE': # Confirm return {'FINISHED'} elif event.type in ('RIGHTMOUSE', 'ESC'): # Cancel + context.object.location.x = self.init_loc_x return {'CANCELLED'} return {'RUNNING_MODAL'} def invoke(self, context, event): + self.init_loc_x = context.object.location.x self.value = event.mouse_x self.execute(context) - print(context.window_manager.modal_handler_add(self)) + context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index f4374f7f355..a173137e50c 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -333,7 +333,8 @@ 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 @@ -879,7 +880,8 @@ 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: @@ -986,6 +988,24 @@ 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 @@ -4546,7 +4566,9 @@ 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 diff --git a/doc/python_api/rst/change_log.rst b/doc/python_api/rst/change_log.rst index 4d8f9a5171e..c1f3c2e4267 100644 --- a/doc/python_api/rst/change_log.rst +++ b/doc/python_api/rst/change_log.rst @@ -2397,3 +2397,1502 @@ Removed * **ffmpeg_packetsize** * **ffmpeg_video_bitrate** +2.62 to 2.63 +============ + +bpy.types.ThemeView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeView3D.camera` +* :class:`bpy.types.ThemeView3D.empty` + +bpy.types.KeyingSet +------------------- + +Added +^^^^^ + +* :class:`bpy.types.KeyingSet.bl_description` +* :class:`bpy.types.KeyingSet.bl_idname` + +Renamed +^^^^^^^ + +* **name** -> :class:`bpy.types.KeyingSet.bl_label` + +bpy.types.BlendDataScenes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataScenes.tag` + +bpy.types.RenderEngine +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderEngine.camera_override` + +bpy.types.BackgroundImage +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BackgroundImage.show_on_foreground` + +bpy.types.CyclesRenderSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesRenderSettings.preview_active_layer` +* :class:`bpy.types.CyclesRenderSettings.sample_clamp` + +bpy.types.ToolSettings +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.ToolSettings.double_threshold` + +bpy.types.Image +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Image.render_slot` + +bpy.types.MovieTrackingStabilization +------------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingStabilization.filter_type` + +bpy.types.DomainFluidSettings +----------------------------- + +Removed +^^^^^^^ + +* **viscosity_preset** + +bpy.types.ParticleSettings +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ParticleSettings.use_rotations` + +bpy.types.SceneGameData +----------------------- + +Renamed +^^^^^^^ + +* **dome_tesselation** -> :class:`bpy.types.SceneGameData.dome_tessellation` + +bpy.types.RegionView3D +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RegionView3D.update` + +bpy.types.Scene +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Scene.active_layer` + +bpy.types.ShaderNodeTexEnvironment +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexEnvironment.projection` + +bpy.types.UserPreferencesEdit +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesEdit.fcurve_unselected_alpha` + +bpy.types.MeshTextureFace +------------------------- + +Removed +^^^^^^^ + +* **pin_uv** +* **select_uv** + +bpy.types.Menu +-------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.Menu.path_menu` (self, searchpaths, operator, props_default, filter_ext), *was (self, searchpaths, operator, props_default)* + +bpy.types.CompositorNodeDistanceMatte +------------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeDistanceMatte.channel` + +bpy.types.KeyingSetInfo +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.KeyingSetInfo.bl_description` + +bpy.types.KeyingSets +-------------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.KeyingSets.new` (idname, name), *was (name)* + +bpy.types.CompositorNodeOutputFile +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeOutputFile.active_input` +* :class:`bpy.types.CompositorNodeOutputFile.active_input_index` +* :class:`bpy.types.CompositorNodeOutputFile.base_path` + +Removed +^^^^^^^ + +* **filepath** +* **frame_end** +* **frame_start** + +Renamed +^^^^^^^ + +* **image_settings** -> :class:`bpy.types.CompositorNodeOutputFile.format` + +bpy.types.CyclesCameraSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesCameraSettings.aperture_fstop` +* :class:`bpy.types.CyclesCameraSettings.aperture_type` + +bpy.types.Struct +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Struct.translation_context` + +bpy.types.ThemeSequenceEditor +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeSequenceEditor.movieclip_strip` +* :class:`bpy.types.ThemeSequenceEditor.preview_back` + +bpy.types.TexMapping +-------------------- + +Renamed +^^^^^^^ + +* **location** -> :class:`bpy.types.TexMapping.translation` + +bpy.types.ArmatureActuator +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ArmatureActuator.influence` + +bpy.types.ThemeTextEditor +------------------------- + +Removed +^^^^^^^ + +* **scroll_bar** + +bpy.types.ThemeUserInterface +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeUserInterface.wcol_tooltip` + +bpy.types.MeshEdge +------------------ + +Removed +^^^^^^^ + +* **is_fgon** + +bpy.types.Brush +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Brush.sculpt_capabilities` + +Renamed +^^^^^^^ + +* **use_space_atten** -> :class:`bpy.types.Brush.use_space_attenuation` + +bpy.types.ShaderNodeMapping +--------------------------- + +Renamed +^^^^^^^ + +* **location** -> :class:`bpy.types.ShaderNodeMapping.translation` + +bpy.types.Mesh +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Mesh.auto_texspace` +* :class:`bpy.types.Mesh.calc_tessface` +* :class:`bpy.types.Mesh.loops` +* :class:`bpy.types.Mesh.polygons` +* :class:`bpy.types.Mesh.tessface_uv_textures` +* :class:`bpy.types.Mesh.tessface_vertex_colors` +* :class:`bpy.types.Mesh.tessfaces` +* :class:`bpy.types.Mesh.unit_test_compare` +* :class:`bpy.types.Mesh.uv_layer_clone` +* :class:`bpy.types.Mesh.uv_layer_clone_index` +* :class:`bpy.types.Mesh.uv_layer_stencil` +* :class:`bpy.types.Mesh.uv_layer_stencil_index` +* :class:`bpy.types.Mesh.uv_layers` + +Removed +^^^^^^^ + +* **faces** +* **layers_float** +* **layers_string** + +Renamed +^^^^^^^ + +* **layers_int** -> :class:`bpy.types.Mesh.polygon_layers_float` +* **layers_int** -> :class:`bpy.types.Mesh.polygon_layers_int` +* **layers_int** -> :class:`bpy.types.Mesh.polygon_layers_string` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.Mesh.update` (calc_edges, calc_tessface), *was (calc_edges)* + +bpy.types.Key +------------- + +Added +^^^^^ + +* :class:`bpy.types.Key.eval_time` + +bpy.types.LatticeModifier +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.LatticeModifier.strength` + +bpy.types.UserPreferencesView +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesView.quit_dialog` + + +2.63 to 2.64 +============ + +bpy.types.CyclesLampSettings +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CyclesLampSettings.samples` + +bpy.types.Histogram +------------------- + +Added +^^^^^ + +* :class:`bpy.types.Histogram.show_line` + +bpy.types.ThemeView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeView3D.bone_pose_active` +* :class:`bpy.types.ThemeView3D.skin_root` + +bpy.types.GameObjectSettings +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.GameObjectSettings.fall_speed` +* :class:`bpy.types.GameObjectSettings.jump_speed` +* :class:`bpy.types.GameObjectSettings.step_height` + + +bpy.types.BlendData +------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendData.masks` + + +bpy.types.TextureNodeMixRGB +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodeMixRGB.use_clamp` + +bpy.types.SmokeCollSettings +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SmokeCollSettings.collision_type` + +bpy.types.CompositorNodes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodes.active` + +bpy.types.RenderEngine +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderEngine.resolution_x` +* :class:`bpy.types.RenderEngine.resolution_y` +* :class:`bpy.types.RenderEngine.tile_x` +* :class:`bpy.types.RenderEngine.tile_y` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.RenderEngine.begin_result` (x, y, w, h, layer), *was (x, y, w, h)* +* :class:`bpy.types.RenderEngine.end_result` (result, cancel), *was (result)* + +bpy.types.BackgroundImage +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BackgroundImage.draw_depth` +* :class:`bpy.types.BackgroundImage.frame_method` + +bpy.types.SmokeDomainSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SmokeDomainSettings.cell_size` +* :class:`bpy.types.SmokeDomainSettings.density` +* :class:`bpy.types.SmokeDomainSettings.domain_resolution` +* :class:`bpy.types.SmokeDomainSettings.scale` +* :class:`bpy.types.SmokeDomainSettings.start_point` + +bpy.types.CyclesRenderSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesRenderSettings.aa_samples` +* :class:`bpy.types.CyclesRenderSettings.ao_samples` +* :class:`bpy.types.CyclesRenderSettings.blur_glossy` +* :class:`bpy.types.CyclesRenderSettings.diffuse_samples` +* :class:`bpy.types.CyclesRenderSettings.glossy_samples` +* :class:`bpy.types.CyclesRenderSettings.mesh_light_samples` +* :class:`bpy.types.CyclesRenderSettings.preview_aa_samples` +* :class:`bpy.types.CyclesRenderSettings.preview_start_resolution` +* :class:`bpy.types.CyclesRenderSettings.progressive` +* :class:`bpy.types.CyclesRenderSettings.transmission_samples` + +Removed +^^^^^^^ + +* **blur_caustics** +* **debug_min_size** + +bpy.types.ActionGroup +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ActionGroup.color_set` +* :class:`bpy.types.ActionGroup.colors` + +Removed +^^^^^^^ + +* **custom_color** + +bpy.types.WipeSequence +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.WipeSequence.input_1` +* :class:`bpy.types.WipeSequence.input_count` + +bpy.types.ToolSettings +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.ToolSettings.snap_node_element` +* :class:`bpy.types.ToolSettings.use_proportional_edit_mask` + +bpy.types.ThemeClipEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeClipEditor.space_list` +* :class:`bpy.types.ThemeClipEditor.strips` +* :class:`bpy.types.ThemeClipEditor.strips_selected` + +bpy.types.Image +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Image.colorspace_settings` +* :class:`bpy.types.Image.frame_duration` +* :class:`bpy.types.Image.gl_touch` +* :class:`bpy.types.Image.scale` +* :class:`bpy.types.Image.view_as_render` + + +bpy.types.ThemeDopeSheet +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.ThemeDopeSheet.summary` + +bpy.types.MovieClipUser +----------------------- + +Renamed +^^^^^^^ + +* **current_frame** -> :class:`bpy.types.MovieClipUser.frame_current` + +bpy.types.TransformSequence +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TransformSequence.input_1` +* :class:`bpy.types.TransformSequence.input_count` + +bpy.types.ImageSequence +----------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.DupliObject +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.DupliObject.index` +* :class:`bpy.types.DupliObject.particle_index` + +bpy.types.RenderSettings +------------------------ + +Removed +^^^^^^^ + +* **use_color_management** +* **use_radiosity** + +bpy.types.Curve +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Curve.bevel_factor_end` +* :class:`bpy.types.Curve.bevel_factor_start` + +bpy.types.MovieClip +------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieClip.colorspace_settings` +* :class:`bpy.types.MovieClip.frame_duration` +* :class:`bpy.types.MovieClip.frame_offset` +* :class:`bpy.types.MovieClip.frame_start` + +bpy.types.CompositorNodeTree +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeTree.chunk_size` +* :class:`bpy.types.CompositorNodeTree.edit_quality` +* :class:`bpy.types.CompositorNodeTree.render_quality` +* :class:`bpy.types.CompositorNodeTree.two_pass` +* :class:`bpy.types.CompositorNodeTree.use_opencl` + +bpy.types.SpaceUVEditor +----------------------- + +Removed +^^^^^^^ + +* **cursor_location** +* **pivot_point** + +bpy.types.RemeshModifier +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.RemeshModifier.use_smooth_shade` + +bpy.types.CurveMapping +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.CurveMapping.update` + +bpy.types.CompositorNodeMixRGB +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeMixRGB.use_clamp` + +bpy.types.ParticleSettings +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ParticleSettings.use_scale_dupli` + +bpy.types.SceneGameData +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SceneGameData.deactivation_angular_threshold` +* :class:`bpy.types.SceneGameData.deactivation_linear_threshold` +* :class:`bpy.types.SceneGameData.deactivation_time` + +bpy.types.SoundSequence +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SoundSequence.show_waveform` + +bpy.types.Scene +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Scene.display_settings` +* :class:`bpy.types.Scene.sequence_editor_clear` +* :class:`bpy.types.Scene.sequence_editor_create` +* :class:`bpy.types.Scene.sequencer_colorspace_settings` +* :class:`bpy.types.Scene.view_settings` + +Removed +^^^^^^^ + +* **collada_export** + +bpy.types.Armature +------------------ + +Removed +^^^^^^^ + +* **use_deform_envelopes** +* **use_deform_preserve_volume** +* **use_deform_vertex_groups** + +bpy.types.MeshUVLoopLayer +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MeshUVLoopLayer.name` + +bpy.types.CurveMap +------------------ + +Added +^^^^^ + +* :class:`bpy.types.CurveMap.evaluate` + +bpy.types.ShaderNodeTexEnvironment +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexEnvironment.image_user` + +bpy.types.SolidifyModifier +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SolidifyModifier.use_flip_normals` + +bpy.types.TextureNodeMath +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodeMath.use_clamp` + +bpy.types.SceneRenderLayer +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SceneRenderLayer.layers_exclude` +* :class:`bpy.types.SceneRenderLayer.samples` + +bpy.types.CompositorNodeViewer +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeViewer.center_x` +* :class:`bpy.types.CompositorNodeViewer.center_y` +* :class:`bpy.types.CompositorNodeViewer.tile_order` + +bpy.types.ClothCollisionSettings +-------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ClothCollisionSettings.vertex_group_self_collisions` + +bpy.types.SpeedControlSequence +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.SpeedControlSequence.input_1` +* :class:`bpy.types.SpeedControlSequence.input_count` + +bpy.types.ActionConstraint +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ActionConstraint.use_bone_object_action` + +bpy.types.CompositorNodeScale +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeScale.frame_method` +* :class:`bpy.types.CompositorNodeScale.offset_x` +* :class:`bpy.types.CompositorNodeScale.offset_y` + +bpy.types.SpaceDopeSheetEditor +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.SpaceDopeSheetEditor.show_group_colors` + +bpy.types.MetaSequence +---------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.ShaderNodeMixRGB +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeMixRGB.use_clamp` + +bpy.types.FollowTrackConstraint +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.FollowTrackConstraint.frame_method` + +bpy.types.EffectSequence +------------------------ + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.ThemeNLAEditor +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.ThemeNLAEditor.active_action` +* :class:`bpy.types.ThemeNLAEditor.active_action_unset` +* :class:`bpy.types.ThemeNLAEditor.meta_strips` +* :class:`bpy.types.ThemeNLAEditor.meta_strips_selected` +* :class:`bpy.types.ThemeNLAEditor.sound_strips` +* :class:`bpy.types.ThemeNLAEditor.sound_strips_selected` +* :class:`bpy.types.ThemeNLAEditor.transition_strips` +* :class:`bpy.types.ThemeNLAEditor.transition_strips_selected` +* :class:`bpy.types.ThemeNLAEditor.tweak` +* :class:`bpy.types.ThemeNLAEditor.tweak_duplicate` + +Removed +^^^^^^^ + +* **bars** +* **bars_selected** + +bpy.types.SculptCapabilities +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SculptCapabilities.has_overlay` +* :class:`bpy.types.SculptCapabilities.has_texture_angle` +* :class:`bpy.types.SculptCapabilities.has_texture_angle_source` + +bpy.types.ImageFormatSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ImageFormatSettings.display_settings` +* :class:`bpy.types.ImageFormatSettings.view_settings` + + +bpy.types.Property +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Property.is_library_editable` + +bpy.types.MovieTrackingTrack +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingTrack.grease_pencil` +* :class:`bpy.types.MovieTrackingTrack.motion_model` +* :class:`bpy.types.MovieTrackingTrack.use_alpha_preview` +* :class:`bpy.types.MovieTrackingTrack.use_brute` +* :class:`bpy.types.MovieTrackingTrack.use_mask` +* :class:`bpy.types.MovieTrackingTrack.use_normalization` + +Removed +^^^^^^^ + +* **pattern_max** +* **pattern_min** +* **pyramid_levels** +* **search_max** +* **search_min** +* **tracker** + +bpy.types.CompositorNodeBlur +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeBlur.use_variable_size` + +bpy.types.Object +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Object.dm_info` +* :class:`bpy.types.Object.is_deform_modified` +* :class:`bpy.types.Object.layers_local_view` + +Renamed +^^^^^^^ + +* **animation_visualisation** -> :class:`bpy.types.Object.animation_visualization` + +bpy.types.UserPreferencesSystem +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesSystem.use_gpu_mipmap` + +Removed +^^^^^^^ + +* **compute_device** +* **compute_device_type** + +bpy.types.Sequence +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Sequence.modifiers` +* :class:`bpy.types.Sequence.use_linear_modifiers` + +Removed +^^^^^^^ + +* **input_1** +* **input_2** +* **input_3** +* **input_count** +* **waveform** + +bpy.types.ConsoleLine +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ConsoleLine.type` + +bpy.types.Region +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Region.view2d` +* :class:`bpy.types.Region.x` +* :class:`bpy.types.Region.y` + +bpy.types.SpaceClipEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceClipEditor.grease_pencil_source` +* :class:`bpy.types.SpaceClipEditor.mask` +* :class:`bpy.types.SpaceClipEditor.mask_draw_type` +* :class:`bpy.types.SpaceClipEditor.pivot_point` +* :class:`bpy.types.SpaceClipEditor.show_graph_hidden` +* :class:`bpy.types.SpaceClipEditor.show_graph_only_selected` +* :class:`bpy.types.SpaceClipEditor.show_mask_smooth` +* :class:`bpy.types.SpaceClipEditor.show_seconds` + +bpy.types.NodeSocket +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.NodeSocket.hide` +* :class:`bpy.types.NodeSocket.is_linked` + +bpy.types.MovieClipSequence +--------------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.Node +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Node.color` +* :class:`bpy.types.Node.hide` +* :class:`bpy.types.Node.mute` +* :class:`bpy.types.Node.select` +* :class:`bpy.types.Node.show_options` +* :class:`bpy.types.Node.show_preview` +* :class:`bpy.types.Node.use_custom_color` + +bpy.types.SceneSequence +----------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.CompositorNodeOutputFile +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeOutputFile.file_slots` +* :class:`bpy.types.CompositorNodeOutputFile.layer_slots` + +Removed +^^^^^^^ + +* **active_input** + +bpy.types.ObjectBase +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.ObjectBase.layers_local_view` + +bpy.types.CyclesCameraSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesCameraSettings.fisheye_fov` +* :class:`bpy.types.CyclesCameraSettings.fisheye_lens` +* :class:`bpy.types.CyclesCameraSettings.panorama_type` + +bpy.types.CompositorNodeDefocus +------------------------------- + +Removed +^^^^^^^ + +* **samples** + +bpy.types.KeyMapItems +--------------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.KeyMapItems.new` (idname, type, value, any, shift, ctrl, alt, oskey, key_modifier, head), *was (idname, type, value, any, shift, ctrl, alt, oskey, key_modifier)* + +bpy.types.CollisionSettings +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CollisionSettings.stickiness` + +Removed +^^^^^^^ + +* **stickness** + +bpy.types.GlowSequence +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.GlowSequence.input_1` +* :class:`bpy.types.GlowSequence.input_count` + +bpy.types.MouseSensor +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.MouseSensor.use_pulse` + +bpy.types.MovieSequence +----------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.Pose +-------------- + +Renamed +^^^^^^^ + +* **animation_visualisation** -> :class:`bpy.types.Pose.animation_visualization` + +bpy.types.ThemeSequenceEditor +----------------------------- + +Removed +^^^^^^^ + +* **plugin_strip** + +bpy.types.IMAGE_UV_sculpt +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.IMAGE_UV_sculpt.prop_unified_weight` + +bpy.types.SpaceImageEditor +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceImageEditor.cursor_location` +* :class:`bpy.types.SpaceImageEditor.mask` +* :class:`bpy.types.SpaceImageEditor.mask_draw_type` +* :class:`bpy.types.SpaceImageEditor.mode` +* :class:`bpy.types.SpaceImageEditor.pivot_point` +* :class:`bpy.types.SpaceImageEditor.show_mask_smooth` +* :class:`bpy.types.SpaceImageEditor.show_maskedit` + +Removed +^^^^^^^ + +* **curve** +* **use_grease_pencil** +* **use_image_paint** + +bpy.types.UserPreferencesFilePaths +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesFilePaths.i18n_branches_directory` + +Removed +^^^^^^^ + +* **sequence_plugin_directory** +* **texture_plugin_directory** + +bpy.types.CompositorNodeDilateErode +----------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeDilateErode.edge` +* :class:`bpy.types.CompositorNodeDilateErode.falloff` +* :class:`bpy.types.CompositorNodeDilateErode.type` + +bpy.types.ScrewModifier +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.ScrewModifier.use_smooth_shade` + +bpy.types.SpaceNodeEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceNodeEditor.cursor_location` +* :class:`bpy.types.SpaceNodeEditor.edit_tree` +* :class:`bpy.types.SpaceNodeEditor.show_highlight` +* :class:`bpy.types.SpaceNodeEditor.use_hidden_preview` + +bpy.types.SpaceView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceView3D.layers_local_view` +* :class:`bpy.types.SpaceView3D.show_backface_culling` + +bpy.types.Area +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Area.x` +* :class:`bpy.types.Area.y` + +bpy.types.RenderLayer +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderLayer.layers_exclude` + +bpy.types.MovieTracking +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTracking.dopesheet` + +bpy.types.MovieTrackingSettings +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingSettings.default_motion_model` +* :class:`bpy.types.MovieTrackingSettings.use_default_brute` +* :class:`bpy.types.MovieTrackingSettings.use_default_mask` +* :class:`bpy.types.MovieTrackingSettings.use_default_normalization` +* :class:`bpy.types.MovieTrackingSettings.use_tripod_solver` + +Removed +^^^^^^^ + +* **default_pyramid_levels** +* **default_tracker** + +bpy.types.CompositorNodeIDMask +------------------------------ + +Renamed +^^^^^^^ + +* **use_smooth_mask** -> :class:`bpy.types.CompositorNodeIDMask.use_antialiasing` + +bpy.types.UserPreferencesInput +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesInput.ndof_orbit_sensitivity` +* :class:`bpy.types.UserPreferencesInput.ndof_view_rotate_method` + +bpy.types.Brush +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Brush.mask_tool` +* :class:`bpy.types.Brush.weight` + +bpy.types.SpaceSequenceEditor +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceSequenceEditor.overlay_type` + +Removed +^^^^^^^ + +* **use_grease_pencil** + +bpy.types.MovieTrackingMarkers +------------------------------ + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.MovieTrackingMarkers.find_frame` (frame, exact), *was (frame)* + +bpy.types.UILayout +------------------ + +Added +^^^^^ + +* :class:`bpy.types.UILayout.template_colormanaged_view_settings` +* :class:`bpy.types.UILayout.template_colorspace_settings` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.UILayout.template_image_settings` (image_settings, color_management), *was (image_settings)* + +bpy.types.ID +------------ + +Added +^^^^^ + +* :class:`bpy.types.ID.is_library_indirect` + +bpy.types.SpaceGraphEditor +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceGraphEditor.show_group_colors` + +bpy.types.Mesh +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Mesh.skin_vertices` + +Removed +^^^^^^^ + +* **sticky** + +bpy.types.ShaderNodes +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodes.active` + +bpy.types.ColorSequence +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.ColorSequence.input_count` + +bpy.types.ShaderNodeMath +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeMath.use_clamp` + +bpy.types.Paint +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Paint.input_samples` + +bpy.types.ShaderNodeTexImage +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexImage.image_user` +* :class:`bpy.types.ShaderNodeTexImage.projection` +* :class:`bpy.types.ShaderNodeTexImage.projection_blend` + +bpy.types.UserPreferencesView +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesView.use_mouse_depth_cursor` + +Renamed +^^^^^^^ + +* **use_mouse_auto_depth** -> :class:`bpy.types.UserPreferencesView.use_mouse_depth_navigate` + +bpy.types.CompositorNodeMath +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeMath.use_clamp` + +bpy.types.Material +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Material.use_uv_project` + +bpy.types.ThemeNodeEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeNodeEditor.frame_node` +* :class:`bpy.types.ThemeNodeEditor.node_active` +* :class:`bpy.types.ThemeNodeEditor.node_selected` + +bpy.types.Camera +---------------- + +Removed +^^^^^^^ + +* **use_panorama** + +bpy.types.UnifiedPaintSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.UnifiedPaintSettings.use_unified_weight` +* :class:`bpy.types.UnifiedPaintSettings.weight` + +bpy.types.TextureNodes +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodes.active` + +bpy.types.MovieTrackingMarker +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingMarker.pattern_bound_box` +* :class:`bpy.types.MovieTrackingMarker.pattern_corners` +* :class:`bpy.types.MovieTrackingMarker.search_max` +* :class:`bpy.types.MovieTrackingMarker.search_min` + +bpy.types.CyclesWorldSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CyclesWorldSettings.samples` + +bpy.types.LatticePoint +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.LatticePoint.select` diff --git a/doc/python_api/sphinx_changelog_gen.py b/doc/python_api/sphinx_changelog_gen.py index 3ded1035123..afc253940d4 100644 --- a/doc/python_api/sphinx_changelog_gen.py +++ b/doc/python_api/sphinx_changelog_gen.py @@ -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 diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 24223ad1ad0..bd2f3e8e3bf 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -400,7 +400,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']: diff --git a/extern/Eigen3/Eigen/Cholesky b/extern/Eigen3/Eigen/Cholesky index 53f7bf911a4..f727f5d89c0 100644 --- a/extern/Eigen3/Eigen/Cholesky +++ b/extern/Eigen3/Eigen/Cholesky @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup Cholesky_Module Cholesky module * * @@ -24,8 +22,9 @@ namespace Eigen { #include "src/misc/Solve.h" #include "src/Cholesky/LLT.h" #include "src/Cholesky/LDLT.h" - -} // namespace Eigen +#ifdef EIGEN_USE_LAPACKE +#include "src/Cholesky/LLT_MKL.h" +#endif #include "src/Core/util/ReenableStupidWarnings.h" diff --git a/extern/Eigen3/Eigen/CholmodSupport b/extern/Eigen3/Eigen/CholmodSupport new file mode 100644 index 00000000000..745b884e74d --- /dev/null +++ b/extern/Eigen3/Eigen/CholmodSupport @@ -0,0 +1,45 @@ +#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H +#define EIGEN_CHOLMODSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { + #include <cholmod.h> +} + +/** \ingroup Support_modules + * \defgroup CholmodSupport_Module CholmodSupport module + * + * This module provides an interface to the Cholmod library which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package. + * It provides the two following main factorization classes: + * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. + * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). + * + * For the sake of completeness, this module also propose the two following classes: + * - class CholmodSimplicialLLT + * - class CholmodSimplicialLDLT + * Note that these classes does not bring any particular advantage compared to the built-in + * SimplicialLLT and SimplicialLDLT factorization classes. + * + * \code + * #include <Eigen/CholmodSupport> + * \endcode + * + * In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be linked to the cholmod library and its dependencies. + * The dependencies depend on how cholmod has been compiled. + * For a cmake based project, you can use our FindCholmod.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/CholmodSupport/CholmodSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_CHOLMODSUPPORT_MODULE_H + diff --git a/extern/Eigen3/Eigen/Core b/extern/Eigen3/Eigen/Core index a5025e37ead..d4801702261 100644 --- a/extern/Eigen3/Eigen/Core +++ b/extern/Eigen3/Eigen/Core @@ -4,24 +4,9 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CORE_H #define EIGEN_CORE_H @@ -34,6 +19,12 @@ // defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization. #include "src/Core/util/Macros.h" +#include <complex> + +// this include file manages BLAS and MKL related macros +// and inclusion of their respective header files +#include "src/Core/util/MKL_support.h" + // if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into // account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks #if !EIGEN_ALIGN @@ -136,7 +127,7 @@ #endif // MSVC for windows mobile does not have the errno.h file -#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) +#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION) #define EIGEN_HAS_ERRNO #endif @@ -146,7 +137,6 @@ #include <cstddef> #include <cstdlib> #include <cmath> -#include <complex> #include <cassert> #include <functional> #include <iosfwd> @@ -175,9 +165,6 @@ #include <new> #endif -// defined in bits/termios.h -#undef B0 - /** \brief Namespace containing all symbols from the %Eigen library. */ namespace Eigen { @@ -201,6 +188,8 @@ inline static const char *SimdInstructionSetsInUse(void) { #endif } +} // end namespace Eigen + #define STAGE10_FULL_EIGEN2_API 10 #define STAGE20_RESOLVE_API_CONFLICTS 20 #define STAGE30_FULL_EIGEN3_API 30 @@ -247,6 +236,10 @@ using std::ptrdiff_t; * \endcode */ +/** \defgroup Support_modules Support modules [category] + * Category of modules which add support for external libraries. + */ + #include "src/Core/util/Constants.h" #include "src/Core/util/ForwardDeclarations.h" #include "src/Core/util/Meta.h" @@ -318,15 +311,15 @@ using std::ptrdiff_t; #include "src/Core/CommaInitializer.h" #include "src/Core/Flagged.h" #include "src/Core/ProductBase.h" -#include "src/Core/Product.h" +#include "src/Core/GeneralProduct.h" #include "src/Core/TriangularMatrix.h" #include "src/Core/SelfAdjointView.h" -#include "src/Core/SolveTriangular.h" +#include "src/Core/products/GeneralBlockPanelKernel.h" #include "src/Core/products/Parallelizer.h" #include "src/Core/products/CoeffBasedProduct.h" -#include "src/Core/products/GeneralBlockPanelKernel.h" #include "src/Core/products/GeneralMatrixVector.h" #include "src/Core/products/GeneralMatrixMatrix.h" +#include "src/Core/SolveTriangular.h" #include "src/Core/products/GeneralMatrixMatrixTriangular.h" #include "src/Core/products/SelfadjointMatrixVector.h" #include "src/Core/products/SelfadjointMatrixMatrix.h" @@ -347,7 +340,20 @@ using std::ptrdiff_t; #include "src/Core/ArrayBase.h" #include "src/Core/ArrayWrapper.h" -} // namespace Eigen +#ifdef EIGEN_USE_BLAS +#include "src/Core/products/GeneralMatrixMatrix_MKL.h" +#include "src/Core/products/GeneralMatrixVector_MKL.h" +#include "src/Core/products/GeneralMatrixMatrixTriangular_MKL.h" +#include "src/Core/products/SelfadjointMatrixMatrix_MKL.h" +#include "src/Core/products/SelfadjointMatrixVector_MKL.h" +#include "src/Core/products/TriangularMatrixMatrix_MKL.h" +#include "src/Core/products/TriangularMatrixVector_MKL.h" +#include "src/Core/products/TriangularSolverMatrix_MKL.h" +#endif // EIGEN_USE_BLAS + +#ifdef EIGEN_USE_MKL_VML +#include "src/Core/Assign_MKL.h" +#endif #include "src/Core/GlobalFunctions.h" diff --git a/extern/Eigen3/Eigen/Eigen2Support b/extern/Eigen3/Eigen/Eigen2Support index d96592a8de9..36156d29a92 100644 --- a/extern/Eigen3/Eigen/Eigen2Support +++ b/extern/Eigen3/Eigen/Eigen2Support @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2SUPPORT_H #define EIGEN2SUPPORT_H @@ -31,9 +16,8 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - -/** \defgroup Eigen2Support_Module Eigen2 support module +/** \ingroup Support_modules + * \defgroup Eigen2Support_Module Eigen2 support module * This module provides a couple of deprecated functions improving the compatibility with Eigen2. * * To use it, define EIGEN2_SUPPORT before including any Eigen header @@ -56,13 +40,29 @@ namespace Eigen { #include "src/Eigen2Support/MathFunctions.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" // Eigen2 used to include iostream #include<iostream> +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_MATRIX_TYPEDEFS \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) + #define USING_PART_OF_NAMESPACE_EIGEN \ EIGEN_USING_MATRIX_TYPEDEFS \ using Eigen::Matrix; \ diff --git a/extern/Eigen3/Eigen/Eigenvalues b/extern/Eigen3/Eigen/Eigenvalues index 250c0f46652..af99ccd1fab 100644 --- a/extern/Eigen3/Eigen/Eigenvalues +++ b/extern/Eigen3/Eigen/Eigenvalues @@ -9,8 +9,7 @@ #include "Jacobi" #include "Householder" #include "LU" - -namespace Eigen { +#include "Geometry" /** \defgroup Eigenvalues_Module Eigenvalues module * @@ -35,8 +34,11 @@ namespace Eigen { #include "src/Eigenvalues/ComplexSchur.h" #include "src/Eigenvalues/ComplexEigenSolver.h" #include "src/Eigenvalues/MatrixBaseEigenvalues.h" - -} // namespace Eigen +#ifdef EIGEN_USE_LAPACKE +#include "src/Eigenvalues/RealSchur_MKL.h" +#include "src/Eigenvalues/ComplexSchur_MKL.h" +#include "src/Eigenvalues/SelfAdjointEigenSolver_MKL.h" +#endif #include "src/Core/util/ReenableStupidWarnings.h" diff --git a/extern/Eigen3/Eigen/Geometry b/extern/Eigen3/Eigen/Geometry index 78277c0c560..efd9d4504cb 100644 --- a/extern/Eigen3/Eigen/Geometry +++ b/extern/Eigen3/Eigen/Geometry @@ -13,8 +13,6 @@ #define M_PI 3.14159265358979323846 #endif -namespace Eigen { - /** \defgroup Geometry_Module Geometry module * * @@ -58,8 +56,6 @@ namespace Eigen { #include "src/Eigen2Support/Geometry/All.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_GEOMETRY_MODULE_H diff --git a/extern/Eigen3/Eigen/Householder b/extern/Eigen3/Eigen/Householder index 6b86cf65c55..6e348db5c43 100644 --- a/extern/Eigen3/Eigen/Householder +++ b/extern/Eigen3/Eigen/Householder @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup Householder_Module Householder module * This module provides Householder transformations. * @@ -19,8 +17,6 @@ namespace Eigen { #include "src/Householder/HouseholderSequence.h" #include "src/Householder/BlockHouseholder.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_HOUSEHOLDER_MODULE_H diff --git a/extern/Eigen3/Eigen/IterativeLinearSolvers b/extern/Eigen3/Eigen/IterativeLinearSolvers new file mode 100644 index 00000000000..315c2dd1ee7 --- /dev/null +++ b/extern/Eigen3/Eigen/IterativeLinearSolvers @@ -0,0 +1,40 @@ +#ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H +#define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Sparse_modules + * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module + * + * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse. + * Those solvers are accessible via the following classes: + * - ConjugateGradient for selfadjoint (hermitian) matrices, + * - BiCGSTAB for general square matrices. + * + * These iterative solvers are associated with some preconditioners: + * - IdentityPreconditioner - not really useful + * - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices. + * - IncompleteILUT - incomplete LU factorization with dual thresholding + * + * Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport. + * + * \code + * #include <Eigen/IterativeLinearSolvers> + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/IterativeLinearSolvers/IterativeSolverBase.h" +#include "src/IterativeLinearSolvers/BasicPreconditioners.h" +#include "src/IterativeLinearSolvers/ConjugateGradient.h" +#include "src/IterativeLinearSolvers/BiCGSTAB.h" +#include "src/IterativeLinearSolvers/IncompleteLUT.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H diff --git a/extern/Eigen3/Eigen/Jacobi b/extern/Eigen3/Eigen/Jacobi index afa67681379..ba8a4dc36a5 100644 --- a/extern/Eigen3/Eigen/Jacobi +++ b/extern/Eigen3/Eigen/Jacobi @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup Jacobi_Module Jacobi module * This module provides Jacobi and Givens rotations. * @@ -21,8 +19,6 @@ namespace Eigen { #include "src/Jacobi/Jacobi.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_JACOBI_MODULE_H diff --git a/extern/Eigen3/Eigen/LU b/extern/Eigen3/Eigen/LU index 226f88ca38a..db579550448 100644 --- a/extern/Eigen3/Eigen/LU +++ b/extern/Eigen3/Eigen/LU @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup LU_Module LU module * This module includes %LU decomposition and related notions such as matrix inversion and determinant. * This module defines the following MatrixBase methods: @@ -23,6 +21,9 @@ namespace Eigen { #include "src/misc/Image.h" #include "src/LU/FullPivLU.h" #include "src/LU/PartialPivLU.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/LU/PartialPivLU_MKL.h" +#endif #include "src/LU/Determinant.h" #include "src/LU/Inverse.h" @@ -34,8 +35,6 @@ namespace Eigen { #include "src/Eigen2Support/LU.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_LU_MODULE_H diff --git a/extern/Eigen3/Eigen/LeastSquares b/extern/Eigen3/Eigen/LeastSquares index 93a6302dcd9..35137c25db0 100644 --- a/extern/Eigen3/Eigen/LeastSquares +++ b/extern/Eigen3/Eigen/LeastSquares @@ -15,8 +15,6 @@ #include "Eigenvalues" #include "Geometry" -namespace Eigen { - /** \defgroup LeastSquares_Module LeastSquares module * This module provides linear regression and related features. * @@ -27,8 +25,6 @@ namespace Eigen { #include "src/Eigen2Support/LeastSquares.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN2_SUPPORT diff --git a/extern/Eigen3/Eigen/OrderingMethods b/extern/Eigen3/Eigen/OrderingMethods new file mode 100644 index 00000000000..1e2d87452e5 --- /dev/null +++ b/extern/Eigen3/Eigen/OrderingMethods @@ -0,0 +1,23 @@ +#ifndef EIGEN_ORDERINGMETHODS_MODULE_H +#define EIGEN_ORDERINGMETHODS_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Sparse_modules + * \defgroup OrderingMethods_Module OrderingMethods module + * + * This module is currently for internal use only. + * + * + * \code + * #include <Eigen/OrderingMethods> + * \endcode + */ + +#include "src/OrderingMethods/Amd.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ORDERINGMETHODS_MODULE_H diff --git a/extern/Eigen3/Eigen/PaStiXSupport b/extern/Eigen3/Eigen/PaStiXSupport new file mode 100644 index 00000000000..7c616ee5eac --- /dev/null +++ b/extern/Eigen3/Eigen/PaStiXSupport @@ -0,0 +1,46 @@ +#ifndef EIGEN_PASTIXSUPPORT_MODULE_H +#define EIGEN_PASTIXSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include <complex.h> +extern "C" { +#include <pastix_nompi.h> +#include <pastix.h> +} + +#ifdef complex +#undef complex +#endif + +/** \ingroup Support_modules + * \defgroup PaStiXSupport_Module PaStiXSupport module + * + * This module provides an interface to the <a href="http://pastix.gforge.inria.fr/">PaSTiX</a> library. + * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver. + * It provides the two following main factorization classes: + * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization. + * - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization. + * - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern). + * + * \code + * #include <Eigen/PaStiXSupport> + * \endcode + * + * In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies. + * The dependencies depend on how PaSTiX has been compiled. + * For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/PaStiXSupport/PaStiXSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PASTIXSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/PardisoSupport b/extern/Eigen3/Eigen/PardisoSupport new file mode 100644 index 00000000000..99330ce7a7d --- /dev/null +++ b/extern/Eigen3/Eigen/PardisoSupport @@ -0,0 +1,30 @@ +#ifndef EIGEN_PARDISOSUPPORT_MODULE_H +#define EIGEN_PARDISOSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include <mkl_pardiso.h> + +#include <unsupported/Eigen/SparseExtra> + +/** \ingroup Support_modules + * \defgroup PardisoSupport_Module PardisoSupport module + * + * This module brings support for the Intel(R) MKL PARDISO direct sparse solvers. + * + * \code + * #include <Eigen/PardisoSupport> + * \endcode + * + * In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be linked to the MKL library and its dependencies. + * See this \ref TopicUsingIntelMKL "page" for more information on MKL-Eigen integration. + * + */ + +#include "src/PardisoSupport/PardisoSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PARDISOSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/QR b/extern/Eigen3/Eigen/QR index 97c1788ee30..ac5b0269354 100644 --- a/extern/Eigen3/Eigen/QR +++ b/extern/Eigen3/Eigen/QR @@ -9,8 +9,6 @@ #include "Jacobi" #include "Householder" -namespace Eigen { - /** \defgroup QR_Module QR module * * @@ -28,13 +26,15 @@ namespace Eigen { #include "src/QR/HouseholderQR.h" #include "src/QR/FullPivHouseholderQR.h" #include "src/QR/ColPivHouseholderQR.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/QR/HouseholderQR_MKL.h" +#include "src/QR/ColPivHouseholderQR_MKL.h" +#endif #ifdef EIGEN2_SUPPORT #include "src/Eigen2Support/QR.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #ifdef EIGEN2_SUPPORT diff --git a/extern/Eigen3/Eigen/SVD b/extern/Eigen3/Eigen/SVD index 7c987a9dd36..fd310017ad1 100644 --- a/extern/Eigen3/Eigen/SVD +++ b/extern/Eigen3/Eigen/SVD @@ -7,8 +7,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup SVD_Module SVD module * * @@ -24,14 +22,15 @@ namespace Eigen { #include "src/misc/Solve.h" #include "src/SVD/JacobiSVD.h" +#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) +#include "src/SVD/JacobiSVD_MKL.h" +#endif #include "src/SVD/UpperBidiagonalization.h" #ifdef EIGEN2_SUPPORT #include "src/Eigen2Support/SVD.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_SVD_MODULE_H diff --git a/extern/Eigen3/Eigen/Sparse b/extern/Eigen3/Eigen/Sparse index 7425b3a412a..2d1757172eb 100644 --- a/extern/Eigen3/Eigen/Sparse +++ b/extern/Eigen3/Eigen/Sparse @@ -1,69 +1,23 @@ #ifndef EIGEN_SPARSE_MODULE_H #define EIGEN_SPARSE_MODULE_H -#include "Core" - -#include "src/Core/util/DisableStupidWarnings.h" - -#include <vector> -#include <map> -#include <cstdlib> -#include <cstring> -#include <algorithm> - -#ifdef EIGEN2_SUPPORT -#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET -#endif - -#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET -#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token. -#endif - -namespace Eigen { - -/** \defgroup Sparse_Module Sparse module +/** \defgroup Sparse_modules Sparse modules * - * - * - * See the \ref TutorialSparse "Sparse tutorial" + * Meta-module including all related modules: + * - SparseCore + * - OrderingMethods + * - SparseCholesky + * - IterativeLinearSolvers * * \code * #include <Eigen/Sparse> * \endcode */ -/** The type used to identify a general sparse storage. */ -struct Sparse {}; - -#include "src/Sparse/SparseUtil.h" -#include "src/Sparse/SparseMatrixBase.h" -#include "src/Sparse/CompressedStorage.h" -#include "src/Sparse/AmbiVector.h" -#include "src/Sparse/SparseMatrix.h" -#include "src/Sparse/DynamicSparseMatrix.h" -#include "src/Sparse/MappedSparseMatrix.h" -#include "src/Sparse/SparseVector.h" -#include "src/Sparse/CoreIterators.h" -#include "src/Sparse/SparseBlock.h" -#include "src/Sparse/SparseTranspose.h" -#include "src/Sparse/SparseCwiseUnaryOp.h" -#include "src/Sparse/SparseCwiseBinaryOp.h" -#include "src/Sparse/SparseDot.h" -#include "src/Sparse/SparseAssign.h" -#include "src/Sparse/SparseRedux.h" -#include "src/Sparse/SparseFuzzy.h" -#include "src/Sparse/SparseProduct.h" -#include "src/Sparse/SparseSparseProduct.h" -#include "src/Sparse/SparseDenseProduct.h" -#include "src/Sparse/SparseDiagonalProduct.h" -#include "src/Sparse/SparseTriangularView.h" -#include "src/Sparse/SparseSelfAdjointView.h" -#include "src/Sparse/TriangularSolver.h" -#include "src/Sparse/SparseView.h" - -} // namespace Eigen - -#include "src/Core/util/ReenableStupidWarnings.h" +#include "SparseCore" +#include "OrderingMethods" +#include "SparseCholesky" +#include "IterativeLinearSolvers" #endif // EIGEN_SPARSE_MODULE_H diff --git a/extern/Eigen3/Eigen/SparseCholesky b/extern/Eigen3/Eigen/SparseCholesky new file mode 100644 index 00000000000..5f82742f7d8 --- /dev/null +++ b/extern/Eigen3/Eigen/SparseCholesky @@ -0,0 +1,30 @@ +#ifndef EIGEN_SPARSECHOLESKY_MODULE_H +#define EIGEN_SPARSECHOLESKY_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Sparse_modules + * \defgroup SparseCholesky_Module SparseCholesky module + * + * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices. + * Those decompositions are accessible via the following classes: + * - SimplicialLLt, + * - SimplicialLDLt + * + * Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module. + * + * \code + * #include <Eigen/SparseCholesky> + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/SparseCholesky/SimplicialCholesky.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECHOLESKY_MODULE_H diff --git a/extern/Eigen3/Eigen/SparseCore b/extern/Eigen3/Eigen/SparseCore new file mode 100644 index 00000000000..41d28c92824 --- /dev/null +++ b/extern/Eigen3/Eigen/SparseCore @@ -0,0 +1,66 @@ +#ifndef EIGEN_SPARSECORE_MODULE_H +#define EIGEN_SPARSECORE_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include <vector> +#include <map> +#include <cstdlib> +#include <cstring> +#include <algorithm> + +/** \ingroup Sparse_modules + * \defgroup SparseCore_Module SparseCore module + * + * This module provides a sparse matrix representation, and basic associatd matrix manipulations + * and operations. + * + * See the \ref TutorialSparse "Sparse tutorial" + * + * \code + * #include <Eigen/SparseCore> + * \endcode + * + * This module depends on: Core. + */ + +namespace Eigen { + +/** The type used to identify a general sparse storage. */ +struct Sparse {}; + +} + +#include "src/SparseCore/SparseUtil.h" +#include "src/SparseCore/SparseMatrixBase.h" +#include "src/SparseCore/CompressedStorage.h" +#include "src/SparseCore/AmbiVector.h" +#include "src/SparseCore/SparseMatrix.h" +#include "src/SparseCore/MappedSparseMatrix.h" +#include "src/SparseCore/SparseVector.h" +#include "src/SparseCore/CoreIterators.h" +#include "src/SparseCore/SparseBlock.h" +#include "src/SparseCore/SparseTranspose.h" +#include "src/SparseCore/SparseCwiseUnaryOp.h" +#include "src/SparseCore/SparseCwiseBinaryOp.h" +#include "src/SparseCore/SparseDot.h" +#include "src/SparseCore/SparsePermutation.h" +#include "src/SparseCore/SparseAssign.h" +#include "src/SparseCore/SparseRedux.h" +#include "src/SparseCore/SparseFuzzy.h" +#include "src/SparseCore/ConservativeSparseSparseProduct.h" +#include "src/SparseCore/SparseSparseProductWithPruning.h" +#include "src/SparseCore/SparseProduct.h" +#include "src/SparseCore/SparseDenseProduct.h" +#include "src/SparseCore/SparseDiagonalProduct.h" +#include "src/SparseCore/SparseTriangularView.h" +#include "src/SparseCore/SparseSelfAdjointView.h" +#include "src/SparseCore/TriangularSolver.h" +#include "src/SparseCore/SparseView.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECORE_MODULE_H + diff --git a/extern/Eigen3/Eigen/StdDeque b/extern/Eigen3/Eigen/StdDeque index a4f96232d8c..f27234778f4 100644 --- a/extern/Eigen3/Eigen/StdDeque +++ b/extern/Eigen3/Eigen/StdDeque @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDDEQUE_MODULE_H #define EIGEN_STDDEQUE_MODULE_H diff --git a/extern/Eigen3/Eigen/StdList b/extern/Eigen3/Eigen/StdList index d914ded4f93..225c1e18f8e 100644 --- a/extern/Eigen3/Eigen/StdList +++ b/extern/Eigen3/Eigen/StdList @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDLIST_MODULE_H #define EIGEN_STDLIST_MODULE_H diff --git a/extern/Eigen3/Eigen/StdVector b/extern/Eigen3/Eigen/StdVector index 3d8995e5aae..6b22627f6f6 100644 --- a/extern/Eigen3/Eigen/StdVector +++ b/extern/Eigen3/Eigen/StdVector @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDVECTOR_MODULE_H #define EIGEN_STDVECTOR_MODULE_H diff --git a/extern/Eigen3/Eigen/SuperLUSupport b/extern/Eigen3/Eigen/SuperLUSupport new file mode 100644 index 00000000000..575e14fbc29 --- /dev/null +++ b/extern/Eigen3/Eigen/SuperLUSupport @@ -0,0 +1,59 @@ +#ifndef EIGEN_SUPERLUSUPPORT_MODULE_H +#define EIGEN_SUPERLUSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#ifdef EMPTY +#define EIGEN_EMPTY_WAS_ALREADY_DEFINED +#endif + +typedef int int_t; +#include <slu_Cnames.h> +#include <supermatrix.h> +#include <slu_util.h> + +// slu_util.h defines a preprocessor token named EMPTY which is really polluting, +// so we remove it in favor of a SUPERLU_EMPTY token. +// If EMPTY was already defined then we don't undef it. + +#if defined(EIGEN_EMPTY_WAS_ALREADY_DEFINED) +# undef EIGEN_EMPTY_WAS_ALREADY_DEFINED +#elif defined(EMPTY) +# undef EMPTY +#endif + +#define SUPERLU_EMPTY (-1) + +namespace Eigen { struct SluMatrix; } + +/** \ingroup Support_modules + * \defgroup SuperLUSupport_Module SuperLUSupport module + * + * This module provides an interface to the <a href="http://crd-legacy.lbl.gov/~xiaoye/SuperLU/">SuperLU</a> library. + * It provides the following factorization class: + * - class SuperLU: a supernodal sequential LU factorization. + * - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative methods). + * + * \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting. + * + * \code + * #include <Eigen/SuperLUSupport> + * \endcode + * + * In order to use this module, the superlu headers must be accessible from the include paths, and your binary must be linked to the superlu library and its dependencies. + * The dependencies depend on how superlu has been compiled. + * For a cmake based project, you can use our FindSuperLU.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/SuperLUSupport/SuperLUSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SUPERLUSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/UmfPackSupport b/extern/Eigen3/Eigen/UmfPackSupport new file mode 100644 index 00000000000..984f64a8419 --- /dev/null +++ b/extern/Eigen3/Eigen/UmfPackSupport @@ -0,0 +1,36 @@ +#ifndef EIGEN_UMFPACKSUPPORT_MODULE_H +#define EIGEN_UMFPACKSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include <umfpack.h> +} + +/** \ingroup Support_modules + * \defgroup UmfPackSupport_Module UmfPackSupport module + * + * This module provides an interface to the UmfPack library which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package. + * It provides the following factorization class: + * - class UmfPackLU: a multifrontal sequential LU factorization. + * + * \code + * #include <Eigen/UmfPackSupport> + * \endcode + * + * In order to use this module, the umfpack headers must be accessible from the include paths, and your binary must be linked to the umfpack library and its dependencies. + * The dependencies depend on how umfpack has been compiled. + * For a cmake based project, you can use our FindUmfPack.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/UmfPackSupport/UmfPackSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_UMFPACKSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/src/Cholesky/LDLT.h b/extern/Eigen3/Eigen/src/Cholesky/LDLT.h index a19e947a4c6..68e54b1d4ad 100644 --- a/extern/Eigen3/Eigen/src/Cholesky/LDLT.h +++ b/extern/Eigen3/Eigen/src/Cholesky/LDLT.h @@ -1,43 +1,33 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Keir Mierle <mierle@gmail.com> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2011 Timothy E. Holy <tim.holy@gmail.com > // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LDLT_H #define EIGEN_LDLT_H +namespace Eigen { + namespace internal { template<typename MatrixType, int UpLo> struct LDLT_Traits; } -/** \ingroup cholesky_Module +/** \ingroup Cholesky_Module * * \class LDLT * * \brief Robust Cholesky decomposition of a matrix with pivoting * * \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. * * Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite * matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L @@ -48,14 +38,10 @@ template<typename MatrixType, int UpLo> struct LDLT_Traits; * on D also stabilizes the computation. * * Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky - * decomposition to determine whether a system of equations has a solution. + * decomposition to determine whether a system of equations has a solution. * * \sa MatrixBase::ldlt(), class LLT */ - /* THIS PART OF THE DOX IS CURRENTLY DISABLED BECAUSE INACCURATE BECAUSE OF BUG IN THE DECOMPOSITION CODE - * Note that during the decomposition, only the upper triangular part of A is considered. Therefore, - * the strict lower part does not have to store correct values. - */ template<typename _MatrixType, int _UpLo> class LDLT { public: @@ -98,6 +84,11 @@ template<typename _MatrixType, int _UpLo> class LDLT m_isInitialized(false) {} + /** \brief Constructor with decomposition + * + * This calculates the decomposition for the input \a matrix. + * \sa LDLT(Index size) + */ LDLT(const MatrixType& matrix) : m_matrix(matrix.rows(), matrix.cols()), m_transpositions(matrix.rows()), @@ -107,6 +98,14 @@ template<typename _MatrixType, int _UpLo> class LDLT compute(matrix); } + /** Clear any existing decomposition + * \sa rankUpdate(w,sigma) + */ + void setZero() + { + m_isInitialized = false; + } + /** \returns a view of the upper triangular matrix U */ inline typename Traits::MatrixU matrixU() const { @@ -130,14 +129,14 @@ template<typename _MatrixType, int _UpLo> class LDLT } /** \returns the coefficients of the diagonal matrix D */ - inline Diagonal<const MatrixType> vectorD(void) const + inline Diagonal<const MatrixType> vectorD() const { eigen_assert(m_isInitialized && "LDLT is not initialized."); return m_matrix.diagonal(); } /** \returns true if the matrix is positive (semidefinite) */ - inline bool isPositive(void) const + inline bool isPositive() const { eigen_assert(m_isInitialized && "LDLT is not initialized."); return m_sign == 1; @@ -196,6 +195,9 @@ template<typename _MatrixType, int _UpLo> class LDLT LDLT& compute(const MatrixType& matrix); + template <typename Derived> + LDLT& rankUpdate(const MatrixBase<Derived>& w,RealScalar alpha=1); + /** \returns the internal LDLT decomposition matrix * * TODO: document the storage layout @@ -211,6 +213,17 @@ template<typename _MatrixType, int _UpLo> class LDLT inline Index rows() const { return m_matrix.rows(); } inline Index cols() const { return m_matrix.cols(); } + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Success; + } + protected: /** \internal @@ -249,7 +262,7 @@ template<> struct ldlt_inplace<Lower> return true; } - RealScalar cutoff = 0, biggest_in_corner; + RealScalar cutoff(0), biggest_in_corner; for (Index k = 0; k < size; ++k) { @@ -317,6 +330,61 @@ template<> struct ldlt_inplace<Lower> return true; } + + // Reference for the algorithm: Davis and Hager, "Multiple Rank + // Modifications of a Sparse Cholesky Factorization" (Algorithm 1) + // Trivial rearrangements of their computations (Timothy E. Holy) + // allow their algorithm to work for rank-1 updates even if the + // original matrix is not of full rank. + // Here only rank-1 updates are implemented, to reduce the + // requirement for intermediate storage and improve accuracy + template<typename MatrixType, typename WDerived> + static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, typename MatrixType::RealScalar sigma=1) + { + using internal::isfinite; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + + const Index size = mat.rows(); + eigen_assert(mat.cols() == size && w.size()==size); + + RealScalar alpha = 1; + + // Apply the update + for (Index j = 0; j < size; j++) + { + // Check for termination due to an original decomposition of low-rank + if (!(isfinite)(alpha)) + break; + + // Update the diagonal terms + RealScalar dj = real(mat.coeff(j,j)); + Scalar wj = w.coeff(j); + RealScalar swj2 = sigma*abs2(wj); + RealScalar gamma = dj*alpha + swj2; + + mat.coeffRef(j,j) += swj2/alpha; + alpha += swj2/dj; + + + // Update the terms of L + Index rs = size-j-1; + w.tail(rs) -= wj * mat.col(j).tail(rs); + if(gamma != 0) + mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs); + } + return true; + } + + template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType> + static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, typename MatrixType::RealScalar sigma=1) + { + // Apply the permutation to the input w + tmp = transpositions * w; + + return ldlt_inplace<Lower>::updateInPlace(mat,tmp,sigma); + } }; template<> struct ldlt_inplace<Upper> @@ -327,22 +395,29 @@ template<> struct ldlt_inplace<Upper> Transpose<MatrixType> matt(mat); return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign); } + + template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType> + static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, typename MatrixType::RealScalar sigma=1) + { + Transpose<MatrixType> matt(mat); + return ldlt_inplace<Lower>::update(matt, transpositions, tmp, w.conjugate(), sigma); + } }; template<typename MatrixType> struct LDLT_Traits<MatrixType,Lower> { typedef const TriangularView<const MatrixType, UnitLower> MatrixL; typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m; } - inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); } + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } }; template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper> { typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL; typedef const TriangularView<const MatrixType, UnitUpper> MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); } - inline static MatrixU getU(const MatrixType& m) { return m; } + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } }; } // end namespace internal @@ -367,6 +442,37 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a) return *this; } +/** Update the LDLT decomposition: given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T. + * \param w a vector to be incorporated into the decomposition. + * \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column vectors. Optional; default value is +1. + * \sa setZero() + */ +template<typename MatrixType, int _UpLo> +template<typename Derived> +LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w,typename NumTraits<typename MatrixType::Scalar>::Real sigma) +{ + const Index size = w.rows(); + if (m_isInitialized) + { + eigen_assert(m_matrix.rows()==size); + } + else + { + m_matrix.resize(size,size); + m_matrix.setZero(); + m_transpositions.resize(size); + for (Index i = 0; i < size; i++) + m_transpositions.coeffRef(i) = i; + m_temporary.resize(size); + m_sign = sigma>=0 ? 1 : -1; + m_isInitialized = true; + } + + internal::ldlt_inplace<UpLo>::update(m_matrix, m_transpositions, m_temporary, w, sigma); + + return *this; +} + namespace internal { template<typename _MatrixType, int _UpLo, typename Rhs> struct solve_retval<LDLT<_MatrixType,_UpLo>, Rhs> @@ -481,4 +587,6 @@ MatrixBase<Derived>::ldlt() const return LDLT<PlainObject>(derived()); } +} // end namespace Eigen + #endif // EIGEN_LDLT_H diff --git a/extern/Eigen3/Eigen/src/Cholesky/LLT.h b/extern/Eigen3/Eigen/src/Cholesky/LLT.h index 3bb76b5787f..41d14e532f1 100644 --- a/extern/Eigen3/Eigen/src/Cholesky/LLT.h +++ b/extern/Eigen3/Eigen/src/Cholesky/LLT.h @@ -3,39 +3,28 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LLT_H #define EIGEN_LLT_H +namespace Eigen { + namespace internal{ template<typename MatrixType, int UpLo> struct LLT_Traits; } -/** \ingroup cholesky_Module +/** \ingroup Cholesky_Module * * \class LLT * * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features * * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. * * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite * matrix A such that A = LL^* = U^*U, where L is lower triangular. @@ -49,6 +38,9 @@ template<typename MatrixType, int UpLo> struct LLT_Traits; * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations * has a solution. * + * Example: \include LLT_example.cpp + * Output: \verbinclude LLT_example.out + * * \sa MatrixBase::llt(), class LDLT */ /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH) @@ -178,6 +170,9 @@ template<typename _MatrixType, int _UpLo> class LLT inline Index rows() const { return m_matrix.rows(); } inline Index cols() const { return m_matrix.cols(); } + template<typename VectorType> + LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); + protected: /** \internal * Used to compute and store L @@ -190,16 +185,85 @@ template<typename _MatrixType, int _UpLo> class LLT namespace internal { -template<int UpLo> struct llt_inplace; +template<typename Scalar, int UpLo> struct llt_inplace; + +template<typename MatrixType, typename VectorType> +static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::ColXpr ColXpr; + typedef typename internal::remove_all<ColXpr>::type ColXprCleaned; + typedef typename ColXprCleaned::SegmentReturnType ColXprSegment; + typedef Matrix<Scalar,Dynamic,1> TempVectorType; + typedef typename TempVectorType::SegmentReturnType TempVecSegment; + + int n = mat.cols(); + eigen_assert(mat.rows()==n && vec.size()==n); + + TempVectorType temp; + + if(sigma>0) + { + // This version is based on Givens rotations. + // It is faster than the other one below, but only works for updates, + // i.e., for sigma > 0 + temp = sqrt(sigma) * vec; + + for(int i=0; i<n; ++i) + { + JacobiRotation<Scalar> g; + g.makeGivens(mat(i,i), -temp(i), &mat(i,i)); + + int rs = n-i-1; + if(rs>0) + { + ColXprSegment x(mat.col(i).tail(rs)); + TempVecSegment y(temp.tail(rs)); + apply_rotation_in_the_plane(x, y, g); + } + } + } + else + { + temp = vec; + RealScalar beta = 1; + for(int j=0; j<n; ++j) + { + RealScalar Ljj = real(mat.coeff(j,j)); + RealScalar dj = abs2(Ljj); + Scalar wj = temp.coeff(j); + RealScalar swj2 = sigma*abs2(wj); + RealScalar gamma = dj*beta + swj2; + + RealScalar x = dj + swj2/beta; + if (x<=RealScalar(0)) + return j; + RealScalar nLjj = sqrt(x); + mat.coeffRef(j,j) = nLjj; + beta += swj2/dj; + + // Update the terms of L + Index rs = n-j-1; + if(rs) + { + temp.tail(rs) -= (wj/Ljj) * mat.col(j).tail(rs); + if(gamma != 0) + mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*conj(wj)/gamma)*temp.tail(rs); + } + } + } + return -1; +} -template<> struct llt_inplace<Lower> +template<typename Scalar> struct llt_inplace<Scalar, Lower> { + typedef typename NumTraits<Scalar>::Real RealScalar; template<typename MatrixType> static typename MatrixType::Index unblocked(MatrixType& mat) { typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; eigen_assert(mat.rows()==mat.cols()); const Index size = mat.rows(); @@ -254,21 +318,35 @@ template<> struct llt_inplace<Lower> } return -1; } -}; -template<> struct llt_inplace<Upper> + template<typename MatrixType, typename VectorType> + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); + } +}; + +template<typename Scalar> struct llt_inplace<Scalar, Upper> { + typedef typename NumTraits<Scalar>::Real RealScalar; + template<typename MatrixType> static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat) { Transpose<MatrixType> matt(mat); - return llt_inplace<Lower>::unblocked(matt); + return llt_inplace<Scalar, Lower>::unblocked(matt); } template<typename MatrixType> static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat) { Transpose<MatrixType> matt(mat); - return llt_inplace<Lower>::blocked(matt); + return llt_inplace<Scalar, Lower>::blocked(matt); + } + template<typename MatrixType, typename VectorType> + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + Transpose<MatrixType> matt(mat); + return llt_inplace<Scalar, Lower>::rankUpdate(matt, vec.conjugate(), sigma); } }; @@ -276,33 +354,35 @@ template<typename MatrixType> struct LLT_Traits<MatrixType,Lower> { typedef const TriangularView<const MatrixType, Lower> MatrixL; typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m; } - inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); } + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } static bool inplace_decomposition(MatrixType& m) - { return llt_inplace<Lower>::blocked(m)==-1; } + { return llt_inplace<typename MatrixType::Scalar, Lower>::blocked(m)==-1; } }; template<typename MatrixType> struct LLT_Traits<MatrixType,Upper> { typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL; typedef const TriangularView<const MatrixType, Upper> MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); } - inline static MatrixU getU(const MatrixType& m) { return m; } + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } static bool inplace_decomposition(MatrixType& m) - { return llt_inplace<Upper>::blocked(m)==-1; } + { return llt_inplace<typename MatrixType::Scalar, Upper>::blocked(m)==-1; } }; } // end namespace internal /** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix * - * * \returns a reference to *this + * + * Example: \include TutorialLinAlgComputeTwice.cpp + * Output: \verbinclude TutorialLinAlgComputeTwice.out */ template<typename MatrixType, int _UpLo> LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a) { - assert(a.rows()==a.cols()); + eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); m_matrix.resize(size, size); m_matrix = a; @@ -314,6 +394,26 @@ LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a) return *this; } +/** Performs a rank one update (or dowdate) of the current decomposition. + * If A = LL^* before the rank one update, + * then after it we have LL^* = A + sigma * v v^* where \a v must be a vector + * of same dimension. + */ +template<typename _MatrixType, int _UpLo> +template<typename VectorType> +LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType); + eigen_assert(v.size()==m_matrix.cols()); + eigen_assert(m_isInitialized); + if(internal::llt_inplace<typename MatrixType::Scalar, UpLo>::rankUpdate(m_matrix,v,sigma)>=0) + m_info = NumericalIssue; + else + m_info = Success; + + return *this; +} + namespace internal { template<typename _MatrixType, int UpLo, typename Rhs> struct solve_retval<LLT<_MatrixType, UpLo>, Rhs> @@ -383,4 +483,6 @@ SelfAdjointView<MatrixType, UpLo>::llt() const return LLT<PlainObject,UpLo>(m_matrix); } +} // end namespace Eigen + #endif // EIGEN_LLT_H diff --git a/extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h b/extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h new file mode 100644 index 00000000000..64daa445cf7 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h @@ -0,0 +1,102 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * LLt decomposition based on LAPACKE_?potrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_LLT_MKL_H +#define EIGEN_LLT_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" +#include <iostream> + +namespace Eigen { + +namespace internal { + +template<typename Scalar> struct mkl_llt; + +#define EIGEN_MKL_LLT(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template<> struct mkl_llt<EIGTYPE> \ +{ \ + template<typename MatrixType> \ + static inline typename MatrixType::Index potrf(MatrixType& m, char uplo) \ + { \ + lapack_int matrix_order; \ + lapack_int size, lda, info, StorageOrder; \ + EIGTYPE* a; \ + eigen_assert(m.rows()==m.cols()); \ + /* Set up parameters for ?potrf */ \ + size = m.rows(); \ + StorageOrder = MatrixType::Flags&RowMajorBit?RowMajor:ColMajor; \ + matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + a = &(m.coeffRef(0,0)); \ + lda = m.outerStride(); \ +\ + info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \ + info = (info==0) ? Success : NumericalIssue; \ + return info; \ + } \ +}; \ +template<> struct llt_inplace<EIGTYPE, Lower> \ +{ \ + template<typename MatrixType> \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt<EIGTYPE>::potrf(m, 'L'); \ + } \ + template<typename MatrixType, typename VectorType> \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); } \ +}; \ +template<> struct llt_inplace<EIGTYPE, Upper> \ +{ \ + template<typename MatrixType> \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt<EIGTYPE>::potrf(m, 'U'); \ + } \ + template<typename MatrixType, typename VectorType> \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { \ + Transpose<MatrixType> matt(mat); \ + return llt_inplace<EIGTYPE, Lower>::rankUpdate(matt, vec.conjugate(), sigma); \ + } \ +}; + +EIGEN_MKL_LLT(double, double, d) +EIGEN_MKL_LLT(float, float, s) +EIGEN_MKL_LLT(dcomplex, MKL_Complex16, z) +EIGEN_MKL_LLT(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_LLT_MKL_H diff --git a/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h b/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h new file mode 100644 index 00000000000..37f142150ff --- /dev/null +++ b/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h @@ -0,0 +1,579 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CHOLMODSUPPORT_H +#define EIGEN_CHOLMODSUPPORT_H + +namespace Eigen { + +namespace internal { + +template<typename Scalar, typename CholmodType> +void cholmod_configure_matrix(CholmodType& mat) +{ + if (internal::is_same<Scalar,float>::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same<Scalar,double>::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_DOUBLE; + } + else if (internal::is_same<Scalar,std::complex<float> >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same<Scalar,std::complex<double> >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_DOUBLE; + } + else + { + eigen_assert(false && "Scalar type not supported by CHOLMOD"); + } +} + +} // namespace internal + +/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object. + * Note that the data are shared. + */ +template<typename _Scalar, int _Options, typename _Index> +cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + typedef SparseMatrix<_Scalar,_Options,_Index> MatrixType; + cholmod_sparse res; + res.nzmax = mat.nonZeros(); + res.nrow = mat.rows();; + res.ncol = mat.cols(); + res.p = mat.outerIndexPtr(); + res.i = mat.innerIndexPtr(); + res.x = mat.valuePtr(); + res.sorted = 1; + if(mat.isCompressed()) + { + res.packed = 1; + } + else + { + res.packed = 0; + res.nz = mat.innerNonZeroPtr(); + } + + res.dtype = 0; + res.stype = -1; + + if (internal::is_same<_Index,int>::value) + { + res.itype = CHOLMOD_INT; + } + else + { + eigen_assert(false && "Index type different than int is not supported yet"); + } + + // setup res.xtype + internal::cholmod_configure_matrix<_Scalar>(res); + + res.stype = 0; + + return res; +} + +template<typename _Scalar, int _Options, typename _Index> +const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.const_cast_derived()); + return res; +} + +/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix. + * The data are not copied but shared. */ +template<typename _Scalar, int _Options, typename _Index, unsigned int UpLo> +cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<SparseMatrix<_Scalar,_Options,_Index>, UpLo>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived()); + + if(UpLo==Upper) res.stype = 1; + if(UpLo==Lower) res.stype = -1; + + return res; +} + +/** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix. + * The data are not copied but shared. */ +template<typename Derived> +cholmod_dense viewAsCholmod(MatrixBase<Derived>& mat) +{ + EIGEN_STATIC_ASSERT((internal::traits<Derived>::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + typedef typename Derived::Scalar Scalar; + + cholmod_dense res; + res.nrow = mat.rows(); + res.ncol = mat.cols(); + res.nzmax = res.nrow * res.ncol; + res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride(); + res.x = mat.derived().data(); + res.z = 0; + + internal::cholmod_configure_matrix<Scalar>(res); + + return res; +} + +/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix. + * The data are not copied but shared. */ +template<typename Scalar, int Flags, typename Index> +MappedSparseMatrix<Scalar,Flags,Index> viewAsEigen(cholmod_sparse& cm) +{ + return MappedSparseMatrix<Scalar,Flags,Index> + (cm.nrow, cm.ncol, reinterpret_cast<Index*>(cm.p)[cm.ncol], + reinterpret_cast<Index*>(cm.p), reinterpret_cast<Index*>(cm.i),reinterpret_cast<Scalar*>(cm.x) ); +} + +enum CholmodMode { + CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodBase + * \brief The base class for the direct Cholesky factorization of Cholmod + * \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT + */ +template<typename _MatrixType, int _UpLo, typename Derived> +class CholmodBase : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef MatrixType CholMatrixType; + typedef typename MatrixType::Index Index; + + public: + + CholmodBase() + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + cholmod_start(&m_cholmod); + } + + CholmodBase(const MatrixType& matrix) + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + cholmod_start(&m_cholmod); + compute(matrix); + } + + ~CholmodBase() + { + if(m_cholmodFactor) + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + cholmod_finish(&m_cholmod); + } + + inline Index cols() const { return m_cholmodFactor->n; } + inline Index rows() const { return m_cholmodFactor->n; } + + Derived& derived() { return *static_cast<Derived*>(this); } + const Derived& derived() const { return *static_cast<const Derived*>(this); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + Derived& compute(const MatrixType& matrix) + { + analyzePattern(matrix); + factorize(matrix); + return derived(); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::solve_retval<CholmodBase, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<CholmodBase, Rhs>(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::sparse_solve_retval<CholmodBase, Rhs> + solve(const SparseMatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval<CholmodBase, Rhs>(*this, b.derived()); + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + if(m_cholmodFactor) + { + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + m_cholmodFactor = 0; + } + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>()); + m_cholmodFactor = cholmod_analyze(&A, &m_cholmod); + + this->m_isInitialized = true; + this->m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>()); + cholmod_factorize(&A, m_cholmodFactor, &m_cholmod); + + this->m_info = Success; + m_factorizationIsOk = true; + } + + /** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations. + * See the Cholmod user guide for details. */ + cholmod_common& cholmod() { return m_cholmod; } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + eigen_assert(size==b.rows()); + + // note: cd stands for Cholmod Dense + cholmod_dense b_cd = viewAsCholmod(b.const_cast_derived()); + cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod); + if(!x_cd) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols()); + cholmod_free_dense(&x_cd, &m_cholmod); + } + + /** \internal */ + template<typename RhsScalar, int RhsOptions, typename RhsIndex, typename DestScalar, int DestOptions, typename DestIndex> + void _solve(const SparseMatrix<RhsScalar,RhsOptions,RhsIndex> &b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + eigen_assert(size==b.rows()); + + // note: cs stands for Cholmod Sparse + cholmod_sparse b_cs = viewAsCholmod(b); + cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod); + if(!x_cs) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + dest = viewAsEigen<DestScalar,DestOptions,DestIndex>(*x_cs); + cholmod_free_sparse(&x_cs, &m_cholmod); + } + #endif // EIGEN_PARSED_BY_DOXYGEN + + template<typename Stream> + void dumpMemory(Stream& s) + {} + + protected: + mutable cholmod_common m_cholmod; + cholmod_factor* m_cholmodFactor; + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLLT + * \brief A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest. + * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLLT + */ +template<typename _MatrixType, int _UpLo = Lower> +class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLLT() : Base() { init(); } + + CholmodSimplicialLLT(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodSimplicialLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + } +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLDLT + * \brief A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest. + * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLDLT + */ +template<typename _MatrixType, int _UpLo = Lower> +class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLDLT() : Base() { init(); } + + CholmodSimplicialLDLT(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodSimplicialLDLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSupernodalLLT + * \brief A supernodal Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization + * using the Cholmod library. + * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. + * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename _MatrixType, int _UpLo = Lower> +class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSupernodalLLT() : Base() { init(); } + + CholmodSupernodalLLT(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodSupernodalLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodDecomposition + * \brief A general Cholesky factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization + * using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * This variant permits to change the underlying Cholesky method at runtime. + * On the other hand, it does not provide access to the result of the factorization. + * The default is to let Cholmod automatically choose between a simplicial and supernodal factorization. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename _MatrixType, int _UpLo = Lower> +class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodDecomposition> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodDecomposition() : Base() { init(); } + + CholmodDecomposition(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodDecomposition() {} + + void setMode(CholmodMode mode) + { + switch(mode) + { + case CholmodAuto: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + break; + case CholmodSimplicialLLt: + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + break; + case CholmodSupernodalLLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + break; + case CholmodLDLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + break; + default: + break; + } + } + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + } +}; + +namespace internal { + +template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs> +struct solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> + : solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs> +struct sparse_solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> + : sparse_solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CHOLMODSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/Core/Array.h b/extern/Eigen3/Eigen/src/Core/Array.h index a11fb1b53d5..aaa38997838 100644 --- a/extern/Eigen3/Eigen/src/Core/Array.h +++ b/extern/Eigen3/Eigen/src/Core/Array.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAY_H #define EIGEN_ARRAY_H +namespace Eigen { + /** \class Array * \ingroup Core_Module * @@ -316,5 +303,6 @@ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) +} // end namespace Eigen #endif // EIGEN_ARRAY_H diff --git a/extern/Eigen3/Eigen/src/Core/ArrayBase.h b/extern/Eigen3/Eigen/src/Core/ArrayBase.h index 9399ac3d15c..004b117c933 100644 --- a/extern/Eigen3/Eigen/src/Core/ArrayBase.h +++ b/extern/Eigen3/Eigen/src/Core/ArrayBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAYBASE_H #define EIGEN_ARRAYBASE_H +namespace Eigen { + template<typename ExpressionType> class MatrixWrapper; /** \class ArrayBase @@ -159,7 +146,7 @@ template<typename Derived> class ArrayBase /** \returns an \link MatrixBase Matrix \endlink expression of this array * \sa MatrixBase::array() */ MatrixWrapper<Derived> matrix() { return derived(); } - const MatrixWrapper<Derived> matrix() const { return derived(); } + const MatrixWrapper<const Derived> matrix() const { return derived(); } // template<typename Dest> // inline void evalTo(Dest& dst) const { dst = matrix(); } @@ -174,10 +161,10 @@ template<typename Derived> class ArrayBase protected: // mixing arrays and matrices is not legal template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} // mixing arrays and matrices is not legal template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} }; /** replaces \c *this by \c *this - \a other. @@ -236,4 +223,6 @@ ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_ARRAYBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h b/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h index 07f082e1edc..87af7fda937 100644 --- a/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h +++ b/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAYWRAPPER_H #define EIGEN_ARRAYWRAPPER_H +namespace Eigen { + /** \class ArrayWrapper * \ingroup Core_Module * @@ -61,7 +48,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > typedef typename internal::nested<ExpressionType>::type NestedExpressionType; - inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {} + inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {} inline Index rows() const { return m_expression.rows(); } inline Index cols() const { return m_expression.cols(); } @@ -71,7 +58,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } inline const Scalar* data() const { return m_expression.data(); } - inline const CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return m_expression.coeff(row, col); } @@ -86,7 +73,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > return m_expression.const_cast_derived().coeffRef(row, col); } - inline const CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index index) const { return m_expression.coeff(index); } @@ -128,8 +115,14 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > template<typename Dest> inline void evalTo(Dest& dst) const { dst = m_expression; } + const typename internal::remove_all<NestedExpressionType>::type& + nestedExpression() const + { + return m_expression; + } + protected: - const NestedExpressionType m_expression; + NestedExpressionType m_expression; }; /** \class MatrixWrapper @@ -168,7 +161,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > typedef typename internal::nested<ExpressionType>::type NestedExpressionType; - inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {} + inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {} inline Index rows() const { return m_expression.rows(); } inline Index cols() const { return m_expression.cols(); } @@ -178,7 +171,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } inline const Scalar* data() const { return m_expression.data(); } - inline const CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return m_expression.coeff(row, col); } @@ -193,7 +186,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > return m_expression.derived().coeffRef(row, col); } - inline const CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index index) const { return m_expression.coeff(index); } @@ -232,8 +225,16 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); } + const typename internal::remove_all<NestedExpressionType>::type& + nestedExpression() const + { + return m_expression; + } + protected: - const NestedExpressionType m_expression; + NestedExpressionType m_expression; }; +} // end namespace Eigen + #endif // EIGEN_ARRAYWRAPPER_H diff --git a/extern/Eigen3/Eigen/src/Core/Assign.h b/extern/Eigen3/Eigen/src/Core/Assign.h index 3a17152f043..cd29a88f0da 100644 --- a/extern/Eigen3/Eigen/src/Core/Assign.h +++ b/extern/Eigen3/Eigen/src/Core/Assign.h @@ -5,28 +5,15 @@ // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ASSIGN_H #define EIGEN_ASSIGN_H +namespace Eigen { + namespace internal { /*************************************************************************** @@ -152,7 +139,7 @@ struct assign_DefaultTraversal_CompleteUnrolling inner = Index % Derived1::InnerSizeAtCompileTime }; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { dst.copyCoeffByOuterInner(outer, inner, src); assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); @@ -162,13 +149,13 @@ struct assign_DefaultTraversal_CompleteUnrolling template<typename Derived1, typename Derived2, int Stop> struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} }; template<typename Derived1, typename Derived2, int Index, int Stop> struct assign_DefaultTraversal_InnerUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) { dst.copyCoeffByOuterInner(outer, Index, src); assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer); @@ -178,7 +165,7 @@ struct assign_DefaultTraversal_InnerUnrolling template<typename Derived1, typename Derived2, int Stop> struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop> { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} }; /*********************** @@ -188,7 +175,7 @@ struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop> template<typename Derived1, typename Derived2, int Index, int Stop> struct assign_LinearTraversal_CompleteUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { dst.copyCoeff(Index, src); assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); @@ -198,7 +185,7 @@ struct assign_LinearTraversal_CompleteUnrolling template<typename Derived1, typename Derived2, int Stop> struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} }; /************************** @@ -214,7 +201,7 @@ struct assign_innervec_CompleteUnrolling JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment }; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src); assign_innervec_CompleteUnrolling<Derived1, Derived2, @@ -225,13 +212,13 @@ struct assign_innervec_CompleteUnrolling template<typename Derived1, typename Derived2, int Stop> struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop> { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} }; template<typename Derived1, typename Derived2, int Index, int Stop> struct assign_innervec_InnerUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) { dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src); assign_innervec_InnerUnrolling<Derived1, Derived2, @@ -242,7 +229,7 @@ struct assign_innervec_InnerUnrolling template<typename Derived1, typename Derived2, int Stop> struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop> { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} }; /*************************************************************************** @@ -251,24 +238,25 @@ struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop> template<typename Derived1, typename Derived2, int Traversal = assign_traits<Derived1, Derived2>::Traversal, - int Unrolling = assign_traits<Derived1, Derived2>::Unrolling> + int Unrolling = assign_traits<Derived1, Derived2>::Unrolling, + int Version = Specialized> struct assign_impl; /************************ *** Default traversal *** ************************/ -template<typename Derived1, typename Derived2, int Unrolling> -struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling> +template<typename Derived1, typename Derived2, int Unrolling, int Version> +struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version> { - inline static void run(Derived1 &, const Derived2 &) { } + static inline void run(Derived1 &, const Derived2 &) { } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { const Index innerSize = dst.innerSize(); const Index outerSize = dst.outerSize(); @@ -278,21 +266,21 @@ struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling> } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version> { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> ::run(dst, src); } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version> { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { const Index outerSize = dst.outerSize(); for(Index outer = 0; outer < outerSize; ++outer) @@ -305,11 +293,11 @@ struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling> *** Linear traversal *** ***********************/ -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { const Index size = dst.size(); for(Index i = 0; i < size; ++i) @@ -317,10 +305,10 @@ struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling> } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version> { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> ::run(dst, src); @@ -331,11 +319,11 @@ struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling> *** Inner vectorization *** **************************/ -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { const Index innerSize = dst.innerSize(); const Index outerSize = dst.outerSize(); @@ -346,21 +334,21 @@ struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling> } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version> { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> ::run(dst, src); } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version> { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { const Index outerSize = dst.outerSize(); for(Index outer = 0; outer < outerSize; ++outer) @@ -398,11 +386,11 @@ struct unaligned_assign_impl<false> } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version> { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { const Index size = dst.size(); typedef packet_traits<typename Derived1::Scalar> PacketTraits; @@ -412,7 +400,7 @@ struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling> srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment }; const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0 - : first_aligned(&dst.coeffRef(0), size); + : internal::first_aligned(&dst.coeffRef(0), size); const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart); @@ -426,11 +414,11 @@ struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling> } }; -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version> { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { enum { size = Derived1::SizeAtCompileTime, packetSize = packet_traits<typename Derived1::Scalar>::size, @@ -445,11 +433,11 @@ struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnroll *** Slice vectorization *** ***************************/ -template<typename Derived1, typename Derived2> -struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling> +template<typename Derived1, typename Derived2, int Version> +struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { typedef packet_traits<typename Derived1::Scalar> PacketTraits; enum { @@ -463,7 +451,7 @@ struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling> const Index outerSize = dst.outerSize(); const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0 - : first_aligned(&dst.coeffRef(0,0), innerSize); + : internal::first_aligned(&dst.coeffRef(0,0), innerSize); for(Index outer = 0; outer < outerSize; ++outer) { @@ -531,19 +519,19 @@ struct assign_selector; template<typename Derived, typename OtherDerived> struct assign_selector<Derived,OtherDerived,false,false> { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } }; template<typename Derived, typename OtherDerived> struct assign_selector<Derived,OtherDerived,true,false> { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } }; template<typename Derived, typename OtherDerived> struct assign_selector<Derived,OtherDerived,false,true> { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } }; template<typename Derived, typename OtherDerived> struct assign_selector<Derived,OtherDerived,true,true> { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } }; } // end namespace internal @@ -590,4 +578,6 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue< return derived(); } +} // end namespace Eigen + #endif // EIGEN_ASSIGN_H diff --git a/extern/Eigen3/Eigen/src/Core/Assign_MKL.h b/extern/Eigen3/Eigen/src/Core/Assign_MKL.h new file mode 100644 index 00000000000..428c6367b92 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/Assign_MKL.h @@ -0,0 +1,224 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin() + ******************************************************************************** +*/ + +#ifndef EIGEN_ASSIGN_VML_H +#define EIGEN_ASSIGN_VML_H + +namespace Eigen { + +namespace internal { + +template<typename Op> struct vml_call +{ enum { IsSupported = 0 }; }; + +template<typename Dst, typename Src, typename UnaryOp> +class vml_assign_traits +{ + private: + enum { + DstHasDirectAccess = Dst::Flags & DirectAccessBit, + SrcHasDirectAccess = Src::Flags & DirectAccessBit, + + StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)), + InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime) + : int(Dst::RowsAtCompileTime), + InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime) + : int(Dst::MaxRowsAtCompileTime), + MaxSizeAtCompileTime = Dst::SizeAtCompileTime, + + MightEnableVml = vml_call<UnaryOp>::IsSupported && StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess + && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1, + MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), + VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize, + LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD, + MayEnableVml = MightEnableVml && LargeEnough, + MayLinearize = MayEnableVml && MightLinearize + }; + public: + enum { + Traversal = MayLinearize ? LinearVectorizedTraversal + : MayEnableVml ? InnerVectorizedTraversal + : DefaultTraversal + }; +}; + +template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling, + int VmlTraversal = vml_assign_traits<Derived1, Derived2, UnaryOp>::Traversal > +struct vml_assign_impl + : assign_impl<Derived1, Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn> +{ +}; + +template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling> +struct vml_assign_impl<Derived1, Derived2, UnaryOp, Traversal, Unrolling, InnerVectorizedTraversal> +{ + typedef typename Derived1::Scalar Scalar; + typedef typename Derived1::Index Index; + static inline void run(Derived1& dst, const CwiseUnaryOp<UnaryOp, Derived2>& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl<Derived1,Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>::run(dst,src); + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) { + const Scalar *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) : + &(src.nestedExpression().coeffRef(0, outer)); + Scalar *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); + vml_call<UnaryOp>::run(src.functor(), innerSize, src_ptr, dst_ptr ); + } + } +}; + +template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling> +struct vml_assign_impl<Derived1, Derived2, UnaryOp, Traversal, Unrolling, LinearVectorizedTraversal> +{ + static inline void run(Derived1& dst, const CwiseUnaryOp<UnaryOp, Derived2>& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl<Derived1,Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>::run(dst,src); + vml_call<UnaryOp>::run(src.functor(), dst.size(), src.nestedExpression().data(), dst.data() ); + } +}; + +// Macroses + +#define EIGEN_MKL_VML_SPECIALIZE_ASSIGN(TRAVERSAL,UNROLLING) \ + template<typename Derived1, typename Derived2, typename UnaryOp> \ + struct assign_impl<Derived1, Eigen::CwiseUnaryOp<UnaryOp, Derived2>, TRAVERSAL, UNROLLING, Specialized> { \ + static inline void run(Derived1 &dst, const Eigen::CwiseUnaryOp<UnaryOp, Derived2> &src) { \ + vml_assign_impl<Derived1,Derived2,UnaryOp,TRAVERSAL,UNROLLING>::run(dst, src); \ + } \ + }; + +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) + + +#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1) +#define EIGEN_MKL_VML_MODE VML_HA +#else +#define EIGEN_MKL_VML_MODE VML_LA +#endif + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst, vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& func, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + EIGENTYPE exponent = func.m_exponent; \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(&size, (const VMLTYPE*)src, (const VMLTYPE*)&exponent, \ + (VMLTYPE*)dst, &vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vs##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) + + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vms##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) + + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) +//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) + +// The vm*powx functions are not avaibale in the windows version of MKL. +#ifdef _WIN32 +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzpowx_, dcomplex, MKL_Complex16) +#endif + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_ASSIGN_VML_H diff --git a/extern/Eigen3/Eigen/src/Core/BandMatrix.h b/extern/Eigen3/Eigen/src/Core/BandMatrix.h index 2570d7b559f..ffd7fe8b301 100644 --- a/extern/Eigen3/Eigen/src/Core/BandMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/BandMatrix.h @@ -3,30 +3,16 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BANDMATRIX_H #define EIGEN_BANDMATRIX_H -namespace internal { +namespace Eigen { +namespace internal { template<typename Derived> class BandMatrixBase : public EigenBase<Derived> @@ -343,4 +329,6 @@ class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_BANDMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/Block.h b/extern/Eigen3/Eigen/src/Core/Block.h index d470bc13400..5f29cb3d1b3 100644 --- a/extern/Eigen3/Eigen/src/Core/Block.h +++ b/extern/Eigen3/Eigen/src/Core/Block.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCK_H #define EIGEN_BLOCK_H +namespace Eigen { + /** \class Block * \ingroup Core_Module * @@ -242,6 +229,21 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H inline Index outerStride() const; #endif + const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const + { + return m_xpr; + } + + Index startRow() const + { + return m_startRow.value(); + } + + Index startCol() const + { + return m_startCol.value(); + } + protected: const typename XprType::Nested m_xpr; @@ -304,6 +306,11 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true> init(); } + const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const + { + return m_xpr; + } + /** \sa MapBase::innerStride() */ inline Index innerStride() const { @@ -341,9 +348,10 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true> : m_xpr.innerStride(); } - const typename XprType::Nested m_xpr; + typename XprType::Nested m_xpr; Index m_outerStride; }; +} // end namespace Eigen #endif // EIGEN_BLOCK_H diff --git a/extern/Eigen3/Eigen/src/Core/BooleanRedux.h b/extern/Eigen3/Eigen/src/Core/BooleanRedux.h index 5c3444a57c9..57efd8e6953 100644 --- a/extern/Eigen3/Eigen/src/Core/BooleanRedux.h +++ b/extern/Eigen3/Eigen/src/Core/BooleanRedux.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ALLANDANY_H #define EIGEN_ALLANDANY_H +namespace Eigen { + namespace internal { template<typename Derived, int UnrollCount> @@ -35,7 +22,7 @@ struct all_unroller row = (UnrollCount-1) % Derived::RowsAtCompileTime }; - inline static bool run(const Derived &mat) + static inline bool run(const Derived &mat) { return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col); } @@ -44,13 +31,13 @@ struct all_unroller template<typename Derived> struct all_unroller<Derived, 1> { - inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } }; template<typename Derived> struct all_unroller<Derived, Dynamic> { - inline static bool run(const Derived &) { return false; } + static inline bool run(const Derived &) { return false; } }; template<typename Derived, int UnrollCount> @@ -61,7 +48,7 @@ struct any_unroller row = (UnrollCount-1) % Derived::RowsAtCompileTime }; - inline static bool run(const Derived &mat) + static inline bool run(const Derived &mat) { return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col); } @@ -70,13 +57,13 @@ struct any_unroller template<typename Derived> struct any_unroller<Derived, 1> { - inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } }; template<typename Derived> struct any_unroller<Derived, Dynamic> { - inline static bool run(const Derived &) { return false; } + static inline bool run(const Derived &) { return false; } }; } // end namespace internal @@ -146,4 +133,6 @@ inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const return derived().template cast<bool>().template cast<Index>().sum(); } +} // end namespace Eigen + #endif // EIGEN_ALLANDANY_H diff --git a/extern/Eigen3/Eigen/src/Core/CommaInitializer.h b/extern/Eigen3/Eigen/src/Core/CommaInitializer.h index 92422bf2fa0..4adce64143c 100644 --- a/extern/Eigen3/Eigen/src/Core/CommaInitializer.h +++ b/extern/Eigen3/Eigen/src/Core/CommaInitializer.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMMAINITIALIZER_H #define EIGEN_COMMAINITIALIZER_H +namespace Eigen { + /** \class CommaInitializer * \ingroup Core_Module * @@ -147,4 +134,6 @@ DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other) return CommaInitializer<Derived>(*static_cast<Derived *>(this), other); } +} // end namespace Eigen + #endif // EIGEN_COMMAINITIALIZER_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h index 7386b2e1843..1b93af31b60 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_BINARY_OP_H #define EIGEN_CWISE_BINARY_OP_H +namespace Eigen { + /** \class CwiseBinaryOp * \ingroup Core_Module * @@ -167,8 +154,8 @@ class CwiseBinaryOp : internal::no_assignment_operator, const BinaryOp& functor() const { return m_functor; } protected: - const LhsNested m_lhs; - const RhsNested m_rhs; + LhsNested m_lhs; + RhsNested m_rhs; const BinaryOp m_functor; }; @@ -237,4 +224,6 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_CWISE_BINARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h index c616e7ae13d..2635a62b07b 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_NULLARY_OP_H #define EIGEN_CWISE_NULLARY_OP_H +namespace Eigen { + /** \class CwiseNullaryOp * \ingroup Core_Module * @@ -101,6 +88,9 @@ class CwiseNullaryOp : internal::no_assignment_operator, return m_functor.packetOp(index); } + /** \returns the functor representing the nullary operation */ + const NullaryOp& functor() const { return m_functor; } + protected: const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows; const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols; @@ -238,6 +228,8 @@ DenseBase<Derived>::Constant(const Scalar& value) * assumed to be a(0), a(1), ..., a(size). This assumption allows for better vectorization * and yields faster code than the random access version. * + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * * \only_for_vectors * * Example: \include DenseBase_LinSpaced_seq.cpp @@ -270,6 +262,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig * \brief Sets a linearly space vector. * * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. * * \only_for_vectors * @@ -381,6 +374,7 @@ PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& valu * \brief Sets a linearly space vector. * * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. * * \only_for_vectors * @@ -396,6 +390,23 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index size, const return derived() = Derived::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size)); } +/** + * \brief Sets a linearly space vector. + * + * The function fill *this with equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * \sa setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp + */ +template<typename Derived> +EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return setLinSpaced(size(), low, high); +} + // zero: /** \returns an expression of a zero matrix. @@ -848,4 +859,6 @@ template<typename Derived> EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW() { return Derived::Unit(3); } +} // end namespace Eigen + #endif // EIGEN_CWISE_NULLARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h index 958571d64bf..063355ae521 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_UNARY_OP_H #define EIGEN_CWISE_UNARY_OP_H +namespace Eigen { + /** \class CwiseUnaryOp * \ingroup Core_Module * @@ -95,7 +82,7 @@ class CwiseUnaryOp : internal::no_assignment_operator, nestedExpression() { return m_xpr.const_cast_derived(); } protected: - const typename XprType::Nested m_xpr; + typename XprType::Nested m_xpr; const UnaryOp m_functor; }; @@ -134,4 +121,6 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense> } }; +} // end namespace Eigen + #endif // EIGEN_CWISE_UNARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h b/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h index d24ef037314..66f73a9505b 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_UNARY_VIEW_H #define EIGEN_CWISE_UNARY_VIEW_H +namespace Eigen { + /** \class CwiseUnaryView * \ingroup Core_Module * @@ -97,7 +84,7 @@ class CwiseUnaryView : internal::no_assignment_operator, protected: // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC - const typename internal::nested<MatrixType>::type m_matrix; + typename internal::nested<MatrixType>::type m_matrix; ViewOp m_functor; }; @@ -143,6 +130,6 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> } }; - +} // end namespace Eigen #endif // EIGEN_CWISE_UNARY_VIEW_H diff --git a/extern/Eigen3/Eigen/src/Core/DenseBase.h b/extern/Eigen3/Eigen/src/Core/DenseBase.h index 920904f243a..1cc0314ef0b 100644 --- a/extern/Eigen3/Eigen/src/Core/DenseBase.h +++ b/extern/Eigen3/Eigen/src/Core/DenseBase.h @@ -4,28 +4,15 @@ // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DENSEBASE_H #define EIGEN_DENSEBASE_H +namespace Eigen { + /** \class DenseBase * \ingroup Core_Module * @@ -376,12 +363,13 @@ template<typename Derived> class DenseBase inline Derived& operator*=(const Scalar& other); inline Derived& operator/=(const Scalar& other); + typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType; /** \returns the matrix or vector obtained by evaluating this expression. * * Notice that in the case of a plain matrix or vector (not an expression) this function just returns * a const reference, in order to avoid a useless copy. */ - EIGEN_STRONG_INLINE const typename internal::eval<Derived>::type eval() const + EIGEN_STRONG_INLINE EvalReturnType eval() const { // Even though MSVC does not honor strong inlining when the return type // is a dynamic matrix, we desperately need strong inlining for fixed @@ -540,4 +528,6 @@ template<typename Derived> class DenseBase template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&); }; +} // end namespace Eigen + #endif // EIGEN_DENSEBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h b/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h index e45238fb584..72704c2d79f 100644 --- a/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h +++ b/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DENSECOEFFSBASE_H #define EIGEN_DENSECOEFFSBASE_H +namespace Eigen { + namespace internal { template<typename T> struct add_const_on_value_type_if_arithmetic { @@ -710,16 +697,16 @@ namespace internal { template<typename Derived, bool JustReturnZero> struct first_aligned_impl { - inline static typename Derived::Index run(const Derived&) + static inline typename Derived::Index run(const Derived&) { return 0; } }; template<typename Derived> struct first_aligned_impl<Derived, false> { - inline static typename Derived::Index run(const Derived& m) + static inline typename Derived::Index run(const Derived& m) { - return first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); + return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); } }; @@ -729,7 +716,7 @@ struct first_aligned_impl<Derived, false> * documentation. */ template<typename Derived> -inline static typename Derived::Index first_aligned(const Derived& m) +static inline typename Derived::Index first_aligned(const Derived& m) { return first_aligned_impl <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)> @@ -762,4 +749,6 @@ struct outer_stride_at_compile_time<Derived, false> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_DENSECOEFFSBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/DenseStorage.h b/extern/Eigen3/Eigen/src/Core/DenseStorage.h index 813053b00dd..1fc2daf2c40 100644 --- a/extern/Eigen3/Eigen/src/Core/DenseStorage.h +++ b/extern/Eigen3/Eigen/src/Core/DenseStorage.h @@ -5,24 +5,9 @@ // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIXSTORAGE_H #define EIGEN_MATRIXSTORAGE_H @@ -33,6 +18,8 @@ #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN #endif +namespace Eigen { + namespace internal { struct constructor_without_unaligned_array_assert {}; @@ -104,8 +91,8 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt : m_data(internal::constructor_without_unaligned_array_assert()) {} inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } - inline static DenseIndex rows(void) {return _Rows;} - inline static DenseIndex cols(void) {return _Cols;} + static inline DenseIndex rows(void) {return _Rows;} + static inline DenseIndex cols(void) {return _Cols;} inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} inline void resize(DenseIndex,DenseIndex,DenseIndex) {} inline const T *data() const { return m_data.array; } @@ -120,14 +107,24 @@ template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0 inline DenseStorage(internal::constructor_without_unaligned_array_assert) {} inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} inline void swap(DenseStorage& ) {} - inline static DenseIndex rows(void) {return _Rows;} - inline static DenseIndex cols(void) {return _Cols;} + static inline DenseIndex rows(void) {return _Rows;} + static inline DenseIndex cols(void) {return _Cols;} inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} inline void resize(DenseIndex,DenseIndex,DenseIndex) {} inline const T *data() const { return 0; } inline T *data() { return 0; } }; +// more specializations for null matrices; these are necessary to resolve ambiguities +template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options> +: public DenseStorage<T, 0, 0, 0, _Options> { }; + +template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options> +: public DenseStorage<T, 0, 0, 0, _Options> { }; + +template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options> +: public DenseStorage<T, 0, 0, 0, _Options> { }; + // dynamic-size matrix with fixed-size storage template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options> { @@ -241,7 +238,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } - inline static DenseIndex rows(void) {return _Rows;} + static inline DenseIndex rows(void) {return _Rows;} inline DenseIndex cols(void) const {return m_cols;} inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols) { @@ -278,7 +275,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } inline DenseIndex rows(void) const {return m_rows;} - inline static DenseIndex cols(void) {return _Cols;} + static inline DenseIndex cols(void) {return _Cols;} inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex) { m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols); @@ -301,4 +298,6 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn inline T *data() { return m_data; } }; +} // end namespace Eigen + #endif // EIGEN_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/Diagonal.h b/extern/Eigen3/Eigen/src/Core/Diagonal.h index 61d3b063a44..16261968a0f 100644 --- a/extern/Eigen3/Eigen/src/Core/Diagonal.h +++ b/extern/Eigen3/Eigen/src/Core/Diagonal.h @@ -2,29 +2,17 @@ // for linear algebra. // // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DIAGONAL_H #define EIGEN_DIAGONAL_H +namespace Eigen { + /** \class Diagonal * \ingroup Core_Module * @@ -53,16 +41,15 @@ struct traits<Diagonal<MatrixType,DiagIndex> > typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; typedef typename MatrixType::StorageKind StorageKind; enum { - AbsDiagIndex = DiagIndex<0 ? -DiagIndex : DiagIndex, // only used if DiagIndex != Dynamic - // FIXME these computations are broken in the case where the matrix is rectangular and DiagIndex!=0 RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic - : (EIGEN_SIZE_MIN_PREFER_DYNAMIC(MatrixType::RowsAtCompileTime, - MatrixType::ColsAtCompileTime) - AbsDiagIndex), + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), ColsAtCompileTime = 1, MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic : DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, - MatrixType::MaxColsAtCompileTime) - : (EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime) - AbsDiagIndex), + MatrixType::MaxColsAtCompileTime) + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), MaxColsAtCompileTime = 1, MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0, Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, @@ -101,6 +88,15 @@ template<typename MatrixType, int DiagIndex> class Diagonal return 0; } + typedef typename internal::conditional< + internal::is_lvalue<MatrixType>::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + inline const Scalar* data() const { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + inline Scalar& coeffRef(Index row, Index) { EIGEN_STATIC_ASSERT_LVALUE(MatrixType) @@ -133,8 +129,19 @@ template<typename MatrixType, int DiagIndex> class Diagonal return m_matrix.coeff(index+rowOffset(), index+colOffset()); } + const typename internal::remove_all<typename MatrixType::Nested>::type& + nestedExpression() const + { + return m_matrix; + } + + int index() const + { + return m_index.value(); + } + protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; const internal::variable_if_dynamic<Index, DiagIndex> m_index; private: @@ -224,4 +231,6 @@ MatrixBase<Derived>::diagonal() const return derived(); } +} // end namespace Eigen + #endif // EIGEN_DIAGONAL_H diff --git a/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h b/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h index f41a74bfae7..88190da684d 100644 --- a/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H +namespace Eigen { + #ifndef EIGEN_PARSED_BY_DOXYGEN template<typename Derived> class DiagonalBase : public EigenBase<Derived> @@ -72,7 +59,7 @@ class DiagonalBase : public EigenBase<Derived> const DiagonalProduct<MatrixDerived, Derived, OnTheLeft> operator*(const MatrixBase<MatrixDerived> &matrix) const; - inline const DiagonalWrapper<CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> > + inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> > inverse() const { return diagonal().cwiseInverse(); @@ -251,13 +238,13 @@ class DiagonalWrapper #endif /** Constructor from expression of diagonal coefficients to wrap. */ - inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} + inline DiagonalWrapper(DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} /** \returns a const reference to the wrapped expression of diagonal coefficients. */ const DiagonalVectorType& diagonal() const { return m_diagonal; } protected: - const typename DiagonalVectorType::Nested m_diagonal; + typename DiagonalVectorType::Nested m_diagonal; }; /** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients @@ -303,4 +290,6 @@ bool MatrixBase<Derived>::isDiagonal(RealScalar prec) const return true; } +} // end namespace Eigen + #endif // EIGEN_DIAGONALMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h b/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h index de0c6ed11b7..598c6b3e19a 100644 --- a/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h +++ b/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DIAGONALPRODUCT_H #define EIGEN_DIAGONALPRODUCT_H +namespace Eigen { + namespace internal { template<typename MatrixType, typename DiagonalType, int ProductOrder> struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> > @@ -107,8 +94,8 @@ class DiagonalProduct : internal::no_assignment_operator, m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id)); } - const typename MatrixType::Nested m_matrix; - const typename DiagonalType::Nested m_diagonal; + typename MatrixType::Nested m_matrix; + typename DiagonalType::Nested m_diagonal; }; /** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal. @@ -131,5 +118,6 @@ DiagonalBase<DiagonalDerived>::operator*(const MatrixBase<MatrixDerived> &matrix return DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>(matrix.derived(), derived()); } +} // end namespace Eigen #endif // EIGEN_DIAGONALPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/Dot.h b/extern/Eigen3/Eigen/src/Core/Dot.h index 42da7849896..ae9274e36dd 100644 --- a/extern/Eigen3/Eigen/src/Core/Dot.h +++ b/extern/Eigen3/Eigen/src/Core/Dot.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DOT_H #define EIGEN_DOT_H +namespace Eigen { + namespace internal { // helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot @@ -176,7 +163,7 @@ template<typename Derived, int p> struct lpNorm_selector { typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar; - inline static RealScalar run(const MatrixBase<Derived>& m) + static inline RealScalar run(const MatrixBase<Derived>& m) { return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); } @@ -185,7 +172,7 @@ struct lpNorm_selector template<typename Derived> struct lpNorm_selector<Derived, 1> { - inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) + static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) { return m.cwiseAbs().sum(); } @@ -194,7 +181,7 @@ struct lpNorm_selector<Derived, 1> template<typename Derived> struct lpNorm_selector<Derived, 2> { - inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) + static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) { return m.norm(); } @@ -203,7 +190,7 @@ struct lpNorm_selector<Derived, 2> template<typename Derived> struct lpNorm_selector<Derived, Infinity> { - inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) + static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) { return m.cwiseAbs().maxCoeff(); } @@ -269,4 +256,6 @@ bool MatrixBase<Derived>::isUnitary(RealScalar prec) const return true; } +} // end namespace Eigen + #endif // EIGEN_DOT_H diff --git a/extern/Eigen3/Eigen/src/Core/EigenBase.h b/extern/Eigen3/Eigen/src/Core/EigenBase.h index 0472539af33..0bbd28bec21 100644 --- a/extern/Eigen3/Eigen/src/Core/EigenBase.h +++ b/extern/Eigen3/Eigen/src/Core/EigenBase.h @@ -4,28 +4,14 @@ // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EIGENBASE_H #define EIGEN_EIGENBASE_H +namespace Eigen { /** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T). * @@ -169,4 +155,6 @@ inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &o other.derived().applyThisOnTheLeft(derived()); } +} // end namespace Eigen + #endif // EIGEN_EIGENBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/Flagged.h b/extern/Eigen3/Eigen/src/Core/Flagged.h index 458213ab553..1f2955fc1de 100644 --- a/extern/Eigen3/Eigen/src/Core/Flagged.h +++ b/extern/Eigen3/Eigen/src/Core/Flagged.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FLAGGED_H #define EIGEN_FLAGGED_H +namespace Eigen { + /** \class Flagged * \ingroup Core_Module * @@ -148,4 +135,6 @@ DenseBase<Derived>::flagged() const return derived(); } +} // end namespace Eigen + #endif // EIGEN_FLAGGED_H diff --git a/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h b/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h index 11c1f8f709a..807c7a29346 100644 --- a/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h +++ b/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FORCEALIGNEDACCESS_H #define EIGEN_FORCEALIGNEDACCESS_H +namespace Eigen { + /** \class ForceAlignedAccess * \ingroup Core_Module * @@ -154,4 +141,6 @@ MatrixBase<Derived>::forceAlignedAccessIf() return derived(); } +} // end namespace Eigen + #endif // EIGEN_FORCEALIGNEDACCESS_H diff --git a/extern/Eigen3/Eigen/src/Core/Functors.h b/extern/Eigen3/Eigen/src/Core/Functors.h index 54636e0d459..278c46c6b61 100644 --- a/extern/Eigen3/Eigen/src/Core/Functors.h +++ b/extern/Eigen3/Eigen/src/Core/Functors.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FUNCTORS_H #define EIGEN_FUNCTORS_H +namespace Eigen { + namespace internal { // associative functors: @@ -178,6 +165,18 @@ struct functor_traits<scalar_hypot_op<Scalar> > { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 }; }; +/** \internal + * \brief Template functor to compute the pow of two scalars + */ +template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) + inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); } +}; +template<typename Scalar, typename OtherScalar> +struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > { + enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; +}; + // other binary functors: /** \internal @@ -220,6 +219,38 @@ struct functor_traits<scalar_quotient_op<Scalar> > { }; }; +/** \internal + * \brief Template functor to compute the and of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator&& + */ +struct scalar_boolean_and_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; } +}; +template<> struct functor_traits<scalar_boolean_and_op> { + enum { + Cost = NumTraits<bool>::AddCost, + PacketAccess = false + }; +}; + +/** \internal + * \brief Template functor to compute the or of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator|| + */ +struct scalar_boolean_or_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; } +}; +template<> struct functor_traits<scalar_boolean_or_op> { + enum { + Cost = NumTraits<bool>::AddCost, + PacketAccess = false + }; +}; + // unary functors: /** \internal @@ -249,7 +280,7 @@ struct functor_traits<scalar_opposite_op<Scalar> > template<typename Scalar> struct scalar_abs_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs(a); } + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs(a); } template<typename Packet> EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pabs(a); } @@ -271,7 +302,7 @@ struct functor_traits<scalar_abs_op<Scalar> > template<typename Scalar> struct scalar_abs2_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs2(a); } + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); } template<typename Packet> EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pmul(a,a); } @@ -287,7 +318,7 @@ struct functor_traits<scalar_abs2_op<Scalar> > */ template<typename Scalar> struct scalar_conjugate_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) - EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return conj(a); } + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return internal::conj(a); } template<typename Packet> EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } }; @@ -324,7 +355,7 @@ template<typename Scalar> struct scalar_real_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return real(a); } + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); } }; template<typename Scalar> struct functor_traits<scalar_real_op<Scalar> > @@ -339,7 +370,7 @@ template<typename Scalar> struct scalar_imag_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return imag(a); } + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); } }; template<typename Scalar> struct functor_traits<scalar_imag_op<Scalar> > @@ -354,7 +385,7 @@ template<typename Scalar> struct scalar_real_ref_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return real_ref(*const_cast<Scalar*>(&a)); } + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast<Scalar*>(&a)); } }; template<typename Scalar> struct functor_traits<scalar_real_ref_op<Scalar> > @@ -369,7 +400,7 @@ template<typename Scalar> struct scalar_imag_ref_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return imag_ref(*const_cast<Scalar*>(&a)); } + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast<Scalar*>(&a)); } }; template<typename Scalar> struct functor_traits<scalar_imag_ref_op<Scalar> > @@ -383,7 +414,7 @@ struct functor_traits<scalar_imag_ref_op<Scalar> > */ template<typename Scalar> struct scalar_exp_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) - inline const Scalar operator() (const Scalar& a) const { return exp(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::exp(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } }; @@ -399,7 +430,7 @@ struct functor_traits<scalar_exp_op<Scalar> > */ template<typename Scalar> struct scalar_log_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) - inline const Scalar operator() (const Scalar& a) const { return log(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::log(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::plog(a); } }; @@ -584,7 +615,7 @@ template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_o template <typename Scalar, bool RandomAccess> struct linspaced_op { typedef typename packet_traits<Scalar>::type Packet; - linspaced_op(Scalar low, Scalar high, int num_steps) : impl(low, (high-low)/(num_steps-1)) {} + linspaced_op(Scalar low, Scalar high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {} template<typename Index> EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } @@ -657,7 +688,7 @@ struct functor_traits<scalar_add_op<Scalar> > */ template<typename Scalar> struct scalar_sqrt_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) - inline const Scalar operator() (const Scalar& a) const { return sqrt(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::sqrt(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } }; @@ -675,7 +706,7 @@ struct functor_traits<scalar_sqrt_op<Scalar> > */ template<typename Scalar> struct scalar_cos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) - inline Scalar operator() (const Scalar& a) const { return cos(a); } + inline Scalar operator() (const Scalar& a) const { return internal::cos(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } }; @@ -694,7 +725,7 @@ struct functor_traits<scalar_cos_op<Scalar> > */ template<typename Scalar> struct scalar_sin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) - inline const Scalar operator() (const Scalar& a) const { return sin(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::sin(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::psin(a); } }; @@ -714,7 +745,7 @@ struct functor_traits<scalar_sin_op<Scalar> > */ template<typename Scalar> struct scalar_tan_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) - inline const Scalar operator() (const Scalar& a) const { return tan(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::tan(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } }; @@ -733,7 +764,7 @@ struct functor_traits<scalar_tan_op<Scalar> > */ template<typename Scalar> struct scalar_acos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) - inline const Scalar operator() (const Scalar& a) const { return acos(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } }; @@ -752,7 +783,7 @@ struct functor_traits<scalar_acos_op<Scalar> > */ template<typename Scalar> struct scalar_asin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) - inline const Scalar operator() (const Scalar& a) const { return asin(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); } typedef typename packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } }; @@ -782,6 +813,20 @@ struct functor_traits<scalar_pow_op<Scalar> > { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; }; /** \internal + * \brief Template functor to compute the quotient between a scalar and array entries. + * \sa class CwiseUnaryOp, Cwise::inverse() + */ +template<typename Scalar> +struct scalar_inverse_mult_op { + scalar_inverse_mult_op(const Scalar& other) : m_other(other) {} + inline Scalar operator() (const Scalar& a) const { return m_other / a; } + template<typename Packet> + inline const Packet packetOp(const Packet& a) const + { return internal::pdiv(pset1<Packet>(m_other),a); } + Scalar m_other; +}; + +/** \internal * \brief Template functor to compute the inverse of a scalar * \sa class CwiseUnaryOp, Cwise::inverse() */ @@ -939,4 +984,6 @@ struct functor_traits<std::binary_compose<T0,T1,T2> > } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_FUNCTORS_H diff --git a/extern/Eigen3/Eigen/src/Core/Fuzzy.h b/extern/Eigen3/Eigen/src/Core/Fuzzy.h index d266eed0ac6..d74edcfdb9d 100644 --- a/extern/Eigen3/Eigen/src/Core/Fuzzy.h +++ b/extern/Eigen3/Eigen/src/Core/Fuzzy.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FUZZY_H #define EIGEN_FUZZY_H +namespace Eigen { + namespace internal { @@ -35,8 +22,8 @@ struct isApprox_selector static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec) { using std::min; - const typename internal::nested<Derived,2>::type nested(x); - const typename internal::nested<OtherDerived,2>::type otherNested(y); + typename internal::nested<Derived,2>::type nested(x); + typename internal::nested<OtherDerived,2>::type otherNested(y); return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); } }; @@ -158,4 +145,6 @@ bool DenseBase<Derived>::isMuchSmallerThan( return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec); } +} // end namespace Eigen + #endif // EIGEN_FUZZY_H diff --git a/extern/Eigen3/Eigen/src/Core/GeneralProduct.h b/extern/Eigen3/Eigen/src/Core/GeneralProduct.h new file mode 100644 index 00000000000..bfc2a67b12f --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/GeneralProduct.h @@ -0,0 +1,613 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GENERAL_PRODUCT_H +#define EIGEN_GENERAL_PRODUCT_H + +namespace Eigen { + +/** \class GeneralProduct + * \ingroup Core_Module + * + * \brief Expression of the product of two general matrices or vectors + * + * \param LhsNested the type used to store the left-hand side + * \param RhsNested the type used to store the right-hand side + * \param ProductMode the type of the product + * + * This class represents an expression of the product of two general matrices. + * We call a general matrix, a dense matrix with full storage. For instance, + * This excludes triangular, selfadjoint, and sparse matrices. + * It is the return type of the operator* between general matrices. Its template + * arguments are determined automatically by ProductReturnType. Therefore, + * GeneralProduct should never be used direclty. To determine the result type of a + * function which involves a matrix product, use ProductReturnType::Type. + * + * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase<OtherDerived>&) + */ +template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value> +class GeneralProduct; + +enum { + Large = 2, + Small = 3 +}; + +namespace internal { + +template<int Rows, int Cols, int Depth> struct product_type_selector; + +template<int Size, int MaxSize> struct product_size_category +{ + enum { is_large = MaxSize == Dynamic || + Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, + value = is_large ? Large + : Size == 1 ? 1 + : Small + }; +}; + +template<typename Lhs, typename Rhs> struct product_type +{ + typedef typename remove_all<Lhs>::type _Lhs; + typedef typename remove_all<Rhs>::type _Rhs; + enum { + MaxRows = _Lhs::MaxRowsAtCompileTime, + Rows = _Lhs::RowsAtCompileTime, + MaxCols = _Rhs::MaxColsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, + _Rhs::MaxRowsAtCompileTime), + Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, + _Rhs::RowsAtCompileTime), + LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD + }; + + // the splitting into different lines of code here, introducing the _select enums and the typedef below, + // is to work around an internal compiler error with gcc 4.1 and 4.2. +private: + enum { + rows_select = product_size_category<Rows,MaxRows>::value, + cols_select = product_size_category<Cols,MaxCols>::value, + depth_select = product_size_category<Depth,MaxDepth>::value + }; + typedef product_type_selector<rows_select, cols_select, depth_select> selector; + +public: + enum { + value = selector::ret + }; +#ifdef EIGEN_DEBUG_PRODUCT + static void debug() + { + EIGEN_DEBUG_VAR(Rows); + EIGEN_DEBUG_VAR(Cols); + EIGEN_DEBUG_VAR(Depth); + EIGEN_DEBUG_VAR(rows_select); + EIGEN_DEBUG_VAR(cols_select); + EIGEN_DEBUG_VAR(depth_select); + EIGEN_DEBUG_VAR(value); + } +#endif +}; + + +/* The following allows to select the kind of product at compile time + * based on the three dimensions of the product. + * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ +// FIXME I'm not sure the current mapping is the ideal one. +template<int M, int N> struct product_type_selector<M,N,1> { enum { ret = OuterProduct }; }; +template<int Depth> struct product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector<Small,1, Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<Small,Small,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<Small, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector<Small, Large, 1> { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector<Large, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; +template<> struct product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<Large,1, Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<Large,1, Large> { enum { ret = GemvProduct }; }; +template<> struct product_type_selector<Small,1, Large> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<Small,Small,Large> { enum { ret = GemmProduct }; }; +template<> struct product_type_selector<Large,Small,Large> { enum { ret = GemmProduct }; }; +template<> struct product_type_selector<Small,Large,Large> { enum { ret = GemmProduct }; }; +template<> struct product_type_selector<Large,Large,Large> { enum { ret = GemmProduct }; }; +template<> struct product_type_selector<Large,Small,Small> { enum { ret = GemmProduct }; }; +template<> struct product_type_selector<Small,Large,Small> { enum { ret = GemmProduct }; }; +template<> struct product_type_selector<Large,Large,Small> { enum { ret = GemmProduct }; }; + +} // end namespace internal + +/** \class ProductReturnType + * \ingroup Core_Module + * + * \brief Helper class to get the correct and optimized returned type of operator* + * + * \param Lhs the type of the left-hand side + * \param Rhs the type of the right-hand side + * \param ProductMode the type of the product (determined automatically by internal::product_mode) + * + * This class defines the typename Type representing the optimized product expression + * between two matrix expressions. In practice, using ProductReturnType<Lhs,Rhs>::Type + * is the recommended way to define the result type of a function returning an expression + * which involve a matrix product. The class Product should never be + * used directly. + * + * \sa class Product, MatrixBase::operator*(const MatrixBase<OtherDerived>&) + */ +template<typename Lhs, typename Rhs, int ProductType> +struct ProductReturnType +{ + // TODO use the nested type to reduce instanciations ???? +// typedef typename internal::nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested; +// typedef typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested; + + typedef GeneralProduct<Lhs/*Nested*/, Rhs/*Nested*/, ProductType> Type; +}; + +template<typename Lhs, typename Rhs> +struct ProductReturnType<Lhs,Rhs,CoeffBasedProductMode> +{ + typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested; + typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested; + typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeAssigningBit | EvalBeforeNestingBit> Type; +}; + +template<typename Lhs, typename Rhs> +struct ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode> +{ + typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested; + typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested; + typedef CoeffBasedProduct<LhsNested, RhsNested, NestByRefBit> Type; +}; + +// this is a workaround for sun CC +template<typename Lhs, typename Rhs> +struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode> +{}; + +/*********************************************************************** +* Implementation of Inner Vector Vector Product +***********************************************************************/ + +// FIXME : maybe the "inner product" could return a Scalar +// instead of a 1x1 matrix ?? +// Pro: more natural for the user +// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix +// product ends up to a row-vector times col-vector product... To tackle this use +// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x); + +namespace internal { + +template<typename Lhs, typename Rhs> +struct traits<GeneralProduct<Lhs,Rhs,InnerProduct> > + : traits<Matrix<typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> > +{}; + +} + +template<typename Lhs, typename Rhs> +class GeneralProduct<Lhs, Rhs, InnerProduct> + : internal::no_assignment_operator, + public Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> +{ + typedef Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> Base; + public: + GeneralProduct(const Lhs& lhs, const Rhs& rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); + } + + /** Convertion to scalar */ + operator const typename Base::Scalar() const { + return Base::coeff(0,0); + } +}; + +/*********************************************************************** +* Implementation of Outer Vector Vector Product +***********************************************************************/ + +namespace internal { +template<int StorageOrder> struct outer_product_selector; + +template<typename Lhs, typename Rhs> +struct traits<GeneralProduct<Lhs,Rhs,OuterProduct> > + : traits<ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> > +{}; + +} + +template<typename Lhs, typename Rhs> +class GeneralProduct<Lhs, Rhs, OuterProduct> + : public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const + { + internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); + } +}; + +namespace internal { + +template<> struct outer_product_selector<ColMajor> { + template<typename ProductType, typename Dest> + static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { + typedef typename Dest::Index Index; + // FIXME make sure lhs is sequentially stored + // FIXME not very good if rhs is real and lhs complex while alpha is real too + const Index cols = dest.cols(); + for (Index j=0; j<cols; ++j) + dest.col(j) += (alpha * prod.rhs().coeff(j)) * prod.lhs(); + } +}; + +template<> struct outer_product_selector<RowMajor> { + template<typename ProductType, typename Dest> + static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { + typedef typename Dest::Index Index; + // FIXME make sure rhs is sequentially stored + // FIXME not very good if lhs is real and rhs complex while alpha is real too + const Index rows = dest.rows(); + for (Index i=0; i<rows; ++i) + dest.row(i) += (alpha * prod.lhs().coeff(i)) * prod.rhs(); + } +}; + +} // end namespace internal + +/*********************************************************************** +* Implementation of General Matrix Vector Product +***********************************************************************/ + +/* According to the shape/flags of the matrix we have to distinghish 3 different cases: + * 1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine + * 2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine + * 3 - all other cases are handled using a simple loop along the outer-storage direction. + * Therefore we need a lower level meta selector. + * Furthermore, if the matrix is the rhs, then the product has to be transposed. + */ +namespace internal { + +template<typename Lhs, typename Rhs> +struct traits<GeneralProduct<Lhs,Rhs,GemvProduct> > + : traits<ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> > +{}; + +template<int Side, int StorageOrder, bool BlasCompatible> +struct gemv_selector; + +} // end namespace internal + +template<typename Lhs, typename Rhs> +class GeneralProduct<Lhs, Rhs, GemvProduct> + : public ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + typedef typename Lhs::Scalar LhsScalar; + typedef typename Rhs::Scalar RhsScalar; + + GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + { +// EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value), +// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; + typedef typename internal::conditional<int(Side)==OnTheRight,_LhsNested,_RhsNested>::type MatrixType; + + template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const + { + eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); + internal::gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor, + bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)>::run(*this, dst, alpha); + } +}; + +namespace internal { + +// The vector is on the left => transposition +template<int StorageOrder, bool BlasCompatible> +struct gemv_selector<OnTheLeft,StorageOrder,BlasCompatible> +{ + template<typename ProductType, typename Dest> + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + Transpose<Dest> destT(dest); + enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; + gemv_selector<OnTheRight,OtherStorageOrder,BlasCompatible> + ::run(GeneralProduct<Transpose<const typename ProductType::_RhsNested>,Transpose<const typename ProductType::_LhsNested>, GemvProduct> + (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); + } +}; + +template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if; + +template<typename Scalar,int Size,int MaxSize> +struct gemv_static_vector_if<Scalar,Size,MaxSize,false> +{ + EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } +}; + +template<typename Scalar,int Size> +struct gemv_static_vector_if<Scalar,Size,Dynamic,true> +{ + EIGEN_STRONG_INLINE Scalar* data() { return 0; } +}; + +template<typename Scalar,int Size,int MaxSize> +struct gemv_static_vector_if<Scalar,Size,MaxSize,true> +{ + #if EIGEN_ALIGN_STATICALLY + internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0> m_data; + EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } + #else + // Some architectures cannot align on the stack, + // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. + enum { + ForceAlignment = internal::packet_traits<Scalar>::Vectorizable, + PacketSize = internal::packet_traits<Scalar>::size + }; + internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize)+(ForceAlignment?PacketSize:0),0> m_data; + EIGEN_STRONG_INLINE Scalar* data() { + return ForceAlignment + ? reinterpret_cast<Scalar*>((reinterpret_cast<size_t>(m_data.array) & ~(size_t(15))) + 16) + : m_data.array; + } + #endif +}; + +template<> struct gemv_selector<OnTheRight,ColMajor,true> +{ + template<typename ProductType, typename Dest> + static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename ProductType::Index Index; + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::RealScalar RealScalar; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest; + + ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); + ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, + ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex), + MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal + }; + + gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest; + + bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0)); + bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; + + RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha); + + ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), + evalToDest ? dest.data() : static_dest.data()); + + if(!evalToDest) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = dest.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + if(!alphaIsCompatible) + { + MappedDest(actualDestPtr, dest.size()).setZero(); + compatibleAlpha = RhsScalar(1); + } + else + MappedDest(actualDestPtr, dest.size()) = dest; + } + + general_matrix_vector_product + <Index,LhsScalar,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhs.data(), actualRhs.innerStride(), + actualDestPtr, 1, + compatibleAlpha); + + if (!evalToDest) + { + if(!alphaIsCompatible) + dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); + else + dest = MappedDest(actualDestPtr, dest.size()); + } + } +}; + +template<> struct gemv_selector<OnTheRight,RowMajor,true> +{ + template<typename ProductType, typename Dest> + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::Index Index; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::_ActualRhsType _ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + + typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 + }; + + gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs; + + ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), + DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data()); + + if(!DirectlyUseRhs) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = actualRhs.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs; + } + + general_matrix_vector_product + <Index,LhsScalar,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhsPtr, 1, + dest.data(), dest.innerStride(), + actualAlpha); + } +}; + +template<> struct gemv_selector<OnTheRight,ColMajor,false> +{ + template<typename ProductType, typename Dest> + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure dest is sequentially stored in memory, otherwise use a temp + const Index size = prod.rhs().rows(); + for(Index k=0; k<size; ++k) + dest += (alpha*prod.rhs().coeff(k)) * prod.lhs().col(k); + } +}; + +template<> struct gemv_selector<OnTheRight,RowMajor,false> +{ + template<typename ProductType, typename Dest> + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp + const Index rows = prod.rows(); + for(Index i=0; i<rows; ++i) + dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum(); + } +}; + +} // end namespace internal + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** \returns the matrix product of \c *this and \a other. + * + * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*(). + * + * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*() + */ +template<typename Derived> +template<typename OtherDerived> +inline const typename ProductReturnType<Derived, OtherDerived>::Type +MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const +{ + // A note regarding the function declaration: In MSVC, this function will sometimes + // not be inlined since DenseStorage is an unwindable object for dynamic + // matrices and product types are holding a member to store the result. + // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) +#ifdef EIGEN_DEBUG_PRODUCT + internal::product_type<Derived,OtherDerived>::debug(); +#endif + return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); +} + +/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. + * + * The returned product will behave like any other expressions: the coefficients of the product will be + * computed once at a time as requested. This might be useful in some extremely rare cases when only + * a small and no coherent fraction of the result's coefficients have to be computed. + * + * \warning This version of the matrix product can be much much slower. So use it only if you know + * what you are doing and that you measured a true speed improvement. + * + * \sa operator*(const MatrixBase&) + */ +template<typename Derived> +template<typename OtherDerived> +const typename LazyProductReturnType<Derived,OtherDerived>::Type +MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const +{ + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) + + return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h b/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h index 8ed83532712..858fb243ec8 100644 --- a/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERIC_PACKET_MATH_H #define EIGEN_GENERIC_PACKET_MATH_H +namespace Eigen { + namespace internal { /** \internal @@ -312,7 +299,7 @@ template<int Offset,typename PacketType> struct palign_impl { // by default data are aligned, so there is nothing to be done :) - inline static void run(PacketType&, const PacketType&) {} + static inline void run(PacketType&, const PacketType&) {} }; /** \internal update \a first using the concatenation of the \a Offset last elements @@ -335,5 +322,7 @@ template<> inline std::complex<double> pmul(const std::complex<double>& a, const } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_GENERIC_PACKET_MATH_H diff --git a/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h b/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h index 144145a955c..e63726c4735 100644 --- a/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h +++ b/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h @@ -4,24 +4,9 @@ // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GLOBAL_FUNCTIONS_H #define EIGEN_GLOBAL_FUNCTIONS_H @@ -66,13 +51,36 @@ namespace std template<typename Derived> inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived> - pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) { \ - return x.derived().pow(exponent); \ + pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) { + return x.derived().pow(exponent); + } + + template<typename Derived> + inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived> + pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<Derived>& exponents) + { + return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>( + x.derived(), + exponents.derived() + ); } } namespace Eigen { + /** + * \brief Component-wise division of a scalar by array elements. + **/ + template <typename Derived> + inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived> + operator/(typename Derived::Scalar s, const Eigen::ArrayBase<Derived>& a) + { + return Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>( + a.derived(), + Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>(s) + ); + } + namespace internal { EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op) diff --git a/extern/Eigen3/Eigen/src/Core/IO.h b/extern/Eigen3/Eigen/src/Core/IO.h index f3cfcdbf4a3..cc8e18a0076 100644 --- a/extern/Eigen3/Eigen/src/Core/IO.h +++ b/extern/Eigen3/Eigen/src/Core/IO.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_IO_H #define EIGEN_IO_H +namespace Eigen { + enum { DontAlignCols = 1 }; enum { StreamPrecision = -1, FullPrecision = -2 }; @@ -171,7 +158,7 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& return s; } - const typename Derived::Nested m = _m; + typename Derived::Nested m = _m; typedef typename Derived::Scalar Scalar; typedef typename Derived::Index Index; @@ -257,4 +244,6 @@ std::ostream & operator << return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); } +} // end namespace Eigen + #endif // EIGEN_IO_H diff --git a/extern/Eigen3/Eigen/src/Core/Map.h b/extern/Eigen3/Eigen/src/Core/Map.h index 2bf80b3af3d..15a19226e29 100644 --- a/extern/Eigen3/Eigen/src/Core/Map.h +++ b/extern/Eigen3/Eigen/src/Core/Map.h @@ -4,28 +4,15 @@ // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MAP_H #define EIGEN_MAP_H +namespace Eigen { + /** \class Map * \ingroup Core_Module * @@ -200,4 +187,6 @@ inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> this->_set_noalias(Eigen::Map<const Matrix>(data)); } +} // end namespace Eigen + #endif // EIGEN_MAP_H diff --git a/extern/Eigen3/Eigen/src/Core/MapBase.h b/extern/Eigen3/Eigen/src/Core/MapBase.h index 9426e2d24dd..a388d61ea92 100644 --- a/extern/Eigen3/Eigen/src/Core/MapBase.h +++ b/extern/Eigen3/Eigen/src/Core/MapBase.h @@ -4,24 +4,9 @@ // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MAPBASE_H #define EIGEN_MAPBASE_H @@ -30,6 +15,7 @@ EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \ YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT) +namespace Eigen { /** \class MapBase * \ingroup Core_Module @@ -251,5 +237,6 @@ template<typename Derived> class MapBase<Derived, WriteAccessors> using Base::Base::operator=; }; +} // end namespace Eigen #endif // EIGEN_MAPBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/MathFunctions.h b/extern/Eigen3/Eigen/src/Core/MathFunctions.h index 2b454db21e9..05e913f2fec 100644 --- a/extern/Eigen3/Eigen/src/Core/MathFunctions.h +++ b/extern/Eigen3/Eigen/src/Core/MathFunctions.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATHFUNCTIONS_H #define EIGEN_MATHFUNCTIONS_H +namespace Eigen { + namespace internal { /** \internal \struct global_math_functions_filtering_base @@ -309,8 +296,7 @@ struct abs2_impl<std::complex<RealScalar> > { static inline RealScalar run(const std::complex<RealScalar>& x) { - using std::norm; - return norm(x); + return real(x)*real(x) + imag(x)*imag(x); } }; @@ -553,7 +539,7 @@ struct pow_default_impl<Scalar, true> { static inline Scalar run(Scalar x, Scalar y) { - Scalar res = 1; + Scalar res(1); eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0); if(y & 1) res *= x; y >>= 1; @@ -838,6 +824,19 @@ template<> struct scalar_fuzzy_impl<bool> }; +/**************************************************************************** +* Special functions * +****************************************************************************/ + +// std::isfinite is non standard, so let's define our own version, +// even though it is not very efficient. +template<typename T> bool (isfinite)(const T& x) +{ + return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest(); +} + } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_MATHFUNCTIONS_H diff --git a/extern/Eigen3/Eigen/src/Core/Matrix.h b/extern/Eigen3/Eigen/src/Core/Matrix.h index 982c9256af0..99160b591b0 100644 --- a/extern/Eigen3/Eigen/src/Core/Matrix.h +++ b/extern/Eigen3/Eigen/src/Core/Matrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIX_H #define EIGEN_MATRIX_H +namespace Eigen { + /** \class Matrix * \ingroup Core_Module * @@ -411,25 +398,8 @@ EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) #undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES #undef EIGEN_MAKE_TYPEDEFS +#undef EIGEN_MAKE_FIXED_TYPEDEFS -#undef EIGEN_MAKE_TYPEDEFS_LARGE - -#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ -using Eigen::Matrix##SizeSuffix##TypeSuffix; \ -using Eigen::Vector##SizeSuffix##TypeSuffix; \ -using Eigen::RowVector##SizeSuffix##TypeSuffix; - -#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ - -#define EIGEN_USING_MATRIX_TYPEDEFS \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) +} // end namespace Eigen #endif // EIGEN_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/MatrixBase.h b/extern/Eigen3/Eigen/src/Core/MatrixBase.h index 62877bce09e..c1e0ed132cc 100644 --- a/extern/Eigen3/Eigen/src/Core/MatrixBase.h +++ b/extern/Eigen3/Eigen/src/Core/MatrixBase.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIXBASE_H #define EIGEN_MATRIXBASE_H +namespace Eigen { + /** \class MatrixBase * \ingroup Core_Module * @@ -250,8 +237,7 @@ template<typename Derived> class MatrixBase // huuuge hack. make Eigen2's matrix.part<Diagonal>() work in eigen3. Problem: Diagonal is now a class template instead // of an integer constant. Solution: overload the part() method template wrt template parameters list. - // Note: replacing next line by "template<template<typename T, int n> class U>" produces a mysterious error C2082 in MSVC. - template<template<typename, int> class U> + template<template<typename T, int n> class U> const DiagonalWrapper<ConstDiagonalReturnType> part() const { return diagonal().asDiagonal(); } #endif // EIGEN2_SUPPORT @@ -331,7 +317,7 @@ template<typename Derived> class MatrixBase /** \returns an \link ArrayBase Array \endlink expression of this matrix * \sa ArrayBase::matrix() */ ArrayWrapper<Derived> array() { return derived(); } - const ArrayWrapper<Derived> array() const { return derived(); } + const ArrayWrapper<const Derived> array() const { return derived(); } /////////// LU module /////////// @@ -466,6 +452,8 @@ template<typename Derived> class MatrixBase const MatrixFunctionReturnValue<Derived> sinh() const; const MatrixFunctionReturnValue<Derived> cos() const; const MatrixFunctionReturnValue<Derived> sin() const; + const MatrixSquareRootReturnValue<Derived> sqrt() const; + const MatrixLogarithmReturnValue<Derived> log() const; #ifdef EIGEN2_SUPPORT template<typename ProductDerived, typename Lhs, typename Rhs> @@ -512,10 +500,12 @@ template<typename Derived> class MatrixBase protected: // mixing arrays and matrices is not legal template<typename OtherDerived> Derived& operator+=(const ArrayBase<OtherDerived>& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} // mixing arrays and matrices is not legal template<typename OtherDerived> Derived& operator-=(const ArrayBase<OtherDerived>& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} }; +} // end namespace Eigen + #endif // EIGEN_MATRIXBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/NestByValue.h b/extern/Eigen3/Eigen/src/Core/NestByValue.h index a6104d2a426..a893b1761b5 100644 --- a/extern/Eigen3/Eigen/src/Core/NestByValue.h +++ b/extern/Eigen3/Eigen/src/Core/NestByValue.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_NESTBYVALUE_H #define EIGEN_NESTBYVALUE_H +namespace Eigen { + /** \class NestByValue * \ingroup Core_Module * @@ -119,4 +106,6 @@ DenseBase<Derived>::nestByValue() const return NestByValue<Derived>(derived()); } +} // end namespace Eigen + #endif // EIGEN_NESTBYVALUE_H diff --git a/extern/Eigen3/Eigen/src/Core/NoAlias.h b/extern/Eigen3/Eigen/src/Core/NoAlias.h index da64affcf9a..ecb3fa2850e 100644 --- a/extern/Eigen3/Eigen/src/Core/NoAlias.h +++ b/extern/Eigen3/Eigen/src/Core/NoAlias.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_NOALIAS_H #define EIGEN_NOALIAS_H +namespace Eigen { + /** \class NoAlias * \ingroup Core_Module * @@ -133,4 +120,6 @@ NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias() return derived(); } +} // end namespace Eigen + #endif // EIGEN_NOALIAS_H diff --git a/extern/Eigen3/Eigen/src/Core/NumTraits.h b/extern/Eigen3/Eigen/src/Core/NumTraits.h index 73ef05dfe7a..c94ef026b42 100644 --- a/extern/Eigen3/Eigen/src/Core/NumTraits.h +++ b/extern/Eigen3/Eigen/src/Core/NumTraits.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_NUMTRAITS_H #define EIGEN_NUMTRAITS_H +namespace Eigen { + /** \class NumTraits * \ingroup Core_Module * @@ -81,14 +68,14 @@ template<typename T> struct GenericNumTraits >::type NonInteger; typedef T Nested; - inline static Real epsilon() { return std::numeric_limits<T>::epsilon(); } - inline static Real dummy_precision() + static inline Real epsilon() { return std::numeric_limits<T>::epsilon(); } + static inline Real dummy_precision() { // make sure to override this for floating-point types return Real(0); } - inline static T highest() { return (std::numeric_limits<T>::max)(); } - inline static T lowest() { return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); } + static inline T highest() { return (std::numeric_limits<T>::max)(); } + static inline T lowest() { return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); } #ifdef EIGEN2_SUPPORT enum { @@ -104,12 +91,12 @@ template<typename T> struct NumTraits : GenericNumTraits<T> template<> struct NumTraits<float> : GenericNumTraits<float> { - inline static float dummy_precision() { return 1e-5f; } + static inline float dummy_precision() { return 1e-5f; } }; template<> struct NumTraits<double> : GenericNumTraits<double> { - inline static double dummy_precision() { return 1e-12; } + static inline double dummy_precision() { return 1e-12; } }; template<> struct NumTraits<long double> @@ -130,8 +117,8 @@ template<typename _Real> struct NumTraits<std::complex<_Real> > MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost }; - inline static Real epsilon() { return NumTraits<Real>::epsilon(); } - inline static Real dummy_precision() { return NumTraits<Real>::dummy_precision(); } + static inline Real epsilon() { return NumTraits<Real>::epsilon(); } + static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); } }; template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols> @@ -155,6 +142,6 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > }; }; - +} // end namespace Eigen #endif // EIGEN_NUMTRAITS_H diff --git a/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h b/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h index a064e053e51..bc29f814205 100644 --- a/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PERMUTATIONMATRIX_H #define EIGEN_PERMUTATIONMATRIX_H +namespace Eigen { + template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKind> class PermutedImpl; /** \class PermutationBase @@ -56,6 +43,8 @@ namespace internal { template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> struct permut_matrix_product_retval; +template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> +struct permut_sparsematrix_product_retval; enum PermPermProduct_t {PermPermProduct}; } // end namespace internal @@ -511,7 +500,7 @@ class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesTyp protected: - const typename IndicesType::Nested m_indices; + typename IndicesType::Nested m_indices; }; /** \returns the matrix with the permutation applied to the columns. @@ -608,7 +597,7 @@ struct permut_matrix_product_retval protected: const PermutationType& m_permutation; - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; /* Template partial specialization for transposed/inverse permutations */ @@ -693,4 +682,6 @@ const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() con return derived(); } +} // end namespace Eigen + #endif // EIGEN_PERMUTATIONMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h b/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h index 612254e9da9..71c74309acc 100644 --- a/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h +++ b/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DENSESTORAGEBASE_H #define EIGEN_DENSESTORAGEBASE_H @@ -32,6 +17,8 @@ # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED #endif +namespace Eigen { + namespace internal { template<typename Index> @@ -47,13 +34,13 @@ EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols) throw_std_bad_alloc(); } -template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl; +template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl; template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl; } // end namespace internal -/** +/** \class PlainObjectBase * \brief %Dense storage base class for matrices and arrays. * * This class can be extended with the help of the plugin mechanism described on the page @@ -61,8 +48,29 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct m * * \sa \ref TopicClassHierarchy */ +#ifdef EIGEN_PARSED_BY_DOXYGEN +namespace internal { + +// this is a warkaround to doxygen not being able to understand the inheritence logic +// when it is hidden by the dense_xpr_base helper struct. +template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > + : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > + : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; + +} // namespace internal + +template<typename Derived> +class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived> +#else template<typename Derived> class PlainObjectBase : public internal::dense_xpr_base<Derived>::type +#endif { public: enum { Options = internal::traits<Derived>::Options }; @@ -443,68 +451,68 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type * \see class Map */ //@{ - inline static ConstMapType Map(const Scalar* data) + static inline ConstMapType Map(const Scalar* data) { return ConstMapType(data); } - inline static MapType Map(Scalar* data) + static inline MapType Map(Scalar* data) { return MapType(data); } - inline static ConstMapType Map(const Scalar* data, Index size) + static inline ConstMapType Map(const Scalar* data, Index size) { return ConstMapType(data, size); } - inline static MapType Map(Scalar* data, Index size) + static inline MapType Map(Scalar* data, Index size) { return MapType(data, size); } - inline static ConstMapType Map(const Scalar* data, Index rows, Index cols) + static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) { return ConstMapType(data, rows, cols); } - inline static MapType Map(Scalar* data, Index rows, Index cols) + static inline MapType Map(Scalar* data, Index rows, Index cols) { return MapType(data, rows, cols); } - inline static ConstAlignedMapType MapAligned(const Scalar* data) + static inline ConstAlignedMapType MapAligned(const Scalar* data) { return ConstAlignedMapType(data); } - inline static AlignedMapType MapAligned(Scalar* data) + static inline AlignedMapType MapAligned(Scalar* data) { return AlignedMapType(data); } - inline static ConstAlignedMapType MapAligned(const Scalar* data, Index size) + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) { return ConstAlignedMapType(data, size); } - inline static AlignedMapType MapAligned(Scalar* data, Index size) + static inline AlignedMapType MapAligned(Scalar* data, Index size) { return AlignedMapType(data, size); } - inline static ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) { return ConstAlignedMapType(data, rows, cols); } - inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) + static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) { return AlignedMapType(data, rows, cols); } template<int Outer, int Inner> - inline static typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride) + static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride) { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); } template<int Outer, int Inner> - inline static typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride) + static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride) { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); } template<int Outer, int Inner> - inline static typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) + static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); } template<int Outer, int Inner> - inline static typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride) + static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride) { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); } template<int Outer, int Inner> - inline static typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) + static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } template<int Outer, int Inner> - inline static typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) + static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } template<int Outer, int Inner> - inline static typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride) + static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride) { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } template<int Outer, int Inner> - inline static typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride) + static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride) { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } template<int Outer, int Inner> - inline static typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) + static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } template<int Outer, int Inner> - inline static typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride) + static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride) { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } template<int Outer, int Inner> - inline static typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) + static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } template<int Outer, int Inner> - inline static typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) + static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } //@} @@ -594,6 +602,9 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type template<typename T0, typename T1> EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) { + EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) && + bool(NumTraits<T1>::IsInteger), + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); internal::check_rows_cols_for_overflow(rows, cols); @@ -623,7 +634,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type public: #ifndef EIGEN_PARSED_BY_DOXYGEN - EIGEN_STRONG_INLINE static void _check_template_params() + static EIGEN_STRONG_INLINE void _check_template_params() { EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) @@ -751,4 +762,6 @@ struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_DENSESTORAGEBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/Product.h b/extern/Eigen3/Eigen/src/Core/Product.h index e2035b242b1..30aa8943b4c 100644 --- a/extern/Eigen3/Eigen/src/Core/Product.h +++ b/extern/Eigen3/Eigen/src/Core/Product.h @@ -1,625 +1,98 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PRODUCT_H #define EIGEN_PRODUCT_H -/** \class GeneralProduct +template<typename Lhs, typename Rhs> class Product; +template<typename Lhs, typename Rhs, typename StorageKind> class ProductImpl; + +/** \class Product * \ingroup Core_Module * - * \brief Expression of the product of two general matrices or vectors + * \brief Expression of the product of two arbitrary matrices or vectors * - * \param LhsNested the type used to store the left-hand side - * \param RhsNested the type used to store the right-hand side - * \param ProductMode the type of the product + * \param Lhs the type of the left-hand side expression + * \param Rhs the type of the right-hand side expression * - * This class represents an expression of the product of two general matrices. - * We call a general matrix, a dense matrix with full storage. For instance, - * This excludes triangular, selfadjoint, and sparse matrices. - * It is the return type of the operator* between general matrices. Its template - * arguments are determined automatically by ProductReturnType. Therefore, - * GeneralProduct should never be used direclty. To determine the result type of a - * function which involves a matrix product, use ProductReturnType::Type. + * This class represents an expression of the product of two arbitrary matrices. * - * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase<OtherDerived>&) */ -template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value> -class GeneralProduct; - -enum { - Large = 2, - Small = 3 -}; namespace internal { - -template<int Rows, int Cols, int Depth> struct product_type_selector; - -template<int Size, int MaxSize> struct product_size_category -{ - enum { is_large = MaxSize == Dynamic || - Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, - value = is_large ? Large - : Size == 1 ? 1 - : Small - }; -}; - -template<typename Lhs, typename Rhs> struct product_type -{ - typedef typename remove_all<Lhs>::type _Lhs; - typedef typename remove_all<Rhs>::type _Rhs; - enum { - MaxRows = _Lhs::MaxRowsAtCompileTime, - Rows = _Lhs::RowsAtCompileTime, - MaxCols = _Rhs::MaxColsAtCompileTime, - Cols = _Rhs::ColsAtCompileTime, - MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, - _Rhs::MaxRowsAtCompileTime), - Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, - _Rhs::RowsAtCompileTime), - LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD - }; - - // the splitting into different lines of code here, introducing the _select enums and the typedef below, - // is to work around an internal compiler error with gcc 4.1 and 4.2. -private: - enum { - rows_select = product_size_category<Rows,MaxRows>::value, - cols_select = product_size_category<Cols,MaxCols>::value, - depth_select = product_size_category<Depth,MaxDepth>::value - }; - typedef product_type_selector<rows_select, cols_select, depth_select> selector; - -public: +template<typename Lhs, typename Rhs> +struct traits<Product<Lhs, Rhs> > +{ + typedef MatrixXpr XprKind; + typedef typename remove_all<Lhs>::type LhsCleaned; + typedef typename remove_all<Rhs>::type RhsCleaned; + typedef typename scalar_product_traits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar; + typedef typename promote_storage_type<typename traits<LhsCleaned>::StorageKind, + typename traits<RhsCleaned>::StorageKind>::ret StorageKind; + typedef typename promote_index_type<typename traits<LhsCleaned>::Index, + typename traits<RhsCleaned>::Index>::type Index; enum { - value = selector::ret + RowsAtCompileTime = LhsCleaned::RowsAtCompileTime, + ColsAtCompileTime = RhsCleaned::ColsAtCompileTime, + MaxRowsAtCompileTime = LhsCleaned::MaxRowsAtCompileTime, + MaxColsAtCompileTime = RhsCleaned::MaxColsAtCompileTime, + Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0), // TODO should be no storage order + CoeffReadCost = 0 // TODO CoeffReadCost should not be part of the expression traits }; -#ifdef EIGEN_DEBUG_PRODUCT - static void debug() - { - EIGEN_DEBUG_VAR(Rows); - EIGEN_DEBUG_VAR(Cols); - EIGEN_DEBUG_VAR(Depth); - EIGEN_DEBUG_VAR(rows_select); - EIGEN_DEBUG_VAR(cols_select); - EIGEN_DEBUG_VAR(depth_select); - EIGEN_DEBUG_VAR(value); - } -#endif }; - - -/* The following allows to select the kind of product at compile time - * based on the three dimensions of the product. - * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ -// FIXME I'm not sure the current mapping is the ideal one. -template<int M, int N> struct product_type_selector<M,N,1> { enum { ret = OuterProduct }; }; -template<int Depth> struct product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; -template<> struct product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; -template<> struct product_type_selector<Small,1, Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<Small,Small,Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<Small, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; }; -template<> struct product_type_selector<Small, Large, 1> { enum { ret = LazyCoeffBasedProductMode }; }; -template<> struct product_type_selector<Large, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; }; -template<> struct product_type_selector<1, Large,Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; -template<> struct product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<Large,1, Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<Large,1, Large> { enum { ret = GemvProduct }; }; -template<> struct product_type_selector<Small,1, Large> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<Small,Small,Large> { enum { ret = GemmProduct }; }; -template<> struct product_type_selector<Large,Small,Large> { enum { ret = GemmProduct }; }; -template<> struct product_type_selector<Small,Large,Large> { enum { ret = GemmProduct }; }; -template<> struct product_type_selector<Large,Large,Large> { enum { ret = GemmProduct }; }; -template<> struct product_type_selector<Large,Small,Small> { enum { ret = GemmProduct }; }; -template<> struct product_type_selector<Small,Large,Small> { enum { ret = GemmProduct }; }; -template<> struct product_type_selector<Large,Large,Small> { enum { ret = GemmProduct }; }; - } // end namespace internal -/** \class ProductReturnType - * \ingroup Core_Module - * - * \brief Helper class to get the correct and optimized returned type of operator* - * - * \param Lhs the type of the left-hand side - * \param Rhs the type of the right-hand side - * \param ProductMode the type of the product (determined automatically by internal::product_mode) - * - * This class defines the typename Type representing the optimized product expression - * between two matrix expressions. In practice, using ProductReturnType<Lhs,Rhs>::Type - * is the recommended way to define the result type of a function returning an expression - * which involve a matrix product. The class Product should never be - * used directly. - * - * \sa class Product, MatrixBase::operator*(const MatrixBase<OtherDerived>&) - */ -template<typename Lhs, typename Rhs, int ProductType> -struct ProductReturnType -{ - // TODO use the nested type to reduce instanciations ???? -// typedef typename internal::nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested; -// typedef typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested; - - typedef GeneralProduct<Lhs/*Nested*/, Rhs/*Nested*/, ProductType> Type; -}; - -template<typename Lhs, typename Rhs> -struct ProductReturnType<Lhs,Rhs,CoeffBasedProductMode> -{ - typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested; - typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested; - typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeAssigningBit | EvalBeforeNestingBit> Type; -}; - -template<typename Lhs, typename Rhs> -struct ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode> -{ - typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested; - typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested; - typedef CoeffBasedProduct<LhsNested, RhsNested, NestByRefBit> Type; -}; - -// this is a workaround for sun CC -template<typename Lhs, typename Rhs> -struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode> -{}; - -/*********************************************************************** -* Implementation of Inner Vector Vector Product -***********************************************************************/ - -// FIXME : maybe the "inner product" could return a Scalar -// instead of a 1x1 matrix ?? -// Pro: more natural for the user -// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix -// product ends up to a row-vector times col-vector product... To tackle this use -// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x); - -namespace internal { - -template<typename Lhs, typename Rhs> -struct traits<GeneralProduct<Lhs,Rhs,InnerProduct> > - : traits<Matrix<typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> > -{}; - -} - -template<typename Lhs, typename Rhs> -class GeneralProduct<Lhs, Rhs, InnerProduct> - : internal::no_assignment_operator, - public Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> -{ - typedef Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> Base; - public: - GeneralProduct(const Lhs& lhs, const Rhs& rhs) - { - EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); - } - - /** Convertion to scalar */ - operator const typename Base::Scalar() const { - return Base::coeff(0,0); - } -}; - -/*********************************************************************** -* Implementation of Outer Vector Vector Product -***********************************************************************/ - -namespace internal { -template<int StorageOrder> struct outer_product_selector; - -template<typename Lhs, typename Rhs> -struct traits<GeneralProduct<Lhs,Rhs,OuterProduct> > - : traits<ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> > -{}; - -} template<typename Lhs, typename Rhs> -class GeneralProduct<Lhs, Rhs, OuterProduct> - : public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> +class Product : public ProductImpl<Lhs,Rhs,typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, + typename internal::traits<Rhs>::StorageKind>::ret> { public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) - - GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + + typedef typename ProductImpl< + Lhs, Rhs, + typename internal::promote_storage_type<typename Lhs::StorageKind, + typename Rhs::StorageKind>::ret>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(Product) + + typedef typename Lhs::Nested LhsNested; + typedef typename Rhs::Nested RhsNested; + typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned; + typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned; + + Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) { - EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + eigen_assert(lhs.cols() == rhs.rows() + && "invalid matrix product" + && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); } - template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const - { - internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); - } -}; + inline Index rows() const { return m_lhs.rows(); } + inline Index cols() const { return m_rhs.cols(); } -namespace internal { + const LhsNestedCleaned& lhs() const { return m_lhs; } + const RhsNestedCleaned& rhs() const { return m_rhs; } -template<> struct outer_product_selector<ColMajor> { - template<typename ProductType, typename Dest> - static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { - typedef typename Dest::Index Index; - // FIXME make sure lhs is sequentially stored - // FIXME not very good if rhs is real and lhs complex while alpha is real too - const Index cols = dest.cols(); - for (Index j=0; j<cols; ++j) - dest.col(j) += (alpha * prod.rhs().coeff(j)) * prod.lhs(); - } -}; + protected: -template<> struct outer_product_selector<RowMajor> { - template<typename ProductType, typename Dest> - static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { - typedef typename Dest::Index Index; - // FIXME make sure rhs is sequentially stored - // FIXME not very good if lhs is real and rhs complex while alpha is real too - const Index rows = dest.rows(); - for (Index i=0; i<rows; ++i) - dest.row(i) += (alpha * prod.lhs().coeff(i)) * prod.rhs(); - } + const LhsNested m_lhs; + const RhsNested m_rhs; }; -} // end namespace internal - -/*********************************************************************** -* Implementation of General Matrix Vector Product -***********************************************************************/ - -/* According to the shape/flags of the matrix we have to distinghish 3 different cases: - * 1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine - * 2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine - * 3 - all other cases are handled using a simple loop along the outer-storage direction. - * Therefore we need a lower level meta selector. - * Furthermore, if the matrix is the rhs, then the product has to be transposed. - */ -namespace internal { - -template<typename Lhs, typename Rhs> -struct traits<GeneralProduct<Lhs,Rhs,GemvProduct> > - : traits<ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> > -{}; - -template<int Side, int StorageOrder, bool BlasCompatible> -struct gemv_selector; - -} // end namespace internal - template<typename Lhs, typename Rhs> -class GeneralProduct<Lhs, Rhs, GemvProduct> - : public ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> +class ProductImpl<Lhs,Rhs,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs> >::type { + typedef Product<Lhs, Rhs> Derived; public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) - - typedef typename Lhs::Scalar LhsScalar; - typedef typename Rhs::Scalar RhsScalar; - - GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - { -// EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value), -// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - } - - enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; - typedef typename internal::conditional<int(Side)==OnTheRight,_LhsNested,_RhsNested>::type MatrixType; - - template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const - { - eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); - internal::gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor, - bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)>::run(*this, dst, alpha); - } -}; - -namespace internal { - -// The vector is on the left => transposition -template<int StorageOrder, bool BlasCompatible> -struct gemv_selector<OnTheLeft,StorageOrder,BlasCompatible> -{ - template<typename ProductType, typename Dest> - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - Transpose<Dest> destT(dest); - enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; - gemv_selector<OnTheRight,OtherStorageOrder,BlasCompatible> - ::run(GeneralProduct<Transpose<const typename ProductType::_RhsNested>,Transpose<const typename ProductType::_LhsNested>, GemvProduct> - (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); - } -}; - -template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if; - -template<typename Scalar,int Size,int MaxSize> -struct gemv_static_vector_if<Scalar,Size,MaxSize,false> -{ - EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } -}; - -template<typename Scalar,int Size> -struct gemv_static_vector_if<Scalar,Size,Dynamic,true> -{ - EIGEN_STRONG_INLINE Scalar* data() { return 0; } -}; - -template<typename Scalar,int Size,int MaxSize> -struct gemv_static_vector_if<Scalar,Size,MaxSize,true> -{ - #if EIGEN_ALIGN_STATICALLY - internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0> m_data; - EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } - #else - // Some architectures cannot align on the stack, - // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. - enum { - ForceAlignment = internal::packet_traits<Scalar>::Vectorizable, - PacketSize = internal::packet_traits<Scalar>::size - }; - internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize)+(ForceAlignment?PacketSize:0),0> m_data; - EIGEN_STRONG_INLINE Scalar* data() { - return ForceAlignment - ? reinterpret_cast<Scalar*>((reinterpret_cast<size_t>(m_data.array) & ~(size_t(15))) + 16) - : m_data.array; - } - #endif -}; - -template<> struct gemv_selector<OnTheRight,ColMajor,true> -{ - template<typename ProductType, typename Dest> - static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename ProductType::Index Index; - typedef typename ProductType::LhsScalar LhsScalar; - typedef typename ProductType::RhsScalar RhsScalar; - typedef typename ProductType::Scalar ResScalar; - typedef typename ProductType::RealScalar RealScalar; - typedef typename ProductType::ActualLhsType ActualLhsType; - typedef typename ProductType::ActualRhsType ActualRhsType; - typedef typename ProductType::LhsBlasTraits LhsBlasTraits; - typedef typename ProductType::RhsBlasTraits RhsBlasTraits; - typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest; - - const ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); - const ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); - - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) - * RhsBlasTraits::extractScalarFactor(prod.rhs()); - - enum { - // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 - // on, the other hand it is good for the cache to pack the vector anyways... - EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, - ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex), - MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal - }; - - gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest; - - // this is written like this (i.e., with a ?:) to workaround an ICE with ICC 12 - bool alphaIsCompatible = (!ComplexByReal) ? true : (imag(actualAlpha)==RealScalar(0)); - bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; - - RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha); - - ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), - evalToDest ? dest.data() : static_dest.data()); - - if(!evalToDest) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = dest.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - if(!alphaIsCompatible) - { - MappedDest(actualDestPtr, dest.size()).setZero(); - compatibleAlpha = RhsScalar(1); - } - else - MappedDest(actualDestPtr, dest.size()) = dest; - } - general_matrix_vector_product - <Index,LhsScalar,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run( - actualLhs.rows(), actualLhs.cols(), - &actualLhs.coeffRef(0,0), actualLhs.outerStride(), - actualRhs.data(), actualRhs.innerStride(), - actualDestPtr, 1, - compatibleAlpha); - - if (!evalToDest) - { - if(!alphaIsCompatible) - dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); - else - dest = MappedDest(actualDestPtr, dest.size()); - } - } -}; - -template<> struct gemv_selector<OnTheRight,RowMajor,true> -{ - template<typename ProductType, typename Dest> - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename ProductType::LhsScalar LhsScalar; - typedef typename ProductType::RhsScalar RhsScalar; - typedef typename ProductType::Scalar ResScalar; - typedef typename ProductType::Index Index; - typedef typename ProductType::ActualLhsType ActualLhsType; - typedef typename ProductType::ActualRhsType ActualRhsType; - typedef typename ProductType::_ActualRhsType _ActualRhsType; - typedef typename ProductType::LhsBlasTraits LhsBlasTraits; - typedef typename ProductType::RhsBlasTraits RhsBlasTraits; - - typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs()); - typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs()); - - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) - * RhsBlasTraits::extractScalarFactor(prod.rhs()); - - enum { - // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 - // on, the other hand it is good for the cache to pack the vector anyways... - DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 - }; - - gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs; - - ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), - DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data()); - - if(!DirectlyUseRhs) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = actualRhs.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs; - } - - general_matrix_vector_product - <Index,LhsScalar,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run( - actualLhs.rows(), actualLhs.cols(), - &actualLhs.coeffRef(0,0), actualLhs.outerStride(), - actualRhsPtr, 1, - &dest.coeffRef(0,0), dest.innerStride(), - actualAlpha); - } -}; - -template<> struct gemv_selector<OnTheRight,ColMajor,false> -{ - template<typename ProductType, typename Dest> - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename Dest::Index Index; - // TODO makes sure dest is sequentially stored in memory, otherwise use a temp - const Index size = prod.rhs().rows(); - for(Index k=0; k<size; ++k) - dest += (alpha*prod.rhs().coeff(k)) * prod.lhs().col(k); - } -}; - -template<> struct gemv_selector<OnTheRight,RowMajor,false> -{ - template<typename ProductType, typename Dest> - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename Dest::Index Index; - // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp - const Index rows = prod.rows(); - for(Index i=0; i<rows; ++i) - dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum(); - } + typedef typename internal::dense_xpr_base<Product<Lhs, Rhs> >::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) }; -} // end namespace internal - -/*************************************************************************** -* Implementation of matrix base methods -***************************************************************************/ - -/** \returns the matrix product of \c *this and \a other. - * - * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*(). - * - * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*() - */ -template<typename Derived> -template<typename OtherDerived> -inline const typename ProductReturnType<Derived,OtherDerived>::Type -MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const -{ - // A note regarding the function declaration: In MSVC, this function will sometimes - // not be inlined since DenseStorage is an unwindable object for dynamic - // matrices and product types are holding a member to store the result. - // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. - enum { - ProductIsValid = Derived::ColsAtCompileTime==Dynamic - || OtherDerived::RowsAtCompileTime==Dynamic - || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), - AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, - SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) - }; - // note to the lost user: - // * for a dot product use: v1.dot(v2) - // * for a coeff-wise product use: v1.cwiseProduct(v2) - EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) - EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) - EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) -#ifdef EIGEN_DEBUG_PRODUCT - internal::product_type<Derived,OtherDerived>::debug(); -#endif - return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); -} - -/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. - * - * The returned product will behave like any other expressions: the coefficients of the product will be - * computed once at a time as requested. This might be useful in some extremely rare cases when only - * a small and no coherent fraction of the result's coefficients have to be computed. - * - * \warning This version of the matrix product can be much much slower. So use it only if you know - * what you are doing and that you measured a true speed improvement. - * - * \sa operator*(const MatrixBase&) - */ -template<typename Derived> -template<typename OtherDerived> -const typename LazyProductReturnType<Derived,OtherDerived>::Type -MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const -{ - enum { - ProductIsValid = Derived::ColsAtCompileTime==Dynamic - || OtherDerived::RowsAtCompileTime==Dynamic - || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), - AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, - SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) - }; - // note to the lost user: - // * for a dot product use: v1.dot(v2) - // * for a coeff-wise product use: v1.cwiseProduct(v2) - EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) - EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) - EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) - - return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); -} - #endif // EIGEN_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/ProductBase.h b/extern/Eigen3/Eigen/src/Core/ProductBase.h index 91975880fdc..ec12e5c9f6b 100644 --- a/extern/Eigen3/Eigen/src/Core/ProductBase.h +++ b/extern/Eigen3/Eigen/src/Core/ProductBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PRODUCTBASE_H #define EIGEN_PRODUCTBASE_H +namespace Eigen { + /** \class ProductBase * \ingroup Core_Module * @@ -115,10 +102,10 @@ class ProductBase : public MatrixBase<Derived> inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); } template<typename Dest> - inline void addTo(Dest& dst) const { scaleAndAddTo(dst,1); } + inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); } template<typename Dest> - inline void subTo(Dest& dst) const { scaleAndAddTo(dst,-1); } + inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); } template<typename Dest> inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } @@ -181,8 +168,8 @@ class ProductBase : public MatrixBase<Derived> protected: - const LhsNested m_lhs; - const RhsNested m_rhs; + LhsNested m_lhs; + RhsNested m_rhs; mutable PlainObject m_result; }; @@ -286,5 +273,6 @@ Derived& MatrixBase<Derived>::lazyAssign(const ProductBase<ProductDerived, Lhs,R return derived(); } +} // end namespace Eigen #endif // EIGEN_PRODUCTBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/Random.h b/extern/Eigen3/Eigen/src/Core/Random.h index b7d90103a5b..a9f7f434666 100644 --- a/extern/Eigen3/Eigen/src/Core/Random.h +++ b/extern/Eigen3/Eigen/src/Core/Random.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_RANDOM_H #define EIGEN_RANDOM_H +namespace Eigen { + namespace internal { template<typename Scalar> struct scalar_random_op { @@ -160,4 +147,6 @@ PlainObjectBase<Derived>::setRandom(Index rows, Index cols) return setRandom(); } +} // end namespace Eigen + #endif // EIGEN_RANDOM_H diff --git a/extern/Eigen3/Eigen/src/Core/Redux.h b/extern/Eigen3/Eigen/src/Core/Redux.h index f9f5a95d546..b7ce7c658a2 100644 --- a/extern/Eigen3/Eigen/src/Core/Redux.h +++ b/extern/Eigen3/Eigen/src/Core/Redux.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REDUX_H #define EIGEN_REDUX_H +namespace Eigen { + namespace internal { // TODO @@ -95,7 +82,7 @@ struct redux_novec_unroller typedef typename Derived::Scalar Scalar; - EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func& func) + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func) { return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func), redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func)); @@ -112,7 +99,7 @@ struct redux_novec_unroller<Func, Derived, Start, 1> typedef typename Derived::Scalar Scalar; - EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func&) + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&) { return mat.coeffByOuterInner(outer, inner); } @@ -125,7 +112,7 @@ template<typename Func, typename Derived, int Start> struct redux_novec_unroller<Func, Derived, Start, 0> { typedef typename Derived::Scalar Scalar; - EIGEN_STRONG_INLINE static Scalar run(const Derived&, const Func&) { return Scalar(); } + static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); } }; /*** vectorization ***/ @@ -141,7 +128,7 @@ struct redux_vec_unroller typedef typename Derived::Scalar Scalar; typedef typename packet_traits<Scalar>::type PacketScalar; - EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func& func) + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func) { return func.packetOp( redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func), @@ -162,7 +149,7 @@ struct redux_vec_unroller<Func, Derived, Start, 1> typedef typename Derived::Scalar Scalar; typedef typename packet_traits<Scalar>::type PacketScalar; - EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func&) + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&) { return mat.template packetByOuterInner<alignment>(outer, inner); } @@ -214,20 +201,33 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling> const Index size = mat.size(); eigen_assert(size && "you are using an empty matrix"); const Index packetSize = packet_traits<Scalar>::size; - const Index alignedStart = first_aligned(mat); + const Index alignedStart = internal::first_aligned(mat); enum { alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit) ? Aligned : Unaligned }; - const Index alignedSize = ((size-alignedStart)/packetSize)*packetSize; - const Index alignedEnd = alignedStart + alignedSize; + const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize); + const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize); + const Index alignedEnd2 = alignedStart + alignedSize2; + const Index alignedEnd = alignedStart + alignedSize; Scalar res; if(alignedSize) { - PacketScalar packet_res = mat.template packet<alignment>(alignedStart); - for(Index index = alignedStart + packetSize; index < alignedEnd; index += packetSize) - packet_res = func.packetOp(packet_res, mat.template packet<alignment>(index)); - res = func.predux(packet_res); + PacketScalar packet_res0 = mat.template packet<alignment>(alignedStart); + if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop + { + PacketScalar packet_res1 = mat.template packet<alignment>(alignedStart+packetSize); + for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize) + { + packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(index)); + packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment>(index+packetSize)); + } + + packet_res0 = func.packetOp(packet_res0,packet_res1); + if(alignedEnd>alignedEnd2) + packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(alignedEnd2)); + } + res = func.predux(packet_res0); for(Index index = 0; index < alignedStart; ++index) res = func(res,mat.coeff(index)); @@ -296,7 +296,7 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling> Size = Derived::SizeAtCompileTime, VectorizedSize = (Size / PacketSize) * PacketSize }; - EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func) + static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) { eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func)); @@ -401,4 +401,6 @@ MatrixBase<Derived>::trace() const return derived().diagonal().sum(); } +} // end namespace Eigen + #endif // EIGEN_REDUX_H diff --git a/extern/Eigen3/Eigen/src/Core/Replicate.h b/extern/Eigen3/Eigen/src/Core/Replicate.h index 4c171f8d580..b61fdc29e2f 100644 --- a/extern/Eigen3/Eigen/src/Core/Replicate.h +++ b/extern/Eigen3/Eigen/src/Core/Replicate.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REPLICATE_H #define EIGEN_REPLICATE_H +namespace Eigen { + /** * \class Replicate * \ingroup Core_Module @@ -92,7 +79,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate } template<typename OriginalMatrixType> - inline Replicate(const OriginalMatrixType& matrix, int rowFactor, int colFactor) + inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor) : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) { EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value), @@ -127,9 +114,13 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate return m_matrix.template packet<LoadMode>(actual_row, actual_col); } + const _MatrixTypeNested& nestedExpression() const + { + return m_matrix; + } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor; const internal::variable_if_dynamic<Index, ColFactor> m_colFactor; }; @@ -181,4 +172,6 @@ VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); } +} // end namespace Eigen + #endif // EIGEN_REPLICATE_H diff --git a/extern/Eigen3/Eigen/src/Core/ReturnByValue.h b/extern/Eigen3/Eigen/src/Core/ReturnByValue.h index 24c5a4e215d..613912ffa8c 100644 --- a/extern/Eigen3/Eigen/src/Core/ReturnByValue.h +++ b/extern/Eigen3/Eigen/src/Core/ReturnByValue.h @@ -4,28 +4,15 @@ // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_RETURNBYVALUE_H #define EIGEN_RETURNBYVALUE_H +namespace Eigen { + /** \class ReturnByValue * \ingroup Core_Module * @@ -96,4 +83,6 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_RETURNBYVALUE_H diff --git a/extern/Eigen3/Eigen/src/Core/Reverse.h b/extern/Eigen3/Eigen/src/Core/Reverse.h index 600744ae758..e30ae3d281b 100644 --- a/extern/Eigen3/Eigen/src/Core/Reverse.h +++ b/extern/Eigen3/Eigen/src/Core/Reverse.h @@ -5,28 +5,15 @@ // Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com> // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REVERSE_H #define EIGEN_REVERSE_H +namespace Eigen { + /** \class Reverse * \ingroup Core_Module * @@ -183,8 +170,14 @@ template<typename MatrixType, int Direction> class Reverse m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x)); } + const typename internal::remove_all<typename MatrixType::Nested>::type& + nestedExpression() const + { + return m_matrix; + } + protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; /** \returns an expression of the reverse of *this. @@ -226,5 +219,6 @@ inline void DenseBase<Derived>::reverseInPlace() derived() = derived().reverse().eval(); } +} // end namespace Eigen #endif // EIGEN_REVERSE_H diff --git a/extern/Eigen3/Eigen/src/Core/Select.h b/extern/Eigen3/Eigen/src/Core/Select.h index d0cd66a261a..2bf6e91d0aa 100644 --- a/extern/Eigen3/Eigen/src/Core/Select.h +++ b/extern/Eigen3/Eigen/src/Core/Select.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELECT_H #define EIGEN_SELECT_H +namespace Eigen { + /** \class Select * \ingroup Core_Module * @@ -101,10 +88,25 @@ class Select : internal::no_assignment_operator, return m_else.coeff(i); } + const ConditionMatrixType& conditionMatrix() const + { + return m_condition; + } + + const ThenMatrixType& thenMatrix() const + { + return m_then; + } + + const ElseMatrixType& elseMatrix() const + { + return m_else; + } + protected: - const typename ConditionMatrixType::Nested m_condition; - const typename ThenMatrixType::Nested m_then; - const typename ElseMatrixType::Nested m_else; + typename ConditionMatrixType::Nested m_condition; + typename ThenMatrixType::Nested m_then; + typename ElseMatrixType::Nested m_else; }; @@ -155,4 +157,6 @@ DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar, derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); } +} // end namespace Eigen + #endif // EIGEN_SELECT_H diff --git a/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h b/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h index 4bb68755eee..82cc4da736a 100644 --- a/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h +++ b/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINTMATRIX_H #define EIGEN_SELFADJOINTMATRIX_H +namespace Eigen { + /** \class SelfAdjointView * \ingroup Core_Module * @@ -82,7 +69,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView }; typedef typename MatrixType::PlainObject PlainObject; - inline SelfAdjointView(const MatrixType& matrix) : m_matrix(matrix) + inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) {} inline Index rows() const { return m_matrix.rows(); } @@ -199,7 +186,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView #endif protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; }; @@ -222,7 +209,7 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), U row = (UnrollCount-1) % Derived1::RowsAtCompileTime }; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount-1, ClearOpposite>::run(dst, src); @@ -236,7 +223,7 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), U template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, 0, ClearOpposite> { - inline static void run(Derived1 &, const Derived2 &) {} + static inline void run(Derived1 &, const Derived2 &) {} }; template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite> @@ -247,7 +234,7 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), U row = (UnrollCount-1) % Derived1::RowsAtCompileTime }; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount-1, ClearOpposite>::run(dst, src); @@ -261,14 +248,14 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), U template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, 0, ClearOpposite> { - inline static void run(Derived1 &, const Derived2 &) {} + static inline void run(Derived1 &, const Derived2 &) {} }; template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dynamic, ClearOpposite> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -285,7 +272,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dyn template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dynamic, ClearOpposite> { - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { typedef typename Derived1::Index Index; for(Index i = 0; i < dst.rows(); ++i) @@ -322,4 +309,6 @@ MatrixBase<Derived>::selfadjointView() return derived(); } +} // end namespace Eigen + #endif // EIGEN_SELFADJOINTMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h b/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h index 4e9ca88745d..0caf2bab1d8 100644 --- a/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFCWISEBINARYOP_H #define EIGEN_SELFCWISEBINARYOP_H +namespace Eigen { + /** \class SelfCwiseBinaryOp * \ingroup Core_Module * @@ -163,6 +150,16 @@ template<typename BinaryOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp return Base::operator=(rhs); } + Lhs& expression() const + { + return m_matrix; + } + + const BinaryOp& functor() const + { + return m_functor; + } + protected: Lhs& m_matrix; const BinaryOp& m_functor; @@ -192,4 +189,6 @@ inline Derived& DenseBase<Derived>::operator/=(const Scalar& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_SELFCWISEBINARYOP_H diff --git a/extern/Eigen3/Eigen/src/Core/SolveTriangular.h b/extern/Eigen3/Eigen/src/Core/SolveTriangular.h index a23014a343f..ef17f288e29 100644 --- a/extern/Eigen3/Eigen/src/Core/SolveTriangular.h +++ b/extern/Eigen3/Eigen/src/Core/SolveTriangular.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SOLVETRIANGULAR_H #define EIGEN_SOLVETRIANGULAR_H +namespace Eigen { + namespace internal { // Forward declarations: @@ -98,12 +85,22 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic> typedef typename Rhs::Index Index; typedef blas_traits<Lhs> LhsProductTraits; typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType; + static void run(const Lhs& lhs, Rhs& rhs) { - const ActualLhsType actualLhs = LhsProductTraits::extract(lhs); + typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs); + + const Index size = lhs.rows(); + const Index othersize = Side==OnTheLeft? rhs.cols() : rhs.rows(); + + typedef internal::gemm_blocking_space<(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, + Rhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxRowsAtCompileTime,4> BlockingType; + + BlockingType blocking(rhs.rows(), rhs.cols(), size); + triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor, (Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor> - ::run(lhs.rows(), Side==OnTheLeft? rhs.cols() : rhs.rows(), &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride()); + ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking); } }; @@ -177,10 +174,8 @@ template<int Side, typename OtherDerived> void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived>& _other) const { OtherDerived& other = _other.const_cast_derived(); - eigen_assert(cols() == rows()); - eigen_assert( (Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols()) ); - eigen_assert(!(Mode & ZeroDiag)); - eigen_assert((Mode & (Upper|Lower)) != 0); + eigen_assert( cols() == rows() && ((Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols())) ); + eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit && OtherDerived::IsVectorAtCompileTime }; typedef typename internal::conditional<copy, @@ -255,9 +250,11 @@ template<int Side, typename TriangularType, typename Rhs> struct triangular_solv protected: const TriangularType& m_triangularMatrix; - const typename Rhs::Nested m_rhs; + typename Rhs::Nested m_rhs; }; } // namespace internal +} // end namespace Eigen + #endif // EIGEN_SOLVETRIANGULAR_H diff --git a/extern/Eigen3/Eigen/src/Core/StableNorm.h b/extern/Eigen3/Eigen/src/Core/StableNorm.h index f667272e4a4..d8bf7db70e4 100644 --- a/extern/Eigen3/Eigen/src/Core/StableNorm.h +++ b/extern/Eigen3/Eigen/src/Core/StableNorm.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STABLENORM_H #define EIGEN_STABLENORM_H +namespace Eigen { + namespace internal { template<typename ExpressionType, typename Scalar> inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale) @@ -58,9 +45,9 @@ MatrixBase<Derived>::stableNorm() const { using std::min; const Index blockSize = 4096; - RealScalar scale = 0; - RealScalar invScale = 1; - RealScalar ssq = 0; // sum of square + RealScalar scale(0); + RealScalar invScale(1); + RealScalar ssq(0); // sum of square enum { Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0 }; @@ -187,4 +174,6 @@ MatrixBase<Derived>::hypotNorm() const return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>()); } +} // end namespace Eigen + #endif // EIGEN_STABLENORM_H diff --git a/extern/Eigen3/Eigen/src/Core/Stride.h b/extern/Eigen3/Eigen/src/Core/Stride.h index 0430f111627..1e3f5fe9fff 100644 --- a/extern/Eigen3/Eigen/src/Core/Stride.h +++ b/extern/Eigen3/Eigen/src/Core/Stride.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STRIDE_H #define EIGEN_STRIDE_H +namespace Eigen { + /** \class Stride * \ingroup Core_Module * @@ -116,4 +103,6 @@ class OuterStride : public Stride<Value, 0> OuterStride(Index v) : Base(v,0) {} }; +} // end namespace Eigen + #endif // EIGEN_STRIDE_H diff --git a/extern/Eigen3/Eigen/src/Core/Swap.h b/extern/Eigen3/Eigen/src/Core/Swap.h index 5fb03286675..fd73cf3ad7e 100644 --- a/extern/Eigen3/Eigen/src/Core/Swap.h +++ b/extern/Eigen3/Eigen/src/Core/Swap.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SWAP_H #define EIGEN_SWAP_H +namespace Eigen { + /** \class SwapWrapper * \ingroup Core_Module * @@ -52,6 +39,15 @@ template<typename ExpressionType> class SwapWrapper inline Index cols() const { return m_expression.cols(); } inline Index outerStride() const { return m_expression.outerStride(); } inline Index innerStride() const { return m_expression.innerStride(); } + + typedef typename internal::conditional< + internal::is_lvalue<ExpressionType>::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } + inline const Scalar* data() const { return m_expression.data(); } inline Scalar& coeffRef(Index row, Index col) { @@ -119,8 +115,12 @@ template<typename ExpressionType> class SwapWrapper _other.template writePacket<LoadMode>(index, tmp); } + ExpressionType& expression() const { return m_expression; } + protected: ExpressionType& m_expression; }; +} // end namespace Eigen + #endif // EIGEN_SWAP_H diff --git a/extern/Eigen3/Eigen/src/Core/Transpose.h b/extern/Eigen3/Eigen/src/Core/Transpose.h index 3f7c7df6ee1..045a1cce671 100644 --- a/extern/Eigen3/Eigen/src/Core/Transpose.h +++ b/extern/Eigen3/Eigen/src/Core/Transpose.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSPOSE_H #define EIGEN_TRANSPOSE_H +namespace Eigen { + /** \class Transpose * \ingroup Core_Module * @@ -91,7 +78,7 @@ template<typename MatrixType> class Transpose nestedExpression() { return m_matrix.const_cast_derived(); } protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; namespace internal { @@ -152,12 +139,12 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense> return derived().nestedExpression().coeffRef(index); } - inline const CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return derived().nestedExpression().coeff(col, row); } - inline const CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index index) const { return derived().nestedExpression().coeff(index); } @@ -422,4 +409,6 @@ void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const } #endif +} // end namespace Eigen + #endif // EIGEN_TRANSPOSE_H diff --git a/extern/Eigen3/Eigen/src/Core/Transpositions.h b/extern/Eigen3/Eigen/src/Core/Transpositions.h index 88fdfb2226f..2cd268a5fa0 100644 --- a/extern/Eigen3/Eigen/src/Core/Transpositions.h +++ b/extern/Eigen3/Eigen/src/Core/Transpositions.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSPOSITIONS_H #define EIGEN_TRANSPOSITIONS_H +namespace Eigen { + /** \class Transpositions * \ingroup Core_Module * @@ -404,7 +391,7 @@ struct transposition_matrix_product_retval protected: const TranspositionType& m_transpositions; - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; } // end namespace internal @@ -444,4 +431,6 @@ class Transpose<TranspositionsBase<TranspositionsDerived> > const TranspositionType& m_transpositions; }; +} // end namespace Eigen + #endif // EIGEN_TRANSPOSITIONS_H diff --git a/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h b/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h index 033e81036f3..de9540063c2 100644 --- a/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULARMATRIX_H #define EIGEN_TRIANGULARMATRIX_H +namespace Eigen { + namespace internal { template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval; @@ -273,11 +260,8 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView inline const TriangularView<MatrixConjugateReturnType,Mode> conjugate() const { return m_matrix.conjugate(); } - /** \sa MatrixBase::adjoint() */ - inline TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint() - { return m_matrix.adjoint(); } /** \sa MatrixBase::adjoint() const */ - inline const TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const + inline const TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const { return m_matrix.adjoint(); } /** \sa MatrixBase::transpose() */ @@ -288,11 +272,13 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView } /** \sa MatrixBase::transpose() const */ inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const - { return m_matrix.transpose(); } + { + return m_matrix.transpose(); + } /** Efficient triangular matrix times vector/matrix product */ template<typename OtherDerived> - TriangularProduct<Mode,true,MatrixType,false,OtherDerived,OtherDerived::IsVectorAtCompileTime> + TriangularProduct<Mode,true,MatrixType,false,OtherDerived, OtherDerived::IsVectorAtCompileTime> operator*(const MatrixBase<OtherDerived>& rhs) const { return TriangularProduct @@ -375,7 +361,8 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView template<typename OtherDerived> void swap(MatrixBase<OtherDerived> const & other) { - TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived()); + SwapWrapper<MatrixType> swaper(const_cast<MatrixType&>(m_matrix)); + TriangularView<SwapWrapper<MatrixType>,Mode>(swaper).lazyAssign(other.derived()); } Scalar determinant() const @@ -433,7 +420,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView template<typename ProductDerived, typename Lhs, typename Rhs> EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase<ProductDerived, Lhs,Rhs>& prod, const Scalar& alpha); - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; }; /*************************************************************************** @@ -452,7 +439,7 @@ struct triangular_assignment_selector typedef typename Derived1::Scalar Scalar; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src); @@ -480,7 +467,7 @@ struct triangular_assignment_selector template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite> { - inline static void run(Derived1 &, const Derived2 &) {} + static inline void run(Derived1 &, const Derived2 &) {} }; template<typename Derived1, typename Derived2, bool ClearOpposite> @@ -488,7 +475,7 @@ struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearO { typedef typename Derived1::Index Index; typedef typename Derived1::Scalar Scalar; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -506,7 +493,7 @@ template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -524,7 +511,7 @@ template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -542,7 +529,7 @@ template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -560,7 +547,7 @@ template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -580,7 +567,7 @@ template<typename Derived1, typename Derived2, bool ClearOpposite> struct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite> { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -835,4 +822,6 @@ bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const return true; } +} // end namespace Eigen + #endif // EIGEN_TRIANGULARMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/VectorBlock.h b/extern/Eigen3/Eigen/src/Core/VectorBlock.h index 858e4c7865a..6f4effca055 100644 --- a/extern/Eigen3/Eigen/src/Core/VectorBlock.h +++ b/extern/Eigen3/Eigen/src/Core/VectorBlock.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_VECTORBLOCK_H #define EIGEN_VECTORBLOCK_H +namespace Eigen { + /** \class VectorBlock * \ingroup Core_Module * @@ -292,5 +279,6 @@ DenseBase<Derived>::tail() const return typename ConstFixedSegmentReturnType<Size>::Type(derived(), size() - Size); } +} // end namespace Eigen #endif // EIGEN_VECTORBLOCK_H diff --git a/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h b/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h index 20f6881575b..862c0f33608 100644 --- a/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h +++ b/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARTIAL_REDUX_H #define EIGEN_PARTIAL_REDUX_H +namespace Eigen { + /** \class PartialReduxExpr * \ingroup Core_Module * @@ -110,7 +97,7 @@ class PartialReduxExpr : internal::no_assignment_operator, } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; const MemberOp m_functor; }; @@ -237,7 +224,10 @@ template<typename ExpressionType, int Direction> class VectorwiseOp typename ExtendedType<OtherDerived>::Type extendedTo(const DenseBase<OtherDerived>& other) const { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxColsAtCompileTime==1), + YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED) + EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxRowsAtCompileTime==1), + YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED) return typename ExtendedType<OtherDerived>::Type (other.derived(), Direction==Vertical ? 1 : m_matrix.rows(), @@ -418,10 +408,9 @@ template<typename ExpressionType, int Direction> class VectorwiseOp ExpressionType& operator=(const DenseBase<OtherDerived>& other) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) //eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME - for(Index j=0; j<subVectors(); ++j) - subVector(j) = other; - return const_cast<ExpressionType&>(m_matrix); + return const_cast<ExpressionType&>(m_matrix = extendedTo(other.derived())); } /** Adds the vector \a other to each subvector of \c *this */ @@ -429,9 +418,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp ExpressionType& operator+=(const DenseBase<OtherDerived>& other) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - for(Index j=0; j<subVectors(); ++j) - subVector(j) += other.derived(); - return const_cast<ExpressionType&>(m_matrix); + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return const_cast<ExpressionType&>(m_matrix += extendedTo(other.derived())); } /** Substracts the vector \a other to each subvector of \c *this */ @@ -439,8 +427,29 @@ template<typename ExpressionType, int Direction> class VectorwiseOp ExpressionType& operator-=(const DenseBase<OtherDerived>& other) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - for(Index j=0; j<subVectors(); ++j) - subVector(j) -= other.derived(); + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return const_cast<ExpressionType&>(m_matrix -= extendedTo(other.derived())); + } + + /** Multiples each subvector of \c *this by the vector \a other */ + template<typename OtherDerived> + ExpressionType& operator*=(const DenseBase<OtherDerived>& other) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + m_matrix *= extendedTo(other.derived()); + return const_cast<ExpressionType&>(m_matrix); + } + + /** Divides each subvector of \c *this by the vector \a other */ + template<typename OtherDerived> + ExpressionType& operator/=(const DenseBase<OtherDerived>& other) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + m_matrix /= extendedTo(other.derived()); return const_cast<ExpressionType&>(m_matrix); } @@ -451,7 +460,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp const typename ExtendedType<OtherDerived>::Type> operator+(const DenseBase<OtherDerived>& other) const { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) return m_matrix + extendedTo(other.derived()); } @@ -462,10 +472,39 @@ template<typename ExpressionType, int Direction> class VectorwiseOp const typename ExtendedType<OtherDerived>::Type> operator-(const DenseBase<OtherDerived>& other) const { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) return m_matrix - extendedTo(other.derived()); } + /** Returns the expression where each subvector is the product of the vector \a other + * by the corresponding subvector of \c *this */ + template<typename OtherDerived> EIGEN_STRONG_INLINE + CwiseBinaryOp<internal::scalar_product_op<Scalar>, + const ExpressionTypeNestedCleaned, + const typename ExtendedType<OtherDerived>::Type> + operator*(const DenseBase<OtherDerived>& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return m_matrix * extendedTo(other.derived()); + } + + /** Returns the expression where each subvector is the quotient of the corresponding + * subvector of \c *this by the vector \a other */ + template<typename OtherDerived> + CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, + const ExpressionTypeNestedCleaned, + const typename ExtendedType<OtherDerived>::Type> + operator/(const DenseBase<OtherDerived>& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return m_matrix / extendedTo(other.derived()); + } + /////////// Geometry module /////////// #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS @@ -509,7 +548,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp * Example: \include MatrixBase_colwise.cpp * Output: \verbinclude MatrixBase_colwise.out * - * \sa rowwise(), class VectorwiseOp + * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template<typename Derived> inline const typename DenseBase<Derived>::ConstColwiseReturnType @@ -520,7 +559,7 @@ DenseBase<Derived>::colwise() const /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations * - * \sa rowwise(), class VectorwiseOp + * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template<typename Derived> inline typename DenseBase<Derived>::ColwiseReturnType @@ -534,7 +573,7 @@ DenseBase<Derived>::colwise() * Example: \include MatrixBase_rowwise.cpp * Output: \verbinclude MatrixBase_rowwise.out * - * \sa colwise(), class VectorwiseOp + * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template<typename Derived> inline const typename DenseBase<Derived>::ConstRowwiseReturnType @@ -545,7 +584,7 @@ DenseBase<Derived>::rowwise() const /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations * - * \sa colwise(), class VectorwiseOp + * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template<typename Derived> inline typename DenseBase<Derived>::RowwiseReturnType @@ -554,4 +593,6 @@ DenseBase<Derived>::rowwise() return derived(); } +} // end namespace Eigen + #endif // EIGEN_PARTIAL_REDUX_H diff --git a/extern/Eigen3/Eigen/src/Core/Visitor.h b/extern/Eigen3/Eigen/src/Core/Visitor.h index 378ebcba174..916bfd096a9 100644 --- a/extern/Eigen3/Eigen/src/Core/Visitor.h +++ b/extern/Eigen3/Eigen/src/Core/Visitor.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_VISITOR_H #define EIGEN_VISITOR_H +namespace Eigen { + namespace internal { template<typename Visitor, typename Derived, int UnrollCount> @@ -35,7 +22,7 @@ struct visitor_impl row = (UnrollCount-1) % Derived::RowsAtCompileTime }; - inline static void run(const Derived &mat, Visitor& visitor) + static inline void run(const Derived &mat, Visitor& visitor) { visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor); visitor(mat.coeff(row, col), row, col); @@ -45,7 +32,7 @@ struct visitor_impl template<typename Visitor, typename Derived> struct visitor_impl<Visitor, Derived, 1> { - inline static void run(const Derived &mat, Visitor& visitor) + static inline void run(const Derived &mat, Visitor& visitor) { return visitor.init(mat.coeff(0, 0), 0, 0); } @@ -55,7 +42,7 @@ template<typename Visitor, typename Derived> struct visitor_impl<Visitor, Derived, Dynamic> { typedef typename Derived::Index Index; - inline static void run(const Derived& mat, Visitor& visitor) + static inline void run(const Derived& mat, Visitor& visitor) { visitor.init(mat.coeff(0,0), 0, 0); for(Index i = 1; i < mat.rows(); ++i) @@ -245,4 +232,6 @@ DenseBase<Derived>::maxCoeff(IndexType* index) const return maxVisitor.res; } +} // end namespace Eigen + #endif // EIGEN_VISITOR_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h index f8adf1b6385..68d9a2bff8d 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h +++ b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_ALTIVEC_H #define EIGEN_COMPLEX_ALTIVEC_H +namespace Eigen { + namespace internal { static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 }; @@ -168,7 +155,7 @@ template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const P template<int Offset> struct palign_impl<Offset,Packet2cf> { - EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second) + static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) { if (Offset==1) { @@ -225,4 +212,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& x } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COMPLEX_ALTIVEC_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h index dc34ebbd660..75de1931198 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Konstantinos Margaritis <markos@codex.gr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKET_MATH_ALTIVEC_H #define EIGEN_PACKET_MATH_ALTIVEC_H +namespace Eigen { + namespace internal { #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD @@ -487,7 +474,7 @@ template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a) template<int Offset> struct palign_impl<Offset,Packet4f> { - EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second) + static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) { if (Offset!=0) first = vec_sld(first, second, Offset*4); @@ -497,7 +484,7 @@ struct palign_impl<Offset,Packet4f> template<int Offset> struct palign_impl<Offset,Packet4i> { - EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second) + static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) { if (Offset!=0) first = vec_sld(first, second, Offset*4); @@ -506,4 +493,6 @@ struct palign_impl<Offset,Packet4i> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PACKET_MATH_ALTIVEC_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h b/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h index 957adc8fe42..097373c84dc 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h +++ b/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. /* All the parameters defined in this file can be specialized in the diff --git a/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h index 212887184c2..795b4be7303 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h +++ b/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_NEON_H #define EIGEN_COMPLEX_NEON_H +namespace Eigen { + namespace internal { static uint32x4_t p4ui_CONJ_XOR = EIGEN_INIT_NEON_PACKET4(0x00000000, 0x80000000, 0x00000000, 0x80000000); @@ -267,4 +254,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, con } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COMPLEX_NEON_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h index 6c7cd159097..a20250f7c65 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h @@ -5,28 +5,15 @@ // Copyright (C) 2010 Konstantinos Margaritis <markos@codex.gr> // Heavily based on Gael's SSE version. // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKET_MATH_NEON_H #define EIGEN_PACKET_MATH_NEON_H +namespace Eigen { + namespace internal { #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD @@ -158,7 +145,8 @@ template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& /*a*/, co } // for some weird raisons, it has to be overloaded for packet of integers -template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); } +template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vmlaq_f32(c,a,b); } +template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return vmlaq_s32(c,a,b); } template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return vminq_f32(a,b); } template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b) { return vminq_s32(a,b); } @@ -431,4 +419,6 @@ PALIGN_NEON(3,Packet4i,vextq_s32) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PACKET_MATH_NEON_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h index c352bb3e6cf..12df987754c 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h +++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_SSE_H #define EIGEN_COMPLEX_SSE_H +namespace Eigen { + namespace internal { //---------- float ---------- @@ -102,7 +89,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<flo Packet2cf res; #if EIGEN_GNUC_AT_MOST(4,2) // workaround annoying "may be used uninitialized in this function" warning with gcc 4.2 - res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), (const __m64*)&from); + res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), reinterpret_cast<const __m64*>(&from)); #else res.v = _mm_loadl_pi(res.v, (const __m64*)&from); #endif @@ -151,7 +138,7 @@ template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const P template<int Offset> struct palign_impl<Offset,Packet2cf> { - EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second) + static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) { if (Offset==1) { @@ -350,7 +337,7 @@ template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const template<int Offset> struct palign_impl<Offset,Packet1cd> { - EIGEN_STRONG_INLINE static void run(Packet1cd& /*first*/, const Packet1cd& /*second*/) + static EIGEN_STRONG_INLINE void run(Packet1cd& /*first*/, const Packet1cd& /*second*/) { // FIXME is it sure we never have to align a Packet1cd? // Even though a std::complex<double> has 16 bytes, it is not necessarily aligned on a 16 bytes boundary... @@ -444,4 +431,6 @@ EIGEN_STRONG_INLINE Packet1cd pcplxflip/*<Packet1cd>*/(const Packet1cd& x) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COMPLEX_SSE_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h index 9d56d82180b..3f41a4e2600 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -4,24 +4,9 @@ // Copyright (C) 2007 Julien Pommier // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. /* The sin, cos, exp, and log functions of this file come from * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ @@ -30,6 +15,8 @@ #ifndef EIGEN_MATH_FUNCTIONS_SSE_H #define EIGEN_MATH_FUNCTIONS_SSE_H +namespace Eigen { + namespace internal { template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED @@ -121,7 +108,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); - _EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647949f); + _EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647950f); _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f); _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f); @@ -168,7 +155,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x) y = pmadd(y, z, x); y = padd(y, p4f_1); - /* build 2^n */ + // build 2^n emm0 = _mm_cvttps_epi32(fx); emm0 = _mm_add_epi32(emm0, p4i_0x7f); emm0 = _mm_slli_epi32(emm0, 23); @@ -392,4 +379,6 @@ Packet4f psqrt<Packet4f>(const Packet4f& _x) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_MATH_FUNCTIONS_SSE_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h index 908e27368e8..10d9182190f 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKET_MATH_SSE_H #define EIGEN_PACKET_MATH_SSE_H +namespace Eigen { + namespace internal { #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD @@ -110,9 +97,18 @@ template<> struct unpacket_traits<Packet4f> { typedef float type; enum {size=4} template<> struct unpacket_traits<Packet2d> { typedef double type; enum {size=2}; }; template<> struct unpacket_traits<Packet4i> { typedef int type; enum {size=4}; }; +#if defined(_MSC_VER) && (_MSC_VER==1500) +// Workaround MSVC 9 internal compiler error. +// TODO: It has been detected with win64 builds (amd64), so let's check whether it also happens in 32bits+SSE mode +// TODO: let's check whether there does not exist a better fix, like adding a pset0() function. (it crashed on pset1(0)). +template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float& from) { return _mm_set_ps(from,from,from,from); } +template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set_pd(from,from); } +template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) { return _mm_set_epi32(from,from,from,from); } +#else template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float& from) { return _mm_set1_ps(from); } template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set1_pd(from); } template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) { return _mm_set1_epi32(from); } +#endif template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a) { return _mm_add_ps(pset1<Packet4f>(a), _mm_set_ps(3,2,1,0)); } template<> EIGEN_STRONG_INLINE Packet2d plset<double>(const double& a) { return _mm_add_pd(pset1<Packet2d>(a),_mm_set_pd(1,0)); } @@ -282,7 +278,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from) { - return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd((const double*)from)), 0, 0, 1, 1); + return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(from))), 0, 0, 1, 1); } template<> EIGEN_STRONG_INLINE Packet2d ploaddup<Packet2d>(const double* from) { return pset1<Packet2d>(from[0]); } @@ -302,8 +298,8 @@ template<> EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet2d& _mm_storel_pd((to), from); _mm_storeh_pd((to+1), from); } -template<> EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castps_pd(from)); } -template<> EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castsi128_pd(from)); } +template<> EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast<double*>(to), _mm_castps_pd(from)); } +template<> EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast<double*>(to), _mm_castsi128_pd(from)); } // some compilers might be tempted to perform multiple moves instead of using a vector path. template<> EIGEN_STRONG_INLINE void pstore1<Packet4f>(float* to, const float& a) @@ -541,7 +537,7 @@ template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a) template<int Offset> struct palign_impl<Offset,Packet4f> { - EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second) + static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) { if (Offset!=0) first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4)); @@ -551,7 +547,7 @@ struct palign_impl<Offset,Packet4f> template<int Offset> struct palign_impl<Offset,Packet4i> { - EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second) + static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) { if (Offset!=0) first = _mm_alignr_epi8(second,first, Offset*4); @@ -561,7 +557,7 @@ struct palign_impl<Offset,Packet4i> template<int Offset> struct palign_impl<Offset,Packet2d> { - EIGEN_STRONG_INLINE static void run(Packet2d& first, const Packet2d& second) + static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) { if (Offset==1) first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8)); @@ -572,7 +568,7 @@ struct palign_impl<Offset,Packet2d> template<int Offset> struct palign_impl<Offset,Packet4f> { - EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second) + static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) { if (Offset==1) { @@ -595,7 +591,7 @@ struct palign_impl<Offset,Packet4f> template<int Offset> struct palign_impl<Offset,Packet4i> { - EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second) + static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) { if (Offset==1) { @@ -618,7 +614,7 @@ struct palign_impl<Offset,Packet4i> template<int Offset> struct palign_impl<Offset,Packet2d> { - EIGEN_STRONG_INLINE static void run(Packet2d& first, const Packet2d& second) + static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) { if (Offset==1) { @@ -631,4 +627,6 @@ struct palign_impl<Offset,Packet2d> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PACKET_MATH_SSE_H diff --git a/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h b/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h index dc20f7e1e29..403d25fa9eb 100644 --- a/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COEFFBASED_PRODUCT_H #define EIGEN_COEFFBASED_PRODUCT_H +namespace Eigen { + namespace internal { /********************************************************************************* @@ -224,8 +211,8 @@ class CoeffBasedProduct { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this).diagonal(index); } protected: - const LhsNested m_lhs; - const RhsNested m_rhs; + typename internal::add_const_on_value_type<LhsNested>::type m_lhs; + typename internal::add_const_on_value_type<RhsNested>::type m_rhs; mutable PlainObject m_result; }; @@ -252,7 +239,7 @@ template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar> struct product_coeff_impl<DefaultTraversal, UnrollingIndex, Lhs, Rhs, RetScalar> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { product_coeff_impl<DefaultTraversal, UnrollingIndex-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res); res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col); @@ -263,7 +250,7 @@ template<typename Lhs, typename Rhs, typename RetScalar> struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { res = lhs.coeff(row, 0) * rhs.coeff(0, col); } @@ -273,7 +260,7 @@ template<typename Lhs, typename Rhs, typename RetScalar> struct product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) { eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = lhs.coeff(row, 0) * rhs.coeff(0, col); @@ -291,7 +278,7 @@ struct product_coeff_vectorized_unroller { typedef typename Lhs::Index Index; enum { PacketSize = packet_traits<typename Lhs::Scalar>::size }; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) { product_coeff_vectorized_unroller<UnrollingIndex-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres); pres = padd(pres, pmul( lhs.template packet<Aligned>(row, UnrollingIndex) , rhs.template packet<Aligned>(UnrollingIndex, col) )); @@ -302,7 +289,7 @@ template<typename Lhs, typename Rhs, typename Packet> struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) { pres = pmul(lhs.template packet<Aligned>(row, 0) , rhs.template packet<Aligned>(0, col)); } @@ -314,7 +301,7 @@ struct product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, Re typedef typename Lhs::PacketScalar Packet; typedef typename Lhs::Index Index; enum { PacketSize = packet_traits<typename Lhs::Scalar>::size }; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { Packet pres; product_coeff_vectorized_unroller<UnrollingIndex+1-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres); @@ -327,7 +314,7 @@ template<typename Lhs, typename Rhs, int LhsRows = Lhs::RowsAtCompileTime, int R struct product_coeff_vectorized_dyn_selector { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.row(row).transpose().cwiseProduct(rhs.col(col)).sum(); } @@ -339,7 +326,7 @@ template<typename Lhs, typename Rhs, int RhsCols> struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.transpose().cwiseProduct(rhs.col(col)).sum(); } @@ -349,7 +336,7 @@ template<typename Lhs, typename Rhs, int LhsRows> struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.row(row).transpose().cwiseProduct(rhs).sum(); } @@ -359,7 +346,7 @@ template<typename Lhs, typename Rhs> struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.transpose().cwiseProduct(rhs).sum(); } @@ -369,7 +356,7 @@ template<typename Lhs, typename Rhs, typename RetScalar> struct product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { product_coeff_vectorized_dyn_selector<Lhs,Rhs>::run(row, col, lhs, rhs, res); } @@ -383,7 +370,7 @@ template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int Lo struct product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res); res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex)), rhs.template packet<LoadMode>(UnrollingIndex, col), res); @@ -394,7 +381,7 @@ template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int Lo struct product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res); res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex), pset1<Packet>(rhs.coeff(UnrollingIndex, col)), res); @@ -405,7 +392,7 @@ template<typename Lhs, typename Rhs, typename Packet, int LoadMode> struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col)); } @@ -415,7 +402,7 @@ template<typename Lhs, typename Rhs, typename Packet, int LoadMode> struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col))); } @@ -425,7 +412,7 @@ template<typename Lhs, typename Rhs, typename Packet, int LoadMode> struct product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) { eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col)); @@ -438,7 +425,7 @@ template<typename Lhs, typename Rhs, typename Packet, int LoadMode> struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) { eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col))); @@ -449,4 +436,6 @@ struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COEFFBASED_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h index cd1c37c780e..5eb03c98ccf 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -3,34 +3,23 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_BLOCK_PANEL_H #define EIGEN_GENERAL_BLOCK_PANEL_H +namespace Eigen { + namespace internal { template<typename _LhsScalar, typename _RhsScalar, bool _ConjLhs=false, bool _ConjRhs=false> class gebp_traits; -inline std::ptrdiff_t manage_caching_sizes_second_if_negative(std::ptrdiff_t a, std::ptrdiff_t b) + +/** \internal \returns b if a<=0, and returns a otherwise. */ +inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a, std::ptrdiff_t b) { return a<=0 ? b : a; } @@ -38,9 +27,14 @@ inline std::ptrdiff_t manage_caching_sizes_second_if_negative(std::ptrdiff_t a, /** \internal */ inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdiff_t* l2=0) { - static std::ptrdiff_t m_l1CacheSize = manage_caching_sizes_second_if_negative(queryL1CacheSize(),8 * 1024); - static std::ptrdiff_t m_l2CacheSize = manage_caching_sizes_second_if_negative(queryTopLevelCacheSize(),1*1024*1024); - + static std::ptrdiff_t m_l1CacheSize = 0; + static std::ptrdiff_t m_l2CacheSize = 0; + if(m_l2CacheSize==0) + { + m_l1CacheSize = manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024); + m_l2CacheSize = manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024); + } + if(action==SetAction) { // set the cpu cache size and cache all block sizes from a global cache size in byte @@ -533,7 +527,7 @@ struct gebp_kernel ResPacketSize = Traits::ResPacketSize }; - EIGEN_FLATTEN_ATTRIB + EIGEN_DONT_INLINE EIGEN_FLATTEN_ATTRIB void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index rows, Index depth, Index cols, ResScalar alpha, Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0, RhsScalar* unpackedB = 0) { @@ -595,64 +589,64 @@ struct gebp_kernel if(nr==2) { LhsPacket A0, A1; - RhsPacket B0; + RhsPacket B_0; RhsPacket T0; EIGEN_ASM_COMMENT("mybegin2"); traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[1*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[1*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); traits.loadLhs(&blA[2*LhsProgress], A0); traits.loadLhs(&blA[3*LhsProgress], A1); - traits.loadRhs(&blB[2*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[3*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[2*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[3*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); traits.loadLhs(&blA[4*LhsProgress], A0); traits.loadLhs(&blA[5*LhsProgress], A1); - traits.loadRhs(&blB[4*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[5*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[4*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[5*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); traits.loadLhs(&blA[6*LhsProgress], A0); traits.loadLhs(&blA[7*LhsProgress], A1); - traits.loadRhs(&blB[6*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[7*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[6*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[7*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); EIGEN_ASM_COMMENT("myend"); } else { EIGEN_ASM_COMMENT("mybegin4"); LhsPacket A0, A1; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,T0); + traits.madd(A0,B_0,C0,T0); traits.loadRhs(&blB[2*RhsProgress], B2); - traits.madd(A1,B0,C4,B0); + traits.madd(A1,B_0,C4,B_0); traits.loadRhs(&blB[3*RhsProgress], B3); - traits.loadRhs(&blB[4*RhsProgress], B0); + traits.loadRhs(&blB[4*RhsProgress], B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.loadRhs(&blB[5*RhsProgress], B1); @@ -664,9 +658,9 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.madd(A1,B3,C7,B3); traits.loadLhs(&blA[3*LhsProgress], A1); traits.loadRhs(&blB[7*RhsProgress], B3); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[8*RhsProgress], B0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[8*RhsProgress], B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.loadRhs(&blB[9*RhsProgress], B1); @@ -679,9 +673,9 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.loadLhs(&blA[5*LhsProgress], A1); traits.loadRhs(&blB[11*RhsProgress], B3); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[12*RhsProgress], B0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[12*RhsProgress], B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.loadRhs(&blB[13*RhsProgress], B1); @@ -693,8 +687,8 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.madd(A1,B3,C7,B3); traits.loadLhs(&blA[7*LhsProgress], A1); traits.loadRhs(&blB[15*RhsProgress], B3); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.madd(A0,B2,C2,T0); @@ -712,32 +706,32 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsPacket A0, A1; - RhsPacket B0; + RhsPacket B_0; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[1*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[1*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); } else { LhsPacket A0, A1; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,T0); + traits.madd(A0,B_0,C0,T0); traits.loadRhs(&blB[2*RhsProgress], B2); - traits.madd(A1,B0,C4,B0); + traits.madd(A1,B_0,C4,B_0); traits.loadRhs(&blB[3*RhsProgress], B3); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); @@ -824,42 +818,42 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsPacket A0; - RhsPacket B0, B1; + RhsPacket B_0, B1; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[2*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[2*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadLhs(&blA[1*LhsProgress], A0); traits.loadRhs(&blB[3*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[4*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[4*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadLhs(&blA[2*LhsProgress], A0); traits.loadRhs(&blB[5*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[6*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[6*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadLhs(&blA[3*LhsProgress], A0); traits.loadRhs(&blB[7*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); } else { LhsPacket A0; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.loadRhs(&blB[2*RhsProgress], B2); traits.loadRhs(&blB[3*RhsProgress], B3); - traits.loadRhs(&blB[4*RhsProgress], B0); + traits.loadRhs(&blB[4*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadRhs(&blB[5*RhsProgress], B1); traits.madd(A0,B2,C2,B2); @@ -867,8 +861,8 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.madd(A0,B3,C3,B3); traits.loadLhs(&blA[1*LhsProgress], A0); traits.loadRhs(&blB[7*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[8*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[8*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadRhs(&blB[9*RhsProgress], B1); traits.madd(A0,B2,C2,B2); @@ -877,8 +871,8 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.loadLhs(&blA[2*LhsProgress], A0); traits.loadRhs(&blB[11*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[12*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[12*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadRhs(&blB[13*RhsProgress], B1); traits.madd(A0,B2,C2,B2); @@ -887,7 +881,7 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.loadLhs(&blA[3*LhsProgress], A0); traits.loadRhs(&blB[15*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); traits.madd(A0,B2,C2,B2); traits.madd(A0,B3,C3,B3); @@ -902,26 +896,26 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsPacket A0; - RhsPacket B0, B1; + RhsPacket B_0, B1; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); } else { LhsPacket A0; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); traits.loadRhs(&blB[2*RhsProgress], B2); traits.loadRhs(&blB[3*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); traits.madd(A0,B2,C2,B2); traits.madd(A0,B3,C3,B3); @@ -968,26 +962,26 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsScalar A0; - RhsScalar B0, B1; + RhsScalar B_0, B1; A0 = blA[k]; - B0 = blB[0]; + B_0 = blB[0]; B1 = blB[1]; - MADD(cj,A0,B0,C0,B0); + MADD(cj,A0,B_0,C0,B_0); MADD(cj,A0,B1,C1,B1); } else { LhsScalar A0; - RhsScalar B0, B1, B2, B3; + RhsScalar B_0, B1, B2, B3; A0 = blA[k]; - B0 = blB[0]; + B_0 = blB[0]; B1 = blB[1]; B2 = blB[2]; B3 = blB[3]; - MADD(cj,A0,B0,C0,B0); + MADD(cj,A0,B_0,C0,B_0); MADD(cj,A0,B1,C1,B1); MADD(cj,A0,B2,C2,B2); MADD(cj,A0,B3,C3,B3); @@ -1024,14 +1018,14 @@ EIGEN_ASM_COMMENT("mybegin4"); for(Index k=0; k<depth; k++) { LhsPacket A0, A1; - RhsPacket B0; + RhsPacket B_0; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); blB += RhsProgress; blA += 2*LhsProgress; @@ -1063,10 +1057,10 @@ EIGEN_ASM_COMMENT("mybegin4"); for(Index k=0; k<depth; k++) { LhsPacket A0; - RhsPacket B0; + RhsPacket B_0; traits.loadLhs(blA, A0); - traits.loadRhs(blB, B0); - traits.madd(A0, B0, C0, B0); + traits.loadRhs(blB, B_0); + traits.madd(A0, B_0, C0, B_0); blB += RhsProgress; blA += LhsProgress; } @@ -1088,8 +1082,8 @@ EIGEN_ASM_COMMENT("mybegin4"); for(Index k=0; k<depth; k++) { LhsScalar A0 = blA[k]; - RhsScalar B0 = blB[k]; - MADD(cj, A0, B0, C0, B0); + RhsScalar B_0 = blB[k]; + MADD(cj, A0, B_0, C0, B_0); } res[(j2+0)*resStride + i] += alpha*C0; } @@ -1100,7 +1094,7 @@ EIGEN_ASM_COMMENT("mybegin4"); #undef CJMADD // pack a block of the lhs -// The travesal is as follow (mr==4): +// The traversal is as follow (mr==4): // 0 4 8 12 ... // 1 5 9 13 ... // 2 6 10 14 ... @@ -1116,11 +1110,15 @@ EIGEN_ASM_COMMENT("mybegin4"); template<typename Scalar, typename Index, int Pack1, int Pack2, int StorageOrder, bool Conjugate, bool PanelMode> struct gemm_pack_lhs { - void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, + EIGEN_DONT_INLINE void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, Index stride=0, Index offset=0) { -// enum { PacketSize = packet_traits<Scalar>::size }; + typedef typename packet_traits<Scalar>::type Packet; + enum { PacketSize = packet_traits<Scalar>::size }; + + EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS"); eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); + eigen_assert( (StorageOrder==RowMajor) || ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) ); conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj; const_blas_data_mapper<Scalar, Index, StorageOrder> lhs(_lhs,lhsStride); Index count = 0; @@ -1128,9 +1126,44 @@ struct gemm_pack_lhs for(Index i=0; i<peeled_mc; i+=Pack1) { if(PanelMode) count += Pack1 * offset; - for(Index k=0; k<depth; k++) - for(Index w=0; w<Pack1; w++) - blockA[count++] = cj(lhs(i+w, k)); + + if(StorageOrder==ColMajor) + { + for(Index k=0; k<depth; k++) + { + Packet A, B, C, D; + if(Pack1>=1*PacketSize) A = ploadu<Packet>(&lhs(i+0*PacketSize, k)); + if(Pack1>=2*PacketSize) B = ploadu<Packet>(&lhs(i+1*PacketSize, k)); + if(Pack1>=3*PacketSize) C = ploadu<Packet>(&lhs(i+2*PacketSize, k)); + if(Pack1>=4*PacketSize) D = ploadu<Packet>(&lhs(i+3*PacketSize, k)); + if(Pack1>=1*PacketSize) { pstore(blockA+count, cj.pconj(A)); count+=PacketSize; } + if(Pack1>=2*PacketSize) { pstore(blockA+count, cj.pconj(B)); count+=PacketSize; } + if(Pack1>=3*PacketSize) { pstore(blockA+count, cj.pconj(C)); count+=PacketSize; } + if(Pack1>=4*PacketSize) { pstore(blockA+count, cj.pconj(D)); count+=PacketSize; } + } + } + else + { + for(Index k=0; k<depth; k++) + { + // TODO add a vectorized transpose here + Index w=0; + for(; w<Pack1-3; w+=4) + { + Scalar a(cj(lhs(i+w+0, k))), + b(cj(lhs(i+w+1, k))), + c(cj(lhs(i+w+2, k))), + d(cj(lhs(i+w+3, k))); + blockA[count++] = a; + blockA[count++] = b; + blockA[count++] = c; + blockA[count++] = d; + } + if(Pack1%4) + for(;w<Pack1;++w) + blockA[count++] = cj(lhs(i+w, k)); + } + } if(PanelMode) count += Pack1 * (stride-offset-depth); } if(rows-peeled_mc>=Pack2) @@ -1164,9 +1197,10 @@ struct gemm_pack_rhs<Scalar, Index, nr, ColMajor, Conjugate, PanelMode> { typedef typename packet_traits<Scalar>::type Packet; enum { PacketSize = packet_traits<Scalar>::size }; - void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, + EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0) { + EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS COLMAJOR"); eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj; Index packet_cols = (cols/nr) * nr; @@ -1211,9 +1245,10 @@ template<typename Scalar, typename Index, int nr, bool Conjugate, bool PanelMode struct gemm_pack_rhs<Scalar, Index, nr, RowMajor, Conjugate, PanelMode> { enum { PacketSize = packet_traits<Scalar>::size }; - void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, + EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0) { + EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS ROWMAJOR"); eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj; Index packet_cols = (cols/nr) * nr; @@ -1279,4 +1314,6 @@ inline void setCpuCacheSizes(std::ptrdiff_t l1, std::ptrdiff_t l2) internal::manage_caching_sizes(SetAction, &l1, &l2); } +} // end namespace Eigen + #endif // EIGEN_GENERAL_BLOCK_PANEL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h index ae94a27953b..73a465ec5ee 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_MATRIX_MATRIX_H #define EIGEN_GENERAL_MATRIX_MATRIX_H +namespace Eigen { + namespace internal { template<typename _LhsScalar, typename _RhsScalar> class level3_blocking; @@ -77,7 +64,7 @@ static void run(Index rows, Index cols, Index depth, typedef gebp_traits<LhsScalar,RhsScalar> Traits; - Index kc = blocking.kc(); // cache block size along the K direction + Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction //Index nc = blocking.nc(); // cache block size along the N direction @@ -247,7 +234,7 @@ struct gemm_functor BlockingType& m_blocking; }; -template<int StorageOrder, typename LhsScalar, typename RhsScalar, int MaxRows, int MaxCols, int MaxDepth, +template<int StorageOrder, typename LhsScalar, typename RhsScalar, int MaxRows, int MaxCols, int MaxDepth, int KcFactor=1, bool FiniteAtCompileTime = MaxRows!=Dynamic && MaxCols!=Dynamic && MaxDepth != Dynamic> class gemm_blocking_space; template<typename _LhsScalar, typename _RhsScalar> @@ -280,8 +267,8 @@ class level3_blocking inline RhsScalar* blockW() { return m_blockW; } }; -template<int StorageOrder, typename _LhsScalar, typename _RhsScalar, int MaxRows, int MaxCols, int MaxDepth> -class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, MaxDepth, true> +template<int StorageOrder, typename _LhsScalar, typename _RhsScalar, int MaxRows, int MaxCols, int MaxDepth, int KcFactor> +class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, MaxDepth, KcFactor, true> : public level3_blocking< typename conditional<StorageOrder==RowMajor,_RhsScalar,_LhsScalar>::type, typename conditional<StorageOrder==RowMajor,_LhsScalar,_RhsScalar>::type> @@ -322,8 +309,8 @@ class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, M inline void allocateAll() {} }; -template<int StorageOrder, typename _LhsScalar, typename _RhsScalar, int MaxRows, int MaxCols, int MaxDepth> -class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, MaxDepth, false> +template<int StorageOrder, typename _LhsScalar, typename _RhsScalar, int MaxRows, int MaxCols, int MaxDepth, int KcFactor> +class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, MaxDepth, KcFactor, false> : public level3_blocking< typename conditional<StorageOrder==RowMajor,_RhsScalar,_LhsScalar>::type, typename conditional<StorageOrder==RowMajor,_LhsScalar,_RhsScalar>::type> @@ -347,7 +334,7 @@ class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, M this->m_nc = Transpose ? rows : cols; this->m_kc = depth; - computeProductBlockingSizes<LhsScalar,RhsScalar>(this->m_kc, this->m_mc, this->m_nc); + computeProductBlockingSizes<LhsScalar,RhsScalar,KcFactor>(this->m_kc, this->m_mc, this->m_nc); m_sizeA = this->m_mc * this->m_kc; m_sizeB = this->m_kc * this->m_nc; m_sizeW = this->m_kc*Traits::WorkSpaceFactor; @@ -412,8 +399,8 @@ class GeneralProduct<Lhs, Rhs, GemmProduct> { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); @@ -436,4 +423,6 @@ class GeneralProduct<Lhs, Rhs, GemmProduct> } }; +} // end namespace Eigen + #endif // EIGEN_GENERAL_MATRIX_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h index 5043b64fe2e..432d3a9dc84 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H #define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H +namespace Eigen { + namespace internal { /********************************************************************** @@ -42,14 +29,14 @@ struct tribb_kernel; template <typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, - int ResStorageOrder, int UpLo> + int ResStorageOrder, int UpLo, int Version = Specialized> struct general_matrix_matrix_triangular_product; // as usual if the result is row major => we transpose the product template <typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, - typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int UpLo> -struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,RowMajor,UpLo> -{ + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int UpLo, int Version> +struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,RowMajor,UpLo,Version> +{ typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* lhs, Index lhsStride, const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride, ResScalar alpha) @@ -63,8 +50,8 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder, }; template <typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, - typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int UpLo> -struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,ColMajor,UpLo> + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int UpLo, int Version> +struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,ColMajor,UpLo,Version> { typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* _lhs, Index lhsStride, @@ -201,13 +188,13 @@ TriangularView<MatrixType,UpLo>& TriangularView<MatrixType,UpLo>::assignProduct( typedef internal::blas_traits<Lhs> LhsBlasTraits; typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs; typedef typename internal::remove_all<ActualLhs>::type _ActualLhs; - const ActualLhs actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename internal::add_const_on_value_type<ActualLhs>::type actualLhs = LhsBlasTraits::extract(prod.lhs()); typedef typename internal::remove_all<typename ProductDerived::RhsNested>::type Rhs; typedef internal::blas_traits<Rhs> RhsBlasTraits; typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs; typedef typename internal::remove_all<ActualRhs>::type _ActualRhs; - const ActualRhs actualRhs = RhsBlasTraits::extract(prod.rhs()); + typename internal::add_const_on_value_type<ActualRhs>::type actualRhs = RhsBlasTraits::extract(prod.rhs()); typename ProductDerived::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived()); @@ -222,4 +209,6 @@ TriangularView<MatrixType,UpLo>& TriangularView<MatrixType,UpLo>::assignProduct( return *this; } +} // end namespace Eigen + #endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h new file mode 100644 index 00000000000..3deed068e39 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h @@ -0,0 +1,146 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Level 3 BLAS SYRK/HERK implementation. + ******************************************************************************** +*/ + +#ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H +#define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H + +namespace Eigen { + +namespace internal { + +template <typename Index, typename Scalar, int AStorageOrder, bool ConjugateA, int ResStorageOrder, int UpLo> +struct general_matrix_matrix_rankupdate : + general_matrix_matrix_triangular_product< + Index,Scalar,AStorageOrder,ConjugateA,Scalar,AStorageOrder,ConjugateA,ResStorageOrder,UpLo,BuiltIn> {}; + + +// try to go to BLAS specialization +#define EIGEN_MKL_RANKUPDATE_SPECIALIZE(Scalar) \ +template <typename Index, int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs, int UpLo> \ +struct general_matrix_matrix_triangular_product<Index,Scalar,LhsStorageOrder,ConjugateLhs, \ + Scalar,RhsStorageOrder,ConjugateRhs,ColMajor,UpLo,Specialized> { \ + static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \ + const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha) \ + { \ + if (lhs==rhs) { \ + general_matrix_matrix_rankupdate<Index,Scalar,LhsStorageOrder,ConjugateLhs,ColMajor,UpLo> \ + ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha); \ + } else { \ + general_matrix_matrix_triangular_product<Index, \ + Scalar, LhsStorageOrder, ConjugateLhs, \ + Scalar, RhsStorageOrder, ConjugateRhs, \ + ColMajor, UpLo, BuiltIn> \ + ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha); \ + } \ + } \ +}; + +EIGEN_MKL_RANKUPDATE_SPECIALIZE(double) +//EIGEN_MKL_RANKUPDATE_SPECIALIZE(dcomplex) +EIGEN_MKL_RANKUPDATE_SPECIALIZE(float) +//EIGEN_MKL_RANKUPDATE_SPECIALIZE(scomplex) + +// SYRK for float/double +#define EIGEN_MKL_RANKUPDATE_R(EIGTYPE, MKLTYPE, MKLFUNC) \ +template <typename Index, int AStorageOrder, bool ConjugateA, int UpLo> \ +struct general_matrix_matrix_rankupdate<Index,EIGTYPE,AStorageOrder,ConjugateA,ColMajor,UpLo> { \ + enum { \ + IsLower = (UpLo&Lower) == Lower, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = ((AStorageOrder==ColMajor) && ConjugateA) ? 1 : 0 \ + }; \ + static EIGEN_STRONG_INLINE void run(Index size, Index depth,const EIGTYPE* lhs, Index lhsStride, \ + const EIGTYPE* rhs, Index rhsStride, EIGTYPE* res, Index resStride, EIGTYPE alpha) \ + { \ + /* typedef Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder> MatrixRhs;*/ \ +\ + MKL_INT lda=lhsStride, ldc=resStride, n=size, k=depth; \ + char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'T':'N'; \ + MKLTYPE alpha_, beta_; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(alpha_, alpha); \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(beta_, EIGTYPE(1)); \ + MKLFUNC(&uplo, &trans, &n, &k, &alpha_, lhs, &lda, &beta_, res, &ldc); \ + } \ +}; + +// HERK for complex data +#define EIGEN_MKL_RANKUPDATE_C(EIGTYPE, MKLTYPE, RTYPE, MKLFUNC) \ +template <typename Index, int AStorageOrder, bool ConjugateA, int UpLo> \ +struct general_matrix_matrix_rankupdate<Index,EIGTYPE,AStorageOrder,ConjugateA,ColMajor,UpLo> { \ + enum { \ + IsLower = (UpLo&Lower) == Lower, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = (((AStorageOrder==ColMajor) && ConjugateA) || ((AStorageOrder==RowMajor) && !ConjugateA)) ? 1 : 0 \ + }; \ + static EIGEN_STRONG_INLINE void run(Index size, Index depth,const EIGTYPE* lhs, Index lhsStride, \ + const EIGTYPE* rhs, Index rhsStride, EIGTYPE* res, Index resStride, EIGTYPE alpha) \ + { \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, AStorageOrder> MatrixType; \ +\ + MKL_INT lda=lhsStride, ldc=resStride, n=size, k=depth; \ + char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'C':'N'; \ + RTYPE alpha_, beta_; \ + const EIGTYPE* a_ptr; \ +\ +/* Set alpha_ & beta_ */ \ +/* assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(alpha_, alpha); */\ +/* assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(beta_, EIGTYPE(1));*/ \ + alpha_ = alpha.real(); \ + beta_ = 1.0; \ +/* Copy with conjugation in some cases*/ \ + MatrixType a; \ + if (conjA) { \ + Map<const MatrixType, 0, OuterStride<> > mapA(lhs,n,k,OuterStride<>(lhsStride)); \ + a = mapA.conjugate(); \ + lda = a.outerStride(); \ + a_ptr = a.data(); \ + } else a_ptr=lhs; \ + MKLFUNC(&uplo, &trans, &n, &k, &alpha_, (MKLTYPE*)a_ptr, &lda, &beta_, (MKLTYPE*)res, &ldc); \ + } \ +}; + + +EIGEN_MKL_RANKUPDATE_R(double, double, dsyrk) +EIGEN_MKL_RANKUPDATE_R(float, float, ssyrk) + +//EIGEN_MKL_RANKUPDATE_C(dcomplex, MKL_Complex16, double, zherk) +//EIGEN_MKL_RANKUPDATE_C(scomplex, MKL_Complex8, double, cherk) + + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h new file mode 100644 index 00000000000..060af328ebe --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * General matrix-matrix product functionality based on ?GEMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_GENERAL_MATRIX_MATRIX_MKL_H +#define EIGEN_GENERAL_MATRIX_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements general matrix-matrix multiplication using BLAS +* gemm function via partial specialization of +* general_matrix_matrix_product::run(..) method for float, double, +* std::complex<float> and std::complex<double> types +**********************************************************************/ + +// gemm specialization + +#define GEMM_SPECIALIZATION(EIGTYPE, EIGPREFIX, MKLTYPE, MKLPREFIX) \ +template< \ + typename Index, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct general_matrix_matrix_product<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,RhsStorageOrder,ConjugateRhs,ColMajor> \ +{ \ +static void run(Index rows, Index cols, Index depth, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha, \ + level3_blocking<EIGTYPE, EIGTYPE>& /*blocking*/, \ + GemmParallelInfo<Index>* /*info = 0*/) \ +{ \ + using std::conj; \ +\ + char transa, transb; \ + MKL_INT m, n, k, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX a_tmp, b_tmp; \ + EIGTYPE myone(1);\ +\ +/* Set transpose options */ \ + transa = (LhsStorageOrder==RowMajor) ? ((ConjugateLhs) ? 'C' : 'T') : 'N'; \ + transb = (RhsStorageOrder==RowMajor) ? ((ConjugateRhs) ? 'C' : 'T') : 'N'; \ +\ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ + k = (MKL_INT)depth; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)lhsStride; \ + ldb = (MKL_INT)rhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if ((LhsStorageOrder==ColMajor) && (ConjugateLhs)) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs,m,k,OuterStride<>(lhsStride)); \ + a_tmp = lhs.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else a = _lhs; \ +\ + if ((RhsStorageOrder==ColMajor) && (ConjugateRhs)) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs,k,n,OuterStride<>(rhsStride)); \ + b_tmp = rhs.conjugate(); \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } else b = _rhs; \ +\ + MKLPREFIX##gemm(&transa, &transb, &m, &n, &k, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +}}; + +GEMM_SPECIALIZATION(double, d, double, d) +GEMM_SPECIALIZATION(float, f, float, s) +GEMM_SPECIALIZATION(dcomplex, cd, MKL_Complex16, z) +GEMM_SPECIALIZATION(scomplex, cf, MKL_Complex8, c) + +} // end namespase internal + +} // end namespace Eigen + +#endif // EIGEN_GENERAL_MATRIX_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h index e0e2cbf8f62..ba1f73957db 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_MATRIX_VECTOR_H #define EIGEN_GENERAL_MATRIX_VECTOR_H +namespace Eigen { + namespace internal { /* Optimized col-major matrix * vector product: @@ -40,8 +27,8 @@ namespace internal { * |cplx |real |cplx | invalid, the caller has to do tmp: = A * B; C += alpha*tmp * |cplx |real |real | optimal case, vectorization possible via real-cplx mul */ -template<typename Index, typename LhsScalar, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs> -struct general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjugateLhs,RhsScalar,ConjugateRhs> +template<typename Index, typename LhsScalar, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs, int Version> +struct general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjugateLhs,RhsScalar,ConjugateRhs,Version> { typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; @@ -99,7 +86,7 @@ EIGEN_DONT_INLINE static void run( // How many coeffs of the result do we have to skip to be aligned. // Here we assume data are at least aligned on the base scalar type. - Index alignedStart = first_aligned(res,size); + Index alignedStart = internal::first_aligned(res,size); Index alignedSize = ResPacketSize>1 ? alignedStart + ((size-alignedStart) & ~ResPacketAlignedMask) : 0; const Index peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart; @@ -109,7 +96,7 @@ EIGEN_DONT_INLINE static void run( : FirstAligned; // we cannot assume the first element is aligned because of sub-matrices - const Index lhsAlignmentOffset = first_aligned(lhs,size); + const Index lhsAlignmentOffset = internal::first_aligned(lhs,size); // find how many columns do we have to skip to be aligned with the result (if possible) Index skipColumns = 0; @@ -296,8 +283,8 @@ EIGEN_DONT_INLINE static void run( * - alpha is always a complex (or converted to a complex) * - no vectorization */ -template<typename Index, typename LhsScalar, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs> -struct general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjugateLhs,RhsScalar,ConjugateRhs> +template<typename Index, typename LhsScalar, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs, int Version> +struct general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjugateLhs,RhsScalar,ConjugateRhs,Version> { typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; @@ -351,7 +338,7 @@ EIGEN_DONT_INLINE static void run( // How many coeffs of the result do we have to skip to be aligned. // Here we assume data are at least aligned on the base scalar type // if that's not the case then vectorization is discarded, see below. - Index alignedStart = first_aligned(rhs, depth); + Index alignedStart = internal::first_aligned(rhs, depth); Index alignedSize = RhsPacketSize>1 ? alignedStart + ((depth-alignedStart) & ~RhsPacketAlignedMask) : 0; const Index peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart; @@ -361,7 +348,7 @@ EIGEN_DONT_INLINE static void run( : FirstAligned; // we cannot assume the first element is aligned because of sub-matrices - const Index lhsAlignmentOffset = first_aligned(lhs,depth); + const Index lhsAlignmentOffset = internal::first_aligned(lhs,depth); // find how many rows do we have to skip to be aligned with rhs (if possible) Index skipRows = 0; @@ -556,4 +543,6 @@ EIGEN_DONT_INLINE static void run( } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_GENERAL_MATRIX_VECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h new file mode 100644 index 00000000000..e9de6af3ed1 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h @@ -0,0 +1,131 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * General matrix-vector product functionality based on ?GEMV. + ******************************************************************************** +*/ + +#ifndef EIGEN_GENERAL_MATRIX_VECTOR_MKL_H +#define EIGEN_GENERAL_MATRIX_VECTOR_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements general matrix-vector multiplication using BLAS +* gemv function via partial specialization of +* general_matrix_vector_product::run(..) method for float, double, +* std::complex<float> and std::complex<double> types +**********************************************************************/ + +// gemv specialization + +template<typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs> +struct general_matrix_vector_product_gemv : + general_matrix_vector_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,ConjugateRhs,BuiltIn> {}; + +#define EIGEN_MKL_GEMV_SPECIALIZE(Scalar) \ +template<typename Index, bool ConjugateLhs, bool ConjugateRhs> \ +struct general_matrix_vector_product<Index,Scalar,ColMajor,ConjugateLhs,Scalar,ConjugateRhs,Specialized> { \ +static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const Scalar* lhs, Index lhsStride, \ + const Scalar* rhs, Index rhsIncr, \ + Scalar* res, Index resIncr, Scalar alpha) \ +{ \ + if (ConjugateLhs) { \ + general_matrix_vector_product<Index,Scalar,ColMajor,ConjugateLhs,Scalar,ConjugateRhs,BuiltIn>::run( \ + rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ + } else { \ + general_matrix_vector_product_gemv<Index,Scalar,ColMajor,ConjugateLhs,Scalar,ConjugateRhs>::run( \ + rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ + } \ +} \ +}; \ +template<typename Index, bool ConjugateLhs, bool ConjugateRhs> \ +struct general_matrix_vector_product<Index,Scalar,RowMajor,ConjugateLhs,Scalar,ConjugateRhs,Specialized> { \ +static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const Scalar* lhs, Index lhsStride, \ + const Scalar* rhs, Index rhsIncr, \ + Scalar* res, Index resIncr, Scalar alpha) \ +{ \ + general_matrix_vector_product_gemv<Index,Scalar,RowMajor,ConjugateLhs,Scalar,ConjugateRhs>::run( \ + rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ +} \ +}; \ + +EIGEN_MKL_GEMV_SPECIALIZE(double) +EIGEN_MKL_GEMV_SPECIALIZE(float) +EIGEN_MKL_GEMV_SPECIALIZE(dcomplex) +EIGEN_MKL_GEMV_SPECIALIZE(scomplex) + +#define EIGEN_MKL_GEMV_SPECIALIZATION(EIGTYPE,MKLTYPE,MKLPREFIX) \ +template<typename Index, int LhsStorageOrder, bool ConjugateLhs, bool ConjugateRhs> \ +struct general_matrix_vector_product_gemv<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,ConjugateRhs> \ +{ \ +typedef Matrix<EIGTYPE,Dynamic,1,ColMajor> GEMVVector;\ +\ +static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* lhs, Index lhsStride, \ + const EIGTYPE* rhs, Index rhsIncr, \ + EIGTYPE* res, Index resIncr, EIGTYPE alpha) \ +{ \ + MKL_INT m=rows, n=cols, lda=lhsStride, incx=rhsIncr, incy=resIncr; \ + MKLTYPE alpha_, beta_; \ + const EIGTYPE *x_ptr, myone(1); \ + char trans=(LhsStorageOrder==ColMajor) ? 'N' : (ConjugateLhs) ? 'C' : 'T'; \ + if (LhsStorageOrder==RowMajor) { \ + m=cols; \ + n=rows; \ + }\ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ + GEMVVector x_tmp; \ + if (ConjugateRhs) { \ + Map<const GEMVVector, 0, InnerStride<> > map_x(rhs,cols,1,InnerStride<>(incx)); \ + x_tmp=map_x.conjugate(); \ + x_ptr=x_tmp.data(); \ + incx=1; \ + } else x_ptr=rhs; \ + MKLPREFIX##gemv(&trans, &m, &n, &alpha_, (const MKLTYPE*)lhs, &lda, (const MKLTYPE*)x_ptr, &incx, &beta_, (MKLTYPE*)res, &incy); \ +}\ +}; + +EIGEN_MKL_GEMV_SPECIALIZATION(double, double, d) +EIGEN_MKL_GEMV_SPECIALIZATION(float, float, s) +EIGEN_MKL_GEMV_SPECIALIZATION(dcomplex, MKL_Complex16, z) +EIGEN_MKL_GEMV_SPECIALIZATION(scomplex, MKL_Complex8, c) + +} // end namespase internal + +} // end namespace Eigen + +#endif // EIGEN_GENERAL_MATRIX_VECTOR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h b/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h index ecdedc363ce..5c3e9b7ac15 100644 --- a/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h +++ b/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARALLELIZER_H #define EIGEN_PARALLELIZER_H +namespace Eigen { + namespace internal { /** \internal */ @@ -55,12 +42,23 @@ inline void manage_multi_threading(Action action, int* v) } } +} + +/** Must be call first when calling Eigen from multiple threads */ +inline void initParallel() +{ + int nbt; + internal::manage_multi_threading(GetAction, &nbt); + std::ptrdiff_t l1, l2; + internal::manage_caching_sizes(GetAction, &l1, &l2); +} + /** \returns the max number of threads reserved for Eigen * \sa setNbThreads */ inline int nbThreads() { int ret; - manage_multi_threading(GetAction, &ret); + internal::manage_multi_threading(GetAction, &ret); return ret; } @@ -68,9 +66,11 @@ inline int nbThreads() * \sa nbThreads */ inline void setNbThreads(int v) { - manage_multi_threading(SetAction, &v); + internal::manage_multi_threading(SetAction, &v); } +namespace internal { + template<typename Index> struct GemmParallelInfo { GemmParallelInfo() : sync(-1), users(0), rhs_start(0), rhs_length(0) {} @@ -85,7 +85,9 @@ template<typename Index> struct GemmParallelInfo template<bool Condition, typename Functor, typename Index> void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpose) { -#ifndef EIGEN_HAS_OPENMP + // TODO when EIGEN_USE_BLAS is defined, + // we should still enable OMP for other scalar types +#if !(defined (EIGEN_HAS_OPENMP)) || defined (EIGEN_USE_BLAS) // FIXME the transpose variable is only needed to properly split // the matrix product when multithreading is enabled. This is a temporary // fix to support row-major destination matrices. This whole @@ -117,6 +119,7 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos if(threads==1) return func(0,rows, 0,cols); + Eigen::initParallel(); func.initParallelSession(); if(transpose) @@ -151,4 +154,6 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PARALLELIZER_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h index ccd757cfaf8..48209636eed 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_H #define EIGEN_SELFADJOINT_MATRIX_MATRIX_H +namespace Eigen { + namespace internal { // pack a selfadjoint block diagonal for use with the gebp_kernel @@ -400,8 +387,8 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); @@ -424,4 +411,6 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> } }; +} // end namespace Eigen + #endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h new file mode 100644 index 00000000000..4e5c4125c01 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h @@ -0,0 +1,295 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Self adjoint matrix * matrix product functionality based on ?SYMM/?HEMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H +#define EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + + +/* Optimized selfadjoint matrix * matrix (?SYMM/?HEMM) product */ + +#define EIGEN_MKL_SYMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template <typename Index, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,true,ConjugateLhs,RhsStorageOrder,false,ConjugateRhs,ColMajor> \ +{\ +\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='L', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + EIGTYPE myone(1);\ +\ +/* Set transpose options */ \ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)lhsStride; \ + ldb = (MKL_INT)rhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (LhsStorageOrder==RowMajor) uplo='U'; \ + a = _lhs; \ +\ + if (RhsStorageOrder==RowMajor) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = rhs.adjoint(); \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } else b = _rhs; \ +\ + MKLPREFIX##symm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +\ + } \ +}; + + +#define EIGEN_MKL_HEMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template <typename Index, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,true,ConjugateLhs,RhsStorageOrder,false,ConjugateRhs,ColMajor> \ +{\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='L', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + Matrix<EIGTYPE, Dynamic, Dynamic, LhsStorageOrder> a_tmp; \ + EIGTYPE myone(1); \ +\ +/* Set transpose options */ \ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)lhsStride; \ + ldb = (MKL_INT)rhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (((LhsStorageOrder==ColMajor) && ConjugateLhs) || ((LhsStorageOrder==RowMajor) && (!ConjugateLhs))) { \ + Map<const Matrix<EIGTYPE, Dynamic, Dynamic, LhsStorageOrder>, 0, OuterStride<> > lhs(_lhs,m,m,OuterStride<>(lhsStride)); \ + a_tmp = lhs.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else a = _lhs; \ + if (LhsStorageOrder==RowMajor) uplo='U'; \ +\ + if (RhsStorageOrder==ColMajor && (!ConjugateRhs)) { \ + b = _rhs; } \ + else { \ + if (RhsStorageOrder==ColMajor && ConjugateRhs) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs,m,n,OuterStride<>(rhsStride)); \ + b_tmp = rhs.conjugate(); \ + } else \ + if (ConjugateRhs) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = rhs.adjoint(); \ + } else { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = rhs.transpose(); \ + } \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } \ +\ + MKLPREFIX##hemm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +\ + } \ +}; + +EIGEN_MKL_SYMM_L(double, double, d, d) +EIGEN_MKL_SYMM_L(float, float, f, s) +EIGEN_MKL_HEMM_L(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_HEMM_L(scomplex, MKL_Complex8, cf, c) + + +/* Optimized matrix * selfadjoint matrix (?SYMM/?HEMM) product */ + +#define EIGEN_MKL_SYMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template <typename Index, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,false,ConjugateLhs,RhsStorageOrder,true,ConjugateRhs,ColMajor> \ +{\ +\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='R', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + EIGTYPE myone(1);\ +\ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)rhsStride; \ + ldb = (MKL_INT)lhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (RhsStorageOrder==RowMajor) uplo='U'; \ + a = _rhs; \ +\ + if (LhsStorageOrder==RowMajor) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = lhs.adjoint(); \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } else b = _lhs; \ +\ + MKLPREFIX##symm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +\ + } \ +}; + + +#define EIGEN_MKL_HEMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template <typename Index, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,false,ConjugateLhs,RhsStorageOrder,true,ConjugateRhs,ColMajor> \ +{\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='R', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder> a_tmp; \ + EIGTYPE myone(1); \ +\ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)rhsStride; \ + ldb = (MKL_INT)lhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (((RhsStorageOrder==ColMajor) && ConjugateRhs) || ((RhsStorageOrder==RowMajor) && (!ConjugateRhs))) { \ + Map<const Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder>, 0, OuterStride<> > rhs(_rhs,n,n,OuterStride<>(rhsStride)); \ + a_tmp = rhs.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else a = _rhs; \ + if (RhsStorageOrder==RowMajor) uplo='U'; \ +\ + if (LhsStorageOrder==ColMajor && (!ConjugateLhs)) { \ + b = _lhs; } \ + else { \ + if (LhsStorageOrder==ColMajor && ConjugateLhs) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs,m,n,OuterStride<>(lhsStride)); \ + b_tmp = lhs.conjugate(); \ + } else \ + if (ConjugateLhs) { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs,n,m,OuterStride<>(lhsStride)); \ + b_tmp = lhs.adjoint(); \ + } else { \ + Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs,n,m,OuterStride<>(lhsStride)); \ + b_tmp = lhs.transpose(); \ + } \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } \ +\ + MKLPREFIX##hemm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ + } \ +}; + +EIGEN_MKL_SYMM_R(double, double, d, d) +EIGEN_MKL_SYMM_R(float, float, f, s) +EIGEN_MKL_HEMM_R(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_HEMM_R(scomplex, MKL_Complex8, cf, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h index d6121fc07bd..c3145c69a5f 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_H #define EIGEN_SELFADJOINT_MATRIX_VECTOR_H +namespace Eigen { + namespace internal { /* Optimized selfadjoint matrix * vector product: @@ -32,8 +19,15 @@ namespace internal { * the number of load/stores of the result by a factor 2 and to reduce * the instruction dependency. */ -template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs> -static EIGEN_DONT_INLINE void product_selfadjoint_vector( + +template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs, int Version=Specialized> +struct selfadjoint_matrix_vector_product; + +template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs, int Version> +struct selfadjoint_matrix_vector_product + +{ +static EIGEN_DONT_INLINE void run( Index size, const Scalar* lhs, Index lhsStride, const Scalar* _rhs, Index rhsIncr, @@ -85,14 +79,14 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector( Scalar t1 = cjAlpha * rhs[j+1]; Packet ptmp1 = pset1<Packet>(t1); - Scalar t2 = 0; + Scalar t2(0); Packet ptmp2 = pset1<Packet>(t2); - Scalar t3 = 0; + Scalar t3(0); Packet ptmp3 = pset1<Packet>(t3); size_t starti = FirstTriangular ? 0 : j+2; size_t endi = FirstTriangular ? j : size; - size_t alignedStart = (starti) + first_aligned(&res[starti], endi-starti); + size_t alignedStart = (starti) + internal::first_aligned(&res[starti], endi-starti); size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize); // TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed @@ -148,7 +142,7 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector( register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride; Scalar t1 = cjAlpha * rhs[j]; - Scalar t2 = 0; + Scalar t2(0); // TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed res[j] += cjd.pmul(internal::real(A0[j]), t1); for (Index i=FirstTriangular ? 0 : j+1; i<(FirstTriangular ? j : size); i++) @@ -159,6 +153,7 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector( res[j] += alpha * t2; } } +}; } // end namespace internal @@ -193,8 +188,8 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> eigen_assert(dest.rows()==m_lhs.rows() && dest.cols()==m_rhs.cols()); - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); @@ -232,7 +227,7 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> } - internal::product_selfadjoint_vector<Scalar, Index, (internal::traits<_ActualLhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)> + internal::selfadjoint_matrix_vector_product<Scalar, Index, (internal::traits<_ActualLhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)>::run ( lhs.rows(), // size &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info @@ -274,5 +269,6 @@ struct SelfadjointProductMatrix<Lhs,0,true,Rhs,RhsMode,false> } }; +} // end namespace Eigen #endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h new file mode 100644 index 00000000000..f88d483b653 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h @@ -0,0 +1,114 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Selfadjoint matrix-vector product functionality based on ?SYMV/HEMV. + ******************************************************************************** +*/ + +#ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H +#define EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements selfadjoint matrix-vector multiplication using BLAS +**********************************************************************/ + +// symv/hemv specialization + +template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs> +struct selfadjoint_matrix_vector_product_symv : + selfadjoint_matrix_vector_product<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs,BuiltIn> {}; + +#define EIGEN_MKL_SYMV_SPECIALIZE(Scalar) \ +template<typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs> \ +struct selfadjoint_matrix_vector_product<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs,Specialized> { \ +static EIGEN_DONT_INLINE void run( \ + Index size, const Scalar* lhs, Index lhsStride, \ + const Scalar* _rhs, Index rhsIncr, Scalar* res, Scalar alpha) { \ + enum {\ + IsColMajor = StorageOrder==ColMajor \ + }; \ + if (IsColMajor == ConjugateLhs) {\ + selfadjoint_matrix_vector_product<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs,BuiltIn>::run( \ + size, lhs, lhsStride, _rhs, rhsIncr, res, alpha); \ + } else {\ + selfadjoint_matrix_vector_product_symv<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs>::run( \ + size, lhs, lhsStride, _rhs, rhsIncr, res, alpha); \ + }\ + } \ +}; \ + +EIGEN_MKL_SYMV_SPECIALIZE(double) +EIGEN_MKL_SYMV_SPECIALIZE(float) +EIGEN_MKL_SYMV_SPECIALIZE(dcomplex) +EIGEN_MKL_SYMV_SPECIALIZE(scomplex) + +#define EIGEN_MKL_SYMV_SPECIALIZATION(EIGTYPE,MKLTYPE,MKLFUNC) \ +template<typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs> \ +struct selfadjoint_matrix_vector_product_symv<EIGTYPE,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs> \ +{ \ +typedef Matrix<EIGTYPE,Dynamic,1,ColMajor> SYMVVector;\ +\ +static EIGEN_DONT_INLINE void run( \ +Index size, const EIGTYPE* lhs, Index lhsStride, \ +const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* res, EIGTYPE alpha) \ +{ \ + enum {\ + IsRowMajor = StorageOrder==RowMajor ? 1 : 0, \ + IsLower = UpLo == Lower ? 1 : 0 \ + }; \ + MKL_INT n=size, lda=lhsStride, incx=rhsIncr, incy=1; \ + MKLTYPE alpha_, beta_; \ + const EIGTYPE *x_ptr, myone(1); \ + char uplo=(IsRowMajor) ? (IsLower ? 'U' : 'L') : (IsLower ? 'L' : 'U'); \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ + SYMVVector x_tmp; \ + if (ConjugateRhs) { \ + Map<const SYMVVector, 0, InnerStride<> > map_x(_rhs,size,1,InnerStride<>(incx)); \ + x_tmp=map_x.conjugate(); \ + x_ptr=x_tmp.data(); \ + incx=1; \ + } else x_ptr=_rhs; \ + MKLFUNC(&uplo, &n, &alpha_, (const MKLTYPE*)lhs, &lda, (const MKLTYPE*)x_ptr, &incx, &beta_, (MKLTYPE*)res, &incy); \ +}\ +}; + +EIGEN_MKL_SYMV_SPECIALIZATION(double, double, dsymv) +EIGEN_MKL_SYMV_SPECIALIZATION(float, float, ssymv) +EIGEN_MKL_SYMV_SPECIALIZATION(dcomplex, MKL_Complex16, zhemv) +EIGEN_MKL_SYMV_SPECIALIZATION(scomplex, MKL_Complex8, chemv) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h index 3a4523fa4a9..6a55f3d7715 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINT_PRODUCT_H #define EIGEN_SELFADJOINT_PRODUCT_H @@ -31,6 +16,8 @@ * It corresponds to the level 3 SYRK and level 2 SYR Blas routines. **********************************************************************/ +namespace Eigen { + template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs> struct selfadjoint_rank1_update; @@ -72,7 +59,7 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true> typedef internal::blas_traits<OtherType> OtherBlasTraits; typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType; typedef typename internal::remove_all<ActualOtherType>::type _ActualOtherType; - const ActualOtherType actualOther = OtherBlasTraits::extract(other.derived()); + typename internal::add_const_on_value_type<ActualOtherType>::type actualOther = OtherBlasTraits::extract(other.derived()); Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived()); @@ -105,12 +92,12 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false> typedef internal::blas_traits<OtherType> OtherBlasTraits; typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType; typedef typename internal::remove_all<ActualOtherType>::type _ActualOtherType; - const ActualOtherType actualOther = OtherBlasTraits::extract(other.derived()); + typename internal::add_const_on_value_type<ActualOtherType>::type actualOther = OtherBlasTraits::extract(other.derived()); Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived()); enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 }; - + internal::general_matrix_matrix_triangular_product<Index, Scalar, _ActualOtherType::Flags&RowMajorBit ? RowMajor : ColMajor, OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex, Scalar, _ActualOtherType::Flags&RowMajorBit ? ColMajor : RowMajor, (!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex, @@ -133,4 +120,6 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo> return *this; } +} // end namespace Eigen + #endif // EIGEN_SELFADJOINT_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h index 9f8b8438a5d..57a98cc2de9 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H #define EIGEN_SELFADJOINTRANK2UPTADE_H +namespace Eigen { + namespace internal { /* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu' @@ -76,12 +63,12 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo> typedef internal::blas_traits<DerivedU> UBlasTraits; typedef typename UBlasTraits::DirectLinearAccessType ActualUType; typedef typename internal::remove_all<ActualUType>::type _ActualUType; - const ActualUType actualU = UBlasTraits::extract(u.derived()); + typename internal::add_const_on_value_type<ActualUType>::type actualU = UBlasTraits::extract(u.derived()); typedef internal::blas_traits<DerivedV> VBlasTraits; typedef typename VBlasTraits::DirectLinearAccessType ActualVType; typedef typename internal::remove_all<ActualVType>::type _ActualVType; - const ActualVType actualV = VBlasTraits::extract(v.derived()); + typename internal::add_const_on_value_type<ActualVType>::type actualV = VBlasTraits::extract(v.derived()); // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and // vice versa, and take the complex conjugate of all coefficients and vector entries. @@ -101,4 +88,6 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo> return *this; } +} // end namespace Eigen + #endif // EIGEN_SELFADJOINTRANK2UPTADE_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h index 0c48d2efb75..92cba66f615 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_H #define EIGEN_TRIANGULAR_MATRIX_MATRIX_H +namespace Eigen { + namespace internal { // template<typename Scalar, int mr, int StorageOrder, bool Conjugate, int Mode> @@ -58,23 +45,23 @@ template <typename Scalar, typename Index, int Mode, bool LhsIsTriangular, int LhsStorageOrder, bool ConjugateLhs, int RhsStorageOrder, bool ConjugateRhs, - int ResStorageOrder> + int ResStorageOrder, int Version = Specialized> struct product_triangular_matrix_matrix; template <typename Scalar, typename Index, int Mode, bool LhsIsTriangular, int LhsStorageOrder, bool ConjugateLhs, - int RhsStorageOrder, bool ConjugateRhs> + int RhsStorageOrder, bool ConjugateRhs, int Version> struct product_triangular_matrix_matrix<Scalar,Index,Mode,LhsIsTriangular, LhsStorageOrder,ConjugateLhs, - RhsStorageOrder,ConjugateRhs,RowMajor> + RhsStorageOrder,ConjugateRhs,RowMajor,Version> { static EIGEN_STRONG_INLINE void run( Index rows, Index cols, Index depth, const Scalar* lhs, Index lhsStride, const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, - Scalar alpha) + Scalar alpha, level3_blocking<Scalar,Scalar>& blocking) { product_triangular_matrix_matrix<Scalar, Index, (Mode&(UnitDiag|ZeroDiag)) | ((Mode&Upper) ? Lower : Upper), @@ -84,22 +71,22 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,LhsIsTriangular, LhsStorageOrder==RowMajor ? ColMajor : RowMajor, ConjugateLhs, ColMajor> - ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha); + ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha, blocking); } }; // implements col-major += alpha * op(triangular) * op(general) template <typename Scalar, typename Index, int Mode, int LhsStorageOrder, bool ConjugateLhs, - int RhsStorageOrder, bool ConjugateRhs> + int RhsStorageOrder, bool ConjugateRhs, int Version> struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, LhsStorageOrder,ConjugateLhs, - RhsStorageOrder,ConjugateRhs,ColMajor> + RhsStorageOrder,ConjugateRhs,ColMajor,Version> { typedef gebp_traits<Scalar,Scalar> Traits; enum { - SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), + SmallPanelWidth = 2 * EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), IsLower = (Mode&Lower) == Lower, SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1 }; @@ -109,7 +96,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, - Scalar alpha) + Scalar alpha, level3_blocking<Scalar,Scalar>& blocking) { // strip zeros Index diagSize = (std::min)(_rows,_depth); @@ -120,15 +107,16 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, const_blas_data_mapper<Scalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride); const_blas_data_mapper<Scalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride); - Index kc = depth; // cache block size along the K direction - Index mc = rows; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction + + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*cols; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer; triangularBuffer.setZero(); @@ -186,7 +174,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, pack_lhs(blockA, triangularBuffer.data(), triangularBuffer.outerStride(), actualPanelWidth, actualPanelWidth); gebp_kernel(res+startBlock, resStride, blockA, blockB, actualPanelWidth, actualPanelWidth, cols, alpha, - actualPanelWidth, actual_kc, 0, blockBOffset); + actualPanelWidth, actual_kc, 0, blockBOffset, blockW); // GEBP with remaining micro panel if (lengthTarget>0) @@ -196,7 +184,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, pack_lhs(blockA, &lhs(startTarget,startBlock), lhsStride, actualPanelWidth, lengthTarget); gebp_kernel(res+startTarget, resStride, blockA, blockB, lengthTarget, actualPanelWidth, cols, alpha, - actualPanelWidth, actual_kc, 0, blockBOffset); + actualPanelWidth, actual_kc, 0, blockBOffset, blockW); } } } @@ -210,7 +198,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, gemm_pack_lhs<Scalar, Index, Traits::mr,Traits::LhsProgress, LhsStorageOrder,false>() (blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc); - gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha); + gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha, -1, -1, 0, 0, blockW); } } } @@ -220,10 +208,10 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true, // implements col-major += alpha * op(general) * op(triangular) template <typename Scalar, typename Index, int Mode, int LhsStorageOrder, bool ConjugateLhs, - int RhsStorageOrder, bool ConjugateRhs> + int RhsStorageOrder, bool ConjugateRhs, int Version> struct product_triangular_matrix_matrix<Scalar,Index,Mode,false, LhsStorageOrder,ConjugateLhs, - RhsStorageOrder,ConjugateRhs,ColMajor> + RhsStorageOrder,ConjugateRhs,ColMajor,Version> { typedef gebp_traits<Scalar,Scalar> Traits; enum { @@ -237,7 +225,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, - Scalar alpha) + Scalar alpha, level3_blocking<Scalar,Scalar>& blocking) { // strip zeros Index diagSize = (std::min)(_cols,_depth); @@ -248,16 +236,16 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false, const_blas_data_mapper<Scalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride); const_blas_data_mapper<Scalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride); - Index kc = depth; // cache block size along the K direction - Index mc = rows; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*cols; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer; triangularBuffer.setZero(); @@ -345,13 +333,13 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false, alpha, actual_kc, actual_kc, // strides blockOffset, blockOffset,// offsets - allocatedBlockB); // workspace + blockW); // workspace } } gebp_kernel(res+i2+(IsLower ? 0 : k2)*resStride, resStride, blockA, geb, actual_mc, actual_kc, rs, alpha, - -1, -1, 0, 0, allocatedBlockB); + -1, -1, 0, 0, blockW); } } } @@ -378,26 +366,38 @@ struct TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false> template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const { - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); + typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, + Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType; + + enum { IsLower = (Mode&Lower) == Lower }; + Index stripedRows = ((!LhsIsTriangular) || (IsLower)) ? lhs.rows() : (std::min)(lhs.rows(),lhs.cols()); + Index stripedCols = ((LhsIsTriangular) || (!IsLower)) ? rhs.cols() : (std::min)(rhs.cols(),rhs.rows()); + Index stripedDepth = LhsIsTriangular ? ((!IsLower) ? lhs.cols() : (std::min)(lhs.cols(),lhs.rows())) + : ((IsLower) ? rhs.rows() : (std::min)(rhs.rows(),rhs.cols())); + + BlockingType blocking(stripedRows, stripedCols, stripedDepth); + internal::product_triangular_matrix_matrix<Scalar, Index, Mode, LhsIsTriangular, (internal::traits<_ActualLhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate, (internal::traits<_ActualRhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate, (internal::traits<Dest >::Flags&RowMajorBit) ? RowMajor : ColMajor> ::run( - lhs.rows(), rhs.cols(), lhs.cols(),// LhsIsTriangular ? rhs.cols() : lhs.rows(), // sizes + stripedRows, stripedCols, stripedDepth, // sizes &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info &rhs.coeffRef(0,0), rhs.outerStride(), // rhs info - &dst.coeffRef(0,0), dst.outerStride(), // result info - actualAlpha // alpha + &dst.coeffRef(0,0), dst.outerStride(), // result info + actualAlpha, blocking ); } }; +} // end namespace Eigen #endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h new file mode 100644 index 00000000000..8173da5bb6d --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h @@ -0,0 +1,309 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Triangular matrix * matrix product functionality based on ?TRMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H +#define EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + + +template <typename Scalar, typename Index, + int Mode, bool LhsIsTriangular, + int LhsStorageOrder, bool ConjugateLhs, + int RhsStorageOrder, bool ConjugateRhs, + int ResStorageOrder> +struct product_triangular_matrix_matrix_trmm : + product_triangular_matrix_matrix<Scalar,Index,Mode, + LhsIsTriangular,LhsStorageOrder,ConjugateLhs, + RhsStorageOrder, ConjugateRhs, ResStorageOrder, BuiltIn> {}; + + +// try to go to BLAS specialization +#define EIGEN_MKL_TRMM_SPECIALIZE(Scalar, LhsIsTriangular) \ +template <typename Index, int Mode, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_triangular_matrix_matrix<Scalar,Index, Mode, LhsIsTriangular, \ + LhsStorageOrder,ConjugateLhs, RhsStorageOrder,ConjugateRhs,ColMajor,Specialized> { \ + static inline void run(Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride,\ + const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha) { \ + product_triangular_matrix_matrix_trmm<Scalar,Index,Mode, \ + LhsIsTriangular,LhsStorageOrder,ConjugateLhs, \ + RhsStorageOrder, ConjugateRhs, ColMajor>::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \ + } \ +}; + +EIGEN_MKL_TRMM_SPECIALIZE(double, true) +EIGEN_MKL_TRMM_SPECIALIZE(double, false) +EIGEN_MKL_TRMM_SPECIALIZE(dcomplex, true) +EIGEN_MKL_TRMM_SPECIALIZE(dcomplex, false) +EIGEN_MKL_TRMM_SPECIALIZE(float, true) +EIGEN_MKL_TRMM_SPECIALIZE(float, false) +EIGEN_MKL_TRMM_SPECIALIZE(scomplex, true) +EIGEN_MKL_TRMM_SPECIALIZE(scomplex, false) + +// implements col-major += alpha * op(triangular) * op(general) +#define EIGEN_MKL_TRMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template <typename Index, int Mode, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \ + LhsStorageOrder,ConjugateLhs,RhsStorageOrder,ConjugateRhs,ColMajor> \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = ((LhsStorageOrder==ColMajor) && ConjugateLhs) ? 1 : 0 \ + }; \ +\ + static EIGEN_DONT_INLINE void run( \ + Index _rows, Index _cols, Index _depth, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + Index diagSize = (std::min)(_rows,_depth); \ + Index rows = IsLower ? _rows : diagSize; \ + Index depth = IsLower ? diagSize : _depth; \ + Index cols = _cols; \ +\ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, LhsStorageOrder> MatrixLhs; \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder> MatrixRhs; \ +\ +/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \ + if (rows != depth) { \ +\ + int nthr = mkl_domain_get_max_threads(MKL_BLAS); \ +\ + if (((nthr==1) && (((std::max)(rows,depth)-diagSize)/(double)diagSize < 0.5))) { \ + /* Most likely no benefit to call TRMM or GEMM from MKL*/ \ + product_triangular_matrix_matrix<EIGTYPE,Index,Mode,true, \ + LhsStorageOrder,ConjugateLhs, RhsStorageOrder, ConjugateRhs, ColMajor, BuiltIn>::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \ + /*std::cout << "TRMM_L: A is not square! Go to Eigen TRMM implementation!\n";*/ \ + } else { \ + /* Make sense to call GEMM */ \ + Map<const MatrixLhs, 0, OuterStride<> > lhsMap(_lhs,rows,depth,OuterStride<>(lhsStride)); \ + MatrixLhs aa_tmp=lhsMap.template triangularView<Mode>(); \ + MKL_INT aStride = aa_tmp.outerStride(); \ + gemm_blocking_space<ColMajor,EIGTYPE,EIGTYPE,Dynamic,Dynamic,Dynamic> blocking(_rows,_cols,_depth); \ + general_matrix_matrix_product<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,RhsStorageOrder,ConjugateRhs,ColMajor>::run( \ + rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, resStride, alpha, blocking, 0); \ +\ + /*std::cout << "TRMM_L: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \ + } \ + return; \ + } \ + char side = 'L', transa, uplo, diag = 'N'; \ + EIGTYPE *b; \ + const EIGTYPE *a; \ + MKL_INT m, n, lda, ldb; \ + MKLTYPE alpha_; \ +\ +/* Set alpha_*/ \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(alpha_, alpha); \ +\ +/* Set m, n */ \ + m = (MKL_INT)diagSize; \ + n = (MKL_INT)cols; \ +\ +/* Set trans */ \ + transa = (LhsStorageOrder==RowMajor) ? ((ConjugateLhs) ? 'C' : 'T') : 'N'; \ +\ +/* Set b, ldb */ \ + Map<const MatrixRhs, 0, OuterStride<> > rhs(_rhs,depth,cols,OuterStride<>(rhsStride)); \ + MatrixX##EIGPREFIX b_tmp; \ +\ + if (ConjugateRhs) b_tmp = rhs.conjugate(); else b_tmp = rhs; \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ +\ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (LhsStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + Map<const MatrixLhs, 0, OuterStride<> > lhs(_lhs,rows,depth,OuterStride<>(lhsStride)); \ + MatrixLhs a_tmp; \ +\ + if ((conjA!=0) || (SetDiag==0)) { \ + if (conjA) a_tmp = lhs.conjugate(); else a_tmp = lhs; \ + if (IsZeroDiag) \ + a_tmp.diagonal().setZero(); \ + else if (IsUnitDiag) \ + a_tmp.diagonal().setOnes();\ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _lhs; \ + lda = lhsStride; \ + } \ + /*std::cout << "TRMM_L: A is square! Go to MKL TRMM implementation! \n";*/ \ +/* call ?trmm*/ \ + MKLPREFIX##trmm(&side, &uplo, &transa, &diag, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (MKLTYPE*)b, &ldb); \ +\ +/* Add op(a_triangular)*b into res*/ \ + Map<MatrixX##EIGPREFIX, 0, OuterStride<> > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ + res_tmp=res_tmp+b_tmp; \ + } \ +}; + +EIGEN_MKL_TRMM_L(double, double, d, d) +EIGEN_MKL_TRMM_L(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_TRMM_L(float, float, f, s) +EIGEN_MKL_TRMM_L(scomplex, MKL_Complex8, cf, c) + +// implements col-major += alpha * op(general) * op(triangular) +#define EIGEN_MKL_TRMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template <typename Index, int Mode, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \ + LhsStorageOrder,ConjugateLhs,RhsStorageOrder,ConjugateRhs,ColMajor> \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = ((RhsStorageOrder==ColMajor) && ConjugateRhs) ? 1 : 0 \ + }; \ +\ + static EIGEN_DONT_INLINE void run( \ + Index _rows, Index _cols, Index _depth, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + Index diagSize = (std::min)(_cols,_depth); \ + Index rows = _rows; \ + Index depth = IsLower ? _depth : diagSize; \ + Index cols = IsLower ? diagSize : _cols; \ +\ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, LhsStorageOrder> MatrixLhs; \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder> MatrixRhs; \ +\ +/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \ + if (cols != depth) { \ +\ + int nthr = mkl_domain_get_max_threads(MKL_BLAS); \ +\ + if ((nthr==1) && (((std::max)(cols,depth)-diagSize)/(double)diagSize < 0.5)) { \ + /* Most likely no benefit to call TRMM or GEMM from MKL*/ \ + product_triangular_matrix_matrix<EIGTYPE,Index,Mode,false, \ + LhsStorageOrder,ConjugateLhs, RhsStorageOrder, ConjugateRhs, ColMajor, BuiltIn>::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \ + /*std::cout << "TRMM_R: A is not square! Go to Eigen TRMM implementation!\n";*/ \ + } else { \ + /* Make sense to call GEMM */ \ + Map<const MatrixRhs, 0, OuterStride<> > rhsMap(_rhs,depth,cols, OuterStride<>(rhsStride)); \ + MatrixRhs aa_tmp=rhsMap.template triangularView<Mode>(); \ + MKL_INT aStride = aa_tmp.outerStride(); \ + gemm_blocking_space<ColMajor,EIGTYPE,EIGTYPE,Dynamic,Dynamic,Dynamic> blocking(_rows,_cols,_depth); \ + general_matrix_matrix_product<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,RhsStorageOrder,ConjugateRhs,ColMajor>::run( \ + rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, resStride, alpha, blocking, 0); \ +\ + /*std::cout << "TRMM_R: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \ + } \ + return; \ + } \ + char side = 'R', transa, uplo, diag = 'N'; \ + EIGTYPE *b; \ + const EIGTYPE *a; \ + MKL_INT m, n, lda, ldb; \ + MKLTYPE alpha_; \ +\ +/* Set alpha_*/ \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(alpha_, alpha); \ +\ +/* Set m, n */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)diagSize; \ +\ +/* Set trans */ \ + transa = (RhsStorageOrder==RowMajor) ? ((ConjugateRhs) ? 'C' : 'T') : 'N'; \ +\ +/* Set b, ldb */ \ + Map<const MatrixLhs, 0, OuterStride<> > lhs(_lhs,rows,depth,OuterStride<>(lhsStride)); \ + MatrixX##EIGPREFIX b_tmp; \ +\ + if (ConjugateLhs) b_tmp = lhs.conjugate(); else b_tmp = lhs; \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ +\ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (RhsStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + Map<const MatrixRhs, 0, OuterStride<> > rhs(_rhs,depth,cols, OuterStride<>(rhsStride)); \ + MatrixRhs a_tmp; \ +\ + if ((conjA!=0) || (SetDiag==0)) { \ + if (conjA) a_tmp = rhs.conjugate(); else a_tmp = rhs; \ + if (IsZeroDiag) \ + a_tmp.diagonal().setZero(); \ + else if (IsUnitDiag) \ + a_tmp.diagonal().setOnes();\ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _rhs; \ + lda = rhsStride; \ + } \ + /*std::cout << "TRMM_R: A is square! Go to MKL TRMM implementation! \n";*/ \ +/* call ?trmm*/ \ + MKLPREFIX##trmm(&side, &uplo, &transa, &diag, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (MKLTYPE*)b, &ldb); \ +\ +/* Add op(a_triangular)*b into res*/ \ + Map<MatrixX##EIGPREFIX, 0, OuterStride<> > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ + res_tmp=res_tmp+b_tmp; \ + } \ +}; + +EIGEN_MKL_TRMM_R(double, double, d, d) +EIGEN_MKL_TRMM_R(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_TRMM_R(float, float, f, s) +EIGEN_MKL_TRMM_R(scomplex, MKL_Complex8, cf, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h index 71b4a52ab80..b1c10c201c5 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h @@ -3,45 +3,36 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULARMATRIXVECTOR_H #define EIGEN_TRIANGULARMATRIXVECTOR_H +namespace Eigen { + namespace internal { -template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder> -struct product_triangular_matrix_vector; +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder, int Version=Specialized> +struct triangular_matrix_vector_product; -template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs> -struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor> +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int Version> +struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version> { typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; enum { IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag }; - static EIGEN_DONT_INLINE void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride, + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha) { static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; + Index size = (std::min)(_rows,_cols); + Index rows = IsLower ? _rows : (std::min)(_rows,_cols); + Index cols = IsLower ? (std::min)(_rows,_cols) : _cols; typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); @@ -54,45 +45,57 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C typedef Map<Matrix<ResScalar,Dynamic,1> > ResMap; ResMap res(_res,rows); - for (Index pi=0; pi<cols; pi+=PanelWidth) + for (Index pi=0; pi<size; pi+=PanelWidth) { - Index actualPanelWidth = (std::min)(PanelWidth, cols-pi); + Index actualPanelWidth = (std::min)(PanelWidth, size-pi); for (Index k=0; k<actualPanelWidth; ++k) { Index i = pi + k; - Index s = IsLower ? (HasUnitDiag ? i+1 : i ) : pi; + Index s = IsLower ? ((HasUnitDiag||HasZeroDiag) ? i+1 : i ) : pi; Index r = IsLower ? actualPanelWidth-k : k+1; - if ((!HasUnitDiag) || (--r)>0) + if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); } - Index r = IsLower ? cols - pi - actualPanelWidth : pi; + Index r = IsLower ? rows - pi - actualPanelWidth : pi; if (r>0) { Index s = IsLower ? pi+actualPanelWidth : 0; - general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjLhs,RhsScalar,ConjRhs>::run( + general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjLhs,RhsScalar,ConjRhs,BuiltIn>::run( r, actualPanelWidth, &lhs.coeffRef(s,pi), lhsStride, &rhs.coeffRef(pi), rhsIncr, &res.coeffRef(s), resIncr, alpha); } } + if((!IsLower) && cols>size) + { + general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjLhs,RhsScalar,ConjRhs>::run( + rows, cols-size, + &lhs.coeffRef(0,size), lhsStride, + &rhs.coeffRef(size), rhsIncr, + _res, resIncr, alpha); + } } }; -template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs> -struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor> +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version> +struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version> { typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; enum { IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag }; - static void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride, + static void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha) { static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; + Index diagSize = (std::min)(_rows,_cols); + Index rows = IsLower ? _rows : diagSize; + Index cols = IsLower ? diagSize : _cols; typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); @@ -105,15 +108,15 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C typedef Map<Matrix<ResScalar,Dynamic,1>, 0, InnerStride<> > ResMap; ResMap res(_res,rows,InnerStride<>(resIncr)); - for (Index pi=0; pi<cols; pi+=PanelWidth) + for (Index pi=0; pi<diagSize; pi+=PanelWidth) { - Index actualPanelWidth = (std::min)(PanelWidth, cols-pi); + Index actualPanelWidth = (std::min)(PanelWidth, diagSize-pi); for (Index k=0; k<actualPanelWidth; ++k) { Index i = pi + k; - Index s = IsLower ? pi : (HasUnitDiag ? i+1 : i); + Index s = IsLower ? pi : ((HasUnitDiag||HasZeroDiag) ? i+1 : i); Index r = IsLower ? k+1 : actualPanelWidth-k; - if ((!HasUnitDiag) || (--r)>0) + if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum(); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); @@ -122,13 +125,21 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C if (r>0) { Index s = IsLower ? 0 : pi + actualPanelWidth; - general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjLhs,RhsScalar,ConjRhs>::run( + general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjLhs,RhsScalar,ConjRhs,BuiltIn>::run( actualPanelWidth, r, &lhs.coeffRef(pi,s), lhsStride, &rhs.coeffRef(s), rhsIncr, &res.coeffRef(pi), resIncr, alpha); } } + if(IsLower && rows>diagSize) + { + general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjLhs,RhsScalar,ConjRhs>::run( + rows-diagSize, cols, + &lhs.coeffRef(diagSize,0), lhsStride, + &rhs.coeffRef(0), rhsIncr, + &res.coeffRef(diagSize), resIncr, alpha); + } } }; @@ -180,7 +191,7 @@ struct TriangularProduct<Mode,false,Lhs,true,Rhs,false> { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - typedef TriangularProduct<(Mode & UnitDiag) | ((Mode & Lower) ? Upper : Lower),true,Transpose<const Rhs>,false,Transpose<const Lhs>,true> TriangularProductTranspose; + typedef TriangularProduct<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),true,Transpose<const Rhs>,false,Transpose<const Lhs>,true> TriangularProductTranspose; Transpose<Dest> dstT(dst); internal::trmv_selector<(int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run( TriangularProductTranspose(m_rhs.transpose(),m_lhs.transpose()), dstT, alpha); @@ -208,8 +219,8 @@ template<> struct trmv_selector<ColMajor> typedef typename ProductType::RhsBlasTraits RhsBlasTraits; typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest; - const ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); - const ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); + typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename internal::add_const_on_value_type<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs()); ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) * RhsBlasTraits::extractScalarFactor(prod.rhs()); @@ -247,7 +258,7 @@ template<> struct trmv_selector<ColMajor> MappedDest(actualDestPtr, dest.size()) = dest; } - internal::product_triangular_matrix_vector + internal::triangular_matrix_vector_product <Index,Mode, LhsScalar, LhsBlasTraits::NeedToConjugate, RhsScalar, RhsBlasTraits::NeedToConjugate, @@ -307,7 +318,7 @@ template<> struct trmv_selector<RowMajor> Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs; } - internal::product_triangular_matrix_vector + internal::triangular_matrix_vector_product <Index,Mode, LhsScalar, LhsBlasTraits::NeedToConjugate, RhsScalar, RhsBlasTraits::NeedToConjugate, @@ -322,4 +333,6 @@ template<> struct trmv_selector<RowMajor> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRIANGULARMATRIXVECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h new file mode 100644 index 00000000000..3589b8c5ef6 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h @@ -0,0 +1,247 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Triangular matrix-vector product functionality based on ?TRMV. + ******************************************************************************** +*/ + +#ifndef EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H +#define EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements triangular matrix-vector multiplication using BLAS +**********************************************************************/ + +// trmv/hemv specialization + +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder> +struct triangular_matrix_vector_product_trmv : + triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,StorageOrder,BuiltIn> {}; + +#define EIGEN_MKL_TRMV_SPECIALIZE(Scalar) \ +template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \ +struct triangular_matrix_vector_product<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,ColMajor,Specialized> { \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \ + const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \ + triangular_matrix_vector_product_trmv<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,ColMajor>::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ + } \ +}; \ +template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \ +struct triangular_matrix_vector_product<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,RowMajor,Specialized> { \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \ + const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \ + triangular_matrix_vector_product_trmv<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,RowMajor>::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ + } \ +}; + +EIGEN_MKL_TRMV_SPECIALIZE(double) +EIGEN_MKL_TRMV_SPECIALIZE(float) +EIGEN_MKL_TRMV_SPECIALIZE(dcomplex) +EIGEN_MKL_TRMV_SPECIALIZE(scomplex) + +// implements col-major: res += alpha * op(triangular) * vector +#define EIGEN_MKL_TRMV_CM(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \ +struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,ColMajor> { \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper \ + }; \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha, level3_blocking<EIGTYPE,EIGTYPE>& blocking) \ + { \ + if (ConjLhs || IsZeroDiag) { \ + triangular_matrix_vector_product<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,ColMajor,BuiltIn>::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha, blocking); \ + return; \ + }\ + Index size = (std::min)(_rows,_cols); \ + Index rows = IsLower ? _rows : size; \ + Index cols = IsLower ? size : _cols; \ +\ + typedef VectorX##EIGPREFIX VectorRhs; \ + EIGTYPE *x, *y;\ +\ +/* Set x*/ \ + Map<const VectorRhs, 0, InnerStride<> > rhs(_rhs,cols,InnerStride<>(rhsIncr)); \ + VectorRhs x_tmp; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ +\ +/* Square part handling */\ +\ + char trans, uplo, diag; \ + MKL_INT m, n, lda, incx, incy; \ + EIGTYPE const *a; \ + MKLTYPE alpha_, beta_; \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(alpha_, alpha); \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(beta_, EIGTYPE(1)); \ +\ +/* Set m, n */ \ + n = (MKL_INT)size; \ + lda = lhsStride; \ + incx = 1; \ + incy = resIncr; \ +\ +/* Set uplo, trans and diag*/ \ + trans = 'N'; \ + uplo = IsLower ? 'L' : 'U'; \ + diag = IsUnitDiag ? 'U' : 'N'; \ +\ +/* call ?TRMV*/ \ + MKLPREFIX##trmv(&uplo, &trans, &diag, &n, (const MKLTYPE*)_lhs, &lda, (MKLTYPE*)x, &incx); \ +\ +/* Add op(a_tr)rhs into res*/ \ + MKLPREFIX##axpy(&n, &alpha_,(const MKLTYPE*)x, &incx, (MKLTYPE*)_res, &incy); \ +/* Non-square case - doesn't fit to MKL ?TRMV. Fall to default triangular product*/ \ + if (size<(std::max)(rows,cols)) { \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic> MatrixLhs; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ + if (size<rows) { \ + y = _res + size*resIncr; \ + a = _lhs + size; \ + m = rows-size; \ + n = size; \ + } \ + else { \ + x += size; \ + y = _res; \ + a = _lhs + size*lda; \ + m = size; \ + n = cols-size; \ + } \ + MKLPREFIX##gemv(&trans, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)x, &incx, &beta_, (MKLTYPE*)y, &incy); \ + } \ + } \ +}; + +EIGEN_MKL_TRMV_CM(double, double, d, d) +EIGEN_MKL_TRMV_CM(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_TRMV_CM(float, float, f, s) +EIGEN_MKL_TRMV_CM(scomplex, MKL_Complex8, cf, c) + +// implements row-major: res += alpha * op(triangular) * vector +#define EIGEN_MKL_TRMV_RM(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \ +struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,RowMajor> { \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper \ + }; \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha, level3_blocking<EIGTYPE,EIGTYPE>& blocking) \ + { \ + if (IsZeroDiag) { \ + triangular_matrix_vector_product<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,RowMajor,BuiltIn>::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha, blocking); \ + return; \ + }\ + Index size = (std::min)(_rows,_cols); \ + Index rows = IsLower ? _rows : size; \ + Index cols = IsLower ? size : _cols; \ +\ + typedef VectorX##EIGPREFIX VectorRhs; \ + EIGTYPE *x, *y;\ +\ +/* Set x*/ \ + Map<const VectorRhs, 0, InnerStride<> > rhs(_rhs,cols,InnerStride<>(rhsIncr)); \ + VectorRhs x_tmp; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ +\ +/* Square part handling */\ +\ + char trans, uplo, diag; \ + MKL_INT m, n, lda, incx, incy; \ + EIGTYPE const *a; \ + MKLTYPE alpha_, beta_; \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(alpha_, alpha); \ + assign_scalar_eig2mkl<MKLTYPE, EIGTYPE>(beta_, EIGTYPE(1)); \ +\ +/* Set m, n */ \ + n = (MKL_INT)size; \ + lda = lhsStride; \ + incx = 1; \ + incy = resIncr; \ +\ +/* Set uplo, trans and diag*/ \ + trans = ConjLhs ? 'C' : 'T'; \ + uplo = IsLower ? 'U' : 'L'; \ + diag = IsUnitDiag ? 'U' : 'N'; \ +\ +/* call ?TRMV*/ \ + MKLPREFIX##trmv(&uplo, &trans, &diag, &n, (const MKLTYPE*)_lhs, &lda, (MKLTYPE*)x, &incx); \ +\ +/* Add op(a_tr)rhs into res*/ \ + MKLPREFIX##axpy(&n, &alpha_,(const MKLTYPE*)x, &incx, (MKLTYPE*)_res, &incy); \ +/* Non-square case - doesn't fit to MKL ?TRMV. Fall to default triangular product*/ \ + if (size<(std::max)(rows,cols)) { \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic> MatrixLhs; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ + if (size<rows) { \ + y = _res + size*resIncr; \ + a = _lhs + size*lda; \ + m = rows-size; \ + n = size; \ + } \ + else { \ + x += size; \ + y = _res; \ + a = _lhs + size; \ + m = size; \ + n = cols-size; \ + } \ + MKLPREFIX##gemv(&trans, &n, &m, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)x, &incx, &beta_, (MKLTYPE*)y, &incy); \ + } \ + } \ +}; + +EIGEN_MKL_TRMV_RM(double, double, d, d) +EIGEN_MKL_TRMV_RM(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_TRMV_RM(float, float, f, s) +EIGEN_MKL_TRMV_RM(scomplex, MKL_Complex8, cf, c) + +} // end namespase internal + +} // end namespace Eigen + +#endif // EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h index 4dced6b0eb9..a49ea318345 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_H #define EIGEN_TRIANGULAR_SOLVER_MATRIX_H +namespace Eigen { + namespace internal { // if the rhs is row major, let's transpose the product @@ -34,14 +21,15 @@ struct triangular_solve_matrix<Scalar,Index,Side,Mode,Conjugate,TriStorageOrder, static EIGEN_DONT_INLINE void run( Index size, Index cols, const Scalar* tri, Index triStride, - Scalar* _other, Index otherStride) + Scalar* _other, Index otherStride, + level3_blocking<Scalar,Scalar>& blocking) { triangular_solve_matrix< Scalar, Index, Side==OnTheLeft?OnTheRight:OnTheLeft, (Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper), NumTraits<Scalar>::IsComplex && Conjugate, TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor> - ::run(size, cols, tri, triStride, _other, otherStride); + ::run(size, cols, tri, triStride, _other, otherStride, blocking); } }; @@ -53,7 +41,8 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO static EIGEN_DONT_INLINE void run( Index size, Index otherSize, const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride) + Scalar* _other, Index otherStride, + level3_blocking<Scalar,Scalar>& blocking) { Index cols = otherSize; const_blas_data_mapper<Scalar, Index, TriStorageOrder> tri(_tri,triStride); @@ -65,22 +54,29 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO IsLower = (Mode&Lower) == Lower }; - Index kc = size; // cache block size along the K direction - Index mc = size; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(size,blocking.mc()); // cache block size along the M direction + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*cols; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); conj_if<Conjugate> conj; gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, Conjugate, false> gebp_kernel; gemm_pack_lhs<Scalar, Index, Traits::mr, Traits::LhsProgress, TriStorageOrder> pack_lhs; gemm_pack_rhs<Scalar, Index, Traits::nr, ColMajor, false, true> pack_rhs; + // the goal here is to subdivise the Rhs panels such that we keep some cache + // coherence when accessing the rhs elements + std::ptrdiff_t l1, l2; + manage_caching_sizes(GetAction, &l1, &l2); + Index subcols = cols>0 ? l2/(4 * sizeof(Scalar) * otherStride) : 0; + subcols = std::max<Index>((subcols/Traits::nr)*Traits::nr, Traits::nr); + for(Index k2=IsLower ? 0 : size; IsLower ? k2<size : k2>0; IsLower ? k2+=kc : k2-=kc) @@ -92,16 +88,18 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO // A11 (the triangular part) and A21 the remaining rectangular part. // Then the high level algorithm is: // - B = R1 => general block copy (done during the next step) - // - R1 = L1^-1 B => tricky part + // - R1 = A11^-1 B => tricky part // - update B from the new R1 => actually this has to be performed continuously during the above step - // - R2 = L2 * B => GEPP + // - R2 -= A21 * B => GEPP - // The tricky part: compute R1 = L1^-1 B while updating B from R1 - // The idea is to split L1 into multiple small vertical panels. - // Each panel can be split into a small triangular part A1 which is processed without optimization, - // and the remaining small part A2 which is processed using gebp with appropriate block strides + // The tricky part: compute R1 = A11^-1 B while updating B from R1 + // The idea is to split A11 into multiple small vertical panels. + // Each panel can be split into a small triangular part T1k which is processed without optimization, + // and the remaining small part T2k which is processed using gebp with appropriate block strides + for(Index j2=0; j2<cols; j2+=subcols) { - // for each small vertical panels of lhs + Index actual_cols = (std::min)(cols-j2,subcols); + // for each small vertical panels [T1k^T, T2k^T]^T of lhs for (Index k1=0; k1<actual_kc; k1+=SmallPanelWidth) { Index actualPanelWidth = std::min<Index>(actual_kc-k1, SmallPanelWidth); @@ -114,11 +112,11 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO Index rs = actualPanelWidth - k - 1; // remaining size Scalar a = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(tri(i,i)); - for (Index j=0; j<cols; ++j) + for (Index j=j2; j<j2+actual_cols; ++j) { if (TriStorageOrder==RowMajor) { - Scalar b = 0; + Scalar b(0); const Scalar* l = &tri(i,s); Scalar* r = &other(s,j); for (Index i3=0; i3<k; ++i3) @@ -143,7 +141,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO Index blockBOffset = IsLower ? k1 : lengthTarget; // update the respective rows of B from other - pack_rhs(blockB, _other+startBlock, otherStride, actualPanelWidth, cols, actual_kc, blockBOffset); + pack_rhs(blockB+actual_kc*j2, &other(startBlock,j2), otherStride, actualPanelWidth, actual_cols, actual_kc, blockBOffset); // GEBP if (lengthTarget>0) @@ -152,13 +150,13 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO pack_lhs(blockA, &tri(startTarget,startBlock), triStride, actualPanelWidth, lengthTarget); - gebp_kernel(_other+startTarget, otherStride, blockA, blockB, lengthTarget, actualPanelWidth, cols, Scalar(-1), - actualPanelWidth, actual_kc, 0, blockBOffset); + gebp_kernel(&other(startTarget,j2), otherStride, blockA, blockB+actual_kc*j2, lengthTarget, actualPanelWidth, actual_cols, Scalar(-1), + actualPanelWidth, actual_kc, 0, blockBOffset, blockW); } } } - - // R2 = A2 * B => GEPP + + // R2 -= A21 * B => GEPP { Index start = IsLower ? k2+kc : 0; Index end = IsLower ? size : k2-kc; @@ -169,7 +167,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO { pack_lhs(blockA, &tri(i2, IsLower ? k2 : k2-kc), triStride, actual_kc, actual_mc); - gebp_kernel(_other+i2, otherStride, blockA, blockB, actual_mc, actual_kc, cols, Scalar(-1)); + gebp_kernel(_other+i2, otherStride, blockA, blockB, actual_mc, actual_kc, cols, Scalar(-1), -1, -1, 0, 0, blockW); } } } @@ -185,7 +183,8 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage static EIGEN_DONT_INLINE void run( Index size, Index otherSize, const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride) + Scalar* _other, Index otherStride, + level3_blocking<Scalar,Scalar>& blocking) { Index rows = otherSize; const_blas_data_mapper<Scalar, Index, TriStorageOrder> rhs(_tri,triStride); @@ -198,19 +197,16 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage IsLower = (Mode&Lower) == Lower }; -// Index kc = std::min<Index>(Traits::Max_kc/4,size); // cache block size along the K direction -// Index mc = std::min<Index>(Traits::Max_mc,size); // cache block size along the M direction - // check that !!!! - Index kc = size; // cache block size along the K direction - Index mc = size; // cache block size along the M direction - Index nc = rows; // cache block size along the N direction - computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*size; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*size; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); conj_if<Conjugate> conj; gebp_kernel<Scalar,Scalar, Index, Traits::mr, Traits::nr, false, Conjugate> gebp_kernel; @@ -277,7 +273,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage Scalar(-1), actual_kc, actual_kc, // strides panelOffset, panelOffset, // offsets - allocatedBlockB); // workspace + blockW); // workspace } // unblocked triangular solve @@ -308,7 +304,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage if (rs>0) gebp_kernel(_other+i2+startPanel*otherStride, otherStride, blockA, geb, actual_mc, actual_kc, rs, Scalar(-1), - -1, -1, 0, 0, allocatedBlockB); + -1, -1, 0, 0, blockW); } } } @@ -316,4 +312,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRIANGULAR_SOLVER_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h new file mode 100644 index 00000000000..a4f508b2e83 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h @@ -0,0 +1,155 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Triangular matrix * matrix product functionality based on ?TRMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H +#define EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + +// implements LeftSide op(triangular)^-1 * general +#define EIGEN_MKL_TRSM_L(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template <typename Index, int Mode, bool Conjugate, int TriStorageOrder> \ +struct triangular_solve_matrix<EIGTYPE,Index,OnTheLeft,Mode,Conjugate,TriStorageOrder,ColMajor> \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \ + }; \ + static EIGEN_DONT_INLINE void run( \ + Index size, Index otherSize, \ + const EIGTYPE* _tri, Index triStride, \ + EIGTYPE* _other, Index otherStride, level3_blocking<EIGTYPE,EIGTYPE>& /*blocking*/) \ + { \ + MKL_INT m = size, n = otherSize, lda, ldb; \ + char side = 'L', uplo, diag='N', transa; \ + /* Set alpha_ */ \ + MKLTYPE alpha; \ + EIGTYPE myone(1); \ + assign_scalar_eig2mkl(alpha, myone); \ + ldb = otherStride;\ +\ + const EIGTYPE *a; \ +/* Set trans */ \ + transa = (TriStorageOrder==RowMajor) ? ((Conjugate) ? 'C' : 'T') : 'N'; \ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (TriStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, TriStorageOrder> MatrixTri; \ + Map<const MatrixTri, 0, OuterStride<> > tri(_tri,size,size,OuterStride<>(triStride)); \ + MatrixTri a_tmp; \ +\ + if (conjA) { \ + a_tmp = tri.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _tri; \ + lda = triStride; \ + } \ + if (IsUnitDiag) diag='U'; \ +/* call ?trsm*/ \ + MKLPREFIX##trsm(&side, &uplo, &transa, &diag, &m, &n, &alpha, (const MKLTYPE*)a, &lda, (MKLTYPE*)_other, &ldb); \ + } \ +}; + +EIGEN_MKL_TRSM_L(double, double, d) +EIGEN_MKL_TRSM_L(dcomplex, MKL_Complex16, z) +EIGEN_MKL_TRSM_L(float, float, s) +EIGEN_MKL_TRSM_L(scomplex, MKL_Complex8, c) + + +// implements RightSide general * op(triangular)^-1 +#define EIGEN_MKL_TRSM_R(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template <typename Index, int Mode, bool Conjugate, int TriStorageOrder> \ +struct triangular_solve_matrix<EIGTYPE,Index,OnTheRight,Mode,Conjugate,TriStorageOrder,ColMajor> \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \ + }; \ + static EIGEN_DONT_INLINE void run( \ + Index size, Index otherSize, \ + const EIGTYPE* _tri, Index triStride, \ + EIGTYPE* _other, Index otherStride, level3_blocking<EIGTYPE,EIGTYPE>& /*blocking*/) \ + { \ + MKL_INT m = otherSize, n = size, lda, ldb; \ + char side = 'R', uplo, diag='N', transa; \ + /* Set alpha_ */ \ + MKLTYPE alpha; \ + EIGTYPE myone(1); \ + assign_scalar_eig2mkl(alpha, myone); \ + ldb = otherStride;\ +\ + const EIGTYPE *a; \ +/* Set trans */ \ + transa = (TriStorageOrder==RowMajor) ? ((Conjugate) ? 'C' : 'T') : 'N'; \ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (TriStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, TriStorageOrder> MatrixTri; \ + Map<const MatrixTri, 0, OuterStride<> > tri(_tri,size,size,OuterStride<>(triStride)); \ + MatrixTri a_tmp; \ +\ + if (conjA) { \ + a_tmp = tri.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _tri; \ + lda = triStride; \ + } \ + if (IsUnitDiag) diag='U'; \ +/* call ?trsm*/ \ + MKLPREFIX##trsm(&side, &uplo, &transa, &diag, &m, &n, &alpha, (const MKLTYPE*)a, &lda, (MKLTYPE*)_other, &ldb); \ + /*std::cout << "TRMS_L specialization!\n";*/ \ + } \ +}; + +EIGEN_MKL_TRSM_R(double, double, d) +EIGEN_MKL_TRSM_R(dcomplex, MKL_Complex16, z) +EIGEN_MKL_TRSM_R(float, float, s) +EIGEN_MKL_TRSM_R(scomplex, MKL_Complex8, c) + + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h index 639d4a5b476..ce4d1008801 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H #define EIGEN_TRIANGULAR_SOLVER_VECTOR_H +namespace Eigen { + namespace internal { template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate, int StorageOrder> @@ -147,4 +134,6 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRIANGULAR_SOLVER_VECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h b/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h index f1d93d2f8b9..91496651c82 100644 --- a/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h +++ b/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLASUTIL_H #define EIGEN_BLASUTIL_H @@ -28,6 +13,8 @@ // This file contains many lightweight helper classes used to // implement and control fast level 2 and level 3 BLAS-like routines. +namespace Eigen { + namespace internal { // forward declarations @@ -47,7 +34,7 @@ template< int ResStorageOrder> struct general_matrix_matrix_product; -template<typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs> +template<typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs, int Version=Specialized> struct general_matrix_vector_product; @@ -56,11 +43,15 @@ template<bool Conjugate> struct conj_if; template<> struct conj_if<true> { template<typename T> inline T operator()(const T& x) { return conj(x); } + template<typename T> + inline T pconj(const T& x) { return internal::pconj(x); } }; template<> struct conj_if<false> { template<typename T> inline const T& operator()(const T& x) { return x; } + template<typename T> + inline const T& pconj(const T& x) { return x; } }; template<typename Scalar> struct conj_helper<Scalar,Scalar,false,false> @@ -118,11 +109,11 @@ template<typename RealScalar,bool Conj> struct conj_helper<RealScalar, std::comp }; template<typename From,typename To> struct get_factor { - EIGEN_STRONG_INLINE static To run(const From& x) { return x; } + static EIGEN_STRONG_INLINE To run(const From& x) { return x; } }; template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> { - EIGEN_STRONG_INLINE static typename NumTraits<Scalar>::Real run(const Scalar& x) { return real(x); } + static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return real(x); } }; // Lightweight helper class to access matrix coefficients. @@ -175,7 +166,7 @@ template<typename XprType> struct blas_traits ExtractType, typename _ExtractType::PlainObject >::type DirectLinearAccessType; - static inline const ExtractType extract(const XprType& x) { return x; } + static inline ExtractType extract(const XprType& x) { return x; } static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); } }; @@ -192,7 +183,7 @@ struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> > IsComplex = NumTraits<Scalar>::IsComplex, NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex }; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); } }; @@ -204,7 +195,7 @@ struct blas_traits<CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> > typedef blas_traits<NestedXpr> Base; typedef CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> XprType; typedef typename Base::ExtractType ExtractType; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return x.functor().m_other * Base::extractScalarFactor(x.nestedExpression()); } }; @@ -217,7 +208,7 @@ struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> > typedef blas_traits<NestedXpr> Base; typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType; typedef typename Base::ExtractType ExtractType; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return - Base::extractScalarFactor(x.nestedExpression()); } }; @@ -239,7 +230,7 @@ struct blas_traits<Transpose<NestedXpr> > enum { IsTransposed = Base::IsTransposed ? 0 : 1 }; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); } }; @@ -252,7 +243,7 @@ template<typename T, bool HasUsableDirectAccess=blas_traits<T>::HasUsableDirectA struct extract_data_selector { static const typename T::Scalar* run(const T& m) { - return const_cast<typename T::Scalar*>(&blas_traits<T>::extract(m).coeffRef(0,0)); // FIXME this should be .data() + return blas_traits<T>::extract(m).data(); } }; @@ -268,4 +259,6 @@ template<typename T> const typename T::Scalar* extract_data(const T& m) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_BLASUTIL_H diff --git a/extern/Eigen3/Eigen/src/Core/util/Constants.h b/extern/Eigen3/Eigen/src/Core/util/Constants.h index c3dd3a09d00..3fd45e84f8e 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Constants.h +++ b/extern/Eigen3/Eigen/src/Core/util/Constants.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CONSTANTS_H #define EIGEN_CONSTANTS_H +namespace Eigen { + /** This value means that a quantity is not known at compile-time, and that instead the value is * stored in some runtime variable. * @@ -188,7 +175,9 @@ enum { /** View matrix as an upper triangular matrix with zeros on the diagonal. */ StrictlyUpper=ZeroDiag|Upper, /** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */ - SelfAdjoint=0x10 + SelfAdjoint=0x10, + /** Used to support symmetric, non-selfadjoint, complex matrices. */ + Symmetric=0x20 }; /** \ingroup enums @@ -200,8 +189,6 @@ enum { Aligned=1 }; -enum { ConditionalJumpCost = 5 }; - /** \ingroup enums * Enum used by DenseBase::corner() in Eigen2 compatibility mode. */ // FIXME after the corner() API change, this was not needed anymore, except by AlignedBox @@ -223,8 +210,6 @@ enum DirectionType { BothDirections }; -enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct }; - /** \internal \ingroup enums * Enum to specify how to traverse the entries of a matrix. */ enum { @@ -257,6 +242,13 @@ enum { CompleteUnrolling }; +/** \internal \ingroup enums + * Enum to specify whether to use the default (built-in) implementation or the specialization. */ +enum { + Specialized, + BuiltIn +}; + /** \ingroup enums * Enum containing possible values for the \p _Options template parameter of * Matrix, Array and BandMatrix. */ @@ -280,26 +272,21 @@ enum { OnTheRight = 2 }; -/* the following could as well be written: - * enum NoChange_t { NoChange }; - * but it feels dangerous to disambiguate overloaded functions on enum/integer types. - * If on some platform it is really impossible to get rid of "unused variable" warnings, then - * we can always come back to that solution. +/* the following used to be written as: + * + * struct NoChange_t {}; + * namespace { + * EIGEN_UNUSED NoChange_t NoChange; + * } + * + * on the ground that it feels dangerous to disambiguate overloaded functions on enum/integer types. + * However, this leads to "variable declared but never referenced" warnings on Intel Composer XE, + * and we do not know how to get rid of them (bug 450). */ -struct NoChange_t {}; -namespace { - EIGEN_UNUSED NoChange_t NoChange; -} - -struct Sequential_t {}; -namespace { - EIGEN_UNUSED Sequential_t Sequential; -} -struct Default_t {}; -namespace { - EIGEN_UNUSED Default_t Default; -} +enum NoChange_t { NoChange }; +enum Sequential_t { Sequential }; +enum Default_t { Default }; /** \internal \ingroup enums * Used in AmbiVector. */ @@ -375,7 +362,7 @@ enum QRPreconditioners { #error The preprocessor symbol 'Success' is defined, possibly by the X11 header file X.h #endif -/** \ingroups enums +/** \ingroup enums * Enum for reporting the status of a computation. */ enum ComputationInfo { /** Computation was successful. */ @@ -383,7 +370,10 @@ enum ComputationInfo { /** The provided data did not satisfy the prerequisites. */ NumericalIssue = 1, /** Iterative procedure did not converge. */ - NoConvergence = 2 + NoConvergence = 2, + /** The inputs are invalid, or the algorithm has been improperly called. + * When assertions are enabled, such errors trigger an assert. */ + InvalidInput = 3 }; /** \ingroup enums @@ -436,4 +426,6 @@ struct MatrixXpr {}; /** The type used to identify an array expression */ struct ArrayXpr {}; +} // end namespace Eigen + #endif // EIGEN_CONSTANTS_H diff --git a/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h b/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h index 00730524b26..6a0bf0629c5 100644 --- a/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h @@ -21,15 +21,13 @@ #elif defined __INTEL_COMPILER // 2196 - routine is both "inline" and "noinline" ("noinline" assumed) // ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body - // 2536 - type qualifiers are meaningless here - // ICC 12 generates this warning when a function return type is const qualified, even if that type is a template-parameter-dependent // typedef that may be a reference type. // 279 - controlling expression is constant // ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case. #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS #pragma warning push #endif - #pragma warning disable 2196 2536 279 + #pragma warning disable 2196 279 #elif defined __clang__ // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant // this is really a stupid warning as it warns on compile-time expressions involving enums diff --git a/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h b/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h index 7fbccf98c2b..bcdfe3914e3 100644 --- a/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h +++ b/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h @@ -4,28 +4,14 @@ // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FORWARDDECLARATIONS_H #define EIGEN_FORWARDDECLARATIONS_H +namespace Eigen { namespace internal { template<typename T> struct traits; @@ -133,6 +119,7 @@ template<typename ExpressionType> class WithFormat; template<typename MatrixType> struct CommaInitializer; template<typename Derived> class ReturnByValue; template<typename ExpressionType> class ArrayWrapper; +template<typename ExpressionType> class MatrixWrapper; namespace internal { template<typename DecompositionType, typename Rhs> struct solve_retval_base; @@ -282,6 +269,8 @@ template<typename MatrixType,int Direction> class Homogeneous; // MatrixFunctions module template<typename Derived> struct MatrixExponentialReturnValue; template<typename Derived> class MatrixFunctionReturnValue; +template<typename Derived> class MatrixSquareRootReturnValue; +template<typename Derived> class MatrixLogarithmReturnValue; namespace internal { template <typename Scalar> @@ -304,4 +293,6 @@ template<typename MatrixType, unsigned int Mode> struct eigen2_part_return_type; } #endif +} // end namespace Eigen + #endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/extern/Eigen3/Eigen/src/Core/util/MKL_support.h b/extern/Eigen3/Eigen/src/Core/util/MKL_support.h new file mode 100644 index 00000000000..1e6e355d626 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/util/MKL_support.h @@ -0,0 +1,109 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Include file with common MKL declarations + ******************************************************************************** +*/ + +#ifndef EIGEN_MKL_SUPPORT_H +#define EIGEN_MKL_SUPPORT_H + +#ifdef EIGEN_USE_MKL_ALL + #ifndef EIGEN_USE_BLAS + #define EIGEN_USE_BLAS + #endif + #ifndef EIGEN_USE_LAPACKE + #define EIGEN_USE_LAPACKE + #endif + #ifndef EIGEN_USE_MKL_VML + #define EIGEN_USE_MKL_VML + #endif +#endif + +#ifdef EIGEN_USE_LAPACKE_STRICT + #define EIGEN_USE_LAPACKE +#endif + +#if defined(EIGEN_USE_BLAS) || defined(EIGEN_USE_LAPACKE) || defined(EIGEN_USE_MKL_VML) + #define EIGEN_USE_MKL +#endif + +#if defined EIGEN_USE_MKL + +#include <mkl.h> +#include <mkl_lapacke.h> +#define EIGEN_MKL_VML_THRESHOLD 128 + +namespace Eigen { + +typedef std::complex<double> dcomplex; +typedef std::complex<float> scomplex; + +namespace internal { + +template<typename MKLType, typename EigenType> +static inline void assign_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) { + mklScalar=eigenScalar; +} + +template<typename MKLType, typename EigenType> +static inline void assign_conj_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) { + mklScalar=eigenScalar; +} + +template <> +inline void assign_scalar_eig2mkl<MKL_Complex16,dcomplex>(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=eigenScalar.imag(); +} + +template <> +inline void assign_scalar_eig2mkl<MKL_Complex8,scomplex>(MKL_Complex8& mklScalar, const scomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=eigenScalar.imag(); +} + +template <> +inline void assign_conj_scalar_eig2mkl<MKL_Complex16,dcomplex>(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=-eigenScalar.imag(); +} + +template <> +inline void assign_conj_scalar_eig2mkl<MKL_Complex8,scomplex>(MKL_Complex8& mklScalar, const scomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=-eigenScalar.imag(); +} + +} // end namespace internal + +} // end namespace Eigen + +#endif + +#endif // EIGEN_MKL_SUPPORT_H diff --git a/extern/Eigen3/Eigen/src/Core/util/Macros.h b/extern/Eigen3/Eigen/src/Core/util/Macros.h index b7c2b79af92..d973a68372f 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Macros.h +++ b/extern/Eigen3/Eigen/src/Core/util/Macros.h @@ -1,35 +1,19 @@ - // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MACROS_H #define EIGEN_MACROS_H #define EIGEN_WORLD_VERSION 3 -#define EIGEN_MAJOR_VERSION 0 -#define EIGEN_MINOR_VERSION 5 +#define EIGEN_MAJOR_VERSION 1 +#define EIGEN_MINOR_VERSION 1 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ @@ -235,12 +219,16 @@ #define EIGEN_ONLY_USED_FOR_DEBUG(x) #endif -#if (defined __GNUC__) -#define EIGEN_DEPRECATED __attribute__((deprecated)) -#elif (defined _MSC_VER) -#define EIGEN_DEPRECATED __declspec(deprecated) +#ifndef EIGEN_NO_DEPRECATED_WARNING + #if (defined __GNUC__) + #define EIGEN_DEPRECATED __attribute__((deprecated)) + #elif (defined _MSC_VER) + #define EIGEN_DEPRECATED __declspec(deprecated) + #else + #define EIGEN_DEPRECATED + #endif #else -#define EIGEN_DEPRECATED + #define EIGEN_DEPRECATED #endif #if (defined __GNUC__) @@ -252,7 +240,7 @@ // Suppresses 'unused variable' warnings. #define EIGEN_UNUSED_VARIABLE(var) (void)var; -#if (defined __GNUC__) +#if !defined(EIGEN_ASM_COMMENT) && (defined __GNUC__) #define EIGEN_ASM_COMMENT(X) asm("#" X) #else #define EIGEN_ASM_COMMENT(X) @@ -265,7 +253,7 @@ * If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link * vectorized and non-vectorized code. */ -#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) +#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) || (defined __ARMCC_VERSION) #define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n))) #elif (defined _MSC_VER) #define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n)) diff --git a/extern/Eigen3/Eigen/src/Core/util/Memory.h b/extern/Eigen3/Eigen/src/Core/util/Memory.h index 023716dc9e0..6e06ace44a0 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Memory.h +++ b/extern/Eigen3/Eigen/src/Core/util/Memory.h @@ -7,24 +7,9 @@ // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com> // Copyright (C) 2010 Thomas Capricelli <orzel@freehackers.org> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. /***************************************************************************** @@ -80,6 +65,8 @@ #define EIGEN_HAS_MM_MALLOC 0 #endif +namespace Eigen { + namespace internal { inline void throw_std_bad_alloc() @@ -457,7 +444,7 @@ template<typename T, bool Align> inline void conditional_aligned_delete_auto(T * * There is also the variant first_aligned(const MatrixBase&) defined in DenseCoeffsBase.h. */ template<typename Scalar, typename Index> -inline static Index first_aligned(const Scalar* array, Index size) +static inline Index first_aligned(const Scalar* array, Index size) { typedef typename packet_traits<Scalar>::type Packet; enum { PacketSize = packet_traits<Scalar>::size, @@ -483,7 +470,26 @@ inline static Index first_aligned(const Scalar* array, Index size) } } -} // end namespace internal + +// std::copy is much slower than memcpy, so let's introduce a smart_copy which +// use memcpy on trivial types, i.e., on types that does not require an initialization ctor. +template<typename T, bool UseMemcpy> struct smart_copy_helper; + +template<typename T> void smart_copy(const T* start, const T* end, T* target) +{ + smart_copy_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target); +} + +template<typename T> struct smart_copy_helper<T,true> { + static inline void run(const T* start, const T* end, T* target) + { memcpy(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); } +}; + +template<typename T> struct smart_copy_helper<T,false> { + static inline void run(const T* start, const T* end, T* target) + { std::copy(start, end, target); } +}; + /***************************************************************************** *** Implementation of runtime stack allocation (falling back to malloc) *** @@ -499,8 +505,6 @@ inline static Index first_aligned(const Scalar* array, Index size) #endif #endif -namespace internal { - // This helper class construct the allocated memory, and takes care of destructing and freeing the handled data // at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions. template<typename T> class aligned_stack_memory_handler @@ -531,14 +535,14 @@ template<typename T> class aligned_stack_memory_handler bool m_deallocate; }; -} +} // end namespace internal /** \internal * Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack * if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform * (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap. * The allocated buffer is automatically deleted when exiting the scope of this declaration. - * If BUFFER is non nul, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. + * If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. * Here is an example: * \code * { @@ -619,7 +623,7 @@ template<typename T> class aligned_stack_memory_handler #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true) #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0)) + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0))) /****************************************************************************/ @@ -667,24 +671,24 @@ public: return &value; } - aligned_allocator() throw() + aligned_allocator() { } - aligned_allocator( const aligned_allocator& ) throw() + aligned_allocator( const aligned_allocator& ) { } template<class U> - aligned_allocator( const aligned_allocator<U>& ) throw() + aligned_allocator( const aligned_allocator<U>& ) { } - ~aligned_allocator() throw() + ~aligned_allocator() { } - size_type max_size() const throw() + size_type max_size() const { return (std::numeric_limits<size_type>::max)(); } @@ -701,6 +705,15 @@ public: ::new( p ) T( value ); } + // Support for c++11 +#if (__cplusplus >= 201103L) + template<typename... Args> + void construct(pointer p, Args&&... args) + { + ::new(p) T(std::forward<Args>(args)...); + } +#endif + void destroy( pointer p ) { p->~T(); @@ -720,19 +733,21 @@ public: //---------- Cache sizes ---------- -#if defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) -# if defined(__PIC__) && defined(__i386__) - // Case for x86 with PIC -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("xchgl %%ebx, %%esi;cpuid; xchgl %%ebx,%%esi": "=a" (abcd[0]), "=S" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id)); -# else - // Case for x86_64 or x86 w/o PIC -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id) ); -# endif -#elif defined(_MSC_VER) -# if (_MSC_VER > 1500) -# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id) +#if !defined(EIGEN_NO_CPUID) +# if defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) +# if defined(__PIC__) && defined(__i386__) + // Case for x86 with PIC +# define EIGEN_CPUID(abcd,func,id) \ + __asm__ __volatile__ ("xchgl %%ebx, %%esi;cpuid; xchgl %%ebx,%%esi": "=a" (abcd[0]), "=S" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id)); +# else + // Case for x86_64 or x86 w/o PIC +# define EIGEN_CPUID(abcd,func,id) \ + __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id) ); +# endif +# elif defined(_MSC_VER) +# if (_MSC_VER > 1500) +# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id) +# endif # endif #endif @@ -742,7 +757,7 @@ namespace internal { inline bool cpuid_is_vendor(int abcd[4], const char* vendor) { - return abcd[1]==((int*)(vendor))[0] && abcd[3]==((int*)(vendor))[1] && abcd[2]==((int*)(vendor))[2]; + return abcd[1]==(reinterpret_cast<const int*>(vendor))[0] && abcd[3]==(reinterpret_cast<const int*>(vendor))[1] && abcd[2]==(reinterpret_cast<const int*>(vendor))[2]; } inline void queryCacheSizes_intel_direct(int& l1, int& l2, int& l3) @@ -932,4 +947,6 @@ inline int queryTopLevelCacheSize() } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_MEMORY_H diff --git a/extern/Eigen3/Eigen/src/Core/util/Meta.h b/extern/Eigen3/Eigen/src/Core/util/Meta.h index 4518261efef..a5f31164d15 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Meta.h +++ b/extern/Eigen3/Eigen/src/Core/util/Meta.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_META_H #define EIGEN_META_H +namespace Eigen { + namespace internal { /** \internal @@ -80,8 +67,6 @@ template<> struct is_arithmetic<signed int> { enum { value = true }; }; template<> struct is_arithmetic<unsigned int> { enum { value = true }; }; template<> struct is_arithmetic<signed long> { enum { value = true }; }; template<> struct is_arithmetic<unsigned long> { enum { value = true }; }; -template<> struct is_arithmetic<signed long long> { enum { value = true }; }; -template<> struct is_arithmetic<unsigned long long> { enum { value = true }; }; template <typename T> struct add_const { typedef const T type; }; template <typename T> struct add_const<T&> { typedef T& type; }; @@ -103,6 +88,21 @@ template<bool Condition, typename T> struct enable_if; template<typename T> struct enable_if<true,T> { typedef T type; }; + + +/** \internal + * A base class do disable default copy ctor and copy assignement operator. + */ +class noncopyable +{ + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +protected: + noncopyable() {} + ~noncopyable() {} +}; + + /** \internal * Convenient struct to get the result type of a unary or binary functor. * @@ -226,4 +226,6 @@ template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> > } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_META_H diff --git a/extern/Eigen3/Eigen/src/Core/util/NonMPL2.h b/extern/Eigen3/Eigen/src/Core/util/NonMPL2.h new file mode 100644 index 00000000000..1af67cf18c7 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/util/NonMPL2.h @@ -0,0 +1,3 @@ +#ifdef EIGEN_MPL2_ONLY +#error Including non-MPL2 code in EIGEN_MPL2_ONLY mode +#endif diff --git a/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h b/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h index 99c7c9972f0..b46a75b3783 100644 --- a/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h +++ b/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h @@ -4,24 +4,9 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STATIC_ASSERT_H #define EIGEN_STATIC_ASSERT_H @@ -48,6 +33,8 @@ #else // not CXX0X + namespace Eigen { + namespace internal { template<bool condition> @@ -70,6 +57,7 @@ YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR, UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES, + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED, NUMERIC_TYPE_MUST_BE_REAL, COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED, @@ -95,12 +83,20 @@ YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION, THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY, YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT, - THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS + THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS, + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL, + THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES, + YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED, + YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, + THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, + THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH }; }; } // end namespace internal + } // end namespace Eigen + // Specialized implementation for MSVC to avoid "conditional // expression is constant" warnings. This implementation doesn't // appear to work under GCC, hence the multiple implementations. @@ -195,4 +191,15 @@ EIGEN_STATIC_ASSERT(internal::is_lvalue<Derived>::value, \ THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY) +#define EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) \ + EIGEN_STATIC_ASSERT((internal::is_same<typename internal::traits<Derived>::XprKind, ArrayXpr>::value), \ + THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES) + +#define EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) \ + EIGEN_STATIC_ASSERT((internal::is_same<typename internal::traits<Derived1>::XprKind, \ + typename internal::traits<Derived2>::XprKind \ + >::value), \ + YOU_CANNOT_MIX_ARRAYS_AND_MATRICES) + + #endif // EIGEN_STATIC_ASSERT_H diff --git a/extern/Eigen3/Eigen/src/Core/util/XprHelper.h b/extern/Eigen3/Eigen/src/Core/util/XprHelper.h index c2078f13786..2a65c7cbfa4 100644 --- a/extern/Eigen3/Eigen/src/Core/util/XprHelper.h +++ b/extern/Eigen3/Eigen/src/Core/util/XprHelper.h @@ -4,24 +4,9 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_XPRHELPER_H #define EIGEN_XPRHELPER_H @@ -37,6 +22,8 @@ #define EIGEN_EMPTY_STRUCT_CTOR(X) #endif +namespace Eigen { + typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex; namespace internal { @@ -260,30 +247,27 @@ template<typename T> struct plain_matrix_type_row_major // we should be able to get rid of this one too template<typename T> struct must_nest_by_value { enum { ret = false }; }; -template<class T> -struct is_reference -{ - enum { ret = false }; -}; - -template<class T> -struct is_reference<T&> -{ - enum { ret = true }; -}; - -/** -* \internal The reference selector for template expressions. The idea is that we don't -* need to use references for expressions since they are light weight proxy -* objects which should generate no copying overhead. -**/ +/** \internal The reference selector for template expressions. The idea is that we don't + * need to use references for expressions since they are light weight proxy + * objects which should generate no copying overhead. */ template <typename T> struct ref_selector { typedef typename conditional< bool(traits<T>::Flags & NestByRefBit), T const&, - T + const T + >::type type; +}; + +/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */ +template<typename T1, typename T2> +struct transfer_constness +{ + typedef typename conditional< + bool(internal::is_const<T1>::value), + typename internal::add_const_on_value_type<T2>::type, + T2 >::type type; }; @@ -297,6 +281,8 @@ struct ref_selector * \param T the type of the expression being nested * \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression. * + * Note that if no evaluation occur, then the constness of T is preserved. + * * Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c). * b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it, * the Product expression uses: nested<S, 3>::ret, which turns out to be Matrix3d because the internal logic of @@ -456,4 +442,6 @@ struct is_lvalue } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_XPRHELPER_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Block.h b/extern/Eigen3/Eigen/src/Eigen2Support/Block.h index bc28051e017..604456f40e7 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Block.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Block.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCK2_H #define EIGEN_BLOCK2_H +namespace Eigen { + /** \returns a dynamic-size expression of a corner of *this. * * \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight, @@ -134,4 +121,6 @@ DenseBase<Derived>::corner(CornerType type) const } } +} // end namespace Eigen + #endif // EIGEN_BLOCK2_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h b/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h index 2dc83b6a7dd..d95009b6e29 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_H #define EIGEN_CWISE_H +namespace Eigen { + /** \internal * convenient macro to defined the return type of a cwise binary operation */ #define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \ @@ -200,4 +187,6 @@ inline Cwise<Derived> MatrixBase<Derived>::cwise() return derived(); } +} // end namespace Eigen + #endif // EIGEN_CWISE_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h b/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h index 9c28559c329..482f3064856 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAY_CWISE_OPERATORS_H #define EIGEN_ARRAY_CWISE_OPERATORS_H +namespace Eigen { + /*************************************************************************** * The following functions were defined in Core ***************************************************************************/ @@ -306,4 +293,6 @@ inline ExpressionType& Cwise<ExpressionType>::operator-=(const Scalar& scalar) return m_matrix.const_cast_derived() = *this - scalar; } +} // end namespace Eigen + #endif // EIGEN_ARRAY_CWISE_OPERATORS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h index 78df29d408a..5c928e8fc2d 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h @@ -3,27 +3,14 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * \nonstableyet * @@ -63,7 +50,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim== ~AlignedBox() {} /** \returns the dimension in which the box holds */ - inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : int(AmbientDimAtCompileTime); } + inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; } /** \returns true if the box is null, i.e, empty. */ inline bool isNull() const { return (m_min.cwise() > m_max).any(); } @@ -157,14 +144,16 @@ protected: template<typename Scalar,int AmbiantDim> inline Scalar AlignedBox<Scalar,AmbiantDim>::squaredExteriorDistance(const VectorType& p) const { - Scalar dist2 = 0.; + Scalar dist2(0); Scalar aux; for (int k=0; k<dim(); ++k) { - if ((aux = (p[k]-m_min[k]))<0.) + if ((aux = (p[k]-m_min[k]))<Scalar(0)) dist2 += aux*aux; - else if ( (aux = (m_max[k]-p[k]))<0. ) + else if ( (aux = (m_max[k]-p[k]))<Scalar(0)) dist2 += aux*aux; } return dist2; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h index 9d8244b07a0..e0b00fccccf 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h @@ -112,4 +112,4 @@ #undef Hyperplane #undef ParametrizedLine -#endif // EIGEN2_GEOMETRY_MODULE_H
\ No newline at end of file +#endif // EIGEN2_GEOMETRY_MODULE_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h index f7b2d51e3e2..20f1fceeb19 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -224,3 +210,5 @@ AngleAxis<Scalar>::toRotationMatrix(void) const return res; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h index 81c4f55b173..19cc1bfd883 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h @@ -4,27 +4,14 @@ // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Hyperplane @@ -263,3 +250,5 @@ protected: Coefficients m_coeffs; }; + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h index 411c4b57079..6e4a168a8cd 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h @@ -4,27 +4,13 @@ // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -151,3 +137,5 @@ inline _Scalar ParametrizedLine<_Scalar, _AmbientDim>::intersection(const Hyperp return -(hyperplane.offset()+origin().eigen2_dot(hyperplane.normal())) /(direction().eigen2_dot(hyperplane.normal())); } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h index a75fa42aeac..ec87da054d6 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h @@ -3,27 +3,14 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + template<typename Other, int OtherRows=Other::RowsAtCompileTime, int OtherCols=Other::ColsAtCompileTime> @@ -143,7 +130,7 @@ public: /** \returns a quaternion representing an identity rotation * \sa MatrixBase::Identity() */ - inline static Quaternion Identity() { return Quaternion(1, 0, 0, 0); } + static inline Quaternion Identity() { return Quaternion(1, 0, 0, 0); } /** \sa Quaternion::Identity(), MatrixBase::setIdentity() */ @@ -314,9 +301,9 @@ Quaternion<Scalar>::toRotationMatrix(void) const // it has to be inlined, and so the return by value is not an issue Matrix3 res; - const Scalar tx = 2*this->x(); - const Scalar ty = 2*this->y(); - const Scalar tz = 2*this->z(); + const Scalar tx = Scalar(2)*this->x(); + const Scalar ty = Scalar(2)*this->y(); + const Scalar tz = Scalar(2)*this->z(); const Scalar twx = tx*this->w(); const Scalar twy = ty*this->w(); const Scalar twz = tz*this->w(); @@ -327,15 +314,15 @@ Quaternion<Scalar>::toRotationMatrix(void) const const Scalar tyz = tz*this->y(); const Scalar tzz = tz*this->z(); - res.coeffRef(0,0) = 1-(tyy+tzz); + res.coeffRef(0,0) = Scalar(1)-(tyy+tzz); res.coeffRef(0,1) = txy-twz; res.coeffRef(0,2) = txz+twy; res.coeffRef(1,0) = txy+twz; - res.coeffRef(1,1) = 1-(txx+tzz); + res.coeffRef(1,1) = Scalar(1)-(txx+tzz); res.coeffRef(1,2) = tyz-twx; res.coeffRef(2,0) = txz-twy; res.coeffRef(2,1) = tyz+twx; - res.coeffRef(2,2) = 1-(txx+tyy); + res.coeffRef(2,2) = Scalar(1)-(txx+tyy); return res; } @@ -460,7 +447,7 @@ template<typename Other> struct ei_quaternion_assign_impl<Other,3,3> { typedef typename Other::Scalar Scalar; - inline static void run(Quaternion<Scalar>& q, const Other& mat) + static inline void run(Quaternion<Scalar>& q, const Other& mat) { // This algorithm comes from "Quaternion Calculus and Fast Animation", // Ken Shoemake, 1987 SIGGRAPH course notes @@ -499,8 +486,10 @@ template<typename Other> struct ei_quaternion_assign_impl<Other,4,1> { typedef typename Other::Scalar Scalar; - inline static void run(Quaternion<Scalar>& q, const Other& vec) + static inline void run(Quaternion<Scalar>& q, const Other& vec) { q.coeffs() = vec; } }; + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h index ee7c80e7eaa..3e02b7a4fd1 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -155,3 +141,5 @@ Rotation2D<Scalar>::toRotationMatrix(void) const Scalar cosA = ei_cos(m_angle); return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h index 2f494f198bd..78ad73b60ad 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h @@ -3,27 +3,14 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + // this file aims to contains the various representations of rotation/orientation // in 2D and 3D space excepted Matrix and Quaternion. @@ -113,22 +100,24 @@ Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis */ template<typename Scalar, int Dim> -inline static Matrix<Scalar,2,2> ei_toRotationMatrix(const Scalar& s) +static inline Matrix<Scalar,2,2> ei_toRotationMatrix(const Scalar& s) { EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) return Rotation2D<Scalar>(s).toRotationMatrix(); } template<typename Scalar, int Dim, typename OtherDerived> -inline static Matrix<Scalar,Dim,Dim> ei_toRotationMatrix(const RotationBase<OtherDerived,Dim>& r) +static inline Matrix<Scalar,Dim,Dim> ei_toRotationMatrix(const RotationBase<OtherDerived,Dim>& r) { return r.toRotationMatrix(); } template<typename Scalar, int Dim, typename OtherDerived> -inline static const MatrixBase<OtherDerived>& ei_toRotationMatrix(const MatrixBase<OtherDerived>& mat) +static inline const MatrixBase<OtherDerived>& ei_toRotationMatrix(const MatrixBase<OtherDerived>& mat) { EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, YOU_MADE_A_PROGRAMMING_MISTAKE) return mat; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h index 108e6d7d58f..a07c1c7c762 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -177,3 +163,5 @@ Scaling<Scalar,Dim>::operator* (const TransformType& t) const res.prescale(m_coeffs); return res; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h index 88956c86c73..dceb8020383 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h @@ -4,27 +4,13 @@ // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { // Note that we have to pass Dim and HDim because it is not allowed to use a template // parameter to define a template specialization. To be more precise, in the following @@ -796,3 +782,5 @@ struct ei_transform_product_impl<Other,Dim,HDim, Dim,1> { return ((tr.linear() * other) + tr.translation()) * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); } }; + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h index e651e310212..0fb9a9f9a5a 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -194,3 +180,5 @@ Translation<Scalar,Dim>::operator* (const TransformType& t) const res.pretranslate(m_coeffs); return res; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/LU.h b/extern/Eigen3/Eigen/src/Eigen2Support/LU.h index c23c11baa72..49f19ad76e3 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/LU.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/LU.h @@ -3,28 +3,15 @@ // // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_LU_H #define EIGEN2_LU_H +namespace Eigen { + template<typename MatrixType> class LU : public FullPivLU<MatrixType> { @@ -57,7 +44,6 @@ class LU : public FullPivLU<MatrixType> > ImageResultType; typedef FullPivLU<MatrixType> Base; - LU() : Base() {} template<typename T> explicit LU(const T& t) : Base(t), m_originalMatrix(t) {} @@ -129,5 +115,6 @@ MatrixBase<Derived>::eigen2_lu() const } #endif +} // end namespace Eigen #endif // EIGEN2_LU_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h b/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h index c4288ede2ef..593fc78e6de 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LAZY_H #define EIGEN_LAZY_H +namespace Eigen { + /** \deprecated it is only used by lazy() which is deprecated * * \returns an expression of *this with added flags @@ -79,4 +66,6 @@ Derived& MatrixBase<Derived>::operator-=(const Flagged<ProductBase<ProductDerive other._expression().derived().subTo(derived()); return derived(); } +} // end namespace Eigen + #endif // EIGEN_LAZY_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h b/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h index 4b62ffa92c7..7aff428dc45 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_LEASTSQUARES_H #define EIGEN2_LEASTSQUARES_H +namespace Eigen { + /** \ingroup LeastSquares_Module * * \leastsquares_module @@ -178,5 +165,6 @@ void fitHyperplane(int numPoints, result->offset() = - (result->normal().cwise()* mean).sum(); } +} // end namespace Eigen #endif // EIGEN2_LEASTSQUARES_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h b/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h index 77e85a41e3d..351c32afb60 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h @@ -3,24 +3,9 @@ // // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_MACROS_H #define EIGEN2_MACROS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h b/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h index caa44e63f32..3a8a9ca8146 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_MATH_FUNCTIONS_H #define EIGEN2_MATH_FUNCTIONS_H +namespace Eigen { + template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return internal::real(x); } template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return internal::imag(x); } template<typename T> inline T ei_conj(const T& x) { return internal::conj(x); } @@ -65,4 +52,6 @@ inline bool ei_isApproxOrLessThan(const Scalar& x, const Scalar& y, return internal::isApproxOrLessThan(x, y, precision); } +} // end namespace Eigen + #endif // EIGEN2_MATH_FUNCTIONS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h b/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h index 0283475419e..f86372b6b56 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h @@ -3,28 +3,15 @@ // // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_MEMORY_H #define EIGEN2_MEMORY_H +namespace Eigen { + inline void* ei_aligned_malloc(size_t size) { return internal::aligned_malloc(size); } inline void ei_aligned_free(void *ptr) { internal::aligned_free(ptr); } inline void* ei_aligned_realloc(void *ptr, size_t new_size, size_t old_size) { return internal::aligned_realloc(ptr, new_size, old_size); } @@ -53,6 +40,6 @@ template<typename T> inline void ei_aligned_delete(T *ptr, size_t size) return internal::aligned_delete(ptr, size); } - +} // end namespace Eigen #endif // EIGEN2_MACROS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h b/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h index 6e500b79a2e..fa37cfc961e 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h @@ -3,28 +3,15 @@ // // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_META_H #define EIGEN2_META_H +namespace Eigen { + template<typename T> struct ei_traits : internal::traits<T> {}; @@ -83,4 +70,6 @@ class ei_meta_sqrt template<int Y, int InfX, int SupX> class ei_meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; +} // end namespace Eigen + #endif // EIGEN2_META_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h b/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h index eda91cc32be..4cded5734fa 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MINOR_H #define EIGEN_MINOR_H +namespace Eigen { + /** * \class Minor * @@ -125,4 +112,6 @@ MatrixBase<Derived>::minor(Index row, Index col) const return Minor<Derived>(derived(), row, col); } +} // end namespace Eigen + #endif // EIGEN_MINOR_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/QR.h b/extern/Eigen3/Eigen/src/Eigen2Support/QR.h index 64f5d5ccb30..2042c98510a 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/QR.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/QR.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_QR_H #define EIGEN2_QR_H +namespace Eigen { + template<typename MatrixType> class QR : public HouseholderQR<MatrixType> { @@ -75,5 +62,6 @@ MatrixBase<Derived>::qr() const return QR<PlainObject>(eval()); } +} // end namespace Eigen #endif // EIGEN2_QR_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h b/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h index 16b4b488f0c..3d2eeb44586 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_SVD_H #define EIGEN2_SVD_H +namespace Eigen { + /** \ingroup SVD_Module * \nonstableyet * @@ -390,7 +377,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix) Scalar ek = e[k]/scale; Scalar b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/Scalar(2); Scalar c = (sp*epm1)*(sp*epm1); - Scalar shift = 0.0; + Scalar shift(0); if ((b != 0.0) || (c != 0.0)) { shift = ei_sqrt(b*b + c); @@ -646,4 +633,6 @@ MatrixBase<Derived>::svd() const return SVD<PlainObject>(derived()); } +} // end namespace Eigen + #endif // EIGEN2_SVD_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h b/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h index e94e47a5093..ebbeb3b4958 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER2_H #define EIGEN_TRIANGULAR_SOLVER2_H +namespace Eigen { + const unsigned int UnitDiagBit = UnitDiag; const unsigned int SelfAdjointBit = SelfAdjoint; const unsigned int UpperTriangularBit = Upper; @@ -49,5 +36,7 @@ void Flagged<ExpressionType,Added,Removed>::solveTriangularInPlace(const MatrixB { m_matrix.template triangularView<Added>().solveInPlace(other.derived()); } + +} // end namespace Eigen #endif // EIGEN_TRIANGULAR_SOLVER2_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h b/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h index 010031d1971..71a8080a9fc 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_VECTORBLOCK_H #define EIGEN2_VECTORBLOCK_H +namespace Eigen { + /** \deprecated use DenseMase::head(Index) */ template<typename Derived> inline VectorBlock<Derived> @@ -102,4 +89,6 @@ MatrixBase<Derived>::end() const return VectorBlock<const Derived, Size>(derived(), size() - Size); } +} // end namespace Eigen + #endif // EIGEN2_VECTORBLOCK_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h index 57e00227d72..c4b8a308cee 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h @@ -5,31 +5,17 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_EIGEN_SOLVER_H #define EIGEN_COMPLEX_EIGEN_SOLVER_H -#include "./EigenvaluesCommon.h" #include "./ComplexSchur.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -328,5 +314,6 @@ void ComplexEigenSolver<MatrixType>::sortEigenvalues(bool computeEigenvectors) } } +} // end namespace Eigen #endif // EIGEN_COMPLEX_EIGEN_SOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h index ec93af2e58a..16a9a03d219 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h @@ -5,31 +5,17 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_SCHUR_H #define EIGEN_COMPLEX_SCHUR_H -#include "./EigenvaluesCommon.h" #include "./HessenbergDecomposition.h" +namespace Eigen { + namespace internal { template<typename MatrixType, bool IsComplex> struct complex_schur_reduce_to_hessenberg; } @@ -227,46 +213,6 @@ template<typename _MatrixType> class ComplexSchur friend struct internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>; }; -namespace internal { - -/** Computes the principal value of the square root of the complex \a z. */ -template<typename RealScalar> -std::complex<RealScalar> sqrt(const std::complex<RealScalar> &z) -{ - RealScalar t, tre, tim; - - t = abs(z); - - if (abs(real(z)) <= abs(imag(z))) - { - // No cancellation in these formulas - tre = sqrt(RealScalar(0.5)*(t + real(z))); - tim = sqrt(RealScalar(0.5)*(t - real(z))); - } - else - { - // Stable computation of the above formulas - if (z.real() > RealScalar(0)) - { - tre = t + z.real(); - tim = abs(imag(z))*sqrt(RealScalar(0.5)/tre); - tre = sqrt(RealScalar(0.5)*tre); - } - else - { - tim = t - z.real(); - tre = abs(imag(z))*sqrt(RealScalar(0.5)/tim); - tim = sqrt(RealScalar(0.5)*tim); - } - } - if(z.imag() < RealScalar(0)) - tim = -tim; - - return (std::complex<RealScalar>(tre,tim)); -} -} // end namespace internal - - /** If m_matT(i+1,i) is neglegible in floating point arithmetic * compared to m_matT(i,i) and m_matT(j,j), then set it to zero and * return true, else return false. */ @@ -302,7 +248,7 @@ typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::compu ComplexScalar b = t.coeff(0,1) * t.coeff(1,0); ComplexScalar c = t.coeff(0,0) - t.coeff(1,1); - ComplexScalar disc = internal::sqrt(c*c + RealScalar(4)*b); + ComplexScalar disc = sqrt(c*c + RealScalar(4)*b); ComplexScalar det = t.coeff(0,0) * t.coeff(1,1) - b; ComplexScalar trace = t.coeff(0,0) + t.coeff(1,1); ComplexScalar eival1 = (trace + disc) / RealScalar(2); @@ -406,7 +352,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU) // if we spent too many iterations on the current element, we give up iter++; - if(iter > m_maxIterations) break; + if(iter > m_maxIterations * m_matT.cols()) break; // find il, the top row of the active submatrix il = iu-1; @@ -436,7 +382,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU) } } - if(iter <= m_maxIterations) + if(iter <= m_maxIterations * m_matT.cols()) m_info = Success; else m_info = NoConvergence; @@ -445,4 +391,6 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU) m_matUisUptodate = computeU; } +} // end namespace Eigen + #endif // EIGEN_COMPLEX_SCHUR_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h new file mode 100644 index 00000000000..aa18e696352 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h @@ -0,0 +1,94 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Complex Schur needed to complex unsymmetrical eigenvalues/eigenvectors. + ******************************************************************************** +*/ + +#ifndef EIGEN_COMPLEX_SCHUR_MKL_H +#define EIGEN_COMPLEX_SCHUR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_SCHUR_COMPLEX(EIGTYPE, MKLTYPE, MKLPREFIX, MKLPREFIX_U, EIGCOLROW, MKLCOLROW) \ +template<> inline\ +ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \ +ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, bool computeU) \ +{ \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ + typedef std::complex<RealScalar> ComplexScalar; \ +\ + assert(matrix.cols() == matrix.rows()); \ +\ + m_matUisUptodate = false; \ + if(matrix.cols() == 1) \ + { \ + m_matT = matrix.cast<ComplexScalar>(); \ + if(computeU) m_matU = ComplexMatrixType::Identity(1,1); \ + m_info = Success; \ + m_isInitialized = true; \ + m_matUisUptodate = computeU; \ + return *this; \ + } \ + lapack_int n = matrix.cols(), sdim, info; \ + lapack_int lda = matrix.outerStride(); \ + lapack_int matrix_order = MKLCOLROW; \ + char jobvs, sort='N'; \ + LAPACK_##MKLPREFIX_U##_SELECT1 select = 0; \ + jobvs = (computeU) ? 'V' : 'N'; \ + m_matU.resize(n, n); \ + lapack_int ldvs = m_matU.outerStride(); \ + m_matT = matrix; \ + Matrix<EIGTYPE, Dynamic, Dynamic> w; \ + w.resize(n, 1);\ + info = LAPACKE_##MKLPREFIX##gees( matrix_order, jobvs, sort, select, n, (MKLTYPE*)m_matT.data(), lda, &sdim, (MKLTYPE*)w.data(), (MKLTYPE*)m_matU.data(), ldvs ); \ + if(info == 0) \ + m_info = Success; \ + else \ + m_info = NoConvergence; \ +\ + m_isInitialized = true; \ + m_matUisUptodate = computeU; \ + return *this; \ +\ +} + +EIGEN_MKL_SCHUR_COMPLEX(dcomplex, MKL_Complex16, z, Z, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_COMPLEX(scomplex, MKL_Complex8, c, C, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_COMPLEX(dcomplex, MKL_Complex16, z, Z, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SCHUR_COMPLEX(scomplex, MKL_Complex8, c, C, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_COMPLEX_SCHUR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h index f57353c065f..c16ff2b74e2 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h @@ -4,31 +4,17 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EIGENSOLVER_H #define EIGEN_EIGENSOLVER_H -#include "./EigenvaluesCommon.h" #include "./RealSchur.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -432,7 +418,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors() const Scalar eps = NumTraits<Scalar>::epsilon(); // inefficient! this is already computed in RealSchur - Scalar norm = 0.0; + Scalar norm(0); for (Index j = 0; j < size; ++j) { norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum(); @@ -452,7 +438,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors() // Scalar vector if (q == Scalar(0)) { - Scalar lastr=0, lastw=0; + Scalar lastr(0), lastw(0); Index l = n; m_matT.coeffRef(n,n) = 1.0; @@ -498,7 +484,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors() } else if (q < Scalar(0) && n > 0) // Complex vector { - Scalar lastra=0, lastsa=0, lastw=0; + Scalar lastra(0), lastsa(0), lastw(0); Index l = n-1; // Last vector component imaginary so matrix is triangular @@ -588,4 +574,6 @@ void EigenSolver<MatrixType>::doComputeEigenvectors() } } +} // end namespace Eigen + #endif // EIGEN_EIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h b/extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h deleted file mode 100644 index 749bea79500..00000000000 --- a/extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h +++ /dev/null @@ -1,31 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_EIGENVALUES_COMMON_H -#define EIGEN_EIGENVALUES_COMMON_H - - - -#endif // EIGEN_EIGENVALUES_COMMON_H - diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h index 980af14ce71..07bf1ea0956 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h @@ -4,31 +4,17 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H #define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H -#include "./EigenvaluesCommon.h" #include "./Tridiagonalization.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -236,4 +222,6 @@ compute(const MatrixType& matA, const MatrixType& matB, int options) return *this; } +} // end namespace Eigen + #endif // EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h index c17f155a59b..b8378b08a09 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HESSENBERGDECOMPOSITION_H #define EIGEN_HESSENBERGDECOMPOSITION_H +namespace Eigen { + namespace internal { template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType; @@ -379,6 +366,8 @@ template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType const HessenbergDecomposition<MatrixType>& m_hess; }; -} +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_HESSENBERGDECOMPOSITION_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h index 5591519fb75..6af481c75f6 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIXBASEEIGENVALUES_H #define EIGEN_MATRIXBASEEIGENVALUES_H +namespace Eigen { + namespace internal { template<typename Derived, bool IsComplex> @@ -167,4 +154,6 @@ SelfAdjointView<MatrixType, UpLo>::operatorNorm() const return eigenvalues().cwiseAbs().maxCoeff(); } +} // end namespace Eigen + #endif diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h index cc9af11c117..781692eccd3 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h @@ -4,31 +4,17 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REAL_SCHUR_H #define EIGEN_REAL_SCHUR_H -#include "./EigenvaluesCommon.h" #include "./HessenbergDecomposition.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -235,42 +221,44 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix, // Rows iu+1,...,end are already brought in triangular form. Index iu = m_matT.cols() - 1; Index iter = 0; // iteration count - Scalar exshift = 0.0; // sum of exceptional shifts + Scalar exshift(0); // sum of exceptional shifts Scalar norm = computeNormOfT(); - while (iu >= 0) + if(norm!=0) { - Index il = findSmallSubdiagEntry(iu, norm); - - // Check for convergence - if (il == iu) // One root found - { - m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift; - if (iu > 0) - m_matT.coeffRef(iu, iu-1) = Scalar(0); - iu--; - iter = 0; - } - else if (il == iu-1) // Two roots found - { - splitOffTwoRows(iu, computeU, exshift); - iu -= 2; - iter = 0; - } - else // No convergence yet + while (iu >= 0) { - // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG ) - Vector3s firstHouseholderVector(0,0,0), shiftInfo; - computeShift(iu, iter, exshift, shiftInfo); - iter = iter + 1; - if (iter > m_maxIterations) break; - Index im; - initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector); - performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace); + Index il = findSmallSubdiagEntry(iu, norm); + + // Check for convergence + if (il == iu) // One root found + { + m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift; + if (iu > 0) + m_matT.coeffRef(iu, iu-1) = Scalar(0); + iu--; + iter = 0; + } + else if (il == iu-1) // Two roots found + { + splitOffTwoRows(iu, computeU, exshift); + iu -= 2; + iter = 0; + } + else // No convergence yet + { + // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG ) + Vector3s firstHouseholderVector(0,0,0), shiftInfo; + computeShift(iu, iter, exshift, shiftInfo); + iter = iter + 1; + if (iter > m_maxIterations * m_matT.cols()) break; + Index im; + initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector); + performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace); + } } - } - - if(iter <= m_maxIterations) + } + if(iter <= m_maxIterations * m_matT.cols()) m_info = Success; else m_info = NoConvergence; @@ -288,7 +276,7 @@ inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT() // FIXME to be efficient the following would requires a triangular reduxion code // Scalar norm = m_matT.upper().cwiseAbs().sum() // + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum(); - Scalar norm = 0.0; + Scalar norm(0); for (Index j = 0; j < size; ++j) norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum(); return norm; @@ -471,4 +459,6 @@ inline void RealSchur<MatrixType>::performFrancisQRStep(Index il, Index im, Inde } } +} // end namespace Eigen + #endif // EIGEN_REAL_SCHUR_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h new file mode 100644 index 00000000000..960ec3c764a --- /dev/null +++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h @@ -0,0 +1,83 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Real Schur needed to real unsymmetrical eigenvalues/eigenvectors. + ******************************************************************************** +*/ + +#ifndef EIGEN_REAL_SCHUR_MKL_H +#define EIGEN_REAL_SCHUR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_SCHUR_REAL(EIGTYPE, MKLTYPE, MKLPREFIX, MKLPREFIX_U, EIGCOLROW, MKLCOLROW) \ +template<> inline \ +RealSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \ +RealSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, bool computeU) \ +{ \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ +\ + assert(matrix.cols() == matrix.rows()); \ +\ + lapack_int n = matrix.cols(), sdim, info; \ + lapack_int lda = matrix.outerStride(); \ + lapack_int matrix_order = MKLCOLROW; \ + char jobvs, sort='N'; \ + LAPACK_##MKLPREFIX_U##_SELECT2 select = 0; \ + jobvs = (computeU) ? 'V' : 'N'; \ + m_matU.resize(n, n); \ + lapack_int ldvs = m_matU.outerStride(); \ + m_matT = matrix; \ + Matrix<EIGTYPE, Dynamic, Dynamic> wr, wi; \ + wr.resize(n, 1); wi.resize(n, 1); \ + info = LAPACKE_##MKLPREFIX##gees( matrix_order, jobvs, sort, select, n, (MKLTYPE*)m_matT.data(), lda, &sdim, (MKLTYPE*)wr.data(), (MKLTYPE*)wi.data(), (MKLTYPE*)m_matU.data(), ldvs ); \ + if(info == 0) \ + m_info = Success; \ + else \ + m_info = NoConvergence; \ +\ + m_isInitialized = true; \ + m_matUisUptodate = computeU; \ + return *this; \ +\ +} + +EIGEN_MKL_SCHUR_REAL(double, double, d, D, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_REAL(float, float, s, S, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_REAL(double, double, d, D, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SCHUR_REAL(float, float, s, S, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_REAL_SCHUR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index ad107c63282..acc5576feb1 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -4,34 +4,24 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINTEIGENSOLVER_H #define EIGEN_SELFADJOINTEIGENSOLVER_H -#include "./EigenvaluesCommon.h" #include "./Tridiagonalization.h" +namespace Eigen { + template<typename _MatrixType> class GeneralizedSelfAdjointEigenSolver; +namespace internal { +template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_eigenvalues; +} + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -86,7 +76,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver Options = MatrixType::Options, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime }; - + /** \brief Scalar type for matrices of type \p _MatrixType. */ typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; @@ -98,6 +88,8 @@ template<typename _MatrixType> class SelfAdjointEigenSolver * complex. */ typedef typename NumTraits<Scalar>::Real RealScalar; + + friend struct internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>; /** \brief Type for vector of eigenvalues as returned by eigenvalues(). * @@ -198,6 +190,22 @@ template<typename _MatrixType> class SelfAdjointEigenSolver * \sa SelfAdjointEigenSolver(const MatrixType&, int) */ SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors); + + /** \brief Computes eigendecomposition of given matrix using a direct algorithm + * + * This is a variant of compute(const MatrixType&, int options) which + * directly solves the underlying polynomial equation. + * + * Currently only 3x3 matrices for which the sizes are known at compile time are supported (e.g., Matrix3d). + * + * This method is usually significantly faster than the QR algorithm + * but it might also be less accurate. It is also worth noting that + * for 3x3 matrices it involves trigonometric operations which are + * not necessarily available for all scalar types. + * + * \sa compute(const MatrixType&, int options) + */ + SelfAdjointEigenSolver& computeDirect(const MatrixType& matrix, int options = ComputeEigenvectors); /** \brief Returns the eigenvectors of given matrix. * @@ -401,7 +409,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType> // map the matrix coefficients to [-1:1] to avoid over- and underflow. RealScalar scale = matrix.cwiseAbs().maxCoeff(); - if(scale==Scalar(0)) scale = 1; + if(scale==RealScalar(0)) scale = RealScalar(1); mat = matrix / scale; m_subdiag.resize(n-1); internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors); @@ -466,19 +474,277 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType> return *this; } + +namespace internal { + +template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_eigenvalues +{ + static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options) + { eig.compute(A,options); } +}; + +template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3,false> +{ + typedef typename SolverType::MatrixType MatrixType; + typedef typename SolverType::RealVectorType VectorType; + typedef typename SolverType::Scalar Scalar; + + static inline void computeRoots(const MatrixType& m, VectorType& roots) + { + using std::sqrt; + using std::atan2; + using std::cos; + using std::sin; + const Scalar s_inv3 = Scalar(1.0)/Scalar(3.0); + const Scalar s_sqrt3 = sqrt(Scalar(3.0)); + + // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The + // eigenvalues are the roots to this equation, all guaranteed to be + // real-valued, because the matrix is symmetric. + Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(1,0)*m(2,0)*m(2,1) - m(0,0)*m(2,1)*m(2,1) - m(1,1)*m(2,0)*m(2,0) - m(2,2)*m(1,0)*m(1,0); + Scalar c1 = m(0,0)*m(1,1) - m(1,0)*m(1,0) + m(0,0)*m(2,2) - m(2,0)*m(2,0) + m(1,1)*m(2,2) - m(2,1)*m(2,1); + Scalar c2 = m(0,0) + m(1,1) + m(2,2); + + // Construct the parameters used in classifying the roots of the equation + // and in solving the equation for the roots in closed form. + Scalar c2_over_3 = c2*s_inv3; + Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3; + if (a_over_3 > Scalar(0)) + a_over_3 = Scalar(0); + + Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1)); + + Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3; + if (q > Scalar(0)) + q = Scalar(0); + + // Compute the eigenvalues by solving for the roots of the polynomial. + Scalar rho = sqrt(-a_over_3); + Scalar theta = atan2(sqrt(-q),half_b)*s_inv3; + Scalar cos_theta = cos(theta); + Scalar sin_theta = sin(theta); + roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta; + roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); + roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); + + // Sort in increasing order. + if (roots(0) >= roots(1)) + std::swap(roots(0),roots(1)); + if (roots(1) >= roots(2)) + { + std::swap(roots(1),roots(2)); + if (roots(0) >= roots(1)) + std::swap(roots(0),roots(1)); + } + } + + static inline void run(SolverType& solver, const MatrixType& mat, int options) + { + using std::sqrt; + eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows()); + eigen_assert((options&~(EigVecMask|GenEigMask))==0 + && (options&EigVecMask)!=EigVecMask + && "invalid option parameter"); + bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; + + MatrixType& eivecs = solver.m_eivec; + VectorType& eivals = solver.m_eivalues; + + // map the matrix coefficients to [-1:1] to avoid over- and underflow. + Scalar scale = mat.cwiseAbs().maxCoeff(); + MatrixType scaledMat = mat / scale; + + // compute the eigenvalues + computeRoots(scaledMat,eivals); + + // compute the eigen vectors + if(computeEigenvectors) + { + Scalar safeNorm2 = Eigen::NumTraits<Scalar>::epsilon(); + safeNorm2 *= safeNorm2; + if((eivals(2)-eivals(0))<=Eigen::NumTraits<Scalar>::epsilon()) + { + eivecs.setIdentity(); + } + else + { + scaledMat = scaledMat.template selfadjointView<Lower>(); + MatrixType tmp; + tmp = scaledMat; + + Scalar d0 = eivals(2) - eivals(1); + Scalar d1 = eivals(1) - eivals(0); + int k = d0 > d1 ? 2 : 0; + d0 = d0 > d1 ? d1 : d0; + + tmp.diagonal().array () -= eivals(k); + VectorType cross; + Scalar n; + n = (cross = tmp.row(0).cross(tmp.row(1))).squaredNorm(); + + if(n>safeNorm2) + eivecs.col(k) = cross / sqrt(n); + else + { + n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm(); + + if(n>safeNorm2) + eivecs.col(k) = cross / sqrt(n); + else + { + n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm(); + + if(n>safeNorm2) + eivecs.col(k) = cross / sqrt(n); + else + { + // the input matrix and/or the eigenvaues probably contains some inf/NaN, + // => exit + // scale back to the original size. + eivals *= scale; + + solver.m_info = NumericalIssue; + solver.m_isInitialized = true; + solver.m_eigenvectorsOk = computeEigenvectors; + return; + } + } + } + + tmp = scaledMat; + tmp.diagonal().array() -= eivals(1); + + if(d0<=Eigen::NumTraits<Scalar>::epsilon()) + eivecs.col(1) = eivecs.col(k).unitOrthogonal(); + else + { + n = (cross = eivecs.col(k).cross(tmp.row(0).normalized())).squaredNorm(); + if(n>safeNorm2) + eivecs.col(1) = cross / sqrt(n); + else + { + n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm(); + if(n>safeNorm2) + eivecs.col(1) = cross / sqrt(n); + else + { + n = (cross = eivecs.col(k).cross(tmp.row(2))).squaredNorm(); + if(n>safeNorm2) + eivecs.col(1) = cross / sqrt(n); + else + { + // we should never reach this point, + // if so the last two eigenvalues are likely to ve very closed to each other + eivecs.col(1) = eivecs.col(k).unitOrthogonal(); + } + } + } + + // make sure that eivecs[1] is orthogonal to eivecs[2] + Scalar d = eivecs.col(1).dot(eivecs.col(k)); + eivecs.col(1) = (eivecs.col(1) - d * eivecs.col(k)).normalized(); + } + + eivecs.col(k==2 ? 0 : 2) = eivecs.col(k).cross(eivecs.col(1)).normalized(); + } + } + // Rescale back to the original size. + eivals *= scale; + + solver.m_info = Success; + solver.m_isInitialized = true; + solver.m_eigenvectorsOk = computeEigenvectors; + } +}; + +// 2x2 direct eigenvalues decomposition, code from Hauke Heibel +template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2,false> +{ + typedef typename SolverType::MatrixType MatrixType; + typedef typename SolverType::RealVectorType VectorType; + typedef typename SolverType::Scalar Scalar; + + static inline void computeRoots(const MatrixType& m, VectorType& roots) + { + using std::sqrt; + const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0)); + const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1)); + roots(0) = t1 - t0; + roots(1) = t1 + t0; + } + + static inline void run(SolverType& solver, const MatrixType& mat, int options) + { + eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows()); + eigen_assert((options&~(EigVecMask|GenEigMask))==0 + && (options&EigVecMask)!=EigVecMask + && "invalid option parameter"); + bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; + + MatrixType& eivecs = solver.m_eivec; + VectorType& eivals = solver.m_eivalues; + + // map the matrix coefficients to [-1:1] to avoid over- and underflow. + Scalar scale = mat.cwiseAbs().maxCoeff(); + scale = (std::max)(scale,Scalar(1)); + MatrixType scaledMat = mat / scale; + + // Compute the eigenvalues + computeRoots(scaledMat,eivals); + + // compute the eigen vectors + if(computeEigenvectors) + { + scaledMat.diagonal().array () -= eivals(1); + Scalar a2 = abs2(scaledMat(0,0)); + Scalar c2 = abs2(scaledMat(1,1)); + Scalar b2 = abs2(scaledMat(1,0)); + if(a2>c2) + { + eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0); + eivecs.col(1) /= sqrt(a2+b2); + } + else + { + eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0); + eivecs.col(1) /= sqrt(c2+b2); + } + + eivecs.col(0) << eivecs.col(1).unitOrthogonal(); + } + + // Rescale back to the original size. + eivals *= scale; + + solver.m_info = Success; + solver.m_isInitialized = true; + solver.m_eigenvectorsOk = computeEigenvectors; + } +}; + +} + +template<typename MatrixType> +SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType> +::computeDirect(const MatrixType& matrix, int options) +{ + internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>::run(*this,matrix,options); + return *this; +} + namespace internal { template<int StorageOrder,typename RealScalar, typename Scalar, typename Index> static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n) { - // NOTE this version avoids over & underflow, however since the matrix is prescaled, overflow cannot occur, - // and underflows should be meaningless anyway. So I don't any reason to enable this version, but I keep - // it here for reference: -// RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5); -// RealScalar e = subdiag[end-1]; -// RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e)); RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5); - RealScalar e2 = abs2(subdiag[end-1]); - RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2)); + RealScalar e = subdiag[end-1]; + // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still + // underflow thus leading to inf/NaN values when using the following commented code: +// RealScalar e2 = abs2(subdiag[end-1]); +// RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2)); + // This explain the following, somewhat more complicated, version: + RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e)); + RealScalar x = diag[start] - mu; RealScalar z = subdiag[start]; for (Index k = start; k < end; ++k) @@ -515,6 +781,9 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta } } } + } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_SELFADJOINTEIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h new file mode 100644 index 00000000000..9380956b5f9 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Self-adjoint eigenvalues/eigenvectors. + ******************************************************************************** +*/ + +#ifndef EIGEN_SAEIGENSOLVER_MKL_H +#define EIGEN_SAEIGENSOLVER_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_EIG_SELFADJ(EIGTYPE, MKLTYPE, MKLRTYPE, MKLNAME, EIGCOLROW, MKLCOLROW ) \ +template<> inline\ +SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \ +SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, int options) \ +{ \ + eigen_assert(matrix.cols() == matrix.rows()); \ + eigen_assert((options&~(EigVecMask|GenEigMask))==0 \ + && (options&EigVecMask)!=EigVecMask \ + && "invalid option parameter"); \ + bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; \ + lapack_int n = matrix.cols(), lda, matrix_order, info; \ + m_eivalues.resize(n,1); \ + m_subdiag.resize(n-1); \ + m_eivec = matrix; \ +\ + if(n==1) \ + { \ + m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0)); \ + if(computeEigenvectors) m_eivec.setOnes(n,n); \ + m_info = Success; \ + m_isInitialized = true; \ + m_eigenvectorsOk = computeEigenvectors; \ + return *this; \ + } \ +\ + lda = matrix.outerStride(); \ + matrix_order=MKLCOLROW; \ + char jobz, uplo='L'/*, range='A'*/; \ + jobz = computeEigenvectors ? 'V' : 'N'; \ +\ + info = LAPACKE_##MKLNAME( matrix_order, jobz, uplo, n, (MKLTYPE*)m_eivec.data(), lda, (MKLRTYPE*)m_eivalues.data() ); \ + m_info = (info==0) ? Success : NoConvergence; \ + m_isInitialized = true; \ + m_eigenvectorsOk = computeEigenvectors; \ + return *this; \ +} + + +EIGEN_MKL_EIG_SELFADJ(double, double, double, dsyev, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_EIG_SELFADJ(float, float, float, ssyev, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_EIG_SELFADJ(dcomplex, MKL_Complex16, double, zheev, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_EIG_SELFADJ(scomplex, MKL_Complex8, float, cheev, ColMajor, LAPACK_COL_MAJOR) + +EIGEN_MKL_EIG_SELFADJ(double, double, double, dsyev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_EIG_SELFADJ(float, float, float, ssyev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_EIG_SELFADJ(dcomplex, MKL_Complex16, double, zheev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_EIG_SELFADJ(scomplex, MKL_Complex8, float, cheev, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_SAEIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h b/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h index ae4cdce7aeb..c34b7b3b801 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIDIAGONALIZATION_H #define EIGEN_TRIDIAGONALIZATION_H +namespace Eigen { + namespace internal { template<typename MatrixType> struct TridiagonalizationMatrixTReturnType; @@ -97,13 +84,13 @@ template<typename _MatrixType> class Tridiagonalization typedef internal::TridiagonalizationMatrixTReturnType<MatrixTypeRealView> MatrixTReturnType; typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, - const typename Diagonal<const MatrixType>::RealReturnType, + typename internal::add_const_on_value_type<typename Diagonal<const MatrixType>::RealReturnType>::type, const Diagonal<const MatrixType> >::type DiagonalReturnType; typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, - const typename Diagonal< - Block<const MatrixType,SizeMinusOne,SizeMinusOne> >::RealReturnType, + typename internal::add_const_on_value_type<typename Diagonal< + Block<const MatrixType,SizeMinusOne,SizeMinusOne> >::RealReturnType>::type, const Diagonal< Block<const MatrixType,SizeMinusOne,SizeMinusOne> > >::type SubDiagonalReturnType; @@ -560,9 +547,11 @@ template<typename MatrixType> struct TridiagonalizationMatrixTReturnType Index cols() const { return m_matrix.cols(); } protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRIDIAGONALIZATION_H diff --git a/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h b/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h index b51deb3f3c3..5830fcd35fc 100644 --- a/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h +++ b/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ALIGNEDBOX_H #define EIGEN_ALIGNEDBOX_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * @@ -190,7 +177,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) template<typename Derived> inline bool contains(const MatrixBase<Derived>& a_p) const { - const typename internal::nested<Derived,2>::type p(a_p.derived()); + typename internal::nested<Derived,2>::type p(a_p.derived()); return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all(); } @@ -202,7 +189,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) template<typename Derived> inline AlignedBox& extend(const MatrixBase<Derived>& a_p) { - const typename internal::nested<Derived,2>::type p(a_p.derived()); + typename internal::nested<Derived,2>::type p(a_p.derived()); m_min = m_min.cwiseMin(p); m_max = m_max.cwiseMax(p); return *this; @@ -310,7 +297,7 @@ template<typename Derived> inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const MatrixBase<Derived>& a_p) const { const typename internal::nested<Derived,2*AmbientDim>::type p(a_p.derived()); - Scalar dist2 = 0.; + Scalar dist2(0); Scalar aux; for (Index k=0; k<dim(); ++k) { @@ -331,7 +318,7 @@ inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const Matri template<typename Scalar,int AmbientDim> inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const AlignedBox& b) const { - Scalar dist2 = 0.; + Scalar dist2(0); Scalar aux; for (Index k=0; k<dim(); ++k) { @@ -349,4 +336,40 @@ inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const Align return dist2; } +/** \defgroup alignedboxtypedefs Global aligned box typedefs + * + * \ingroup Geometry_Module + * + * Eigen defines several typedef shortcuts for most common aligned box types. + * + * The general patterns are the following: + * + * \c AlignedBoxSizeType where \c Size can be \c 1, \c 2,\c 3,\c 4 for fixed size boxes or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double. + * + * For example, \c AlignedBox3d is a fixed-size 3x3 aligned box type of doubles, and \c AlignedBoxXf is a dynamic-size aligned box of floats. + * + * \sa class AlignedBox + */ + +#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup alignedboxtypedefs */ \ +typedef AlignedBox<Type, Size> AlignedBox##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 1, 1) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) + +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) + +#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_TYPEDEFS + +} // end namespace Eigen + #endif // EIGEN_ALIGNEDBOX_H diff --git a/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h b/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h index 0ec4624cf98..67197ac78c3 100644 --- a/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h +++ b/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ANGLEAXIS_H #define EIGEN_ANGLEAXIS_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class AngleAxis @@ -144,7 +131,7 @@ public: m_angle = Scalar(other.angle()); } - inline static const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); } + static inline const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. @@ -238,4 +225,6 @@ AngleAxis<Scalar>::toRotationMatrix(void) const return res; } +} // end namespace Eigen + #endif // EIGEN_ANGLEAXIS_H diff --git a/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h b/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h index d246a6ebf4a..e424d240604 100644 --- a/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h +++ b/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EULERANGLES_H #define EIGEN_EULERANGLES_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * @@ -92,5 +79,6 @@ MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const return res; } +} // end namespace Eigen #endif // EIGEN_EULERANGLES_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h b/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h index 2bc4f7e87e3..df03feb55c6 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h +++ b/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HOMOGENEOUS_H #define EIGEN_HOMOGENEOUS_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Homogeneous @@ -121,7 +108,7 @@ template<typename MatrixType,int _Direction> class Homogeneous } protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; /** \geometry_module @@ -216,8 +203,8 @@ template<typename Scalar, int Dim, int Mode,int Options> struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> > { typedef Transform<Scalar, Dim, Mode, Options> TransformType; - typedef typename TransformType::ConstAffinePart type; - static const type run (const TransformType& x) { return x.affine(); } + typedef typename internal::add_const<typename TransformType::ConstAffinePart>::type type; + static type run (const TransformType& x) { return x.affine(); } }; template<typename Scalar, int Dim, int Options> @@ -270,8 +257,8 @@ struct homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> .template replicate<MatrixType::ColsAtCompileTime>(m_rhs.cols()); } - const typename LhsMatrixTypeCleaned::Nested m_lhs; - const typename MatrixType::Nested m_rhs; + typename LhsMatrixTypeCleaned::Nested m_lhs; + typename MatrixType::Nested m_rhs; }; template<typename MatrixType,typename Rhs> @@ -309,10 +296,12 @@ struct homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs> .template replicate<MatrixType::RowsAtCompileTime>(m_lhs.rows()); } - const typename MatrixType::Nested m_lhs; - const typename Rhs::Nested m_rhs; + typename MatrixType::Nested m_lhs; + typename Rhs::Nested m_rhs; }; } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_HOMOGENEOUS_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h b/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h index d85d3e553f8..1b7c7c78c80 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h +++ b/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HYPERPLANE_H #define EIGEN_HYPERPLANE_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Hyperplane @@ -277,4 +264,6 @@ protected: Coefficients m_coeffs; }; +} // end namespace Eigen + #endif // EIGEN_HYPERPLANE_H diff --git a/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h b/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h index 52b46988196..11ad5829cda 100644 --- a/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h +++ b/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ORTHOMETHODS_H #define EIGEN_ORTHOMETHODS_H +namespace Eigen { + /** \geometry_module * * \returns the cross product of \c *this and \a other @@ -43,8 +30,8 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const // Note that there is no need for an expression here since the compiler // optimize such a small temporary very well (even within a complex expression) - const typename internal::nested<Derived,2>::type lhs(derived()); - const typename internal::nested<OtherDerived,2>::type rhs(other.derived()); + typename internal::nested<Derived,2>::type lhs(derived()); + typename internal::nested<OtherDerived,2>::type rhs(other.derived()); return typename cross_product_return_type<OtherDerived>::type( internal::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)), internal::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)), @@ -56,9 +43,9 @@ namespace internal { template< int Arch,typename VectorLhs,typename VectorRhs, typename Scalar = typename VectorLhs::Scalar, - bool Vectorizable = (VectorLhs::Flags&VectorRhs::Flags)&PacketAccessBit> + bool Vectorizable = bool((VectorLhs::Flags&VectorRhs::Flags)&PacketAccessBit)> struct cross3_impl { - inline static typename internal::plain_matrix_type<VectorLhs>::type + static inline typename internal::plain_matrix_type<VectorLhs>::type run(const VectorLhs& lhs, const VectorRhs& rhs) { return typename internal::plain_matrix_type<VectorLhs>::type( @@ -145,7 +132,7 @@ struct unitOrthogonal_selector typedef typename NumTraits<Scalar>::Real RealScalar; typedef typename Derived::Index Index; typedef Matrix<Scalar,2,1> Vector2; - inline static VectorType run(const Derived& src) + static inline VectorType run(const Derived& src) { VectorType perp = VectorType::Zero(src.size()); Index maxi = 0; @@ -167,7 +154,7 @@ struct unitOrthogonal_selector<Derived,3> typedef typename plain_matrix_type<Derived>::type VectorType; typedef typename traits<Derived>::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; - inline static VectorType run(const Derived& src) + static inline VectorType run(const Derived& src) { VectorType perp; /* Let us compute the crossed product of *this with a vector @@ -205,7 +192,7 @@ template<typename Derived> struct unitOrthogonal_selector<Derived,2> { typedef typename plain_matrix_type<Derived>::type VectorType; - inline static VectorType run(const Derived& src) + static inline VectorType run(const Derived& src) { return VectorType(-conj(src.y()), conj(src.x())).normalized(); } }; @@ -226,4 +213,6 @@ MatrixBase<Derived>::unitOrthogonal() const return internal::unitOrthogonal_selector<Derived>::run(derived()); } +} // end namespace Eigen + #endif // EIGEN_ORTHOMETHODS_H diff --git a/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h b/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h index b90f9c088a2..719a904413d 100644 --- a/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h +++ b/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARAMETRIZEDLINE_H #define EIGEN_PARAMETRIZEDLINE_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class ParametrizedLine @@ -106,8 +93,16 @@ public: VectorType projection(const VectorType& p) const { return origin() + direction().dot(p-origin()) * direction(); } + VectorType pointAt( Scalar t ) const; + + template <int OtherOptions> + Scalar intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; + template <int OtherOptions> Scalar intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; + + template <int OtherOptions> + VectorType intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; /** \returns \c *this with scalar type casted to \a NewScalarType * @@ -155,14 +150,46 @@ inline ParametrizedLine<_Scalar, _AmbientDim,_Options>::ParametrizedLine(const H origin() = -hyperplane.normal()*hyperplane.offset(); } -/** \returns the parameter value of the intersection between \c *this and the given hyperplane +/** \returns the point at \a t along this line + */ +template <typename _Scalar, int _AmbientDim, int _Options> +inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType +ParametrizedLine<_Scalar, _AmbientDim,_Options>::pointAt( _Scalar t ) const +{ + return origin() + (direction()*t); +} + +/** \returns the parameter value of the intersection between \c *this and the given \a hyperplane */ template <typename _Scalar, int _AmbientDim, int _Options> template <int OtherOptions> -inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const +inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const { return -(hyperplane.offset()+hyperplane.normal().dot(origin())) / hyperplane.normal().dot(direction()); } + +/** \deprecated use intersectionParameter() + * \returns the parameter value of the intersection between \c *this and the given \a hyperplane + */ +template <typename _Scalar, int _AmbientDim, int _Options> +template <int OtherOptions> +inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const +{ + return intersectionParameter(hyperplane); +} + +/** \returns the point of the intersection between \c *this and the given hyperplane + */ +template <typename _Scalar, int _AmbientDim, int _Options> +template <int OtherOptions> +inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType +ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const +{ + return pointAt(intersectionParameter(hyperplane)); +} + +} // end namespace Eigen + #endif // EIGEN_PARAMETRIZEDLINE_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Quaternion.h b/extern/Eigen3/Eigen/src/Geometry/Quaternion.h index 9180db67d84..8792e2da2ae 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Quaternion.h +++ b/extern/Eigen3/Eigen/src/Geometry/Quaternion.h @@ -4,27 +4,14 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Mathieu Gautier <mathieu.gautier@cea.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_QUATERNION_H #define EIGEN_QUATERNION_H +namespace Eigen { + /*************************************************************************** * Definition of QuaternionBase<Derived> @@ -38,6 +25,12 @@ template<typename Other, struct quaternionbase_assign_impl; } +/** \geometry_module \ingroup Geometry_Module + * \class QuaternionBase + * \brief Base class for quaternion expressions + * \tparam Derived derived type (CRTP) + * \sa class Quaternion + */ template<class Derived> class QuaternionBase : public RotationBase<Derived, 3> { @@ -109,7 +102,7 @@ public: /** \returns a quaternion representing an identity rotation * \sa MatrixBase::Identity() */ - inline static Quaternion<Scalar> Identity() { return Quaternion<Scalar>(1, 0, 0, 0); } + static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(1, 0, 0, 0); } /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity() */ @@ -278,6 +271,9 @@ public: explicit inline Quaternion(const Quaternion<OtherScalar, OtherOptions>& other) { m_coeffs = other.coeffs().template cast<Scalar>(); } + template<typename Derived1, typename Derived2> + static Quaternion FromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b); + inline Coefficients& coeffs() { return m_coeffs;} inline const Coefficients& coeffs() const { return m_coeffs;} @@ -287,7 +283,7 @@ protected: Coefficients m_coeffs; #ifndef EIGEN_PARSED_BY_DOXYGEN - EIGEN_STRONG_INLINE static void _check_template_params() + static EIGEN_STRONG_INLINE void _check_template_params() { EIGEN_STATIC_ASSERT( (_Options & DontAlign) == _Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) @@ -434,7 +430,7 @@ typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd; namespace internal { template<int Arch, class Derived1, class Derived2, typename Scalar, int _Options> struct quat_product { - EIGEN_STRONG_INLINE static Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){ + static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){ return Quaternion<Scalar> ( a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(), @@ -544,9 +540,9 @@ QuaternionBase<Derived>::toRotationMatrix(void) const // it has to be inlined, and so the return by value is not an issue Matrix3 res; - const Scalar tx = 2*this->x(); - const Scalar ty = 2*this->y(); - const Scalar tz = 2*this->z(); + const Scalar tx = Scalar(2)*this->x(); + const Scalar ty = Scalar(2)*this->y(); + const Scalar tz = Scalar(2)*this->z(); const Scalar twx = tx*this->w(); const Scalar twy = ty*this->w(); const Scalar twz = tz*this->w(); @@ -557,15 +553,15 @@ QuaternionBase<Derived>::toRotationMatrix(void) const const Scalar tyz = tz*this->y(); const Scalar tzz = tz*this->z(); - res.coeffRef(0,0) = 1-(tyy+tzz); + res.coeffRef(0,0) = Scalar(1)-(tyy+tzz); res.coeffRef(0,1) = txy-twz; res.coeffRef(0,2) = txz+twy; res.coeffRef(1,0) = txy+twz; - res.coeffRef(1,1) = 1-(txx+tzz); + res.coeffRef(1,1) = Scalar(1)-(txx+tzz); res.coeffRef(1,2) = tyz-twx; res.coeffRef(2,0) = txz-twy; res.coeffRef(2,1) = tyz+twx; - res.coeffRef(2,2) = 1-(txx+tyy); + res.coeffRef(2,2) = Scalar(1)-(txx+tyy); return res; } @@ -618,6 +614,27 @@ inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Deri return derived(); } + +/** Returns a quaternion representing a rotation between + * the two arbitrary vectors \a a and \a b. In other words, the built + * rotation represent a rotation sending the line of direction \a a + * to the line of direction \a b, both lines passing through the origin. + * + * \returns resulting quaternion + * + * Note that the two input vectors do \b not have to be normalized, and + * do not need to have the same norm. + */ +template<typename Scalar, int Options> +template<typename Derived1, typename Derived2> +Quaternion<Scalar,Options> Quaternion<Scalar,Options>::FromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b) +{ + Quaternion quat; + quat.setFromTwoVectors(a, b); + return quat; +} + + /** \returns the multiplicative inverse of \c *this * Note that in most cases, i.e., if you simply want the opposite rotation, * and/or the quaternion is normalized, then it is enough to use the conjugate. @@ -709,7 +726,7 @@ struct quaternionbase_assign_impl<Other,3,3> { typedef typename Other::Scalar Scalar; typedef DenseIndex Index; - template<class Derived> inline static void run(QuaternionBase<Derived>& q, const Other& mat) + template<class Derived> static inline void run(QuaternionBase<Derived>& q, const Other& mat) { // This algorithm comes from "Quaternion Calculus and Fast Animation", // Ken Shoemake, 1987 SIGGRAPH course notes @@ -748,7 +765,7 @@ template<typename Other> struct quaternionbase_assign_impl<Other,4,1> { typedef typename Other::Scalar Scalar; - template<class Derived> inline static void run(QuaternionBase<Derived>& q, const Other& vec) + template<class Derived> static inline void run(QuaternionBase<Derived>& q, const Other& vec) { q.coeffs() = vec; } @@ -756,4 +773,6 @@ struct quaternionbase_assign_impl<Other,4,1> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_QUATERNION_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h b/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h index cf36da1c50c..868e2ef312f 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h +++ b/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ROTATION2D_H #define EIGEN_ROTATION2D_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Rotation2D @@ -121,7 +108,7 @@ public: m_angle = Scalar(other.angle()); } - inline static Rotation2D Identity() { return Rotation2D(0); } + static inline Rotation2D Identity() { return Rotation2D(0); } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. @@ -162,4 +149,6 @@ Rotation2D<Scalar>::toRotationMatrix(void) const return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); } +} // end namespace Eigen + #endif // EIGEN_ROTATION2D_H diff --git a/extern/Eigen3/Eigen/src/Geometry/RotationBase.h b/extern/Eigen3/Eigen/src/Geometry/RotationBase.h index 1abf06bb640..b88661de6b1 100644 --- a/extern/Eigen3/Eigen/src/Geometry/RotationBase.h +++ b/extern/Eigen3/Eigen/src/Geometry/RotationBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ROTATIONBASE_H #define EIGEN_ROTATIONBASE_H +namespace Eigen { + // forward declaration namespace internal { template<typename RotationDerived, typename MatrixType, bool IsVector=MatrixType::IsVectorAtCompileTime> @@ -115,7 +102,7 @@ struct rotation_base_generic_product_selector<RotationDerived,MatrixType,false> { enum { Dim = RotationDerived::Dim }; typedef Matrix<typename RotationDerived::Scalar,Dim,Dim> ReturnType; - inline static ReturnType run(const RotationDerived& r, const MatrixType& m) + static inline ReturnType run(const RotationDerived& r, const MatrixType& m) { return r.toRotationMatrix() * m; } }; @@ -123,7 +110,7 @@ template<typename RotationDerived, typename Scalar, int Dim, int MaxDim> struct rotation_base_generic_product_selector< RotationDerived, DiagonalMatrix<Scalar,Dim,MaxDim>, false > { typedef Transform<Scalar,Dim,Affine> ReturnType; - inline static ReturnType run(const RotationDerived& r, const DiagonalMatrix<Scalar,Dim,MaxDim>& m) + static inline ReturnType run(const RotationDerived& r, const DiagonalMatrix<Scalar,Dim,MaxDim>& m) { ReturnType res(r); res.linear() *= m; @@ -136,7 +123,7 @@ struct rotation_base_generic_product_selector<RotationDerived,OtherVectorType,tr { enum { Dim = RotationDerived::Dim }; typedef Matrix<typename RotationDerived::Scalar,Dim,1> ReturnType; - EIGEN_STRONG_INLINE static ReturnType run(const RotationDerived& r, const OtherVectorType& v) + static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v) { return r._transformVector(v); } @@ -192,20 +179,20 @@ namespace internal { * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis */ template<typename Scalar, int Dim> -inline static Matrix<Scalar,2,2> toRotationMatrix(const Scalar& s) +static inline Matrix<Scalar,2,2> toRotationMatrix(const Scalar& s) { EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) return Rotation2D<Scalar>(s).toRotationMatrix(); } template<typename Scalar, int Dim, typename OtherDerived> -inline static Matrix<Scalar,Dim,Dim> toRotationMatrix(const RotationBase<OtherDerived,Dim>& r) +static inline Matrix<Scalar,Dim,Dim> toRotationMatrix(const RotationBase<OtherDerived,Dim>& r) { return r.toRotationMatrix(); } template<typename Scalar, int Dim, typename OtherDerived> -inline static const MatrixBase<OtherDerived>& toRotationMatrix(const MatrixBase<OtherDerived>& mat) +static inline const MatrixBase<OtherDerived>& toRotationMatrix(const MatrixBase<OtherDerived>& mat) { EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, YOU_MADE_A_PROGRAMMING_MISTAKE) @@ -214,4 +201,6 @@ inline static const MatrixBase<OtherDerived>& toRotationMatrix(const MatrixBase< } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_ROTATIONBASE_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Scaling.h b/extern/Eigen3/Eigen/src/Geometry/Scaling.h index c911d13e1d3..8edcac31c74 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Scaling.h +++ b/extern/Eigen3/Eigen/src/Geometry/Scaling.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SCALING_H #define EIGEN_SCALING_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Scaling @@ -73,7 +60,12 @@ public: /** Concatenates a uniform scaling and an affine transformation */ template<int Dim, int Mode, int Options> - inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim, Mode, Options>& t) const; + inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Mode)> operator* (const Transform<Scalar,Dim, Mode, Options>& t) const + { + Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Mode)> res = t; + res.prescale(factor()); + return res; +} /** Concatenates a uniform scaling and a linear transformation matrix */ // TODO returns an expression @@ -169,14 +161,6 @@ UniformScaling<Scalar>::operator* (const Translation<Scalar,Dim>& t) const return res; } -template<typename Scalar> -template<int Dim,int Mode,int Options> -inline Transform<Scalar,Dim,Mode> -UniformScaling<Scalar>::operator* (const Transform<Scalar,Dim, Mode, Options>& t) const -{ - Transform<Scalar,Dim,Mode> res = t; - res.prescale(factor()); - return res; -} +} // end namespace Eigen #endif // EIGEN_SCALING_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Transform.h b/extern/Eigen3/Eigen/src/Geometry/Transform.h index a694673ebed..4c1ef8eaade 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Transform.h +++ b/extern/Eigen3/Eigen/src/Geometry/Transform.h @@ -5,28 +5,15 @@ // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSFORM_H #define EIGEN_TRANSFORM_H +namespace Eigen { + namespace internal { template<typename Transform> @@ -37,7 +24,7 @@ struct transform_traits Dim = Transform::Dim, HDim = Transform::HDim, Mode = Transform::Mode, - IsProjective = (Mode==Projective) + IsProjective = (int(Mode)==int(Projective)) }; }; @@ -207,9 +194,9 @@ public: /** type of the matrix used to represent the linear part of the transformation */ typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType; /** type of read/write reference to the linear part of the transformation */ - typedef Block<MatrixType,Dim,Dim> LinearPart; + typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact)> LinearPart; /** type of read reference to the linear part of the transformation */ - typedef const Block<ConstMatrixType,Dim,Dim> ConstLinearPart; + typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact)> ConstLinearPart; /** type of read/write reference to the affine part of the transformation */ typedef typename internal::conditional<int(Mode)==int(AffineCompact), MatrixType&, @@ -221,9 +208,9 @@ public: /** type of a vector */ typedef Matrix<Scalar,Dim,1> VectorType; /** type of a read/write reference to the translation part of the rotation */ - typedef Block<MatrixType,Dim,1> TranslationPart; + typedef Block<MatrixType,Dim,1,int(Mode)==(AffineCompact)> TranslationPart; /** type of a read reference to the translation part of the rotation */ - typedef const Block<ConstMatrixType,Dim,1> ConstTranslationPart; + typedef const Block<ConstMatrixType,Dim,1,int(Mode)==(AffineCompact)> ConstTranslationPart; /** corresponding translation type */ typedef Translation<Scalar,Dim> TranslationType; @@ -279,6 +266,9 @@ public: template<typename OtherDerived> inline explicit Transform(const EigenBase<OtherDerived>& other) { + EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); + check_template_params(); internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); } @@ -287,6 +277,9 @@ public: template<typename OtherDerived> inline Transform& operator=(const EigenBase<OtherDerived>& other) { + EIGEN_STATIC_ASSERT((internal::is_same<Scalar,typename OtherDerived::Scalar>::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); + internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); return *this; } @@ -376,9 +369,9 @@ public: inline MatrixType& matrix() { return m_matrix; } /** \returns a read-only expression of the linear part of the transformation */ - inline ConstLinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); } + inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); } /** \returns a writable expression of the linear part of the transformation */ - inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); } + inline LinearPart linear() { return LinearPart(m_matrix,0,0); } /** \returns a read-only expression of the Dim x HDim affine part of the transformation */ inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); } @@ -386,9 +379,9 @@ public: inline AffinePart affine() { return take_affine_part::run(m_matrix); } /** \returns a read-only expression of the translation vector of the transformation */ - inline ConstTranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); } + inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); } /** \returns a writable expression of the translation vector of the transformation */ - inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); } + inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); } /** \returns an expression of the product between the transform \c *this and a matrix expression \a other * @@ -460,15 +453,40 @@ public: { return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other); } - + + #ifdef __INTEL_COMPILER +private: + // this intermediate structure permits to workaround a bug in ICC 11: + // error: template instantiation resulted in unexpected function type of "Eigen::Transform<double, 3, 32, 0> + // (const Eigen::Transform<double, 3, 2, 0> &) const" + // (the meaning of a name may have changed since the template declaration -- the type of the template is: + // "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>, + // Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const") + // + template<int OtherMode,int OtherOptions> struct icc_11_workaround + { + typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType; + typedef typename ProductType::ResultType ResultType; + }; + +public: + /** Concatenates two different transformations */ + template<int OtherMode,int OtherOptions> + inline typename icc_11_workaround<OtherMode,OtherOptions>::ResultType + operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const + { + typedef typename icc_11_workaround<OtherMode,OtherOptions>::ProductType ProductType; + return ProductType::run(*this,other); + } + #else /** Concatenates two different transformations */ template<int OtherMode,int OtherOptions> - inline const typename internal::transform_transform_product_impl< - Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType + inline typename internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const { return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other); } + #endif /** \sa MatrixBase::setIdentity() */ void setIdentity() { m_matrix.setIdentity(); } @@ -512,7 +530,12 @@ public: inline Transform& operator=(const UniformScaling<Scalar>& t); inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); } - inline Transform operator*(const UniformScaling<Scalar>& s) const; + inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Isometry)> operator*(const UniformScaling<Scalar>& s) const + { + Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Isometry),Options> res = *this; + res.scale(s.factor()); + return res; + } inline Transform& operator*=(const DiagonalMatrix<Scalar,Dim>& s) { linear() *= s; return *this; } @@ -571,7 +594,7 @@ public: if(int(Mode)!=int(AffineCompact)) { matrix().template block<1,Dim>(Dim,0).setZero(); - matrix().coeffRef(Dim,Dim) = 1; + matrix().coeffRef(Dim,Dim) = Scalar(1); } } @@ -608,7 +631,7 @@ public: protected: #ifndef EIGEN_PARSED_BY_DOXYGEN - EIGEN_STRONG_INLINE static void check_template_params() + static EIGEN_STRONG_INLINE void check_template_params() { EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) } @@ -941,14 +964,6 @@ inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::o } template<typename Scalar, int Dim, int Mode, int Options> -inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const UniformScaling<Scalar>& s) const -{ - Transform res = *this; - res.scale(s.factor()); - return res; -} - -template<typename Scalar, int Dim, int Mode, int Options> template<typename Derived> inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r) { @@ -1219,7 +1234,7 @@ struct transform_right_product_impl< TransformType, MatrixType, 0 > { typedef typename MatrixType::PlainObject ResultType; - EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) + static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) { return T.matrix() * other; } @@ -1237,11 +1252,11 @@ struct transform_right_product_impl< TransformType, MatrixType, 1 > typedef typename MatrixType::PlainObject ResultType; - EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) + static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) { EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); - typedef Block<ResultType, Dim, OtherCols> TopLeftLhs; + typedef Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime)==Dim> TopLeftLhs; ResultType res(other.rows(),other.cols()); TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other; @@ -1263,15 +1278,13 @@ struct transform_right_product_impl< TransformType, MatrixType, 2 > typedef typename MatrixType::PlainObject ResultType; - EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) + static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) { EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); - typedef Block<ResultType, Dim, OtherCols> TopLeftLhs; - - ResultType res(other.rows(),other.cols()); - TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.linear() * other; - TopLeftLhs(res, 0, 0, Dim, other.cols()).colwise() += T.translation(); + typedef Block<ResultType, Dim, OtherCols, true> TopLeftLhs; + ResultType res(Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(),1,other.cols())); + TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other; return res; } @@ -1422,4 +1435,6 @@ struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptio } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRANSFORM_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Translation.h b/extern/Eigen3/Eigen/src/Geometry/Translation.h index d8fe50f987e..7fda179cc35 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Translation.h +++ b/extern/Eigen3/Eigen/src/Geometry/Translation.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSLATION_H #define EIGEN_TRANSLATION_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Translation @@ -54,6 +41,8 @@ public: typedef Matrix<Scalar,Dim,Dim> LinearMatrixType; /** corresponding affine transformation type */ typedef Transform<Scalar,Dim,Affine> AffineTransformType; + /** corresponding isometric transformation type */ + typedef Transform<Scalar,Dim,Isometry> IsometryTransformType; protected: @@ -114,8 +103,8 @@ public: /** Concatenates a translation and a rotation */ template<typename Derived> - inline AffineTransformType operator*(const RotationBase<Derived,Dim>& r) const - { return *this * r.toRotationMatrix(); } + inline IsometryTransformType operator*(const RotationBase<Derived,Dim>& r) const + { return *this * IsometryTransformType(r); } /** \returns the concatenation of a linear transformation \a l with the translation \a t */ // its a nightmare to define a templated friend function outside its declaration @@ -212,4 +201,6 @@ Translation<Scalar,Dim>::operator* (const EigenBase<OtherDerived>& linear) const return res; } +} // end namespace Eigen + #endif // EIGEN_TRANSLATION_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Umeyama.h b/extern/Eigen3/Eigen/src/Geometry/Umeyama.h index b50f461730e..ac0939cde52 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Umeyama.h +++ b/extern/Eigen3/Eigen/src/Geometry/Umeyama.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_UMEYAMA_H #define EIGEN_UMEYAMA_H @@ -31,6 +16,8 @@ // * Eigen/SVD // * Eigen/Array +namespace Eigen { + #ifndef EIGEN_PARSED_BY_DOXYGEN // These helpers are required since it allows to use mixed types as parameters @@ -180,4 +167,6 @@ umeyama(const MatrixBase<Derived>& src, const MatrixBase<OtherDerived>& dst, boo return Rt; } +} // end namespace Eigen + #endif // EIGEN_UMEYAMA_H diff --git a/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h b/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h index 2af32678d1c..3d8284f2d0c 100644 --- a/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h +++ b/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h @@ -4,34 +4,21 @@ // Copyright (C) 2009 Rohit Garg <rpg.314@gmail.com> // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GEOMETRY_SSE_H #define EIGEN_GEOMETRY_SSE_H +namespace Eigen { + namespace internal { template<class Derived, class OtherDerived> struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned> { - inline static Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b) + static inline Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b) { const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0,0,0,0x80000000)); Quaternion<float> res; @@ -53,7 +40,7 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned> template<typename VectorLhs,typename VectorRhs> struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true> { - inline static typename plain_matrix_type<VectorLhs>::type + static inline typename plain_matrix_type<VectorLhs>::type run(const VectorLhs& lhs, const VectorRhs& rhs) { __m128 a = lhs.template packet<VectorLhs::Flags&AlignedBit ? Aligned : Unaligned>(0); @@ -72,7 +59,7 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true> template<class Derived, class OtherDerived> struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Aligned> { - inline static Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b) + static inline Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b) { const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); @@ -123,4 +110,6 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Aligned> } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_GEOMETRY_SSE_H diff --git a/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h b/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h index 23ce1bfbd46..1991c652738 100644 --- a/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h +++ b/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h @@ -4,30 +4,17 @@ // Copyright (C) 2010 Vincent Lejeune // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCK_HOUSEHOLDER_H #define EIGEN_BLOCK_HOUSEHOLDER_H // This file contains some helper function to deal with block householder reflectors +namespace Eigen { + namespace internal { /** \internal */ @@ -64,7 +51,7 @@ void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vec Matrix<typename MatrixType::Scalar, TFactorSize, TFactorSize> T(nbVecs,nbVecs); make_block_householder_triangular_factor(T, vectors, hCoeffs); - const TriangularView<VectorsType, UnitLower>& V(vectors); + const TriangularView<const VectorsType, UnitLower>& V(vectors); // A -= V T V^* A Matrix<typename MatrixType::Scalar,VectorsType::ColsAtCompileTime,MatrixType::ColsAtCompileTime,0, @@ -76,4 +63,6 @@ void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vec } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_BLOCK_HOUSEHOLDER_H diff --git a/extern/Eigen3/Eigen/src/Householder/Householder.h b/extern/Eigen3/Eigen/src/Householder/Householder.h index 74139c0dcce..3f64b7dde2f 100644 --- a/extern/Eigen3/Eigen/src/Householder/Householder.h +++ b/extern/Eigen3/Eigen/src/Householder/Householder.h @@ -4,28 +4,15 @@ // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HOUSEHOLDER_H #define EIGEN_HOUSEHOLDER_H +namespace Eigen { + namespace internal { template<int n> struct decrement_size { @@ -35,6 +22,22 @@ template<int n> struct decrement_size }; } +/** Computes the elementary reflector H such that: + * \f$ H *this = [ beta 0 ... 0]^T \f$ + * where the transformation H is: + * \f$ H = I - tau v v^*\f$ + * and the vector v is: + * \f$ v^T = [1 essential^T] \f$ + * + * The essential part of the vector \c v is stored in *this. + * + * On output: + * \param tau the scaling factor of the Householder transformation + * \param beta the result of H * \c *this + * + * \sa MatrixBase::makeHouseholder(), MatrixBase::applyHouseholderOnTheLeft(), + * MatrixBase::applyHouseholderOnTheRight() + */ template<typename Derived> void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) { @@ -51,7 +54,7 @@ void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) * * On output: * \param essential the essential part of the vector \c v - * \param tau the scaling factor of the householder transformation + * \param tau the scaling factor of the Householder transformation * \param beta the result of H * \c *this * * \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(), @@ -86,6 +89,21 @@ void MatrixBase<Derived>::makeHouseholder( } } +/** Apply the elementary reflector H given by + * \f$ H = I - tau v v^*\f$ + * with + * \f$ v^T = [1 essential^T] \f$ + * from the left to a vector or matrix. + * + * On input: + * \param essential the essential part of the vector \c v + * \param tau the scaling factor of the Householder transformation + * \param workspace a pointer to working space with at least + * this->cols() * essential.size() entries + * + * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), + * MatrixBase::applyHouseholderOnTheRight() + */ template<typename Derived> template<typename EssentialPart> void MatrixBase<Derived>::applyHouseholderOnTheLeft( @@ -108,6 +126,21 @@ void MatrixBase<Derived>::applyHouseholderOnTheLeft( } } +/** Apply the elementary reflector H given by + * \f$ H = I - tau v v^*\f$ + * with + * \f$ v^T = [1 essential^T] \f$ + * from the right to a vector or matrix. + * + * On input: + * \param essential the essential part of the vector \c v + * \param tau the scaling factor of the Householder transformation + * \param workspace a pointer to working space with at least + * this->cols() * essential.size() entries + * + * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), + * MatrixBase::applyHouseholderOnTheLeft() + */ template<typename Derived> template<typename EssentialPart> void MatrixBase<Derived>::applyHouseholderOnTheRight( @@ -130,4 +163,6 @@ void MatrixBase<Derived>::applyHouseholderOnTheRight( } } +} // end namespace Eigen + #endif // EIGEN_HOUSEHOLDER_H diff --git a/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h b/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h index 717f29c99e9..1e71e16a785 100644 --- a/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h +++ b/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H #define EIGEN_HOUSEHOLDER_SEQUENCE_H +namespace Eigen { + /** \ingroup Householder_Module * \householder_module * \class HouseholderSequence @@ -237,13 +224,20 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS ConjugateReturnType inverse() const { return adjoint(); } /** \internal */ - template<typename DestType> void evalTo(DestType& dst) const + template<typename DestType> inline void evalTo(DestType& dst) const { - Index vecs = m_length; - // FIXME find a way to pass this temporary if the user wants to Matrix<Scalar, DestType::RowsAtCompileTime, 1, - AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> temp(rows()); - if( internal::is_same<typename internal::remove_all<VectorsType>::type,DestType>::value + AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> workspace(rows()); + evalTo(dst, workspace); + } + + /** \internal */ + template<typename Dest, typename Workspace> + void evalTo(Dest& dst, Workspace& workspace) const + { + workspace.resize(rows()); + Index vecs = m_length; + if( internal::is_same<typename internal::remove_all<VectorsType>::type,Dest>::value && internal::extract_data(dst) == internal::extract_data(m_vectors)) { // in-place @@ -254,10 +248,10 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS Index cornerSize = rows() - k - m_shift; if(m_trans) dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data()); else dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data()); // clear the off diagonal vector dst.col(k).tail(rows()-k-1).setZero(); @@ -274,10 +268,10 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS Index cornerSize = rows() - k - m_shift; if(m_trans) dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0)); else dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0)); } } } @@ -285,24 +279,40 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS /** \internal */ template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const { - Matrix<Scalar,1,Dest::RowsAtCompileTime> temp(dst.rows()); + Matrix<Scalar,1,Dest::RowsAtCompileTime,RowMajor,1,Dest::MaxRowsAtCompileTime> workspace(dst.rows()); + applyThisOnTheRight(dst, workspace); + } + + /** \internal */ + template<typename Dest, typename Workspace> + inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const + { + workspace.resize(dst.rows()); for(Index k = 0; k < m_length; ++k) { Index actual_k = m_trans ? m_length-k-1 : k; dst.rightCols(rows()-m_shift-actual_k) - .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), &temp.coeffRef(0)); + .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); } } /** \internal */ template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const { - Matrix<Scalar,1,Dest::ColsAtCompileTime> temp(dst.cols()); + Matrix<Scalar,1,Dest::ColsAtCompileTime,RowMajor,1,Dest::MaxColsAtCompileTime> workspace(dst.cols()); + applyThisOnTheLeft(dst, workspace); + } + + /** \internal */ + template<typename Dest, typename Workspace> + inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const + { + workspace.resize(dst.cols()); for(Index k = 0; k < m_length; ++k) { Index actual_k = m_trans ? k : m_length-k-1; dst.bottomRows(rows()-m_shift-actual_k) - .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), &temp.coeffRef(0)); + .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); } } @@ -426,4 +436,6 @@ HouseholderSequence<VectorsType,CoeffsType,OnTheRight> rightHouseholderSequence( return HouseholderSequence<VectorsType,CoeffsType,OnTheRight>(v, h); } +} // end namespace Eigen + #endif // EIGEN_HOUSEHOLDER_SEQUENCE_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h new file mode 100644 index 00000000000..73ca9bfde6a --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -0,0 +1,149 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BASIC_PRECONDITIONERS_H +#define EIGEN_BASIC_PRECONDITIONERS_H + +namespace Eigen { + +/** \ingroup IterativeLinearSolvers_Module + * \brief A preconditioner based on the digonal entries + * + * This class allows to approximately solve for A.x = b problems assuming A is a diagonal matrix. + * In other words, this preconditioner neglects all off diagonal entries and, in Eigen's language, solves for: + * \code + * A.diagonal().asDiagonal() . x = b + * \endcode + * + * \tparam _Scalar the type of the scalar. + * + * This preconditioner is suitable for both selfadjoint and general problems. + * The diagonal entries are pre-inverted and stored into a dense vector. + * + * \note A variant that has yet to be implemented would attempt to preserve the norm of each column. + * + */ +template <typename _Scalar> +class DiagonalPreconditioner +{ + typedef _Scalar Scalar; + typedef Matrix<Scalar,Dynamic,1> Vector; + typedef typename Vector::Index Index; + + public: + // this typedef is only to export the scalar type and compile-time dimensions to solve_retval + typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType; + + DiagonalPreconditioner() : m_isInitialized(false) {} + + template<typename MatType> + DiagonalPreconditioner(const MatType& mat) : m_invdiag(mat.cols()) + { + compute(mat); + } + + Index rows() const { return m_invdiag.size(); } + Index cols() const { return m_invdiag.size(); } + + template<typename MatType> + DiagonalPreconditioner& analyzePattern(const MatType& ) + { + return *this; + } + + template<typename MatType> + DiagonalPreconditioner& factorize(const MatType& mat) + { + m_invdiag.resize(mat.cols()); + for(int j=0; j<mat.outerSize(); ++j) + { + typename MatType::InnerIterator it(mat,j); + while(it && it.index()!=j) ++it; + if(it && it.index()==j) + m_invdiag(j) = Scalar(1)/it.value(); + else + m_invdiag(j) = 0; + } + m_isInitialized = true; + return *this; + } + + template<typename MatType> + DiagonalPreconditioner& compute(const MatType& mat) + { + return factorize(mat); + } + + template<typename Rhs, typename Dest> + void _solve(const Rhs& b, Dest& x) const + { + x = m_invdiag.array() * b.array() ; + } + + template<typename Rhs> inline const internal::solve_retval<DiagonalPreconditioner, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "DiagonalPreconditioner is not initialized."); + eigen_assert(m_invdiag.size()==b.rows() + && "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<DiagonalPreconditioner, Rhs>(*this, b.derived()); + } + + protected: + Vector m_invdiag; + bool m_isInitialized; +}; + +namespace internal { + +template<typename _MatrixType, typename Rhs> +struct solve_retval<DiagonalPreconditioner<_MatrixType>, Rhs> + : solve_retval_base<DiagonalPreconditioner<_MatrixType>, Rhs> +{ + typedef DiagonalPreconditioner<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} + +/** \ingroup IterativeLinearSolvers_Module + * \brief A naive preconditioner which approximates any matrix as the identity matrix + * + * \sa class DiagonalPreconditioner + */ +class IdentityPreconditioner +{ + public: + + IdentityPreconditioner() {} + + template<typename MatrixType> + IdentityPreconditioner(const MatrixType& ) {} + + template<typename MatrixType> + IdentityPreconditioner& analyzePattern(const MatrixType& ) { return *this; } + + template<typename MatrixType> + IdentityPreconditioner& factorize(const MatrixType& ) { return *this; } + + template<typename MatrixType> + IdentityPreconditioner& compute(const MatrixType& ) { return *this; } + + template<typename Rhs> + inline const Rhs& solve(const Rhs& b) const { return b; } +}; + +} // end namespace Eigen + +#endif // EIGEN_BASIC_PRECONDITIONERS_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h new file mode 100644 index 00000000000..126341be8d8 --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -0,0 +1,254 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BICGSTAB_H +#define EIGEN_BICGSTAB_H + +namespace Eigen { + +namespace internal { + +/** \internal Low-level bi conjugate gradient stabilized algorithm + * \param mat The matrix A + * \param rhs The right hand side vector b + * \param x On input and initial solution, on output the computed solution. + * \param precond A preconditioner being able to efficiently solve for an + * approximation of Ax=b (regardless of b) + * \param iters On input the max number of iteration, on output the number of performed iterations. + * \param tol_error On input the tolerance error, on output an estimation of the relative error. + * \return false in the case of numerical issue, for example a break down of BiCGSTAB. + */ +template<typename MatrixType, typename Rhs, typename Dest, typename Preconditioner> +bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, + const Preconditioner& precond, int& iters, + typename Dest::RealScalar& tol_error) +{ + using std::sqrt; + using std::abs; + typedef typename Dest::RealScalar RealScalar; + typedef typename Dest::Scalar Scalar; + typedef Matrix<Scalar,Dynamic,1> VectorType; + RealScalar tol = tol_error; + int maxIters = iters; + + int n = mat.cols(); + VectorType r = rhs - mat * x; + VectorType r0 = r; + + RealScalar r0_sqnorm = r0.squaredNorm(); + Scalar rho = 1; + Scalar alpha = 1; + Scalar w = 1; + + VectorType v = VectorType::Zero(n), p = VectorType::Zero(n); + VectorType y(n), z(n); + VectorType kt(n), ks(n); + + VectorType s(n), t(n); + + RealScalar tol2 = tol*tol; + int i = 0; + + while ( r.squaredNorm()/r0_sqnorm > tol2 && i<maxIters ) + { + Scalar rho_old = rho; + + rho = r0.dot(r); + if (rho == Scalar(0)) return false; /* New search directions cannot be found */ + Scalar beta = (rho/rho_old) * (alpha / w); + p = r + beta * (p - w * v); + + y = precond.solve(p); + + v.noalias() = mat * y; + + alpha = rho / r0.dot(v); + s = r - alpha * v; + + z = precond.solve(s); + t.noalias() = mat * z; + + w = t.dot(s) / t.squaredNorm(); + x += alpha * y + w * z; + r = s - w * t; + ++i; + } + tol_error = sqrt(r.squaredNorm()/r0_sqnorm); + iters = i; + return true; +} + +} + +template< typename _MatrixType, + typename _Preconditioner = DiagonalPreconditioner<typename _MatrixType::Scalar> > +class BiCGSTAB; + +namespace internal { + +template< typename _MatrixType, typename _Preconditioner> +struct traits<BiCGSTAB<_MatrixType,_Preconditioner> > +{ + typedef _MatrixType MatrixType; + typedef _Preconditioner Preconditioner; +}; + +} + +/** \ingroup IterativeLinearSolvers_Module + * \brief A bi conjugate gradient stabilized solver for sparse square problems + * + * This class allows to solve for A.x = b sparse linear problems using a bi conjugate gradient + * stabilized algorithm. The vectors x and b can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. + * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner + * + * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() + * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations + * and NumTraits<Scalar>::epsilon() for the tolerance. + * + * This class can be used as the direct solver classes. Here is a typical usage example: + * \code + * int n = 10000; + * VectorXd x(n), b(n); + * SparseMatrix<double> A(n,n); + * // fill A and b + * BiCGSTAB<SparseMatrix<double> > solver; + * solver(A); + * x = solver.solve(b); + * std::cout << "#iterations: " << solver.iterations() << std::endl; + * std::cout << "estimated error: " << solver.error() << std::endl; + * // update b, and solve again + * x = solver.solve(b); + * \endcode + * + * By default the iterations start with x=0 as an initial guess of the solution. + * One can control the start using the solveWithGuess() method. Here is a step by + * step execution example starting with a random guess and printing the evolution + * of the estimated error: + * * \code + * x = VectorXd::Random(n); + * solver.setMaxIterations(1); + * int i = 0; + * do { + * x = solver.solveWithGuess(b,x); + * std::cout << i << " : " << solver.error() << std::endl; + * ++i; + * } while (solver.info()!=Success && i<100); + * \endcode + * Note that such a step by step excution is slightly slower. + * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner + */ +template< typename _MatrixType, typename _Preconditioner> +class BiCGSTAB : public IterativeSolverBase<BiCGSTAB<_MatrixType,_Preconditioner> > +{ + typedef IterativeSolverBase<BiCGSTAB> Base; + using Base::mp_matrix; + using Base::m_error; + using Base::m_iterations; + using Base::m_info; + using Base::m_isInitialized; +public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::RealScalar RealScalar; + typedef _Preconditioner Preconditioner; + +public: + + /** Default constructor. */ + BiCGSTAB() : Base() {} + + /** Initialize the solver with matrix \a A for further \c Ax=b solving. + * + * This constructor is a shortcut for the default constructor followed + * by a call to compute(). + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + BiCGSTAB(const MatrixType& A) : Base(A) {} + + ~BiCGSTAB() {} + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A + * \a x0 as an initial solution. + * + * \sa compute() + */ + template<typename Rhs,typename Guess> + inline const internal::solve_retval_with_guess<BiCGSTAB, Rhs, Guess> + solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const + { + eigen_assert(m_isInitialized && "BiCGSTAB is not initialized."); + eigen_assert(Base::rows()==b.rows() + && "BiCGSTAB::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval_with_guess + <BiCGSTAB, Rhs, Guess>(*this, b.derived(), x0); + } + + /** \internal */ + template<typename Rhs,typename Dest> + void _solveWithGuess(const Rhs& b, Dest& x) const + { + bool failed = false; + for(int j=0; j<b.cols(); ++j) + { + m_iterations = Base::maxIterations(); + m_error = Base::m_tolerance; + + typename Dest::ColXpr xj(x,j); + if(!internal::bicgstab(*mp_matrix, b.col(j), xj, Base::m_preconditioner, m_iterations, m_error)) + failed = true; + } + m_info = failed ? NumericalIssue + : m_error <= Base::m_tolerance ? Success + : NoConvergence; + m_isInitialized = true; + } + + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const Rhs& b, Dest& x) const + { + x.setZero(); + _solveWithGuess(b,x); + } + +protected: + +}; + + +namespace internal { + + template<typename _MatrixType, typename _Preconditioner, typename Rhs> +struct solve_retval<BiCGSTAB<_MatrixType, _Preconditioner>, Rhs> + : solve_retval_base<BiCGSTAB<_MatrixType, _Preconditioner>, Rhs> +{ + typedef BiCGSTAB<_MatrixType, _Preconditioner> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_BICGSTAB_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h new file mode 100644 index 00000000000..f64f2534d28 --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h @@ -0,0 +1,251 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CONJUGATE_GRADIENT_H +#define EIGEN_CONJUGATE_GRADIENT_H + +namespace Eigen { + +namespace internal { + +/** \internal Low-level conjugate gradient algorithm + * \param mat The matrix A + * \param rhs The right hand side vector b + * \param x On input and initial solution, on output the computed solution. + * \param precond A preconditioner being able to efficiently solve for an + * approximation of Ax=b (regardless of b) + * \param iters On input the max number of iteration, on output the number of performed iterations. + * \param tol_error On input the tolerance error, on output an estimation of the relative error. + */ +template<typename MatrixType, typename Rhs, typename Dest, typename Preconditioner> +EIGEN_DONT_INLINE +void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x, + const Preconditioner& precond, int& iters, + typename Dest::RealScalar& tol_error) +{ + using std::sqrt; + using std::abs; + typedef typename Dest::RealScalar RealScalar; + typedef typename Dest::Scalar Scalar; + typedef Matrix<Scalar,Dynamic,1> VectorType; + + RealScalar tol = tol_error; + int maxIters = iters; + + int n = mat.cols(); + + VectorType residual = rhs - mat * x; //initial residual + VectorType p(n); + + p = precond.solve(residual); //initial search direction + + VectorType z(n), tmp(n); + RealScalar absNew = internal::real(residual.dot(p)); // the square of the absolute value of r scaled by invM + RealScalar rhsNorm2 = rhs.squaredNorm(); + RealScalar residualNorm2 = 0; + RealScalar threshold = tol*tol*rhsNorm2; + int i = 0; + while(i < maxIters) + { + tmp.noalias() = mat * p; // the bottleneck of the algorithm + + Scalar alpha = absNew / p.dot(tmp); // the amount we travel on dir + x += alpha * p; // update solution + residual -= alpha * tmp; // update residue + + residualNorm2 = residual.squaredNorm(); + if(residualNorm2 < threshold) + break; + + z = precond.solve(residual); // approximately solve for "A z = residual" + + RealScalar absOld = absNew; + absNew = internal::real(residual.dot(z)); // update the absolute value of r + RealScalar beta = absNew / absOld; // calculate the Gram-Schmidt value used to create the new search direction + p = z + beta * p; // update search direction + i++; + } + tol_error = sqrt(residualNorm2 / rhsNorm2); + iters = i; +} + +} + +template< typename _MatrixType, int _UpLo=Lower, + typename _Preconditioner = DiagonalPreconditioner<typename _MatrixType::Scalar> > +class ConjugateGradient; + +namespace internal { + +template< typename _MatrixType, int _UpLo, typename _Preconditioner> +struct traits<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> > +{ + typedef _MatrixType MatrixType; + typedef _Preconditioner Preconditioner; +}; + +} + +/** \ingroup IterativeLinearSolvers_Module + * \brief A conjugate gradient solver for sparse self-adjoint problems + * + * This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm. + * The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner + * + * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() + * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations + * and NumTraits<Scalar>::epsilon() for the tolerance. + * + * This class can be used as the direct solver classes. Here is a typical usage example: + * \code + * int n = 10000; + * VectorXd x(n), b(n); + * SparseMatrix<double> A(n,n); + * // fill A and b + * ConjugateGradient<SparseMatrix<double> > cg; + * cg.compute(A); + * x = cg.solve(b); + * std::cout << "#iterations: " << cg.iterations() << std::endl; + * std::cout << "estimated error: " << cg.error() << std::endl; + * // update b, and solve again + * x = cg.solve(b); + * \endcode + * + * By default the iterations start with x=0 as an initial guess of the solution. + * One can control the start using the solveWithGuess() method. Here is a step by + * step execution example starting with a random guess and printing the evolution + * of the estimated error: + * * \code + * x = VectorXd::Random(n); + * cg.setMaxIterations(1); + * int i = 0; + * do { + * x = cg.solveWithGuess(b,x); + * std::cout << i << " : " << cg.error() << std::endl; + * ++i; + * } while (cg.info()!=Success && i<100); + * \endcode + * Note that such a step by step excution is slightly slower. + * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner + */ +template< typename _MatrixType, int _UpLo, typename _Preconditioner> +class ConjugateGradient : public IterativeSolverBase<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> > +{ + typedef IterativeSolverBase<ConjugateGradient> Base; + using Base::mp_matrix; + using Base::m_error; + using Base::m_iterations; + using Base::m_info; + using Base::m_isInitialized; +public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::RealScalar RealScalar; + typedef _Preconditioner Preconditioner; + + enum { + UpLo = _UpLo + }; + +public: + + /** Default constructor. */ + ConjugateGradient() : Base() {} + + /** Initialize the solver with matrix \a A for further \c Ax=b solving. + * + * This constructor is a shortcut for the default constructor followed + * by a call to compute(). + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + ConjugateGradient(const MatrixType& A) : Base(A) {} + + ~ConjugateGradient() {} + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A + * \a x0 as an initial solution. + * + * \sa compute() + */ + template<typename Rhs,typename Guess> + inline const internal::solve_retval_with_guess<ConjugateGradient, Rhs, Guess> + solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const + { + eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); + eigen_assert(Base::rows()==b.rows() + && "ConjugateGradient::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval_with_guess + <ConjugateGradient, Rhs, Guess>(*this, b.derived(), x0); + } + + /** \internal */ + template<typename Rhs,typename Dest> + void _solveWithGuess(const Rhs& b, Dest& x) const + { + m_iterations = Base::maxIterations(); + m_error = Base::m_tolerance; + + for(int j=0; j<b.cols(); ++j) + { + m_iterations = Base::maxIterations(); + m_error = Base::m_tolerance; + + typename Dest::ColXpr xj(x,j); + internal::conjugate_gradient(mp_matrix->template selfadjointView<UpLo>(), b.col(j), xj, + Base::m_preconditioner, m_iterations, m_error); + } + + m_isInitialized = true; + m_info = m_error <= Base::m_tolerance ? Success : NoConvergence; + } + + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const Rhs& b, Dest& x) const + { + x.setOnes(); + _solveWithGuess(b,x); + } + +protected: + +}; + + +namespace internal { + +template<typename _MatrixType, int _UpLo, typename _Preconditioner, typename Rhs> +struct solve_retval<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner>, Rhs> + : solve_retval_base<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner>, Rhs> +{ + typedef ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CONJUGATE_GRADIENT_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h new file mode 100644 index 00000000000..224304f0eb8 --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h @@ -0,0 +1,466 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_INCOMPLETE_LUT_H +#define EIGEN_INCOMPLETE_LUT_H + +namespace Eigen { + +/** + * \brief Incomplete LU factorization with dual-threshold strategy + * During the numerical factorization, two dropping rules are used : + * 1) any element whose magnitude is less than some tolerance is dropped. + * This tolerance is obtained by multiplying the input tolerance @p droptol + * by the average magnitude of all the original elements in the current row. + * 2) After the elimination of the row, only the @p fill largest elements in + * the L part and the @p fill largest elements in the U part are kept + * (in addition to the diagonal element ). Note that @p fill is computed from + * the input parameter @p fillfactor which is used the ratio to control the fill_in + * relatively to the initial number of nonzero elements. + * + * The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements) + * and when @p fill=n/2 with @p droptol being different to zero. + * + * References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization, + * Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994. + * + * NOTE : The following implementation is derived from the ILUT implementation + * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota + * released under the terms of the GNU LGPL: + * http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README + * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2. + * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012: + * http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html + * alternatively, on GMANE: + * http://comments.gmane.org/gmane.comp.lib.eigen/3302 + */ +template <typename _Scalar> +class IncompleteLUT : internal::noncopyable +{ + typedef _Scalar Scalar; + typedef typename NumTraits<Scalar>::Real RealScalar; + typedef Matrix<Scalar,Dynamic,1> Vector; + typedef SparseMatrix<Scalar,RowMajor> FactorType; + typedef SparseMatrix<Scalar,ColMajor> PermutType; + typedef typename FactorType::Index Index; + + public: + typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType; + + IncompleteLUT() + : m_droptol(NumTraits<Scalar>::dummy_precision()), m_fillfactor(10), + m_analysisIsOk(false), m_factorizationIsOk(false), m_isInitialized(false) + {} + + template<typename MatrixType> + IncompleteLUT(const MatrixType& mat, RealScalar droptol=NumTraits<Scalar>::dummy_precision(), int fillfactor = 10) + : m_droptol(droptol),m_fillfactor(fillfactor), + m_analysisIsOk(false),m_factorizationIsOk(false),m_isInitialized(false) + { + eigen_assert(fillfactor != 0); + compute(mat); + } + + Index rows() const { return m_lu.rows(); } + + Index cols() const { return m_lu.cols(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "IncompleteLUT is not initialized."); + return m_info; + } + + template<typename MatrixType> + void analyzePattern(const MatrixType& amat); + + template<typename MatrixType> + void factorize(const MatrixType& amat); + + /** + * Compute an incomplete LU factorization with dual threshold on the matrix mat + * No pivoting is done in this version + * + **/ + template<typename MatrixType> + IncompleteLUT<Scalar>& compute(const MatrixType& amat) + { + analyzePattern(amat); + factorize(amat); + eigen_assert(m_factorizationIsOk == true); + m_isInitialized = true; + return *this; + } + + void setDroptol(RealScalar droptol); + void setFillfactor(int fillfactor); + + template<typename Rhs, typename Dest> + void _solve(const Rhs& b, Dest& x) const + { + x = m_Pinv * b; + x = m_lu.template triangularView<UnitLower>().solve(x); + x = m_lu.template triangularView<Upper>().solve(x); + x = m_P * x; + } + + template<typename Rhs> inline const internal::solve_retval<IncompleteLUT, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "IncompleteLUT is not initialized."); + eigen_assert(cols()==b.rows() + && "IncompleteLUT::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<IncompleteLUT, Rhs>(*this, b.derived()); + } + +protected: + + template <typename VectorV, typename VectorI> + int QuickSplit(VectorV &row, VectorI &ind, int ncut); + + + /** keeps off-diagonal entries; drops diagonal entries */ + struct keep_diag { + inline bool operator() (const Index& row, const Index& col, const Scalar&) const + { + return row!=col; + } + }; + +protected: + + FactorType m_lu; + RealScalar m_droptol; + int m_fillfactor; + bool m_analysisIsOk; + bool m_factorizationIsOk; + bool m_isInitialized; + ComputationInfo m_info; + PermutationMatrix<Dynamic,Dynamic,Index> m_P; // Fill-reducing permutation + PermutationMatrix<Dynamic,Dynamic,Index> m_Pinv; // Inverse permutation +}; + +/** + * Set control parameter droptol + * \param droptol Drop any element whose magnitude is less than this tolerance + **/ +template<typename Scalar> +void IncompleteLUT<Scalar>::setDroptol(RealScalar droptol) +{ + this->m_droptol = droptol; +} + +/** + * Set control parameter fillfactor + * \param fillfactor This is used to compute the number @p fill_in of largest elements to keep on each row. + **/ +template<typename Scalar> +void IncompleteLUT<Scalar>::setFillfactor(int fillfactor) +{ + this->m_fillfactor = fillfactor; +} + + +/** + * Compute a quick-sort split of a vector + * On output, the vector row is permuted such that its elements satisfy + * abs(row(i)) >= abs(row(ncut)) if i<ncut + * abs(row(i)) <= abs(row(ncut)) if i>ncut + * \param row The vector of values + * \param ind The array of index for the elements in @p row + * \param ncut The number of largest elements to keep + **/ +template <typename Scalar> +template <typename VectorV, typename VectorI> +int IncompleteLUT<Scalar>::QuickSplit(VectorV &row, VectorI &ind, int ncut) +{ + using std::swap; + int mid; + int n = row.size(); /* length of the vector */ + int first, last ; + + ncut--; /* to fit the zero-based indices */ + first = 0; + last = n-1; + if (ncut < first || ncut > last ) return 0; + + do { + mid = first; + RealScalar abskey = std::abs(row(mid)); + for (int j = first + 1; j <= last; j++) { + if ( std::abs(row(j)) > abskey) { + ++mid; + swap(row(mid), row(j)); + swap(ind(mid), ind(j)); + } + } + /* Interchange for the pivot element */ + swap(row(mid), row(first)); + swap(ind(mid), ind(first)); + + if (mid > ncut) last = mid - 1; + else if (mid < ncut ) first = mid + 1; + } while (mid != ncut ); + + return 0; /* mid is equal to ncut */ +} + +template <typename Scalar> +template<typename _MatrixType> +void IncompleteLUT<Scalar>::analyzePattern(const _MatrixType& amat) +{ + // Compute the Fill-reducing permutation + SparseMatrix<Scalar,ColMajor, Index> mat1 = amat; + SparseMatrix<Scalar,ColMajor, Index> mat2 = amat.transpose(); + // Symmetrize the pattern + // FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice. + // on the other hand for a really non-symmetric pattern, mat2*mat1 should be prefered... + SparseMatrix<Scalar,ColMajor, Index> AtA = mat2 + mat1; + AtA.prune(keep_diag()); + internal::minimum_degree_ordering<Scalar, Index>(AtA, m_P); // Then compute the AMD ordering... + + m_Pinv = m_P.inverse(); // ... and the inverse permutation + + m_analysisIsOk = true; +} + +template <typename Scalar> +template<typename _MatrixType> +void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat) +{ + using std::sqrt; + using std::swap; + using std::abs; + + eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix"); + int n = amat.cols(); // Size of the matrix + m_lu.resize(n,n); + // Declare Working vectors and variables + Vector u(n) ; // real values of the row -- maximum size is n -- + VectorXi ju(n); // column position of the values in u -- maximum size is n + VectorXi jr(n); // Indicate the position of the nonzero elements in the vector u -- A zero location is indicated by -1 + + // Apply the fill-reducing permutation + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + SparseMatrix<Scalar,RowMajor, Index> mat; + mat = amat.twistedBy(m_Pinv); + + // Initialization + jr.fill(-1); + ju.fill(0); + u.fill(0); + + // number of largest elements to keep in each row: + int fill_in = static_cast<int> (amat.nonZeros()*m_fillfactor)/n+1; + if (fill_in > n) fill_in = n; + + // number of largest nonzero elements to keep in the L and the U part of the current row: + int nnzL = fill_in/2; + int nnzU = nnzL; + m_lu.reserve(n * (nnzL + nnzU + 1)); + + // global loop over the rows of the sparse matrix + for (int ii = 0; ii < n; ii++) + { + // 1 - copy the lower and the upper part of the row i of mat in the working vector u + + int sizeu = 1; // number of nonzero elements in the upper part of the current row + int sizel = 0; // number of nonzero elements in the lower part of the current row + ju(ii) = ii; + u(ii) = 0; + jr(ii) = ii; + RealScalar rownorm = 0; + + typename FactorType::InnerIterator j_it(mat, ii); // Iterate through the current row ii + for (; j_it; ++j_it) + { + int k = j_it.index(); + if (k < ii) + { + // copy the lower part + ju(sizel) = k; + u(sizel) = j_it.value(); + jr(k) = sizel; + ++sizel; + } + else if (k == ii) + { + u(ii) = j_it.value(); + } + else + { + // copy the upper part + int jpos = ii + sizeu; + ju(jpos) = k; + u(jpos) = j_it.value(); + jr(k) = jpos; + ++sizeu; + } + rownorm += internal::abs2(j_it.value()); + } + + // 2 - detect possible zero row + if(rownorm==0) + { + m_info = NumericalIssue; + return; + } + // Take the 2-norm of the current row as a relative tolerance + rownorm = sqrt(rownorm); + + // 3 - eliminate the previous nonzero rows + int jj = 0; + int len = 0; + while (jj < sizel) + { + // In order to eliminate in the correct order, + // we must select first the smallest column index among ju(jj:sizel) + int k; + int minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment + k += jj; + if (minrow != ju(jj)) + { + // swap the two locations + int j = ju(jj); + swap(ju(jj), ju(k)); + jr(minrow) = jj; jr(j) = k; + swap(u(jj), u(k)); + } + // Reset this location + jr(minrow) = -1; + + // Start elimination + typename FactorType::InnerIterator ki_it(m_lu, minrow); + while (ki_it && ki_it.index() < minrow) ++ki_it; + eigen_internal_assert(ki_it && ki_it.col()==minrow); + Scalar fact = u(jj) / ki_it.value(); + + // drop too small elements + if(abs(fact) <= m_droptol) + { + jj++; + continue; + } + + // linear combination of the current row ii and the row minrow + ++ki_it; + for (; ki_it; ++ki_it) + { + Scalar prod = fact * ki_it.value(); + int j = ki_it.index(); + int jpos = jr(j); + if (jpos == -1) // fill-in element + { + int newpos; + if (j >= ii) // dealing with the upper part + { + newpos = ii + sizeu; + sizeu++; + eigen_internal_assert(sizeu<=n); + } + else // dealing with the lower part + { + newpos = sizel; + sizel++; + eigen_internal_assert(sizel<=ii); + } + ju(newpos) = j; + u(newpos) = -prod; + jr(j) = newpos; + } + else + u(jpos) -= prod; + } + // store the pivot element + u(len) = fact; + ju(len) = minrow; + ++len; + + jj++; + } // end of the elimination on the row ii + + // reset the upper part of the pointer jr to zero + for(int k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1; + + // 4 - partially sort and insert the elements in the m_lu matrix + + // sort the L-part of the row + sizel = len; + len = (std::min)(sizel, nnzL); + typename Vector::SegmentReturnType ul(u.segment(0, sizel)); + typename VectorXi::SegmentReturnType jul(ju.segment(0, sizel)); + QuickSplit(ul, jul, len); + + // store the largest m_fill elements of the L part + m_lu.startVec(ii); + for(int k = 0; k < len; k++) + m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k); + + // store the diagonal element + // apply a shifting rule to avoid zero pivots (we are doing an incomplete factorization) + if (u(ii) == Scalar(0)) + u(ii) = sqrt(m_droptol) * rownorm; + m_lu.insertBackByOuterInnerUnordered(ii, ii) = u(ii); + + // sort the U-part of the row + // apply the dropping rule first + len = 0; + for(int k = 1; k < sizeu; k++) + { + if(abs(u(ii+k)) > m_droptol * rownorm ) + { + ++len; + u(ii + len) = u(ii + k); + ju(ii + len) = ju(ii + k); + } + } + sizeu = len + 1; // +1 to take into account the diagonal element + len = (std::min)(sizeu, nnzU); + typename Vector::SegmentReturnType uu(u.segment(ii+1, sizeu-1)); + typename VectorXi::SegmentReturnType juu(ju.segment(ii+1, sizeu-1)); + QuickSplit(uu, juu, len); + + // store the largest elements of the U part + for(int k = ii + 1; k < ii + len; k++) + m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k); + } + + m_lu.finalize(); + m_lu.makeCompressed(); + + m_factorizationIsOk = true; + m_info = Success; +} + +namespace internal { + +template<typename _MatrixType, typename Rhs> +struct solve_retval<IncompleteLUT<_MatrixType>, Rhs> + : solve_retval_base<IncompleteLUT<_MatrixType>, Rhs> +{ + typedef IncompleteLUT<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_INCOMPLETE_LUT_H + diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h new file mode 100644 index 00000000000..11706cebabd --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h @@ -0,0 +1,254 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H +#define EIGEN_ITERATIVE_SOLVER_BASE_H + +namespace Eigen { + +/** \ingroup IterativeLinearSolvers_Module + * \brief Base class for linear iterative solvers + * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner + */ +template< typename Derived> +class IterativeSolverBase : internal::noncopyable +{ +public: + typedef typename internal::traits<Derived>::MatrixType MatrixType; + typedef typename internal::traits<Derived>::Preconditioner Preconditioner; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::RealScalar RealScalar; + +public: + + Derived& derived() { return *static_cast<Derived*>(this); } + const Derived& derived() const { return *static_cast<const Derived*>(this); } + + /** Default constructor. */ + IterativeSolverBase() + : mp_matrix(0) + { + init(); + } + + /** Initialize the solver with matrix \a A for further \c Ax=b solving. + * + * This constructor is a shortcut for the default constructor followed + * by a call to compute(). + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + IterativeSolverBase(const MatrixType& A) + { + init(); + compute(A); + } + + ~IterativeSolverBase() {} + + /** Initializes the iterative solver for the sparcity pattern of the matrix \a A for further solving \c Ax=b problems. + * + * Currently, this function mostly call analyzePattern on the preconditioner. In the future + * we might, for instance, implement column reodering for faster matrix vector products. + */ + Derived& analyzePattern(const MatrixType& A) + { + m_preconditioner.analyzePattern(A); + m_isInitialized = true; + m_analysisIsOk = true; + m_info = Success; + return derived(); + } + + /** Initializes the iterative solver with the numerical values of the matrix \a A for further solving \c Ax=b problems. + * + * Currently, this function mostly call factorize on the preconditioner. + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + Derived& factorize(const MatrixType& A) + { + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + mp_matrix = &A; + m_preconditioner.factorize(A); + m_factorizationIsOk = true; + m_info = Success; + return derived(); + } + + /** Initializes the iterative solver with the matrix \a A for further solving \c Ax=b problems. + * + * Currently, this function mostly initialized/compute the preconditioner. In the future + * we might, for instance, implement column reodering for faster matrix vector products. + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + Derived& compute(const MatrixType& A) + { + mp_matrix = &A; + m_preconditioner.compute(A); + m_isInitialized = true; + m_analysisIsOk = true; + m_factorizationIsOk = true; + m_info = Success; + return derived(); + } + + /** \internal */ + Index rows() const { return mp_matrix ? mp_matrix->rows() : 0; } + /** \internal */ + Index cols() const { return mp_matrix ? mp_matrix->cols() : 0; } + + /** \returns the tolerance threshold used by the stopping criteria */ + RealScalar tolerance() const { return m_tolerance; } + + /** Sets the tolerance threshold used by the stopping criteria */ + Derived& setTolerance(RealScalar tolerance) + { + m_tolerance = tolerance; + return derived(); + } + + /** \returns a read-write reference to the preconditioner for custom configuration. */ + Preconditioner& preconditioner() { return m_preconditioner; } + + /** \returns a read-only reference to the preconditioner. */ + const Preconditioner& preconditioner() const { return m_preconditioner; } + + /** \returns the max number of iterations */ + int maxIterations() const + { + return (mp_matrix && m_maxIterations<0) ? mp_matrix->cols() : m_maxIterations; + } + + /** Sets the max number of iterations */ + Derived& setMaxIterations(int maxIters) + { + m_maxIterations = maxIters; + return derived(); + } + + /** \returns the number of iterations performed during the last solve */ + int iterations() const + { + eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); + return m_iterations; + } + + /** \returns the tolerance error reached during the last solve */ + RealScalar error() const + { + eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); + return m_error; + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> inline const internal::solve_retval<Derived, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); + eigen_assert(rows()==b.rows() + && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<Derived, Rhs>(derived(), b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::sparse_solve_retval<IterativeSolverBase, Rhs> + solve(const SparseMatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); + eigen_assert(rows()==b.rows() + && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval<IterativeSolverBase, Rhs>(*this, b.derived()); + } + + /** \returns Success if the iterations converged, and NoConvergence otherwise. */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); + return m_info; + } + + /** \internal */ + template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex> + void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const + { + eigen_assert(rows()==b.rows()); + + int rhsCols = b.cols(); + int size = b.rows(); + Eigen::Matrix<DestScalar,Dynamic,1> tb(size); + Eigen::Matrix<DestScalar,Dynamic,1> tx(size); + for(int k=0; k<rhsCols; ++k) + { + tb = b.col(k); + tx = derived().solve(tb); + dest.col(k) = tx.sparseView(0); + } + } + +protected: + void init() + { + m_isInitialized = false; + m_analysisIsOk = false; + m_factorizationIsOk = false; + m_maxIterations = -1; + m_tolerance = NumTraits<Scalar>::epsilon(); + } + const MatrixType* mp_matrix; + Preconditioner m_preconditioner; + + int m_maxIterations; + RealScalar m_tolerance; + + mutable RealScalar m_error; + mutable int m_iterations; + mutable ComputationInfo m_info; + mutable bool m_isInitialized, m_analysisIsOk, m_factorizationIsOk; +}; + +namespace internal { + +template<typename Derived, typename Rhs> +struct sparse_solve_retval<IterativeSolverBase<Derived>, Rhs> + : sparse_solve_retval_base<IterativeSolverBase<Derived>, Rhs> +{ + typedef IterativeSolverBase<Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec().derived()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_ITERATIVE_SOLVER_BASE_H diff --git a/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h b/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h index 98dea6800bc..a9c17dcdf19 100644 --- a/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h +++ b/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_JACOBI_H #define EIGEN_JACOBI_H +namespace Eigen { + /** \ingroup Jacobi_Module * \jacobi_module * \class JacobiRotation @@ -326,7 +313,7 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, // both vectors are sequentially stored in memory => vectorization enum { Peeling = 2 }; - Index alignedStart = first_aligned(y, size); + Index alignedStart = internal::first_aligned(y, size); Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize; const Packet pc = pset1<Packet>(j.c()); @@ -344,7 +331,7 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, Scalar* EIGEN_RESTRICT px = x + alignedStart; Scalar* EIGEN_RESTRICT py = y + alignedStart; - if(first_aligned(x, size)==alignedStart) + if(internal::first_aligned(x, size)==alignedStart) { for(Index i=alignedStart; i<alignedEnd; i+=PacketSize) { @@ -425,6 +412,9 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, } } } -} + +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_JACOBI_H diff --git a/extern/Eigen3/Eigen/src/LU/Determinant.h b/extern/Eigen3/Eigen/src/LU/Determinant.h index b4fe36eb061..d862c5d7784 100644 --- a/extern/Eigen3/Eigen/src/LU/Determinant.h +++ b/extern/Eigen3/Eigen/src/LU/Determinant.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DETERMINANT_H #define EIGEN_DETERMINANT_H +namespace Eigen { + namespace internal { template<typename Derived> @@ -109,4 +96,6 @@ inline typename internal::traits<Derived>::Scalar MatrixBase<Derived>::determina return internal::determinant_impl<typename internal::remove_all<Nested>::type>::run(derived()); } +} // end namespace Eigen + #endif // EIGEN_DETERMINANT_H diff --git a/extern/Eigen3/Eigen/src/LU/FullPivLU.h b/extern/Eigen3/Eigen/src/LU/FullPivLU.h index 46ae7d651c8..e23f96cdcf1 100644 --- a/extern/Eigen3/Eigen/src/LU/FullPivLU.h +++ b/extern/Eigen3/Eigen/src/LU/FullPivLU.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LU_H #define EIGEN_LU_H +namespace Eigen { + /** \ingroup LU_Module * * \class FullPivLU @@ -282,6 +269,7 @@ template<typename _MatrixType> class FullPivLU FullPivLU& setThreshold(Default_t) { m_usePrescribedThreshold = false; + return *this; } /** Returns the threshold that will be used by certain methods such as rank(). @@ -743,4 +731,6 @@ MatrixBase<Derived>::fullPivLu() const return FullPivLU<PlainObject>(eval()); } +} // end namespace Eigen + #endif // EIGEN_LU_H diff --git a/extern/Eigen3/Eigen/src/LU/Inverse.h b/extern/Eigen3/Eigen/src/LU/Inverse.h index 2d3e6d10529..39b8cdbc8dc 100644 --- a/extern/Eigen3/Eigen/src/LU/Inverse.h +++ b/extern/Eigen3/Eigen/src/LU/Inverse.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_INVERSE_H #define EIGEN_INVERSE_H +namespace Eigen { + namespace internal { /********************************** @@ -286,7 +273,7 @@ struct inverse_impl : public ReturnByValue<inverse_impl<MatrixType> > typedef typename MatrixType::Index Index; typedef typename internal::eval<MatrixType>::type MatrixTypeNested; typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; inverse_impl(const MatrixType& matrix) : m_matrix(matrix) @@ -404,4 +391,6 @@ inline void MatrixBase<Derived>::computeInverseWithCheck( computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold); } +} // end namespace Eigen + #endif // EIGEN_INVERSE_H diff --git a/extern/Eigen3/Eigen/src/LU/PartialPivLU.h b/extern/Eigen3/Eigen/src/LU/PartialPivLU.h index 09394b01f5b..c9ff9dd5a36 100644 --- a/extern/Eigen3/Eigen/src/LU/PartialPivLU.h +++ b/extern/Eigen3/Eigen/src/LU/PartialPivLU.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARTIALLU_H #define EIGEN_PARTIALLU_H +namespace Eigen { + /** \ingroup LU_Module * * \class PartialPivLU @@ -506,4 +493,6 @@ MatrixBase<Derived>::lu() const } #endif +} // end namespace Eigen + #endif // EIGEN_PARTIALLU_H diff --git a/extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h b/extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h new file mode 100644 index 00000000000..9035953c82f --- /dev/null +++ b/extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * LU decomposition with partial pivoting based on LAPACKE_?getrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_PARTIALLU_LAPACK_H +#define EIGEN_PARTIALLU_LAPACK_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +namespace internal { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_LU_PARTPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template<int StorageOrder> \ +struct partial_lu_impl<EIGTYPE, StorageOrder, lapack_int> \ +{ \ + /* \internal performs the LU decomposition in-place of the matrix represented */ \ + static lapack_int blocked_lu(lapack_int rows, lapack_int cols, EIGTYPE* lu_data, lapack_int luStride, lapack_int* row_transpositions, lapack_int& nb_transpositions, lapack_int maxBlockSize=256) \ + { \ + EIGEN_UNUSED_VARIABLE(maxBlockSize);\ + lapack_int matrix_order, first_zero_pivot; \ + lapack_int m, n, lda, *ipiv, info; \ + EIGTYPE* a; \ +/* Set up parameters for ?getrf */ \ + matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + lda = luStride; \ + a = lu_data; \ + ipiv = row_transpositions; \ + m = rows; \ + n = cols; \ + nb_transpositions = 0; \ +\ + info = LAPACKE_##MKLPREFIX##getrf( matrix_order, m, n, (MKLTYPE*)a, lda, ipiv ); \ +\ + for(int i=0;i<m;i++) { ipiv[i]--; if (ipiv[i]!=i) nb_transpositions++; } \ +\ + eigen_assert(info >= 0); \ +/* something should be done with nb_transpositions */ \ +\ + first_zero_pivot = info; \ + return first_zero_pivot; \ + } \ +}; + +EIGEN_MKL_LU_PARTPIV(double, double, d) +EIGEN_MKL_LU_PARTPIV(float, float, s) +EIGEN_MKL_LU_PARTPIV(dcomplex, MKL_Complex16, z) +EIGEN_MKL_LU_PARTPIV(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_PARTIALLU_LAPACK_H diff --git a/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h b/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h index 4c6153f0aff..60b7a23763e 100644 --- a/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h +++ b/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h @@ -5,24 +5,9 @@ // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // The SSE code for the 4x4 float and double matrix inverse in this file // comes from the following Intel's library: @@ -42,6 +27,8 @@ #ifndef EIGEN_INVERSE_SSE_H #define EIGEN_INVERSE_SSE_H +namespace Eigen { + namespace internal { template<typename MatrixType, typename ResultType> @@ -335,6 +322,8 @@ struct compute_inverse_size4<Architecture::SSE, double, MatrixType, ResultType> } }; -} +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_INVERSE_SSE_H diff --git a/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h b/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h new file mode 100644 index 00000000000..ce04852b872 --- /dev/null +++ b/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h @@ -0,0 +1,439 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* + +NOTE: this routine has been adapted from the CSparse library: + +Copyright (c) 2006, Timothy A. Davis. +http://www.cise.ufl.edu/research/sparse/CSparse + +CSparse is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +CSparse 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this Module; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "../Core/util/NonMPL2.h" + +#ifndef EIGEN_SPARSE_AMD_H +#define EIGEN_SPARSE_AMD_H + +namespace Eigen { + +namespace internal { + +template<typename T> inline T amd_flip(const T& i) { return -i-2; } +template<typename T> inline T amd_unflip(const T& i) { return i<0 ? amd_flip(i) : i; } +template<typename T0, typename T1> inline bool amd_marked(const T0* w, const T1& j) { return w[j]<0; } +template<typename T0, typename T1> inline void amd_mark(const T0* w, const T1& j) { return w[j] = amd_flip(w[j]); } + +/* clear w */ +template<typename Index> +static int cs_wclear (Index mark, Index lemax, Index *w, Index n) +{ + Index k; + if(mark < 2 || (mark + lemax < 0)) + { + for(k = 0; k < n; k++) + if(w[k] != 0) + w[k] = 1; + mark = 2; + } + return (mark); /* at this point, w[0..n-1] < mark holds */ +} + +/* depth-first search and postorder of a tree rooted at node j */ +template<typename Index> +Index cs_tdfs(Index j, Index k, Index *head, const Index *next, Index *post, Index *stack) +{ + int i, p, top = 0; + if(!head || !next || !post || !stack) return (-1); /* check inputs */ + stack[0] = j; /* place j on the stack */ + while (top >= 0) /* while (stack is not empty) */ + { + p = stack[top]; /* p = top of stack */ + i = head[p]; /* i = youngest child of p */ + if(i == -1) + { + top--; /* p has no unordered children left */ + post[k++] = p; /* node p is the kth postordered node */ + } + else + { + head[p] = next[i]; /* remove i from children of p */ + stack[++top] = i; /* start dfs on child node i */ + } + } + return k; +} + + +/** \internal + * Approximate minimum degree ordering algorithm. + * \returns the permutation P reducing the fill-in of the input matrix \a C + * The input matrix \a C must be a selfadjoint compressed column major SparseMatrix object. Both the upper and lower parts have to be stored, but the diagonal entries are optional. + * On exit the values of C are destroyed */ +template<typename Scalar, typename Index> +void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, PermutationMatrix<Dynamic,Dynamic,Index>& perm) +{ + using std::sqrt; + typedef SparseMatrix<Scalar,ColMajor,Index> CCS; + + int d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, + k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, + ok, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, t; + unsigned int h; + + Index n = C.cols(); + dense = std::max<Index> (16, Index(10 * sqrt(double(n)))); /* find dense threshold */ + dense = std::min<Index> (n-2, dense); + + Index cnz = C.nonZeros(); + perm.resize(n+1); + t = cnz + cnz/5 + 2*n; /* add elbow room to C */ + C.resizeNonZeros(t); + + Index* W = new Index[8*(n+1)]; /* get workspace */ + Index* len = W; + Index* nv = W + (n+1); + Index* next = W + 2*(n+1); + Index* head = W + 3*(n+1); + Index* elen = W + 4*(n+1); + Index* degree = W + 5*(n+1); + Index* w = W + 6*(n+1); + Index* hhead = W + 7*(n+1); + Index* last = perm.indices().data(); /* use P as workspace for last */ + + /* --- Initialize quotient graph ---------------------------------------- */ + Index* Cp = C.outerIndexPtr(); + Index* Ci = C.innerIndexPtr(); + for(k = 0; k < n; k++) + len[k] = Cp[k+1] - Cp[k]; + len[n] = 0; + nzmax = t; + + for(i = 0; i <= n; i++) + { + head[i] = -1; // degree list i is empty + last[i] = -1; + next[i] = -1; + hhead[i] = -1; // hash list i is empty + nv[i] = 1; // node i is just one node + w[i] = 1; // node i is alive + elen[i] = 0; // Ek of node i is empty + degree[i] = len[i]; // degree of node i + } + mark = internal::cs_wclear<Index>(0, 0, w, n); /* clear w */ + elen[n] = -2; /* n is a dead element */ + Cp[n] = -1; /* n is a root of assembly tree */ + w[n] = 0; /* n is a dead element */ + + /* --- Initialize degree lists ------------------------------------------ */ + for(i = 0; i < n; i++) + { + d = degree[i]; + if(d == 0) /* node i is empty */ + { + elen[i] = -2; /* element i is dead */ + nel++; + Cp[i] = -1; /* i is a root of assembly tree */ + w[i] = 0; + } + else if(d > dense) /* node i is dense */ + { + nv[i] = 0; /* absorb i into element n */ + elen[i] = -1; /* node i is dead */ + nel++; + Cp[i] = amd_flip (n); + nv[n]++; + } + else + { + if(head[d] != -1) last[head[d]] = i; + next[i] = head[d]; /* put node i in degree list d */ + head[d] = i; + } + } + + while (nel < n) /* while (selecting pivots) do */ + { + /* --- Select node of minimum approximate degree -------------------- */ + for(k = -1; mindeg < n && (k = head[mindeg]) == -1; mindeg++) {} + if(next[k] != -1) last[next[k]] = -1; + head[mindeg] = next[k]; /* remove k from degree list */ + elenk = elen[k]; /* elenk = |Ek| */ + nvk = nv[k]; /* # of nodes k represents */ + nel += nvk; /* nv[k] nodes of A eliminated */ + + /* --- Garbage collection ------------------------------------------- */ + if(elenk > 0 && cnz + mindeg >= nzmax) + { + for(j = 0; j < n; j++) + { + if((p = Cp[j]) >= 0) /* j is a live node or element */ + { + Cp[j] = Ci[p]; /* save first entry of object */ + Ci[p] = amd_flip (j); /* first entry is now amd_flip(j) */ + } + } + for(q = 0, p = 0; p < cnz; ) /* scan all of memory */ + { + if((j = amd_flip (Ci[p++])) >= 0) /* found object j */ + { + Ci[q] = Cp[j]; /* restore first entry of object */ + Cp[j] = q++; /* new pointer to object j */ + for(k3 = 0; k3 < len[j]-1; k3++) Ci[q++] = Ci[p++]; + } + } + cnz = q; /* Ci[cnz...nzmax-1] now free */ + } + + /* --- Construct new element ---------------------------------------- */ + dk = 0; + nv[k] = -nvk; /* flag k as in Lk */ + p = Cp[k]; + pk1 = (elenk == 0) ? p : cnz; /* do in place if elen[k] == 0 */ + pk2 = pk1; + for(k1 = 1; k1 <= elenk + 1; k1++) + { + if(k1 > elenk) + { + e = k; /* search the nodes in k */ + pj = p; /* list of nodes starts at Ci[pj]*/ + ln = len[k] - elenk; /* length of list of nodes in k */ + } + else + { + e = Ci[p++]; /* search the nodes in e */ + pj = Cp[e]; + ln = len[e]; /* length of list of nodes in e */ + } + for(k2 = 1; k2 <= ln; k2++) + { + i = Ci[pj++]; + if((nvi = nv[i]) <= 0) continue; /* node i dead, or seen */ + dk += nvi; /* degree[Lk] += size of node i */ + nv[i] = -nvi; /* negate nv[i] to denote i in Lk*/ + Ci[pk2++] = i; /* place i in Lk */ + if(next[i] != -1) last[next[i]] = last[i]; + if(last[i] != -1) /* remove i from degree list */ + { + next[last[i]] = next[i]; + } + else + { + head[degree[i]] = next[i]; + } + } + if(e != k) + { + Cp[e] = amd_flip (k); /* absorb e into k */ + w[e] = 0; /* e is now a dead element */ + } + } + if(elenk != 0) cnz = pk2; /* Ci[cnz...nzmax] is free */ + degree[k] = dk; /* external degree of k - |Lk\i| */ + Cp[k] = pk1; /* element k is in Ci[pk1..pk2-1] */ + len[k] = pk2 - pk1; + elen[k] = -2; /* k is now an element */ + + /* --- Find set differences ----------------------------------------- */ + mark = internal::cs_wclear<Index>(mark, lemax, w, n); /* clear w if necessary */ + for(pk = pk1; pk < pk2; pk++) /* scan 1: find |Le\Lk| */ + { + i = Ci[pk]; + if((eln = elen[i]) <= 0) continue;/* skip if elen[i] empty */ + nvi = -nv[i]; /* nv[i] was negated */ + wnvi = mark - nvi; + for(p = Cp[i]; p <= Cp[i] + eln - 1; p++) /* scan Ei */ + { + e = Ci[p]; + if(w[e] >= mark) + { + w[e] -= nvi; /* decrement |Le\Lk| */ + } + else if(w[e] != 0) /* ensure e is a live element */ + { + w[e] = degree[e] + wnvi; /* 1st time e seen in scan 1 */ + } + } + } + + /* --- Degree update ------------------------------------------------ */ + for(pk = pk1; pk < pk2; pk++) /* scan2: degree update */ + { + i = Ci[pk]; /* consider node i in Lk */ + p1 = Cp[i]; + p2 = p1 + elen[i] - 1; + pn = p1; + for(h = 0, d = 0, p = p1; p <= p2; p++) /* scan Ei */ + { + e = Ci[p]; + if(w[e] != 0) /* e is an unabsorbed element */ + { + dext = w[e] - mark; /* dext = |Le\Lk| */ + if(dext > 0) + { + d += dext; /* sum up the set differences */ + Ci[pn++] = e; /* keep e in Ei */ + h += e; /* compute the hash of node i */ + } + else + { + Cp[e] = amd_flip (k); /* aggressive absorb. e->k */ + w[e] = 0; /* e is a dead element */ + } + } + } + elen[i] = pn - p1 + 1; /* elen[i] = |Ei| */ + p3 = pn; + p4 = p1 + len[i]; + for(p = p2 + 1; p < p4; p++) /* prune edges in Ai */ + { + j = Ci[p]; + if((nvj = nv[j]) <= 0) continue; /* node j dead or in Lk */ + d += nvj; /* degree(i) += |j| */ + Ci[pn++] = j; /* place j in node list of i */ + h += j; /* compute hash for node i */ + } + if(d == 0) /* check for mass elimination */ + { + Cp[i] = amd_flip (k); /* absorb i into k */ + nvi = -nv[i]; + dk -= nvi; /* |Lk| -= |i| */ + nvk += nvi; /* |k| += nv[i] */ + nel += nvi; + nv[i] = 0; + elen[i] = -1; /* node i is dead */ + } + else + { + degree[i] = std::min<Index> (degree[i], d); /* update degree(i) */ + Ci[pn] = Ci[p3]; /* move first node to end */ + Ci[p3] = Ci[p1]; /* move 1st el. to end of Ei */ + Ci[p1] = k; /* add k as 1st element in of Ei */ + len[i] = pn - p1 + 1; /* new len of adj. list of node i */ + h %= n; /* finalize hash of i */ + next[i] = hhead[h]; /* place i in hash bucket */ + hhead[h] = i; + last[i] = h; /* save hash of i in last[i] */ + } + } /* scan2 is done */ + degree[k] = dk; /* finalize |Lk| */ + lemax = std::max<Index>(lemax, dk); + mark = internal::cs_wclear<Index>(mark+lemax, lemax, w, n); /* clear w */ + + /* --- Supernode detection ------------------------------------------ */ + for(pk = pk1; pk < pk2; pk++) + { + i = Ci[pk]; + if(nv[i] >= 0) continue; /* skip if i is dead */ + h = last[i]; /* scan hash bucket of node i */ + i = hhead[h]; + hhead[h] = -1; /* hash bucket will be empty */ + for(; i != -1 && next[i] != -1; i = next[i], mark++) + { + ln = len[i]; + eln = elen[i]; + for(p = Cp[i]+1; p <= Cp[i] + ln-1; p++) w[Ci[p]] = mark; + jlast = i; + for(j = next[i]; j != -1; ) /* compare i with all j */ + { + ok = (len[j] == ln) && (elen[j] == eln); + for(p = Cp[j] + 1; ok && p <= Cp[j] + ln - 1; p++) + { + if(w[Ci[p]] != mark) ok = 0; /* compare i and j*/ + } + if(ok) /* i and j are identical */ + { + Cp[j] = amd_flip (i); /* absorb j into i */ + nv[i] += nv[j]; + nv[j] = 0; + elen[j] = -1; /* node j is dead */ + j = next[j]; /* delete j from hash bucket */ + next[jlast] = j; + } + else + { + jlast = j; /* j and i are different */ + j = next[j]; + } + } + } + } + + /* --- Finalize new element------------------------------------------ */ + for(p = pk1, pk = pk1; pk < pk2; pk++) /* finalize Lk */ + { + i = Ci[pk]; + if((nvi = -nv[i]) <= 0) continue;/* skip if i is dead */ + nv[i] = nvi; /* restore nv[i] */ + d = degree[i] + dk - nvi; /* compute external degree(i) */ + d = std::min<Index> (d, n - nel - nvi); + if(head[d] != -1) last[head[d]] = i; + next[i] = head[d]; /* put i back in degree list */ + last[i] = -1; + head[d] = i; + mindeg = std::min<Index> (mindeg, d); /* find new minimum degree */ + degree[i] = d; + Ci[p++] = i; /* place i in Lk */ + } + nv[k] = nvk; /* # nodes absorbed into k */ + if((len[k] = p-pk1) == 0) /* length of adj list of element k*/ + { + Cp[k] = -1; /* k is a root of the tree */ + w[k] = 0; /* k is now a dead element */ + } + if(elenk != 0) cnz = p; /* free unused space in Lk */ + } + + /* --- Postordering ----------------------------------------------------- */ + for(i = 0; i < n; i++) Cp[i] = amd_flip (Cp[i]);/* fix assembly tree */ + for(j = 0; j <= n; j++) head[j] = -1; + for(j = n; j >= 0; j--) /* place unordered nodes in lists */ + { + if(nv[j] > 0) continue; /* skip if j is an element */ + next[j] = head[Cp[j]]; /* place j in list of its parent */ + head[Cp[j]] = j; + } + for(e = n; e >= 0; e--) /* place elements in lists */ + { + if(nv[e] <= 0) continue; /* skip unless e is an element */ + if(Cp[e] != -1) + { + next[e] = head[Cp[e]]; /* place e in list of its parent */ + head[Cp[e]] = e; + } + } + for(k = 0, i = 0; i <= n; i++) /* postorder the assembly tree */ + { + if(Cp[i] == -1) k = internal::cs_tdfs<Index>(i, k, head, next, perm.indices().data(), w); + } + + perm.indices().conservativeResize(n); + + delete[] W; +} + +} // namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_AMD_H diff --git a/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h b/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h new file mode 100644 index 00000000000..82e137c645a --- /dev/null +++ b/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h @@ -0,0 +1,742 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_PASTIXSUPPORT_H +#define EIGEN_PASTIXSUPPORT_H + +namespace Eigen { + +/** \ingroup PaStiXSupport_Module + * \brief Interface to the PaStix solver + * + * This class is used to solve the linear systems A.X = B via the PaStix library. + * The matrix can be either real or complex, symmetric or not. + * + * \sa TutorialSparseDirectSolvers + */ +template<typename _MatrixType, bool IsStrSym = false> class PastixLU; +template<typename _MatrixType, int Options> class PastixLLT; +template<typename _MatrixType, int Options> class PastixLDLT; + +namespace internal +{ + + template<class Pastix> struct pastix_traits; + + template<typename _MatrixType> + struct pastix_traits< PastixLU<_MatrixType> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template<typename _MatrixType, int Options> + struct pastix_traits< PastixLLT<_MatrixType,Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template<typename _MatrixType, int Options> + struct pastix_traits< PastixLDLT<_MatrixType,Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + s_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); + } + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + d_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); + } + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<float> *vals, int *perm, int * invp, std::complex<float> *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<COMPLEX*>(vals), perm, invp, reinterpret_cast<COMPLEX*>(x), nbrhs, iparm, dparm); + } + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<double> *vals, int *perm, int * invp, std::complex<double> *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + z_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<DCOMPLEX*>(vals), perm, invp, reinterpret_cast<DCOMPLEX*>(x), nbrhs, iparm, dparm); + } + + // Convert the matrix to Fortran-style Numbering + template <typename MatrixType> + void c_to_fortran_numbering (MatrixType& mat) + { + if ( !(mat.outerIndexPtr()[0]) ) + { + int i; + for(i = 0; i <= mat.rows(); ++i) + ++mat.outerIndexPtr()[i]; + for(i = 0; i < mat.nonZeros(); ++i) + ++mat.innerIndexPtr()[i]; + } + } + + // Convert to C-style Numbering + template <typename MatrixType> + void fortran_to_c_numbering (MatrixType& mat) + { + // Check the Numbering + if ( mat.outerIndexPtr()[0] == 1 ) + { // Convert to C-style numbering + int i; + for(i = 0; i <= mat.rows(); ++i) + --mat.outerIndexPtr()[i]; + for(i = 0; i < mat.nonZeros(); ++i) + --mat.innerIndexPtr()[i]; + } + } +} + +// This is the base class to interface with PaStiX functions. +// Users should not used this class directly. +template <class Derived> +class PastixBase : internal::noncopyable +{ + public: + typedef typename internal::pastix_traits<Derived>::MatrixType _MatrixType; + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix<Scalar,Dynamic,1> Vector; + typedef SparseMatrix<Scalar, ColMajor> ColSpMatrix; + + public: + + PastixBase() : m_initisOk(false), m_analysisIsOk(false), m_factorizationIsOk(false), m_isInitialized(false), m_pastixdata(0), m_size(0) + { + init(); + } + + ~PastixBase() + { + clean(); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::solve_retval<PastixBase, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "Pastix solver is not initialized."); + eigen_assert(rows()==b.rows() + && "PastixBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<PastixBase, Rhs>(*this, b.derived()); + } + + template<typename Rhs,typename Dest> + bool _solve (const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const; + + /** \internal */ + template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex> + void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(rows()==b.rows()); + + // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. + static const int NbColsAtOnce = 1; + int rhsCols = b.cols(); + int size = b.rows(); + Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols); + for(int k=0; k<rhsCols; k+=NbColsAtOnce) + { + int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce); + tmp.leftCols(actualCols) = b.middleCols(k,actualCols); + tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols)); + dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView(); + } + } + + Derived& derived() + { + return *static_cast<Derived*>(this); + } + const Derived& derived() const + { + return *static_cast<const Derived*>(this); + } + + /** Returns a reference to the integer vector IPARM of PaStiX parameters + * to modify the default parameters. + * The statistics related to the different phases of factorization and solve are saved here as well + * \sa analyzePattern() factorize() + */ + Array<Index,IPARM_SIZE,1>& iparm() + { + return m_iparm; + } + + /** Return a reference to a particular index parameter of the IPARM vector + * \sa iparm() + */ + + int& iparm(int idxparam) + { + return m_iparm(idxparam); + } + + /** Returns a reference to the double vector DPARM of PaStiX parameters + * The statistics related to the different phases of factorization and solve are saved here as well + * \sa analyzePattern() factorize() + */ + Array<RealScalar,IPARM_SIZE,1>& dparm() + { + return m_dparm; + } + + + /** Return a reference to a particular index parameter of the DPARM vector + * \sa dparm() + */ + double& dparm(int idxparam) + { + return m_dparm(idxparam); + } + + inline Index cols() const { return m_size; } + inline Index rows() const { return m_size; } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the PaStiX reports a problem + * \c InvalidInput if the input matrix is invalid + * + * \sa iparm() + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::sparse_solve_retval<PastixBase, Rhs> + solve(const SparseMatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "Pastix LU, LLT or LDLT is not initialized."); + eigen_assert(rows()==b.rows() + && "PastixBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval<PastixBase, Rhs>(*this, b.derived()); + } + + protected: + + // Initialize the Pastix data structure, check the matrix + void init(); + + // Compute the ordering and the symbolic factorization + void analyzePattern(ColSpMatrix& mat); + + // Compute the numerical factorization + void factorize(ColSpMatrix& mat); + + // Free all the data allocated by Pastix + void clean() + { + eigen_assert(m_initisOk && "The Pastix structure should be allocated first"); + m_iparm(IPARM_START_TASK) = API_TASK_CLEAN; + m_iparm(IPARM_END_TASK) = API_TASK_CLEAN; + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar*)0, + m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); + } + + void compute(ColSpMatrix& mat); + + int m_initisOk; + int m_analysisIsOk; + int m_factorizationIsOk; + bool m_isInitialized; + mutable ComputationInfo m_info; + mutable pastix_data_t *m_pastixdata; // Data structure for pastix + mutable int m_comm; // The MPI communicator identifier + mutable Matrix<int,IPARM_SIZE,1> m_iparm; // integer vector for the input parameters + mutable Matrix<double,DPARM_SIZE,1> m_dparm; // Scalar vector for the input parameters + mutable Matrix<Index,Dynamic,1> m_perm; // Permutation vector + mutable Matrix<Index,Dynamic,1> m_invp; // Inverse permutation vector + mutable int m_size; // Size of the matrix +}; + + /** Initialize the PaStiX data structure. + *A first call to this function fills iparm and dparm with the default PaStiX parameters + * \sa iparm() dparm() + */ +template <class Derived> +void PastixBase<Derived>::init() +{ + m_size = 0; + m_iparm.setZero(IPARM_SIZE); + m_dparm.setZero(DPARM_SIZE); + + m_iparm(IPARM_MODIFY_PARAMETER) = API_NO; + pastix(&m_pastixdata, MPI_COMM_WORLD, + 0, 0, 0, 0, + 0, 0, 0, 1, m_iparm.data(), m_dparm.data()); + + m_iparm[IPARM_MATRIX_VERIFICATION] = API_NO; + m_iparm[IPARM_VERBOSE] = 2; + m_iparm[IPARM_ORDERING] = API_ORDER_SCOTCH; + m_iparm[IPARM_INCOMPLETE] = API_NO; + m_iparm[IPARM_OOC_LIMIT] = 2000; + m_iparm[IPARM_RHS_MAKING] = API_RHS_B; + m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO; + + m_iparm(IPARM_START_TASK) = API_TASK_INIT; + m_iparm(IPARM_END_TASK) = API_TASK_INIT; + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar*)0, + 0, 0, 0, 0, m_iparm.data(), m_dparm.data()); + + // Check the returned error + if(m_iparm(IPARM_ERROR_NUMBER)) { + m_info = InvalidInput; + m_initisOk = false; + } + else { + m_info = Success; + m_initisOk = true; + } +} + +template <class Derived> +void PastixBase<Derived>::compute(ColSpMatrix& mat) +{ + eigen_assert(mat.rows() == mat.cols() && "The input matrix should be squared"); + + analyzePattern(mat); + factorize(mat); + + m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO; + m_isInitialized = m_factorizationIsOk; +} + + +template <class Derived> +void PastixBase<Derived>::analyzePattern(ColSpMatrix& mat) +{ + eigen_assert(m_initisOk && "The initialization of PaSTiX failed"); + + // clean previous calls + if(m_size>0) + clean(); + + m_size = mat.rows(); + m_perm.resize(m_size); + m_invp.resize(m_size); + + m_iparm(IPARM_START_TASK) = API_TASK_ORDERING; + m_iparm(IPARM_END_TASK) = API_TASK_ANALYSE; + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(), + mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); + + // Check the returned error + if(m_iparm(IPARM_ERROR_NUMBER)) + { + m_info = NumericalIssue; + m_analysisIsOk = false; + } + else + { + m_info = Success; + m_analysisIsOk = true; + } +} + +template <class Derived> +void PastixBase<Derived>::factorize(ColSpMatrix& mat) +{ +// if(&m_cpyMat != &mat) m_cpyMat = mat; + eigen_assert(m_analysisIsOk && "The analysis phase should be called before the factorization phase"); + m_iparm(IPARM_START_TASK) = API_TASK_NUMFACT; + m_iparm(IPARM_END_TASK) = API_TASK_NUMFACT; + m_size = mat.rows(); + + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(), + mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); + + // Check the returned error + if(m_iparm(IPARM_ERROR_NUMBER)) + { + m_info = NumericalIssue; + m_factorizationIsOk = false; + m_isInitialized = false; + } + else + { + m_info = Success; + m_factorizationIsOk = true; + m_isInitialized = true; + } +} + +/* Solve the system */ +template<typename Base> +template<typename Rhs,typename Dest> +bool PastixBase<Base>::_solve (const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const +{ + eigen_assert(m_isInitialized && "The matrix should be factorized first"); + EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0, + THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + int rhs = 1; + + x = b; /* on return, x is overwritten by the computed solution */ + + for (int i = 0; i < b.cols(); i++){ + m_iparm[IPARM_START_TASK] = API_TASK_SOLVE; + m_iparm[IPARM_END_TASK] = API_TASK_REFINE; + + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, x.rows(), 0, 0, 0, + m_perm.data(), m_invp.data(), &x(0, i), rhs, m_iparm.data(), m_dparm.data()); + } + + // Check the returned error + m_info = m_iparm(IPARM_ERROR_NUMBER)==0 ? Success : NumericalIssue; + + return m_iparm(IPARM_ERROR_NUMBER)==0; +} + +/** \ingroup PaStiXSupport_Module + * \class PastixLU + * \brief Sparse direct LU solver based on PaStiX library + * + * This class is used to solve the linear systems A.X = B with a supernodal LU + * factorization in the PaStiX library. The matrix A should be squared and nonsingular + * PaStiX requires that the matrix A has a symmetric structural pattern. + * This interface can symmetrize the input matrix otherwise. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam IsStrSym Indicates if the input matrix has a symmetric pattern, default is false + * NOTE : Note that if the analysis and factorization phase are called separately, + * the input matrix will be symmetrized at each call, hence it is advised to + * symmetrize the matrix in a end-user program and set \p IsStrSym to true + * + * \sa \ref TutorialSparseDirectSolvers + * + */ +template<typename _MatrixType, bool IsStrSym> +class PastixLU : public PastixBase< PastixLU<_MatrixType> > +{ + public: + typedef _MatrixType MatrixType; + typedef PastixBase<PastixLU<MatrixType> > Base; + typedef typename Base::ColSpMatrix ColSpMatrix; + typedef typename MatrixType::Index Index; + + public: + PastixLU() : Base() + { + init(); + } + + PastixLU(const MatrixType& matrix):Base() + { + init(); + compute(matrix); + } + /** Compute the LU supernodal factorization of \p matrix. + * iparm and dparm can be used to tune the PaStiX parameters. + * see the PaStiX user's manual + * \sa analyzePattern() factorize() + */ + void compute (const MatrixType& matrix) + { + m_structureIsUptodate = false; + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::compute(temp); + } + /** Compute the LU symbolic factorization of \p matrix using its sparsity pattern. + * Several ordering methods can be used at this step. See the PaStiX user's manual. + * The result of this operation can be used with successive matrices having the same pattern as \p matrix + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + m_structureIsUptodate = false; + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::analyzePattern(temp); + } + + /** Compute the LU supernodal factorization of \p matrix + * WARNING The matrix \p matrix should have the same structural pattern + * as the same used in the analysis phase. + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::factorize(temp); + } + protected: + + void init() + { + m_structureIsUptodate = false; + m_iparm(IPARM_SYM) = API_SYM_NO; + m_iparm(IPARM_FACTORIZATION) = API_FACT_LU; + } + + void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) + { + if(IsStrSym) + out = matrix; + else + { + if(!m_structureIsUptodate) + { + // update the transposed structure + m_transposedStructure = matrix.transpose(); + + // Set the elements of the matrix to zero + for (Index j=0; j<m_transposedStructure.outerSize(); ++j) + for(typename ColSpMatrix::InnerIterator it(m_transposedStructure, j); it; ++it) + it.valueRef() = 0.0; + + m_structureIsUptodate = true; + } + + out = m_transposedStructure + matrix; + } + internal::c_to_fortran_numbering(out); + } + + using Base::m_iparm; + using Base::m_dparm; + + ColSpMatrix m_transposedStructure; + bool m_structureIsUptodate; +}; + +/** \ingroup PaStiXSupport_Module + * \class PastixLLT + * \brief A sparse direct supernodal Cholesky (LLT) factorization and solver based on the PaStiX library + * + * This class is used to solve the linear systems A.X = B via a LL^T supernodal Cholesky factorization + * available in the PaStiX library. The matrix A should be symmetric and positive definite + * WARNING Selfadjoint complex matrices are not supported in the current version of PaStiX + * The vectors or matrices X and B can be either dense or sparse + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename _MatrixType, int _UpLo> +class PastixLLT : public PastixBase< PastixLLT<_MatrixType, _UpLo> > +{ + public: + typedef _MatrixType MatrixType; + typedef PastixBase<PastixLLT<MatrixType, _UpLo> > Base; + typedef typename Base::ColSpMatrix ColSpMatrix; + + public: + enum { UpLo = _UpLo }; + PastixLLT() : Base() + { + init(); + } + + PastixLLT(const MatrixType& matrix):Base() + { + init(); + compute(matrix); + } + + /** Compute the L factor of the LL^T supernodal factorization of \p matrix + * \sa analyzePattern() factorize() + */ + void compute (const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::compute(temp); + } + + /** Compute the LL^T symbolic factorization of \p matrix using its sparsity pattern + * The result of this operation can be used with successive matrices having the same pattern as \p matrix + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::analyzePattern(temp); + } + /** Compute the LL^T supernodal numerical factorization of \p matrix + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::factorize(temp); + } + protected: + using Base::m_iparm; + + void init() + { + m_iparm(IPARM_SYM) = API_SYM_YES; + m_iparm(IPARM_FACTORIZATION) = API_FACT_LLT; + } + + void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) + { + // Pastix supports only lower, column-major matrices + out.template selfadjointView<Lower>() = matrix.template selfadjointView<UpLo>(); + internal::c_to_fortran_numbering(out); + } +}; + +/** \ingroup PaStiXSupport_Module + * \class PastixLDLT + * \brief A sparse direct supernodal Cholesky (LLT) factorization and solver based on the PaStiX library + * + * This class is used to solve the linear systems A.X = B via a LDL^T supernodal Cholesky factorization + * available in the PaStiX library. The matrix A should be symmetric and positive definite + * WARNING Selfadjoint complex matrices are not supported in the current version of PaStiX + * The vectors or matrices X and B can be either dense or sparse + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename _MatrixType, int _UpLo> +class PastixLDLT : public PastixBase< PastixLDLT<_MatrixType, _UpLo> > +{ + public: + typedef _MatrixType MatrixType; + typedef PastixBase<PastixLDLT<MatrixType, _UpLo> > Base; + typedef typename Base::ColSpMatrix ColSpMatrix; + + public: + enum { UpLo = _UpLo }; + PastixLDLT():Base() + { + init(); + } + + PastixLDLT(const MatrixType& matrix):Base() + { + init(); + compute(matrix); + } + + /** Compute the L and D factors of the LDL^T factorization of \p matrix + * \sa analyzePattern() factorize() + */ + void compute (const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::compute(temp); + } + + /** Compute the LDL^T symbolic factorization of \p matrix using its sparsity pattern + * The result of this operation can be used with successive matrices having the same pattern as \p matrix + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::analyzePattern(temp); + } + /** Compute the LDL^T supernodal numerical factorization of \p matrix + * + */ + void factorize(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::factorize(temp); + } + + protected: + using Base::m_iparm; + + void init() + { + m_iparm(IPARM_SYM) = API_SYM_YES; + m_iparm(IPARM_FACTORIZATION) = API_FACT_LDLT; + } + + void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) + { + // Pastix supports only lower, column-major matrices + out.template selfadjointView<Lower>() = matrix.template selfadjointView<UpLo>(); + internal::c_to_fortran_numbering(out); + } +}; + +namespace internal { + +template<typename _MatrixType, typename Rhs> +struct solve_retval<PastixBase<_MatrixType>, Rhs> + : solve_retval_base<PastixBase<_MatrixType>, Rhs> +{ + typedef PastixBase<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template<typename _MatrixType, typename Rhs> +struct sparse_solve_retval<PastixBase<_MatrixType>, Rhs> + : sparse_solve_retval_base<PastixBase<_MatrixType>, Rhs> +{ + typedef PastixBase<_MatrixType> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif diff --git a/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h b/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h new file mode 100644 index 00000000000..e6defc8c39e --- /dev/null +++ b/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h @@ -0,0 +1,614 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL PARDISO + ******************************************************************************** +*/ + +#ifndef EIGEN_PARDISOSUPPORT_H +#define EIGEN_PARDISOSUPPORT_H + +namespace Eigen { + +template<typename _MatrixType> class PardisoLU; +template<typename _MatrixType, int Options=Upper> class PardisoLLT; +template<typename _MatrixType, int Options=Upper> class PardisoLDLT; + +namespace internal +{ + template<typename Index> + struct pardiso_run_selector + { + static Index run( _MKL_DSS_HANDLE_t pt, Index maxfct, Index mnum, Index type, Index phase, Index n, void *a, + Index *ia, Index *ja, Index *perm, Index nrhs, Index *iparm, Index msglvl, void *b, void *x) + { + Index error = 0; + ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error); + return error; + } + }; + template<> + struct pardiso_run_selector<long long int> + { + typedef long long int Index; + static Index run( _MKL_DSS_HANDLE_t pt, Index maxfct, Index mnum, Index type, Index phase, Index n, void *a, + Index *ia, Index *ja, Index *perm, Index nrhs, Index *iparm, Index msglvl, void *b, void *x) + { + Index error = 0; + ::pardiso_64(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error); + return error; + } + }; + + template<class Pardiso> struct pardiso_traits; + + template<typename _MatrixType> + struct pardiso_traits< PardisoLU<_MatrixType> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template<typename _MatrixType, int Options> + struct pardiso_traits< PardisoLLT<_MatrixType, Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template<typename _MatrixType, int Options> + struct pardiso_traits< PardisoLDLT<_MatrixType, Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + +} + +template<class Derived> +class PardisoImpl +{ + typedef internal::pardiso_traits<Derived> Traits; + public: + typedef typename Traits::MatrixType MatrixType; + typedef typename Traits::Scalar Scalar; + typedef typename Traits::RealScalar RealScalar; + typedef typename Traits::Index Index; + typedef SparseMatrix<Scalar,RowMajor,Index> SparseMatrixType; + typedef Matrix<Scalar,Dynamic,1> VectorType; + typedef Matrix<Index, 1, MatrixType::ColsAtCompileTime> IntRowVectorType; + typedef Matrix<Index, MatrixType::RowsAtCompileTime, 1> IntColVectorType; + enum { + ScalarIsComplex = NumTraits<Scalar>::IsComplex + }; + + PardisoImpl() + { + eigen_assert((sizeof(Index) >= sizeof(_INTEGER_t) && sizeof(Index) <= 8) && "Non-supported index type"); + m_iparm.setZero(); + m_msglvl = 0; // No output + m_initialized = false; + } + + ~PardisoImpl() + { + pardisoRelease(); + } + + inline Index cols() const { return m_size; } + inline Index rows() const { return m_size; } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_initialized && "Decomposition is not initialized."); + return m_info; + } + + /** \warning for advanced usage only. + * \returns a reference to the parameter array controlling PARDISO. + * See the PARDISO manual to know how to use it. */ + Array<Index,64,1>& pardisoParameterArray() + { + return m_iparm; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + Derived& analyzePattern(const MatrixType& matrix); + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + Derived& factorize(const MatrixType& matrix); + + Derived& compute(const MatrixType& matrix); + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::solve_retval<PardisoImpl, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_initialized && "Pardiso solver is not initialized."); + eigen_assert(rows()==b.rows() + && "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<PardisoImpl, Rhs>(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::sparse_solve_retval<PardisoImpl, Rhs> + solve(const SparseMatrixBase<Rhs>& b) const + { + eigen_assert(m_initialized && "Pardiso solver is not initialized."); + eigen_assert(rows()==b.rows() + && "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval<PardisoImpl, Rhs>(*this, b.derived()); + } + + Derived& derived() + { + return *static_cast<Derived*>(this); + } + const Derived& derived() const + { + return *static_cast<const Derived*>(this); + } + + template<typename BDerived, typename XDerived> + bool _solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>& x) const; + + /** \internal */ + template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex> + void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const + { + eigen_assert(m_size==b.rows()); + + // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. + static const int NbColsAtOnce = 4; + int rhsCols = b.cols(); + int size = b.rows(); + // Pardiso cannot solve in-place, + // so we need two temporaries + Eigen::Matrix<DestScalar,Dynamic,Dynamic,ColMajor> tmp_rhs(size,rhsCols); + Eigen::Matrix<DestScalar,Dynamic,Dynamic,ColMajor> tmp_res(size,rhsCols); + for(int k=0; k<rhsCols; k+=NbColsAtOnce) + { + int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce); + tmp_rhs.leftCols(actualCols) = b.middleCols(k,actualCols); + tmp_res.leftCols(actualCols) = derived().solve(tmp_rhs.leftCols(actualCols)); + dest.middleCols(k,actualCols) = tmp_res.leftCols(actualCols).sparseView(); + } + } + + protected: + void pardisoRelease() + { + if(m_initialized) // Factorization ran at least once + { + internal::pardiso_run_selector<Index>::run(m_pt, 1, 1, m_type, -1, m_size, 0, 0, 0, m_perm.data(), 0, + m_iparm.data(), m_msglvl, 0, 0); + } + } + + void pardisoInit(int type) + { + m_type = type; + bool symmetric = abs(m_type) < 10; + m_iparm[0] = 1; // No solver default + m_iparm[1] = 3; // use Metis for the ordering + m_iparm[2] = 1; // Numbers of processors, value of OMP_NUM_THREADS + m_iparm[3] = 0; // No iterative-direct algorithm + m_iparm[4] = 0; // No user fill-in reducing permutation + m_iparm[5] = 0; // Write solution into x + m_iparm[6] = 0; // Not in use + m_iparm[7] = 2; // Max numbers of iterative refinement steps + m_iparm[8] = 0; // Not in use + m_iparm[9] = 13; // Perturb the pivot elements with 1E-13 + m_iparm[10] = symmetric ? 0 : 1; // Use nonsymmetric permutation and scaling MPS + m_iparm[11] = 0; // Not in use + m_iparm[12] = symmetric ? 0 : 1; // Maximum weighted matching algorithm is switched-off (default for symmetric). + // Try m_iparm[12] = 1 in case of inappropriate accuracy + m_iparm[13] = 0; // Output: Number of perturbed pivots + m_iparm[14] = 0; // Not in use + m_iparm[15] = 0; // Not in use + m_iparm[16] = 0; // Not in use + m_iparm[17] = -1; // Output: Number of nonzeros in the factor LU + m_iparm[18] = -1; // Output: Mflops for LU factorization + m_iparm[19] = 0; // Output: Numbers of CG Iterations + + m_iparm[20] = 0; // 1x1 pivoting + m_iparm[26] = 0; // No matrix checker + m_iparm[27] = (sizeof(RealScalar) == 4) ? 1 : 0; + m_iparm[34] = 1; // C indexing + m_iparm[59] = 1; // Automatic switch between In-Core and Out-of-Core modes + } + + protected: + // cached data to reduce reallocation, etc. + + void manageErrorCode(Index error) + { + switch(error) + { + case 0: + m_info = Success; + break; + case -4: + case -7: + m_info = NumericalIssue; + break; + default: + m_info = InvalidInput; + } + } + + mutable SparseMatrixType m_matrix; + ComputationInfo m_info; + bool m_initialized, m_analysisIsOk, m_factorizationIsOk; + Index m_type, m_msglvl; + mutable void *m_pt[64]; + mutable Array<Index,64,1> m_iparm; + mutable IntColVectorType m_perm; + Index m_size; + + private: + PardisoImpl(PardisoImpl &) {} +}; + +template<class Derived> +Derived& PardisoImpl<Derived>::compute(const MatrixType& a) +{ + m_size = a.rows(); + eigen_assert(a.rows() == a.cols()); + + pardisoRelease(); + memset(m_pt, 0, sizeof(m_pt)); + m_perm.setZero(m_size); + derived().getMatrix(a); + + Index error; + error = internal::pardiso_run_selector<Index>::run(m_pt, 1, 1, m_type, 12, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); + + manageErrorCode(error); + m_analysisIsOk = true; + m_factorizationIsOk = true; + m_initialized = true; + return derived(); +} + +template<class Derived> +Derived& PardisoImpl<Derived>::analyzePattern(const MatrixType& a) +{ + m_size = a.rows(); + eigen_assert(m_size == a.cols()); + + pardisoRelease(); + memset(m_pt, 0, sizeof(m_pt)); + m_perm.setZero(m_size); + derived().getMatrix(a); + + Index error; + error = internal::pardiso_run_selector<Index>::run(m_pt, 1, 1, m_type, 11, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); + + manageErrorCode(error); + m_analysisIsOk = true; + m_factorizationIsOk = false; + m_initialized = true; + return derived(); +} + +template<class Derived> +Derived& PardisoImpl<Derived>::factorize(const MatrixType& a) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + eigen_assert(m_size == a.rows() && m_size == a.cols()); + + derived().getMatrix(a); + + Index error; + error = internal::pardiso_run_selector<Index>::run(m_pt, 1, 1, m_type, 22, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); + + manageErrorCode(error); + m_factorizationIsOk = true; + return derived(); +} + +template<class Base> +template<typename BDerived,typename XDerived> +bool PardisoImpl<Base>::_solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>& x) const +{ + if(m_iparm[0] == 0) // Factorization was not computed + return false; + + //Index n = m_matrix.rows(); + Index nrhs = Index(b.cols()); + eigen_assert(m_size==b.rows()); + eigen_assert(((MatrixBase<BDerived>::Flags & RowMajorBit) == 0 || nrhs == 1) && "Row-major right hand sides are not supported"); + eigen_assert(((MatrixBase<XDerived>::Flags & RowMajorBit) == 0 || nrhs == 1) && "Row-major matrices of unknowns are not supported"); + eigen_assert(((nrhs == 1) || b.outerStride() == b.rows())); + + +// switch (transposed) { +// case SvNoTrans : m_iparm[11] = 0 ; break; +// case SvTranspose : m_iparm[11] = 2 ; break; +// case SvAdjoint : m_iparm[11] = 1 ; break; +// default: +// //std::cerr << "Eigen: transposition option \"" << transposed << "\" not supported by the PARDISO backend\n"; +// m_iparm[11] = 0; +// } + + Scalar* rhs_ptr = const_cast<Scalar*>(b.derived().data()); + Matrix<Scalar,Dynamic,Dynamic,ColMajor> tmp; + + // Pardiso cannot solve in-place + if(rhs_ptr == x.derived().data()) + { + tmp = b; + rhs_ptr = tmp.data(); + } + + Index error; + error = internal::pardiso_run_selector<Index>::run(m_pt, 1, 1, m_type, 33, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), nrhs, m_iparm.data(), m_msglvl, + rhs_ptr, x.derived().data()); + + return error==0; +} + + +/** \ingroup PardisoSupport_Module + * \class PardisoLU + * \brief A sparse direct LU factorization and solver based on the PARDISO library + * + * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization + * using the Intel MKL PARDISO library. The sparse matrix A must be squared and invertible. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename MatrixType> +class PardisoLU : public PardisoImpl< PardisoLU<MatrixType> > +{ + protected: + typedef PardisoImpl< PardisoLU<MatrixType> > Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; + using Base::pardisoInit; + using Base::m_matrix; + friend class PardisoImpl< PardisoLU<MatrixType> >; + + public: + + using Base::compute; + using Base::solve; + + PardisoLU() + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 13 : 11); + } + + PardisoLU(const MatrixType& matrix) + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 13 : 11); + compute(matrix); + } + protected: + void getMatrix(const MatrixType& matrix) + { + m_matrix = matrix; + } + + private: + PardisoLU(PardisoLU& ) {} +}; + +/** \ingroup PardisoSupport_Module + * \class PardisoLLT + * \brief A sparse direct Cholesky (LLT) factorization and solver based on the PARDISO library + * + * This class allows to solve for A.X = B sparse linear problems via a LL^T Cholesky factorization + * using the Intel MKL PARDISO library. The sparse matrix A must be selfajoint and positive definite. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam UpLo can be any bitwise combination of Upper, Lower. The default is Upper, meaning only the upper triangular part has to be used. + * Upper|Lower can be used to tell both triangular parts can be used as input. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename MatrixType, int _UpLo> +class PardisoLLT : public PardisoImpl< PardisoLLT<MatrixType,_UpLo> > +{ + protected: + typedef PardisoImpl< PardisoLLT<MatrixType,_UpLo> > Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::Index Index; + typedef typename Base::RealScalar RealScalar; + using Base::pardisoInit; + using Base::m_matrix; + friend class PardisoImpl< PardisoLLT<MatrixType,_UpLo> >; + + public: + + enum { UpLo = _UpLo }; + using Base::compute; + using Base::solve; + + PardisoLLT() + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 4 : 2); + } + + PardisoLLT(const MatrixType& matrix) + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 4 : 2); + compute(matrix); + } + + protected: + + void getMatrix(const MatrixType& matrix) + { + // PARDISO supports only upper, row-major matrices + PermutationMatrix<Dynamic,Dynamic,Index> p_null; + m_matrix.resize(matrix.rows(), matrix.cols()); + m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null); + } + + private: + PardisoLLT(PardisoLLT& ) {} +}; + +/** \ingroup PardisoSupport_Module + * \class PardisoLDLT + * \brief A sparse direct Cholesky (LDLT) factorization and solver based on the PARDISO library + * + * This class allows to solve for A.X = B sparse linear problems via a LDL^T Cholesky factorization + * using the Intel MKL PARDISO library. The sparse matrix A is assumed to be selfajoint and positive definite. + * For complex matrices, A can also be symmetric only, see the \a Options template parameter. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam Options can be any bitwise combination of Upper, Lower, and Symmetric. The default is Upper, meaning only the upper triangular part has to be used. + * Symmetric can be used for symmetric, non-selfadjoint complex matrices, the default being to assume a selfadjoint matrix. + * Upper|Lower can be used to tell both triangular parts can be used as input. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename MatrixType, int Options> +class PardisoLDLT : public PardisoImpl< PardisoLDLT<MatrixType,Options> > +{ + protected: + typedef PardisoImpl< PardisoLDLT<MatrixType,Options> > Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::Index Index; + typedef typename Base::RealScalar RealScalar; + using Base::pardisoInit; + using Base::m_matrix; + friend class PardisoImpl< PardisoLDLT<MatrixType,Options> >; + + public: + + using Base::compute; + using Base::solve; + enum { UpLo = Options&(Upper|Lower) }; + + PardisoLDLT() + : Base() + { + pardisoInit(Base::ScalarIsComplex ? ( bool(Options&Symmetric) ? 6 : -4 ) : -2); + } + + PardisoLDLT(const MatrixType& matrix) + : Base() + { + pardisoInit(Base::ScalarIsComplex ? ( bool(Options&Symmetric) ? 6 : -4 ) : -2); + compute(matrix); + } + + void getMatrix(const MatrixType& matrix) + { + // PARDISO supports only upper, row-major matrices + PermutationMatrix<Dynamic,Dynamic,Index> p_null; + m_matrix.resize(matrix.rows(), matrix.cols()); + m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null); + } + + private: + PardisoLDLT(PardisoLDLT& ) {} +}; + +namespace internal { + +template<typename _Derived, typename Rhs> +struct solve_retval<PardisoImpl<_Derived>, Rhs> + : solve_retval_base<PardisoImpl<_Derived>, Rhs> +{ + typedef PardisoImpl<_Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template<typename Derived, typename Rhs> +struct sparse_solve_retval<PardisoImpl<Derived>, Rhs> + : sparse_solve_retval_base<PardisoImpl<Derived>, Rhs> +{ + typedef PardisoImpl<Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec().derived()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_PARDISOSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h index f04c6038d6a..2daa23cc354 100644 --- a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h +++ b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H +namespace Eigen { + /** \ingroup QR_Module * * \class ColPivHouseholderQR @@ -528,5 +515,6 @@ MatrixBase<Derived>::colPivHouseholderQr() const return ColPivHouseholderQR<PlainObject>(eval()); } +} // end namespace Eigen #endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_H diff --git a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h new file mode 100644 index 00000000000..745ecf8be98 --- /dev/null +++ b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Householder QR decomposition of a matrix with column pivoting based on + * LAPACKE_?geqp3 function. + ******************************************************************************** +*/ + +#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H +#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_QR_COLPIV(EIGTYPE, MKLTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \ +template<> inline\ +ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >& \ +ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >::compute( \ + const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix) \ +\ +{ \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ + Index rows = matrix.rows();\ + Index cols = matrix.cols();\ + Index size = matrix.diagonalSize();\ +\ + m_qr = matrix;\ + m_hCoeffs.resize(size);\ +\ + m_colsTranspositions.resize(cols);\ + /*Index number_of_transpositions = 0;*/ \ +\ + m_nonzero_pivots = 0; \ + m_maxpivot = RealScalar(0);\ + m_colsPermutation.resize(cols); \ + m_colsPermutation.indices().setZero(); \ +\ + lapack_int lda = m_qr.outerStride(), i; \ + lapack_int matrix_order = MKLCOLROW; \ + LAPACKE_##MKLPREFIX##geqp3( matrix_order, rows, cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \ + m_isInitialized = true; \ + m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \ + m_hCoeffs.adjointInPlace(); \ + RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold(); \ + lapack_int *perm = m_colsPermutation.indices().data(); \ + for(i=0;i<size;i++) { \ + m_nonzero_pivots += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);\ + } \ + for(i=0;i<cols;i++) perm[i]--;\ +\ + /*m_det_pq = (number_of_transpositions%2) ? -1 : 1; // TODO: It's not needed now; fix upon availability in Eigen */ \ +\ + return *this; \ +} + +EIGEN_MKL_QR_COLPIV(double, double, d, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_QR_COLPIV(float, float, s, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_QR_COLPIV(dcomplex, MKL_Complex16, z, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_QR_COLPIV(scomplex, MKL_Complex8, c, ColMajor, LAPACK_COL_MAJOR) + +EIGEN_MKL_QR_COLPIV(double, double, d, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_QR_COLPIV(float, float, s, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_QR_COLPIV(dcomplex, MKL_Complex16, z, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_QR_COLPIV(scomplex, MKL_Complex8, c, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H diff --git a/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h b/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h index dde3013be9d..37898e77cc2 100644 --- a/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h +++ b/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h @@ -4,28 +4,27 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H #define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H +namespace Eigen { + +namespace internal { + +template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType; + +template<typename MatrixType> +struct traits<FullPivHouseholderQRMatrixQReturnType<MatrixType> > +{ + typedef typename MatrixType::PlainObject ReturnType; +}; + +} + /** \ingroup QR_Module * * \class FullPivHouseholderQR @@ -62,7 +61,7 @@ template<typename _MatrixType> class FullPivHouseholderQR typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; - typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, Options, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType; + typedef internal::FullPivHouseholderQRMatrixQReturnType<MatrixType> MatrixQReturnType; typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType; typedef Matrix<Index, 1, ColsAtCompileTime, RowMajor, 1, MaxColsAtCompileTime> IntRowVectorType; typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType; @@ -139,7 +138,9 @@ template<typename _MatrixType> class FullPivHouseholderQR return internal::solve_retval<FullPivHouseholderQR, Rhs>(*this, b.derived()); } - MatrixQType matrixQ(void) const; + /** \returns Expression object representing the matrix Q + */ + MatrixQReturnType matrixQ(void) const; /** \returns a reference to the matrix where the Householder QR decomposition is stored */ @@ -508,28 +509,73 @@ struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs> } }; +/** \ingroup QR_Module + * + * \brief Expression type for return value of FullPivHouseholderQR::matrixQ() + * + * \tparam MatrixType type of underlying dense matrix + */ +template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType + : public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> > +{ +public: + typedef typename MatrixType::Index Index; + typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType; + typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType; + typedef Matrix<typename MatrixType::Scalar, 1, MatrixType::RowsAtCompileTime, RowMajor, 1, + MatrixType::MaxRowsAtCompileTime> WorkVectorType; + + FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr, + const HCoeffsType& hCoeffs, + const IntColVectorType& rowsTranspositions) + : m_qr(qr), + m_hCoeffs(hCoeffs), + m_rowsTranspositions(rowsTranspositions) + {} + + template <typename ResultType> + void evalTo(ResultType& result) const + { + const Index rows = m_qr.rows(); + WorkVectorType workspace(rows); + evalTo(result, workspace); + } + + template <typename ResultType> + void evalTo(ResultType& result, WorkVectorType& workspace) const + { + // compute the product H'_0 H'_1 ... H'_n-1, + // where H_k is the k-th Householder transformation I - h_k v_k v_k' + // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...] + const Index rows = m_qr.rows(); + const Index cols = m_qr.cols(); + const Index size = (std::min)(rows, cols); + workspace.resize(rows); + result.setIdentity(rows, rows); + for (Index k = size-1; k >= 0; k--) + { + result.block(k, k, rows-k, rows-k) + .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k)); + result.row(k).swap(result.row(m_rowsTranspositions.coeff(k))); + } + } + + Index rows() const { return m_qr.rows(); } + Index cols() const { return m_qr.rows(); } + +protected: + typename MatrixType::Nested m_qr; + typename HCoeffsType::Nested m_hCoeffs; + typename IntColVectorType::Nested m_rowsTranspositions; +}; + } // end namespace internal -/** \returns the matrix Q */ template<typename MatrixType> -typename FullPivHouseholderQR<MatrixType>::MatrixQType FullPivHouseholderQR<MatrixType>::matrixQ() const +inline typename FullPivHouseholderQR<MatrixType>::MatrixQReturnType FullPivHouseholderQR<MatrixType>::matrixQ() const { eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - // compute the product H'_0 H'_1 ... H'_n-1, - // where H_k is the k-th Householder transformation I - h_k v_k v_k' - // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...] - Index rows = m_qr.rows(); - Index cols = m_qr.cols(); - Index size = (std::min)(rows,cols); - MatrixQType res = MatrixQType::Identity(rows, rows); - Matrix<Scalar,1,MatrixType::RowsAtCompileTime> temp(rows); - for (Index k = size-1; k >= 0; k--) - { - res.block(k, k, rows-k, rows-k) - .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &temp.coeffRef(k)); - res.row(k).swap(res.row(m_rows_transpositions.coeff(k))); - } - return res; + return MatrixQReturnType(m_qr, m_hCoeffs, m_rows_transpositions); } /** \return the full-pivoting Householder QR decomposition of \c *this. @@ -543,4 +589,6 @@ MatrixBase<Derived>::fullPivHouseholderQr() const return FullPivHouseholderQR<PlainObject>(eval()); } +} // end namespace Eigen + #endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H diff --git a/extern/Eigen3/Eigen/src/QR/HouseholderQR.h b/extern/Eigen3/Eigen/src/QR/HouseholderQR.h index 9ee96de2680..5bcb32c1e18 100644 --- a/extern/Eigen3/Eigen/src/QR/HouseholderQR.h +++ b/extern/Eigen3/Eigen/src/QR/HouseholderQR.h @@ -5,28 +5,15 @@ // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2010 Vincent Lejeune // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_QR_H #define EIGEN_QR_H +namespace Eigen { + /** \ingroup QR_Module * * @@ -351,5 +338,6 @@ MatrixBase<Derived>::householderQr() const return HouseholderQR<PlainObject>(eval()); } +} // end namespace Eigen #endif // EIGEN_QR_H diff --git a/extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h b/extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h new file mode 100644 index 00000000000..5313de604d2 --- /dev/null +++ b/extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Householder QR decomposition of a matrix w/o pivoting based on + * LAPACKE_?geqrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_QR_MKL_H +#define EIGEN_QR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +namespace internal { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_QR_NOPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template<typename MatrixQR, typename HCoeffs> \ +void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs, \ + typename MatrixQR::Index maxBlockSize=32, \ + EIGTYPE* tempData = 0) \ +{ \ + lapack_int m = mat.rows(); \ + lapack_int n = mat.cols(); \ + lapack_int lda = mat.outerStride(); \ + lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \ + hCoeffs.adjointInPlace(); \ +\ +} + +EIGEN_MKL_QR_NOPIV(double, double, d) +EIGEN_MKL_QR_NOPIV(float, float, s) +EIGEN_MKL_QR_NOPIV(dcomplex, MKL_Complex16, z) +EIGEN_MKL_QR_NOPIV(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_QR_MKL_H diff --git a/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h b/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h index 3c423095c31..a7dbf073766 100644 --- a/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h +++ b/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_JACOBISVD_H #define EIGEN_JACOBISVD_H +namespace Eigen { + namespace internal { // forward declaration (needed by ICC) // the empty body is required by MSVC @@ -61,9 +48,12 @@ template<typename MatrixType, int QRPreconditioner, int Case, > struct qr_preconditioner_impl {}; template<typename MatrixType, int QRPreconditioner, int Case> -struct qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false> +class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false> { - static bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&) +public: + typedef typename MatrixType::Index Index; + void allocate(const JacobiSVD<MatrixType, QRPreconditioner>&) {} + bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&) { return false; } @@ -72,134 +62,279 @@ struct qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false> /*** preconditioner using FullPivHouseholderQR ***/ template<typename MatrixType> -struct qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> +class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> { - static bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime + }; + typedef Matrix<Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime> WorkspaceType; + + void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd) + { + if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) + { + m_qr = FullPivHouseholderQR<MatrixType>(svd.rows(), svd.cols()); + } + if (svd.m_computeFullU) m_workspace.resize(svd.rows()); + } + + bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) { if(matrix.rows() > matrix.cols()) { - FullPivHouseholderQR<MatrixType> qr(matrix); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); - if(svd.m_computeFullU) svd.m_matrixU = qr.matrixQ(); - if(svd.computeV()) svd.m_matrixV = qr.colsPermutation(); + m_qr.compute(matrix); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); + if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace); + if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); return true; } return false; } +private: + FullPivHouseholderQR<MatrixType> m_qr; + WorkspaceType m_workspace; }; template<typename MatrixType> -struct qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> +class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> { - static bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + Options = MatrixType::Options + }; + typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime> + TransposeTypeWithSameStorageOrder; + + void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd) + { + if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) + { + m_qr = FullPivHouseholderQR<TransposeTypeWithSameStorageOrder>(svd.cols(), svd.rows()); + } + m_adjoint.resize(svd.cols(), svd.rows()); + if (svd.m_computeFullV) m_workspace.resize(svd.cols()); + } + + bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) { if(matrix.cols() > matrix.rows()) { - typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, - MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> - TransposeTypeWithSameStorageOrder; - FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint()); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); - if(svd.m_computeFullV) svd.m_matrixV = qr.matrixQ(); - if(svd.computeU()) svd.m_matrixU = qr.colsPermutation(); + m_adjoint = matrix.adjoint(); + m_qr.compute(m_adjoint); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); + if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace); + if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); return true; } else return false; } +private: + FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> m_qr; + TransposeTypeWithSameStorageOrder m_adjoint; + typename internal::plain_row_type<MatrixType>::type m_workspace; }; /*** preconditioner using ColPivHouseholderQR ***/ template<typename MatrixType> -struct qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> +class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> { - static bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + + void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd) + { + if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) + { + m_qr = ColPivHouseholderQR<MatrixType>(svd.rows(), svd.cols()); + } + if (svd.m_computeFullU) m_workspace.resize(svd.rows()); + else if (svd.m_computeThinU) m_workspace.resize(svd.cols()); + } + + bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) { if(matrix.rows() > matrix.cols()) { - ColPivHouseholderQR<MatrixType> qr(matrix); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); - if(svd.m_computeFullU) svd.m_matrixU = qr.householderQ(); - else if(svd.m_computeThinU) { + m_qr.compute(matrix); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); + if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace); + else if(svd.m_computeThinU) + { svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace); } - if(svd.computeV()) svd.m_matrixV = qr.colsPermutation(); + if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); return true; } return false; } + +private: + ColPivHouseholderQR<MatrixType> m_qr; + typename internal::plain_col_type<MatrixType>::type m_workspace; }; template<typename MatrixType> -struct qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> +class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> { - static bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + Options = MatrixType::Options + }; + + typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime> + TransposeTypeWithSameStorageOrder; + + void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd) + { + if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) + { + m_qr = ColPivHouseholderQR<TransposeTypeWithSameStorageOrder>(svd.cols(), svd.rows()); + } + if (svd.m_computeFullV) m_workspace.resize(svd.cols()); + else if (svd.m_computeThinV) m_workspace.resize(svd.rows()); + m_adjoint.resize(svd.cols(), svd.rows()); + } + + bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) { if(matrix.cols() > matrix.rows()) { - typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, - MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> - TransposeTypeWithSameStorageOrder; - ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint()); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); - if(svd.m_computeFullV) svd.m_matrixV = qr.householderQ(); - else if(svd.m_computeThinV) { + m_adjoint = matrix.adjoint(); + m_qr.compute(m_adjoint); + + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); + if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace); + else if(svd.m_computeThinV) + { svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace); } - if(svd.computeU()) svd.m_matrixU = qr.colsPermutation(); + if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); return true; } else return false; } + +private: + ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> m_qr; + TransposeTypeWithSameStorageOrder m_adjoint; + typename internal::plain_row_type<MatrixType>::type m_workspace; }; /*** preconditioner using HouseholderQR ***/ template<typename MatrixType> -struct qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> +class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> { - static bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + + void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd) + { + if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) + { + m_qr = HouseholderQR<MatrixType>(svd.rows(), svd.cols()); + } + if (svd.m_computeFullU) m_workspace.resize(svd.rows()); + else if (svd.m_computeThinU) m_workspace.resize(svd.cols()); + } + + bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) { if(matrix.rows() > matrix.cols()) { - HouseholderQR<MatrixType> qr(matrix); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); - if(svd.m_computeFullU) svd.m_matrixU = qr.householderQ(); - else if(svd.m_computeThinU) { + m_qr.compute(matrix); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); + if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace); + else if(svd.m_computeThinU) + { svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace); } if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols()); return true; } return false; } +private: + HouseholderQR<MatrixType> m_qr; + typename internal::plain_col_type<MatrixType>::type m_workspace; }; template<typename MatrixType> -struct qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> +class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> { - static bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + Options = MatrixType::Options + }; + + typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime> + TransposeTypeWithSameStorageOrder; + + void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd) + { + if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) + { + m_qr = HouseholderQR<TransposeTypeWithSameStorageOrder>(svd.cols(), svd.rows()); + } + if (svd.m_computeFullV) m_workspace.resize(svd.cols()); + else if (svd.m_computeThinV) m_workspace.resize(svd.rows()); + m_adjoint.resize(svd.cols(), svd.rows()); + } + + bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) { if(matrix.cols() > matrix.rows()) { - typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, - MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> - TransposeTypeWithSameStorageOrder; - HouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint()); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); - if(svd.m_computeFullV) svd.m_matrixV = qr.householderQ(); - else if(svd.m_computeThinV) { + m_adjoint = matrix.adjoint(); + m_qr.compute(m_adjoint); + + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); + if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace); + else if(svd.m_computeThinV) + { svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace); } if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows()); return true; } else return false; } + +private: + HouseholderQR<TransposeTypeWithSameStorageOrder> m_qr; + TransposeTypeWithSameStorageOrder m_adjoint; + typename internal::plain_row_type<MatrixType>::type m_workspace; }; /*** 2x2 SVD implementation @@ -316,7 +451,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, * Here's an example demonstrating basic usage: * \include JacobiSVD_basic.cpp * Output: \verbinclude JacobiSVD_basic.out - * + * * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms. @@ -324,7 +459,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, * * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to * terminate in finite (and reasonable) time. - * + * * The possible values for QRPreconditioner are: * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR. * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR. @@ -494,7 +629,7 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD * \param b the right-hand-side of the equation to solve. * * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V. - * + * * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving. * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$. */ @@ -535,6 +670,9 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD friend struct internal::svd_precondition_2x2_block_to_be_real; template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything> friend struct internal::qr_preconditioner_impl; + + internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols; + internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows; }; template<typename MatrixType, int QRPreconditioner> @@ -578,6 +716,9 @@ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, u : m_computeThinV ? m_diagSize : 0); m_workMatrix.resize(m_diagSize, m_diagSize); + + if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this); + if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this); } template<typename MatrixType, int QRPreconditioner> @@ -595,8 +736,7 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */ - if(!internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows>::run(*this, matrix) - && !internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols>::run(*this, matrix)) + if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix)) { m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize); if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows); @@ -722,6 +862,6 @@ MatrixBase<Derived>::jacobiSvd(unsigned int computationOptions) const return JacobiSVD<PlainObject>(*this, computationOptions); } - +} // end namespace Eigen #endif // EIGEN_JACOBISVD_H diff --git a/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h b/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h new file mode 100644 index 00000000000..4d479f6b26e --- /dev/null +++ b/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + 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 Intel Corporation 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. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Singular Value Decomposition - SVD. + ******************************************************************************** +*/ + +#ifndef EIGEN_JACOBISVD_MKL_H +#define EIGEN_JACOBISVD_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_SVD(EIGTYPE, MKLTYPE, MKLRTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \ +template<> inline\ +JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPivHouseholderQRPreconditioner>& \ +JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPivHouseholderQRPreconditioner>::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix, unsigned int computationOptions) \ +{ \ + typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ + allocate(matrix.rows(), matrix.cols(), computationOptions); \ +\ + /*const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();*/ \ + m_nonzeroSingularValues = m_diagSize; \ +\ + lapack_int lda = matrix.outerStride(), ldu, ldvt; \ + lapack_int matrix_order = MKLCOLROW; \ + char jobu, jobvt; \ + MKLTYPE *u, *vt, dummy; \ + jobu = (m_computeFullU) ? 'A' : (m_computeThinU) ? 'S' : 'N'; \ + jobvt = (m_computeFullV) ? 'A' : (m_computeThinV) ? 'S' : 'N'; \ + if (computeU()) { \ + ldu = m_matrixU.outerStride(); \ + u = (MKLTYPE*)m_matrixU.data(); \ + } else { ldu=1; u=&dummy; }\ + MatrixType localV; \ + ldvt = (m_computeFullV) ? m_cols : (m_computeThinV) ? m_diagSize : 1; \ + if (computeV()) { \ + localV.resize(ldvt, m_cols); \ + vt = (MKLTYPE*)localV.data(); \ + } else { ldvt=1; vt=&dummy; }\ + Matrix<MKLRTYPE, Dynamic, Dynamic> superb; superb.resize(m_diagSize, 1); \ + MatrixType m_temp; m_temp = matrix; \ + LAPACKE_##MKLPREFIX##gesvd( matrix_order, jobu, jobvt, m_rows, m_cols, (MKLTYPE*)m_temp.data(), lda, (MKLRTYPE*)m_singularValues.data(), u, ldu, vt, ldvt, superb.data()); \ + if (computeV()) m_matrixV = localV.adjoint(); \ + /* for(int i=0;i<m_diagSize;i++) if (m_singularValues.coeffRef(i) < precision) { m_nonzeroSingularValues--; m_singularValues.coeffRef(i)=RealScalar(0);}*/ \ + m_isInitialized = true; \ + return *this; \ +} + +EIGEN_MKL_SVD(double, double, double, d, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SVD(float, float, float , s, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SVD(dcomplex, MKL_Complex16, double, z, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SVD(scomplex, MKL_Complex8, float , c, ColMajor, LAPACK_COL_MAJOR) + +EIGEN_MKL_SVD(double, double, double, d, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SVD(float, float, float , s, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SVD(dcomplex, MKL_Complex16, double, z, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SVD(scomplex, MKL_Complex8, float , c, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_JACOBISVD_MKL_H diff --git a/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h b/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h index 2de197da953..213b3100df5 100644 --- a/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h +++ b/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BIDIAGONALIZATION_H #define EIGEN_BIDIAGONALIZATION_H +namespace Eigen { + namespace internal { // UpperBidiagonalization will probably be replaced by a Bidiagonalization class, don't want to make it stable API. // At the same time, it's useful to keep for now as it's about the only thing that is testing the BandMatrix class. @@ -156,4 +143,6 @@ MatrixBase<Derived>::bidiagonalization() const } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_BIDIAGONALIZATION_H diff --git a/extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h b/extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h deleted file mode 100644 index 93e75f4c601..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h +++ /dev/null @@ -1,346 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H -#define EIGEN_DYNAMIC_SPARSEMATRIX_H - -/** \class DynamicSparseMatrix - * - * \brief A sparse matrix class designed for matrix assembly purpose - * - * \param _Scalar the scalar type, i.e. the type of the coefficients - * - * Unlike SparseMatrix, this class provides a much higher degree of flexibility. In particular, it allows - * random read/write accesses in log(rho*outer_size) where \c rho is the probability that a coefficient is - * nonzero and outer_size is the number of columns if the matrix is column-major and the number of rows - * otherwise. - * - * Internally, the data are stored as a std::vector of compressed vector. The performances of random writes might - * decrease as the number of nonzeros per inner-vector increase. In practice, we observed very good performance - * till about 100 nonzeros/vector, and the performance remains relatively good till 500 nonzeros/vectors. - * - * \see SparseMatrix - */ - -namespace internal { -template<typename _Scalar, int _Options, typename _Index> -struct traits<DynamicSparseMatrix<_Scalar, _Options, _Index> > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits<Scalar>::ReadCost, - SupportedAccessPatterns = OuterRandomAccessPattern - }; -}; -} - -template<typename _Scalar, int _Options, typename _Index> -class DynamicSparseMatrix - : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Options, _Index> > -{ - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(DynamicSparseMatrix) - // FIXME: why are these operator already alvailable ??? - // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=) - // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=) - typedef MappedSparseMatrix<Scalar,Flags> Map; - using Base::IsRowMajor; - using Base::operator=; - enum { - Options = _Options - }; - - protected: - - typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix; - - Index m_innerSize; - std::vector<CompressedStorage<Scalar,Index> > m_data; - - public: - - inline Index rows() const { return IsRowMajor ? outerSize() : m_innerSize; } - inline Index cols() const { return IsRowMajor ? m_innerSize : outerSize(); } - inline Index innerSize() const { return m_innerSize; } - inline Index outerSize() const { return static_cast<Index>(m_data.size()); } - inline Index innerNonZeros(Index j) const { return m_data[j].size(); } - - std::vector<CompressedStorage<Scalar,Index> >& _data() { return m_data; } - const std::vector<CompressedStorage<Scalar,Index> >& _data() const { return m_data; } - - /** \returns the coefficient value at given position \a row, \a col - * This operation involes a log(rho*outer_size) binary search. - */ - inline Scalar coeff(Index row, Index col) const - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data[outer].at(inner); - } - - /** \returns a reference to the coefficient value at given position \a row, \a col - * This operation involes a log(rho*outer_size) binary search. If the coefficient does not - * exist yet, then a sorted insertion into a sequential buffer is performed. - */ - inline Scalar& coeffRef(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data[outer].atWithInsertion(inner); - } - - class InnerIterator; - - void setZero() - { - for (Index j=0; j<outerSize(); ++j) - m_data[j].clear(); - } - - /** \returns the number of non zero coefficients */ - Index nonZeros() const - { - Index res = 0; - for (Index j=0; j<outerSize(); ++j) - res += static_cast<Index>(m_data[j].size()); - return res; - } - - - - void reserve(Index reserveSize = 1000) - { - if (outerSize()>0) - { - Index reserveSizePerVector = (std::max)(reserveSize/outerSize(),Index(4)); - for (Index j=0; j<outerSize(); ++j) - { - m_data[j].reserve(reserveSizePerVector); - } - } - } - - /** Does nothing: provided for compatibility with SparseMatrix */ - inline void startVec(Index /*outer*/) {} - - /** \returns a reference to the non zero coefficient at position \a row, \a col assuming that: - * - the nonzero does not already exist - * - the new coefficient is the last one of the given inner vector. - * - * \sa insert, insertBackByOuterInner */ - inline Scalar& insertBack(Index row, Index col) - { - return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); - } - - /** \sa insertBack */ - inline Scalar& insertBackByOuterInner(Index outer, Index inner) - { - eigen_assert(outer<Index(m_data.size()) && inner<m_innerSize && "out of range"); - eigen_assert(((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner)) - && "wrong sorted insertion"); - m_data[outer].append(0, inner); - return m_data[outer].value(m_data[outer].size()-1); - } - - inline Scalar& insert(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index startId = 0; - Index id = static_cast<Index>(m_data[outer].size()) - 1; - m_data[outer].resize(id+2,1); - - while ( (id >= startId) && (m_data[outer].index(id) > inner) ) - { - m_data[outer].index(id+1) = m_data[outer].index(id); - m_data[outer].value(id+1) = m_data[outer].value(id); - --id; - } - m_data[outer].index(id+1) = inner; - m_data[outer].value(id+1) = 0; - return m_data[outer].value(id+1); - } - - /** Does nothing: provided for compatibility with SparseMatrix */ - inline void finalize() {} - - /** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */ - void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) - { - for (Index j=0; j<outerSize(); ++j) - m_data[j].prune(reference,epsilon); - } - - /** Resize the matrix without preserving the data (the matrix is set to zero) - */ - void resize(Index rows, Index cols) - { - const Index outerSize = IsRowMajor ? rows : cols; - m_innerSize = IsRowMajor ? cols : rows; - setZero(); - if (Index(m_data.size()) != outerSize) - { - m_data.resize(outerSize); - } - } - - void resizeAndKeepData(Index rows, Index cols) - { - const Index outerSize = IsRowMajor ? rows : cols; - const Index innerSize = IsRowMajor ? cols : rows; - if (m_innerSize>innerSize) - { - // remove all coefficients with innerCoord>=innerSize - // TODO - //std::cerr << "not implemented yet\n"; - exit(2); - } - if (m_data.size() != outerSize) - { - m_data.resize(outerSize); - } - } - - inline DynamicSparseMatrix() - : m_innerSize(0), m_data(0) - { - eigen_assert(innerSize()==0 && outerSize()==0); - } - - inline DynamicSparseMatrix(Index rows, Index cols) - : m_innerSize(0) - { - resize(rows, cols); - } - - template<typename OtherDerived> - explicit inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other) - : m_innerSize(0) - { - Base::operator=(other.derived()); - } - - inline DynamicSparseMatrix(const DynamicSparseMatrix& other) - : Base(), m_innerSize(0) - { - *this = other.derived(); - } - - inline void swap(DynamicSparseMatrix& other) - { - //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); - std::swap(m_innerSize, other.m_innerSize); - //std::swap(m_outerSize, other.m_outerSize); - m_data.swap(other.m_data); - } - - inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other) - { - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else - { - resize(other.rows(), other.cols()); - m_data = other.m_data; - } - return *this; - } - - /** Destructor */ - inline ~DynamicSparseMatrix() {} - - public: - - /** \deprecated - * Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */ - EIGEN_DEPRECATED void startFill(Index reserveSize = 1000) - { - setZero(); - reserve(reserveSize); - } - - /** \deprecated use insert() - * inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that: - * 1 - the coefficient does not exist yet - * 2 - this the coefficient with greater inner coordinate for the given outer coordinate. - * In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates - * \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid. - * - * \see fillrand(), coeffRef() - */ - EIGEN_DEPRECATED Scalar& fill(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return insertBack(outer,inner); - } - - /** \deprecated use insert() - * Like fill() but with random inner coordinates. - * Compared to the generic coeffRef(), the unique limitation is that we assume - * the coefficient does not exist yet. - */ - EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col) - { - return insert(row,col); - } - - /** \deprecated use finalize() - * Does nothing. Provided for compatibility with SparseMatrix. */ - EIGEN_DEPRECATED void endFill() {} - -# ifdef EIGEN_DYNAMICSPARSEMATRIX_PLUGIN -# include EIGEN_DYNAMICSPARSEMATRIX_PLUGIN -# endif -}; - -template<typename Scalar, int _Options, typename _Index> -class DynamicSparseMatrix<Scalar,_Options,_Index>::InnerIterator : public SparseVector<Scalar,_Options>::InnerIterator -{ - typedef typename SparseVector<Scalar,_Options>::InnerIterator Base; - public: - InnerIterator(const DynamicSparseMatrix& mat, Index outer) - : Base(mat.m_data[outer]), m_outer(outer) - {} - - inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } - inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } - - protected: - const Index m_outer; -}; - -#endif // EIGEN_DYNAMIC_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h deleted file mode 100644 index aa068835fbb..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h +++ /dev/null @@ -1,146 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H -#define EIGEN_SPARSE_CWISE_UNARY_OP_H - -// template<typename UnaryOp, typename MatrixType> -// struct internal::traits<SparseCwiseUnaryOp<UnaryOp, MatrixType> > : internal::traits<MatrixType> -// { -// typedef typename internal::result_of< -// UnaryOp(typename MatrixType::Scalar) -// >::type Scalar; -// typedef typename MatrixType::Nested MatrixTypeNested; -// typedef typename internal::remove_reference<MatrixTypeNested>::type _MatrixTypeNested; -// enum { -// CoeffReadCost = _MatrixTypeNested::CoeffReadCost + internal::functor_traits<UnaryOp>::Cost -// }; -// }; - -template<typename UnaryOp, typename MatrixType> -class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse> - : public SparseMatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> > -{ - public: - - class InnerIterator; -// typedef typename internal::remove_reference<LhsNested>::type _LhsNested; - - typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) -}; - -template<typename UnaryOp, typename MatrixType> -class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator -{ - typedef typename CwiseUnaryOpImpl::Scalar Scalar; - typedef typename internal::traits<Derived>::_XprTypeNested _MatrixTypeNested; - typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; - typedef typename MatrixType::Index Index; - public: - - EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, Index outer) - : m_iter(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) - {} - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { ++m_iter; return *this; } - - EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_iter.value()); } - - EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_iter; } - - protected: - MatrixTypeIterator m_iter; - const UnaryOp m_functor; -}; - -template<typename ViewOp, typename MatrixType> -class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse> - : public SparseMatrixBase<CwiseUnaryView<ViewOp, MatrixType> > -{ - public: - - class InnerIterator; -// typedef typename internal::remove_reference<LhsNested>::type _LhsNested; - - typedef CwiseUnaryView<ViewOp, MatrixType> Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) -}; - -template<typename ViewOp, typename MatrixType> -class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator -{ - typedef typename CwiseUnaryViewImpl::Scalar Scalar; - typedef typename internal::traits<Derived>::_MatrixTypeNested _MatrixTypeNested; - typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; - typedef typename MatrixType::Index Index; - public: - - EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryView, Index outer) - : m_iter(unaryView.derived().nestedExpression(),outer), m_functor(unaryView.derived().functor()) - {} - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { ++m_iter; return *this; } - - EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_iter.value()); } - EIGEN_STRONG_INLINE Scalar& valueRef() { return m_functor(m_iter.valueRef()); } - - EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_iter; } - - protected: - MatrixTypeIterator m_iter; - const ViewOp m_functor; -}; - -template<typename Derived> -EIGEN_STRONG_INLINE Derived& -SparseMatrixBase<Derived>::operator*=(const Scalar& other) -{ - for (Index j=0; j<outerSize(); ++j) - for (typename Derived::InnerIterator i(derived(),j); i; ++i) - i.valueRef() *= other; - return derived(); -} - -template<typename Derived> -EIGEN_STRONG_INLINE Derived& -SparseMatrixBase<Derived>::operator/=(const Scalar& other) -{ - for (Index j=0; j<outerSize(); ++j) - for (typename Derived::InnerIterator i(derived(),j); i; ++i) - i.valueRef() /= other; - return derived(); -} - -#endif // EIGEN_SPARSE_CWISE_UNARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h b/extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h deleted file mode 100644 index f00b3d6469b..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h +++ /dev/null @@ -1,41 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_SPARSE_FUZZY_H -#define EIGEN_SPARSE_FUZZY_H - -// template<typename Derived> -// template<typename OtherDerived> -// bool SparseMatrixBase<Derived>::isApprox( -// const OtherDerived& other, -// typename NumTraits<Scalar>::Real prec -// ) const -// { -// const typename internal::nested<Derived,2>::type nested(derived()); -// const typename internal::nested<OtherDerived,2>::type otherNested(other.derived()); -// return (nested - otherNested).cwise().abs2().sum() -// <= prec * prec * (std::min)(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum()); -// } - -#endif // EIGEN_SPARSE_FUZZY_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h b/extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h deleted file mode 100644 index 0e175ec6e71..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h +++ /dev/null @@ -1,651 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_SPARSEMATRIX_H -#define EIGEN_SPARSEMATRIX_H - -/** \ingroup Sparse_Module - * - * \class SparseMatrix - * - * \brief The main sparse matrix class - * - * This class implements a sparse matrix using the very common compressed row/column storage - * scheme. - * - * \tparam _Scalar the scalar type, i.e. the type of the coefficients - * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility - * is RowMajor. The default is 0 which means column-major. - * \tparam _Index the type of the indices. Default is \c int. - * - * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN. - */ - -namespace internal { -template<typename _Scalar, int _Options, typename _Index> -struct traits<SparseMatrix<_Scalar, _Options, _Index> > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits<Scalar>::ReadCost, - SupportedAccessPatterns = InnerRandomAccessPattern - }; -}; - -} // end namespace internal - -template<typename _Scalar, int _Options, typename _Index> -class SparseMatrix - : public SparseMatrixBase<SparseMatrix<_Scalar, _Options, _Index> > -{ - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseMatrix) -// using Base::operator=; - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) - // FIXME: why are these operator already alvailable ??? - // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, *=) - // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, /=) - - typedef MappedSparseMatrix<Scalar,Flags> Map; - using Base::IsRowMajor; - typedef CompressedStorage<Scalar,Index> Storage; - enum { - Options = _Options - }; - - protected: - - typedef SparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix; - - Index m_outerSize; - Index m_innerSize; - Index* m_outerIndex; - CompressedStorage<Scalar,Index> m_data; - - public: - - inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } - inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } - - inline Index innerSize() const { return m_innerSize; } - inline Index outerSize() const { return m_outerSize; } - inline Index innerNonZeros(Index j) const { return m_outerIndex[j+1]-m_outerIndex[j]; } - - inline const Scalar* _valuePtr() const { return &m_data.value(0); } - inline Scalar* _valuePtr() { return &m_data.value(0); } - - inline const Index* _innerIndexPtr() const { return &m_data.index(0); } - inline Index* _innerIndexPtr() { return &m_data.index(0); } - - inline const Index* _outerIndexPtr() const { return m_outerIndex; } - inline Index* _outerIndexPtr() { return m_outerIndex; } - - inline Storage& data() { return m_data; } - inline const Storage& data() const { return m_data; } - - inline Scalar coeff(Index row, Index col) const - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data.atInRange(m_outerIndex[outer], m_outerIndex[outer+1], inner); - } - - inline Scalar& coeffRef(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index start = m_outerIndex[outer]; - Index end = m_outerIndex[outer+1]; - eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); - eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient"); - const Index p = m_data.searchLowerIndex(start,end-1,inner); - eigen_assert((p<end) && (m_data.index(p)==inner) && "coeffRef cannot be called on a zero coefficient"); - return m_data.value(p); - } - - public: - - class InnerIterator; - - /** Removes all non zeros */ - inline void setZero() - { - m_data.clear(); - memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); - } - - /** \returns the number of non zero coefficients */ - inline Index nonZeros() const { return static_cast<Index>(m_data.size()); } - - /** Preallocates \a reserveSize non zeros */ - inline void reserve(Index reserveSize) - { - m_data.reserve(reserveSize); - } - - //--- low level purely coherent filling --- - - /** \returns a reference to the non zero coefficient at position \a row, \a col assuming that: - * - the nonzero does not already exist - * - the new coefficient is the last one according to the storage order - * - * Before filling a given inner vector you must call the statVec(Index) function. - * - * After an insertion session, you should call the finalize() function. - * - * \sa insert, insertBackByOuterInner, startVec */ - inline Scalar& insertBack(Index row, Index col) - { - return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); - } - - /** \sa insertBack, startVec */ - inline Scalar& insertBackByOuterInner(Index outer, Index inner) - { - eigen_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)"); - eigen_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)<inner) && "Invalid ordered insertion (invalid inner index)"); - Index p = m_outerIndex[outer+1]; - ++m_outerIndex[outer+1]; - m_data.append(0, inner); - return m_data.value(p); - } - - /** \warning use it only if you know what you are doing */ - inline Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner) - { - Index p = m_outerIndex[outer+1]; - ++m_outerIndex[outer+1]; - m_data.append(0, inner); - return m_data.value(p); - } - - /** \sa insertBack, insertBackByOuterInner */ - inline void startVec(Index outer) - { - eigen_assert(m_outerIndex[outer]==int(m_data.size()) && "You must call startVec for each inner vector sequentially"); - eigen_assert(m_outerIndex[outer+1]==0 && "You must call startVec for each inner vector sequentially"); - m_outerIndex[outer+1] = m_outerIndex[outer]; - } - - //--- - - /** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col. - * The non zero coefficient must \b not already exist. - * - * \warning This function can be extremely slow if the non zero coefficients - * are not inserted in a coherent order. - * - * After an insertion session, you should call the finalize() function. - */ - EIGEN_DONT_INLINE Scalar& insert(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index previousOuter = outer; - if (m_outerIndex[outer+1]==0) - { - // we start a new inner vector - while (previousOuter>=0 && m_outerIndex[previousOuter]==0) - { - m_outerIndex[previousOuter] = static_cast<Index>(m_data.size()); - --previousOuter; - } - m_outerIndex[outer+1] = m_outerIndex[outer]; - } - - // here we have to handle the tricky case where the outerIndex array - // starts with: [ 0 0 0 0 0 1 ...] and we are inserting in, e.g., - // the 2nd inner vector... - bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) - && (size_t(m_outerIndex[outer+1]) == m_data.size()); - - size_t startId = m_outerIndex[outer]; - // FIXME let's make sure sizeof(long int) == sizeof(size_t) - size_t p = m_outerIndex[outer+1]; - ++m_outerIndex[outer+1]; - - float reallocRatio = 1; - if (m_data.allocatedSize()<=m_data.size()) - { - // if there is no preallocated memory, let's reserve a minimum of 32 elements - if (m_data.size()==0) - { - m_data.reserve(32); - } - else - { - // we need to reallocate the data, to reduce multiple reallocations - // we use a smart resize algorithm based on the current filling ratio - // in addition, we use float to avoid integers overflows - float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1); - reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size()); - // furthermore we bound the realloc ratio to: - // 1) reduce multiple minor realloc when the matrix is almost filled - // 2) avoid to allocate too much memory when the matrix is almost empty - reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f); - } - } - m_data.resize(m_data.size()+1,reallocRatio); - - if (!isLastVec) - { - if (previousOuter==-1) - { - // oops wrong guess. - // let's correct the outer offsets - for (Index k=0; k<=(outer+1); ++k) - m_outerIndex[k] = 0; - Index k=outer+1; - while(m_outerIndex[k]==0) - m_outerIndex[k++] = 1; - while (k<=m_outerSize && m_outerIndex[k]!=0) - m_outerIndex[k++]++; - p = 0; - --k; - k = m_outerIndex[k]-1; - while (k>0) - { - m_data.index(k) = m_data.index(k-1); - m_data.value(k) = m_data.value(k-1); - k--; - } - } - else - { - // we are not inserting into the last inner vec - // update outer indices: - Index j = outer+2; - while (j<=m_outerSize && m_outerIndex[j]!=0) - m_outerIndex[j++]++; - --j; - // shift data of last vecs: - Index k = m_outerIndex[j]-1; - while (k>=Index(p)) - { - m_data.index(k) = m_data.index(k-1); - m_data.value(k) = m_data.value(k-1); - k--; - } - } - } - - while ( (p > startId) && (m_data.index(p-1) > inner) ) - { - m_data.index(p) = m_data.index(p-1); - m_data.value(p) = m_data.value(p-1); - --p; - } - - m_data.index(p) = inner; - return (m_data.value(p) = 0); - } - - - - - /** Must be called after inserting a set of non zero entries. - */ - inline void finalize() - { - Index size = static_cast<Index>(m_data.size()); - Index i = m_outerSize; - // find the last filled column - while (i>=0 && m_outerIndex[i]==0) - --i; - ++i; - while (i<=m_outerSize) - { - m_outerIndex[i] = size; - ++i; - } - } - - /** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */ - void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) - { - prune(default_prunning_func(reference,epsilon)); - } - - /** Suppress all nonzeros which do not satisfy the predicate \a keep. - * The functor type \a KeepFunc must implement the following function: - * \code - * bool operator() (const Index& row, const Index& col, const Scalar& value) const; - * \endcode - * \sa prune(Scalar,RealScalar) - */ - template<typename KeepFunc> - void prune(const KeepFunc& keep = KeepFunc()) - { - Index k = 0; - for(Index j=0; j<m_outerSize; ++j) - { - Index previousStart = m_outerIndex[j]; - m_outerIndex[j] = k; - Index end = m_outerIndex[j+1]; - for(Index i=previousStart; i<end; ++i) - { - if(keep(IsRowMajor?j:m_data.index(i), IsRowMajor?m_data.index(i):j, m_data.value(i))) - { - m_data.value(k) = m_data.value(i); - m_data.index(k) = m_data.index(i); - ++k; - } - } - } - m_outerIndex[m_outerSize] = k; - m_data.resize(k,0); - } - - /** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero - * \sa resizeNonZeros(Index), reserve(), setZero() - */ - void resize(Index rows, Index cols) - { - const Index outerSize = IsRowMajor ? rows : cols; - m_innerSize = IsRowMajor ? cols : rows; - m_data.clear(); - if (m_outerSize != outerSize || m_outerSize==0) - { - delete[] m_outerIndex; - m_outerIndex = new Index [outerSize+1]; - m_outerSize = outerSize; - } - memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); - } - - /** Low level API - * Resize the nonzero vector to \a size */ - void resizeNonZeros(Index size) - { - m_data.resize(size); - } - - /** Default constructor yielding an empty \c 0 \c x \c 0 matrix */ - inline SparseMatrix() - : m_outerSize(-1), m_innerSize(0), m_outerIndex(0) - { - resize(0, 0); - } - - /** Constructs a \a rows \c x \a cols empty matrix */ - inline SparseMatrix(Index rows, Index cols) - : m_outerSize(0), m_innerSize(0), m_outerIndex(0) - { - resize(rows, cols); - } - - /** Constructs a sparse matrix from the sparse expression \a other */ - template<typename OtherDerived> - inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other) - : m_outerSize(0), m_innerSize(0), m_outerIndex(0) - { - *this = other.derived(); - } - - /** Copy constructor */ - inline SparseMatrix(const SparseMatrix& other) - : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0) - { - *this = other.derived(); - } - - /** Swap the content of two sparse matrices of same type (optimization) */ - inline void swap(SparseMatrix& other) - { - //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); - std::swap(m_outerIndex, other.m_outerIndex); - std::swap(m_innerSize, other.m_innerSize); - std::swap(m_outerSize, other.m_outerSize); - m_data.swap(other.m_data); - } - - inline SparseMatrix& operator=(const SparseMatrix& other) - { -// std::cout << "SparseMatrix& operator=(const SparseMatrix& other)\n"; - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else - { - resize(other.rows(), other.cols()); - memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); - m_data = other.m_data; - } - return *this; - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - template<typename Lhs, typename Rhs> - inline SparseMatrix& operator=(const SparseSparseProduct<Lhs,Rhs>& product) - { return Base::operator=(product); } - - template<typename OtherDerived> - inline SparseMatrix& operator=(const ReturnByValue<OtherDerived>& other) - { return Base::operator=(other); } - - template<typename OtherDerived> - inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other) - { return Base::operator=(other); } - #endif - - template<typename OtherDerived> - EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other) - { - const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - if (needToTranspose) - { - // two passes algorithm: - // 1 - compute the number of coeffs per dest inner vector - // 2 - do the actual copy/eval - // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed - typedef typename internal::nested<OtherDerived,2>::type OtherCopy; - typedef typename internal::remove_all<OtherCopy>::type _OtherCopy; - OtherCopy otherCopy(other.derived()); - - resize(other.rows(), other.cols()); - Eigen::Map<Matrix<Index, Dynamic, 1> > (m_outerIndex,outerSize()).setZero(); - // pass 1 - // FIXME the above copy could be merged with that pass - for (Index j=0; j<otherCopy.outerSize(); ++j) - for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) - ++m_outerIndex[it.index()]; - - // prefix sum - Index count = 0; - VectorXi positions(outerSize()); - for (Index j=0; j<outerSize(); ++j) - { - Index tmp = m_outerIndex[j]; - m_outerIndex[j] = count; - positions[j] = count; - count += tmp; - } - m_outerIndex[outerSize()] = count; - // alloc - m_data.resize(count); - // pass 2 - for (Index j=0; j<otherCopy.outerSize(); ++j) - { - for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) - { - Index pos = positions[it.index()]++; - m_data.index(pos) = j; - m_data.value(pos) = it.value(); - } - } - return *this; - } - else - { - // there is no special optimization - return SparseMatrixBase<SparseMatrix>::operator=(other.derived()); - } - } - - friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m) - { - EIGEN_DBG_SPARSE( - s << "Nonzero entries:\n"; - for (Index i=0; i<m.nonZeros(); ++i) - { - s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") "; - } - s << std::endl; - s << std::endl; - s << "Column pointers:\n"; - for (Index i=0; i<m.outerSize(); ++i) - { - s << m.m_outerIndex[i] << " "; - } - s << " $" << std::endl; - s << std::endl; - ); - s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m); - return s; - } - - /** Destructor */ - inline ~SparseMatrix() - { - delete[] m_outerIndex; - } - - /** Overloaded for performance */ - Scalar sum() const; - - public: - - /** \deprecated use setZero() and reserve() - * Initializes the filling process of \c *this. - * \param reserveSize approximate number of nonzeros - * Note that the matrix \c *this is zero-ed. - */ - EIGEN_DEPRECATED void startFill(Index reserveSize = 1000) - { - setZero(); - m_data.reserve(reserveSize); - } - - /** \deprecated use insert() - * Like fill() but with random inner coordinates. - */ - EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col) - { - return insert(row,col); - } - - /** \deprecated use insert() - */ - EIGEN_DEPRECATED Scalar& fill(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - if (m_outerIndex[outer+1]==0) - { - // we start a new inner vector - Index i = outer; - while (i>=0 && m_outerIndex[i]==0) - { - m_outerIndex[i] = m_data.size(); - --i; - } - m_outerIndex[outer+1] = m_outerIndex[outer]; - } - else - { - eigen_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion"); - } -// std::cerr << size_t(m_outerIndex[outer+1]) << " == " << m_data.size() << "\n"; - assert(size_t(m_outerIndex[outer+1]) == m_data.size()); - Index p = m_outerIndex[outer+1]; - ++m_outerIndex[outer+1]; - - m_data.append(0, inner); - return m_data.value(p); - } - - /** \deprecated use finalize */ - EIGEN_DEPRECATED void endFill() { finalize(); } - -# ifdef EIGEN_SPARSEMATRIX_PLUGIN -# include EIGEN_SPARSEMATRIX_PLUGIN -# endif - -private: - struct default_prunning_func { - default_prunning_func(Scalar ref, RealScalar eps) : reference(ref), epsilon(eps) {} - inline bool operator() (const Index&, const Index&, const Scalar& value) const - { - return !internal::isMuchSmallerThan(value, reference, epsilon); - } - Scalar reference; - RealScalar epsilon; - }; -}; - -template<typename Scalar, int _Options, typename _Index> -class SparseMatrix<Scalar,_Options,_Index>::InnerIterator -{ - public: - InnerIterator(const SparseMatrix& mat, Index outer) - : m_values(mat._valuePtr()), m_indices(mat._innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]), m_end(mat.m_outerIndex[outer+1]) - {} - - inline InnerIterator& operator++() { m_id++; return *this; } - - inline const Scalar& value() const { return m_values[m_id]; } - inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id]); } - - inline Index index() const { return m_indices[m_id]; } - inline Index outer() const { return m_outer; } - inline Index row() const { return IsRowMajor ? m_outer : index(); } - inline Index col() const { return IsRowMajor ? index() : m_outer; } - - inline operator bool() const { return (m_id < m_end); } - - protected: - const Scalar* m_values; - const Index* m_indices; - const Index m_outer; - Index m_id; - const Index m_end; -}; - -#endif // EIGEN_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h b/extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h deleted file mode 100644 index 19abcd1f8e4..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h +++ /dev/null @@ -1,401 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_SPARSESPARSEPRODUCT_H -#define EIGEN_SPARSESPARSEPRODUCT_H - -namespace internal { - -template<typename Lhs, typename Rhs, typename ResultType> -static void sparse_product_impl2(const Lhs& lhs, const Rhs& rhs, ResultType& res) -{ - typedef typename remove_all<Lhs>::type::Scalar Scalar; - typedef typename remove_all<Lhs>::type::Index Index; - - // make sure to call innerSize/outerSize since we fake the storage order. - Index rows = lhs.innerSize(); - Index cols = rhs.outerSize(); - eigen_assert(lhs.outerSize() == rhs.innerSize()); - - std::vector<bool> mask(rows,false); - Matrix<Scalar,Dynamic,1> values(rows); - Matrix<Index,Dynamic,1> indices(rows); - - // estimate the number of non zero entries - float ratioLhs = float(lhs.nonZeros())/(float(lhs.rows())*float(lhs.cols())); - float avgNnzPerRhsColumn = float(rhs.nonZeros())/float(cols); - float ratioRes = (std::min)(ratioLhs * avgNnzPerRhsColumn, 1.f); - -// int t200 = rows/(log2(200)*1.39); -// int t = (rows*100)/139; - - res.resize(rows, cols); - res.reserve(Index(ratioRes*rows*cols)); - // we compute each column of the result, one after the other - for (Index j=0; j<cols; ++j) - { - - res.startVec(j); - Index nnz = 0; - for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt) - { - Scalar y = rhsIt.value(); - Index k = rhsIt.index(); - for (typename Lhs::InnerIterator lhsIt(lhs, k); lhsIt; ++lhsIt) - { - Index i = lhsIt.index(); - Scalar x = lhsIt.value(); - if(!mask[i]) - { - mask[i] = true; -// values[i] = x * y; -// indices[nnz] = i; - ++nnz; - } - else - values[i] += x * y; - } - } - // FIXME reserve nnz non zeros - // FIXME implement fast sort algorithms for very small nnz - // if the result is sparse enough => use a quick sort - // otherwise => loop through the entire vector - // In order to avoid to perform an expensive log2 when the - // result is clearly very sparse we use a linear bound up to 200. -// if((nnz<200 && nnz<t200) || nnz * log2(nnz) < t) -// { -// if(nnz>1) std::sort(indices.data(),indices.data()+nnz); -// for(int k=0; k<nnz; ++k) -// { -// int i = indices[k]; -// res.insertBackNoCheck(j,i) = values[i]; -// mask[i] = false; -// } -// } -// else -// { -// // dense path -// for(int i=0; i<rows; ++i) -// { -// if(mask[i]) -// { -// mask[i] = false; -// res.insertBackNoCheck(j,i) = values[i]; -// } -// } -// } - - } - res.finalize(); -} - -// perform a pseudo in-place sparse * sparse product assuming all matrices are col major -template<typename Lhs, typename Rhs, typename ResultType> -static void sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) -{ -// return sparse_product_impl2(lhs,rhs,res); - - typedef typename remove_all<Lhs>::type::Scalar Scalar; - typedef typename remove_all<Lhs>::type::Index Index; - - // make sure to call innerSize/outerSize since we fake the storage order. - Index rows = lhs.innerSize(); - Index cols = rhs.outerSize(); - //int size = lhs.outerSize(); - eigen_assert(lhs.outerSize() == rhs.innerSize()); - - // allocate a temporary buffer - AmbiVector<Scalar,Index> tempVector(rows); - - // estimate the number of non zero entries - float ratioLhs = float(lhs.nonZeros())/(float(lhs.rows())*float(lhs.cols())); - float avgNnzPerRhsColumn = float(rhs.nonZeros())/float(cols); - float ratioRes = (std::min)(ratioLhs * avgNnzPerRhsColumn, 1.f); - - // mimics a resizeByInnerOuter: - if(ResultType::IsRowMajor) - res.resize(cols, rows); - else - res.resize(rows, cols); - - res.reserve(Index(ratioRes*rows*cols)); - for (Index j=0; j<cols; ++j) - { - // let's do a more accurate determination of the nnz ratio for the current column j of res - //float ratioColRes = (std::min)(ratioLhs * rhs.innerNonZeros(j), 1.f); - // FIXME find a nice way to get the number of nonzeros of a sub matrix (here an inner vector) - float ratioColRes = ratioRes; - tempVector.init(ratioColRes); - tempVector.setZero(); - for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt) - { - // FIXME should be written like this: tmp += rhsIt.value() * lhs.col(rhsIt.index()) - tempVector.restart(); - Scalar x = rhsIt.value(); - for (typename Lhs::InnerIterator lhsIt(lhs, rhsIt.index()); lhsIt; ++lhsIt) - { - tempVector.coeffRef(lhsIt.index()) += lhsIt.value() * x; - } - } - res.startVec(j); - for (typename AmbiVector<Scalar,Index>::Iterator it(tempVector); it; ++it) - res.insertBackByOuterInner(j,it.index()) = it.value(); - } - res.finalize(); -} - -template<typename Lhs, typename Rhs, typename ResultType, - int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit, - int RhsStorageOrder = traits<Rhs>::Flags&RowMajorBit, - int ResStorageOrder = traits<ResultType>::Flags&RowMajorBit> -struct sparse_product_selector; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor> -{ - typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << __LINE__ << "\n"; - typename remove_all<ResultType>::type _res(res.rows(), res.cols()); - sparse_product_impl<Lhs,Rhs,ResultType>(lhs, rhs, _res); - res.swap(_res); - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << __LINE__ << "\n"; - // we need a col-major matrix to hold the result - typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType; - SparseTemporaryType _res(res.rows(), res.cols()); - sparse_product_impl<Lhs,Rhs,SparseTemporaryType>(lhs, rhs, _res); - res = _res; - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << __LINE__ << "\n"; - // let's transpose the product to get a column x column product - typename remove_all<ResultType>::type _res(res.rows(), res.cols()); - sparse_product_impl<Rhs,Lhs,ResultType>(rhs, lhs, _res); - res.swap(_res); - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << "here...\n"; - typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; - ColMajorMatrix colLhs(lhs); - ColMajorMatrix colRhs(rhs); -// std::cerr << "more...\n"; - sparse_product_impl<ColMajorMatrix,ColMajorMatrix,ResultType>(colLhs, colRhs, res); -// std::cerr << "OK.\n"; - - // let's transpose the product to get a column x column product - -// typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType; -// SparseTemporaryType _res(res.cols(), res.rows()); -// sparse_product_impl<Rhs,Lhs,SparseTemporaryType>(rhs, lhs, _res); -// res = _res.transpose(); - } -}; - -// NOTE the 2 others cases (col row *) must never occur since they are caught -// by ProductReturnType which transforms it to (col col *) by evaluating rhs. - -} // end namespace internal - -// sparse = sparse * sparse -template<typename Derived> -template<typename Lhs, typename Rhs> -inline Derived& SparseMatrixBase<Derived>::operator=(const SparseSparseProduct<Lhs,Rhs>& product) -{ -// std::cerr << "there..." << typeid(Lhs).name() << " " << typeid(Lhs).name() << " " << (Derived::Flags&&RowMajorBit) << "\n"; - internal::sparse_product_selector< - typename internal::remove_all<Lhs>::type, - typename internal::remove_all<Rhs>::type, - Derived>::run(product.lhs(),product.rhs(),derived()); - return derived(); -} - -namespace internal { - -template<typename Lhs, typename Rhs, typename ResultType, - int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit, - int RhsStorageOrder = traits<Rhs>::Flags&RowMajorBit, - int ResStorageOrder = traits<ResultType>::Flags&RowMajorBit> -struct sparse_product_selector2; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor> -{ - typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - sparse_product_impl2<Lhs,Rhs,ResultType>(lhs, rhs, res); - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,RowMajor,ColMajor,ColMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - // prevent warnings until the code is fixed - EIGEN_UNUSED_VARIABLE(lhs); - EIGEN_UNUSED_VARIABLE(rhs); - EIGEN_UNUSED_VARIABLE(res); - -// typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; -// RowMajorMatrix rhsRow = rhs; -// RowMajorMatrix resRow(res.rows(), res.cols()); -// sparse_product_impl2<RowMajorMatrix,Lhs,RowMajorMatrix>(rhsRow, lhs, resRow); -// res = resRow; - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,ColMajor,RowMajor,ColMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; - RowMajorMatrix lhsRow = lhs; - RowMajorMatrix resRow(res.rows(), res.cols()); - sparse_product_impl2<Rhs,RowMajorMatrix,RowMajorMatrix>(rhs, lhsRow, resRow); - res = resRow; - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; - RowMajorMatrix resRow(res.rows(), res.cols()); - sparse_product_impl2<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow); - res = resRow; - } -}; - - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor> -{ - typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol); - res = resCol; - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,RowMajor,ColMajor,RowMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; - ColMajorMatrix lhsCol = lhs; - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2<ColMajorMatrix,Rhs,ColMajorMatrix>(lhsCol, rhs, resCol); - res = resCol; - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,ColMajor,RowMajor,RowMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; - ColMajorMatrix rhsCol = rhs; - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2<Lhs,ColMajorMatrix,ColMajorMatrix>(lhs, rhsCol, resCol); - res = resCol; - } -}; - -template<typename Lhs, typename Rhs, typename ResultType> -struct sparse_product_selector2<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor> -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; -// ColMajorMatrix lhsTr(lhs); -// ColMajorMatrix rhsTr(rhs); -// ColMajorMatrix aux(res.rows(), res.cols()); -// sparse_product_impl2<Rhs,Lhs,ColMajorMatrix>(rhs, lhs, aux); -// // ColMajorMatrix aux2 = aux.transpose(); -// res = aux; - typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; - ColMajorMatrix lhsCol(lhs); - ColMajorMatrix rhsCol(rhs); - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2<ColMajorMatrix,ColMajorMatrix,ColMajorMatrix>(lhsCol, rhsCol, resCol); - res = resCol; - } -}; - -} // end namespace internal - -template<typename Derived> -template<typename Lhs, typename Rhs> -inline void SparseMatrixBase<Derived>::_experimentalNewProduct(const Lhs& lhs, const Rhs& rhs) -{ - //derived().resize(lhs.rows(), rhs.cols()); - internal::sparse_product_selector2< - typename internal::remove_all<Lhs>::type, - typename internal::remove_all<Rhs>::type, - Derived>::run(lhs,rhs,derived()); -} - -// sparse * sparse -template<typename Derived> -template<typename OtherDerived> -inline const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type -SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const -{ - return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); -} - -#endif // EIGEN_SPARSESPARSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h b/extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h deleted file mode 100644 index 319eaf06638..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h +++ /dev/null @@ -1,100 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. - -#ifndef EIGEN_SPARSE_TRIANGULARVIEW_H -#define EIGEN_SPARSE_TRIANGULARVIEW_H - -namespace internal { - -template<typename MatrixType, int Mode> -struct traits<SparseTriangularView<MatrixType,Mode> > -: public traits<MatrixType> -{}; - -} // namespace internal - -template<typename MatrixType, int Mode> class SparseTriangularView - : public SparseMatrixBase<SparseTriangularView<MatrixType,Mode> > -{ - enum { SkipFirst = (Mode==Lower && !(MatrixType::Flags&RowMajorBit)) - || (Mode==Upper && (MatrixType::Flags&RowMajorBit)) }; - public: - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView) - - class InnerIterator; - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - typedef typename internal::conditional<internal::must_nest_by_value<MatrixType>::ret, - MatrixType, const MatrixType&>::type MatrixTypeNested; - - inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const MatrixType& nestedExpression() const { return m_matrix; } - - template<typename OtherDerived> - typename internal::plain_matrix_type_column_major<OtherDerived>::type - solve(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const; - template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const; - - protected: - MatrixTypeNested m_matrix; -}; - -template<typename MatrixType, int Mode> -class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixType::InnerIterator -{ - typedef typename MatrixType::InnerIterator Base; - public: - - EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer) - : Base(view.nestedExpression(), outer) - { - if(SkipFirst) - while((*this) && this->index()<outer) - ++(*this); - } - inline Index row() const { return Base::row(); } - inline Index col() const { return Base::col(); } - - EIGEN_STRONG_INLINE operator bool() const - { - return SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() <= this->outer()); - } -}; - -template<typename Derived> -template<int Mode> -inline const SparseTriangularView<Derived, Mode> -SparseMatrixBase<Derived>::triangularView() const -{ - return derived(); -} - -#endif // EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h new file mode 100644 index 00000000000..9bf38ab2d91 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -0,0 +1,873 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* + +NOTE: the _symbolic, and _numeric functions has been adapted from + the LDL library: + +LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved. + +LDL License: + + Your use or distribution of LDL or any modified version of + LDL implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + */ + +#include "../Core/util/NonMPL2.h" + +#ifndef EIGEN_SIMPLICIAL_CHOLESKY_H +#define EIGEN_SIMPLICIAL_CHOLESKY_H + +namespace Eigen { + +enum SimplicialCholeskyMode { + SimplicialCholeskyLLT, + SimplicialCholeskyLDLT +}; + +/** \ingroup SparseCholesky_Module + * \brief A direct sparse Cholesky factorizations + * + * These classes provide LL^T and LDL^T Cholesky factorizations of sparse matrices that are + * selfadjoint and positive definite. The factorization allows for solving A.X = B where + * X and B can be either dense or sparse. + * + * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization + * such that the factorized matrix is P A P^-1. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + */ +template<typename Derived> +class SimplicialCholeskyBase : internal::noncopyable +{ + public: + typedef typename internal::traits<Derived>::MatrixType MatrixType; + enum { UpLo = internal::traits<Derived>::UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType; + typedef Matrix<Scalar,Dynamic,1> VectorType; + + public: + + /** Default constructor */ + SimplicialCholeskyBase() + : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1) + {} + + SimplicialCholeskyBase(const MatrixType& matrix) + : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1) + { + derived().compute(matrix); + } + + ~SimplicialCholeskyBase() + { + } + + Derived& derived() { return *static_cast<Derived*>(this); } + const Derived& derived() const { return *static_cast<const Derived*>(this); } + + inline Index cols() const { return m_matrix.cols(); } + inline Index rows() const { return m_matrix.rows(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::solve_retval<SimplicialCholeskyBase, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized."); + eigen_assert(rows()==b.rows() + && "SimplicialCholeskyBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<SimplicialCholeskyBase, Rhs>(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::sparse_solve_retval<SimplicialCholeskyBase, Rhs> + solve(const SparseMatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized."); + eigen_assert(rows()==b.rows() + && "SimplicialCholesky::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval<SimplicialCholeskyBase, Rhs>(*this, b.derived()); + } + + /** \returns the permutation P + * \sa permutationPinv() */ + const PermutationMatrix<Dynamic,Dynamic,Index>& permutationP() const + { return m_P; } + + /** \returns the inverse P^-1 of the permutation P + * \sa permutationP() */ + const PermutationMatrix<Dynamic,Dynamic,Index>& permutationPinv() const + { return m_Pinv; } + + /** Sets the shift parameters that will be used to adjust the diagonal coefficients during the numerical factorization. + * + * During the numerical factorization, the diagonal coefficients are transformed by the following linear model:\n + * \c d_ii = \a offset + \a scale * \c d_ii + * + * The default is the identity transformation with \a offset=0, and \a scale=1. + * + * \returns a reference to \c *this. + */ + Derived& setShift(const RealScalar& offset, const RealScalar& scale = 1) + { + m_shiftOffset = offset; + m_shiftScale = scale; + return derived(); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template<typename Stream> + void dumpMemory(Stream& s) + { + int total = 0; + s << " L: " << ((total+=(m_matrix.cols()+1) * sizeof(int) + m_matrix.nonZeros()*(sizeof(int)+sizeof(Scalar))) >> 20) << "Mb" << "\n"; + s << " diag: " << ((total+=m_diag.size() * sizeof(Scalar)) >> 20) << "Mb" << "\n"; + s << " tree: " << ((total+=m_parent.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " nonzeros: " << ((total+=m_nonZerosPerCol.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " perm: " << ((total+=m_P.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " perm^-1: " << ((total+=m_Pinv.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " TOTAL: " << (total>> 20) << "Mb" << "\n"; + } + + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(m_matrix.rows()==b.rows()); + + if(m_info!=Success) + return; + + if(m_P.size()>0) + dest = m_P * b; + else + dest = b; + + if(m_matrix.nonZeros()>0) // otherwise L==I + derived().matrixL().solveInPlace(dest); + + if(m_diag.size()>0) + dest = m_diag.asDiagonal().inverse() * dest; + + if (m_matrix.nonZeros()>0) // otherwise U==I + derived().matrixU().solveInPlace(dest); + + if(m_P.size()>0) + dest = m_Pinv * dest; + } + + /** \internal */ + template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex> + void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(m_matrix.rows()==b.rows()); + + // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. + static const int NbColsAtOnce = 4; + int rhsCols = b.cols(); + int size = b.rows(); + Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols); + for(int k=0; k<rhsCols; k+=NbColsAtOnce) + { + int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce); + tmp.leftCols(actualCols) = b.middleCols(k,actualCols); + tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols)); + dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView(); + } + } + +#endif // EIGEN_PARSED_BY_DOXYGEN + + protected: + + /** Computes the sparse Cholesky decomposition of \a matrix */ + template<bool DoLDLT> + void compute(const MatrixType& matrix) + { + eigen_assert(matrix.rows()==matrix.cols()); + Index size = matrix.cols(); + CholMatrixType ap(size,size); + ordering(matrix, ap); + analyzePattern_preordered(ap, DoLDLT); + factorize_preordered<DoLDLT>(ap); + } + + template<bool DoLDLT> + void factorize(const MatrixType& a) + { + eigen_assert(a.rows()==a.cols()); + int size = a.cols(); + CholMatrixType ap(size,size); + ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P); + factorize_preordered<DoLDLT>(ap); + } + + template<bool DoLDLT> + void factorize_preordered(const CholMatrixType& a); + + void analyzePattern(const MatrixType& a, bool doLDLT) + { + eigen_assert(a.rows()==a.cols()); + int size = a.cols(); + CholMatrixType ap(size,size); + ordering(a, ap); + analyzePattern_preordered(ap,doLDLT); + } + void analyzePattern_preordered(const CholMatrixType& a, bool doLDLT); + + void ordering(const MatrixType& a, CholMatrixType& ap); + + /** keeps off-diagonal entries; drops diagonal entries */ + struct keep_diag { + inline bool operator() (const Index& row, const Index& col, const Scalar&) const + { + return row!=col; + } + }; + + mutable ComputationInfo m_info; + bool m_isInitialized; + bool m_factorizationIsOk; + bool m_analysisIsOk; + + CholMatrixType m_matrix; + VectorType m_diag; // the diagonal coefficients (LDLT mode) + VectorXi m_parent; // elimination tree + VectorXi m_nonZerosPerCol; + PermutationMatrix<Dynamic,Dynamic,Index> m_P; // the permutation + PermutationMatrix<Dynamic,Dynamic,Index> m_Pinv; // the inverse permutation + + RealScalar m_shiftOffset; + RealScalar m_shiftScale; +}; + +template<typename _MatrixType, int _UpLo = Lower> class SimplicialLLT; +template<typename _MatrixType, int _UpLo = Lower> class SimplicialLDLT; +template<typename _MatrixType, int _UpLo = Lower> class SimplicialCholesky; + +namespace internal { + +template<typename _MatrixType, int _UpLo> struct traits<SimplicialLLT<_MatrixType,_UpLo> > +{ + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix<Scalar, ColMajor, Index> CholMatrixType; + typedef SparseTriangularView<CholMatrixType, Eigen::Lower> MatrixL; + typedef SparseTriangularView<typename CholMatrixType::AdjointReturnType, Eigen::Upper> MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } +}; + +template<typename _MatrixType,int _UpLo> struct traits<SimplicialLDLT<_MatrixType,_UpLo> > +{ + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix<Scalar, ColMajor, Index> CholMatrixType; + typedef SparseTriangularView<CholMatrixType, Eigen::UnitLower> MatrixL; + typedef SparseTriangularView<typename CholMatrixType::AdjointReturnType, Eigen::UnitUpper> MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } +}; + +template<typename _MatrixType, int _UpLo> struct traits<SimplicialCholesky<_MatrixType,_UpLo> > +{ + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; +}; + +} + +/** \ingroup SparseCholesky_Module + * \class SimplicialLLT + * \brief A direct sparse LLT Cholesky factorizations + * + * This class provides a LL^T Cholesky factorizations of sparse matrices that are + * selfadjoint and positive definite. The factorization allows for solving A.X = B where + * X and B can be either dense or sparse. + * + * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization + * such that the factorized matrix is P A P^-1. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * \sa class SimplicialLDLT + */ +template<typename _MatrixType, int _UpLo> + class SimplicialLLT : public SimplicialCholeskyBase<SimplicialLLT<_MatrixType,_UpLo> > +{ +public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef SimplicialCholeskyBase<SimplicialLLT> Base; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType; + typedef Matrix<Scalar,Dynamic,1> VectorType; + typedef internal::traits<SimplicialLLT> Traits; + typedef typename Traits::MatrixL MatrixL; + typedef typename Traits::MatrixU MatrixU; +public: + /** Default constructor */ + SimplicialLLT() : Base() {} + /** Constructs and performs the LLT factorization of \a matrix */ + SimplicialLLT(const MatrixType& matrix) + : Base(matrix) {} + + /** \returns an expression of the factor L */ + inline const MatrixL matrixL() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); + return Traits::getL(Base::m_matrix); + } + + /** \returns an expression of the factor U (= L^*) */ + inline const MatrixU matrixU() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); + return Traits::getU(Base::m_matrix); + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + SimplicialLLT& compute(const MatrixType& matrix) + { + Base::template compute<false>(matrix); + return *this; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& a) + { + Base::analyzePattern(a, false); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& a) + { + Base::template factorize<false>(a); + } + + /** \returns the determinant of the underlying matrix from the current factorization */ + Scalar determinant() const + { + Scalar detL = Base::m_matrix.diagonal().prod(); + return internal::abs2(detL); + } +}; + +/** \ingroup SparseCholesky_Module + * \class SimplicialLDLT + * \brief A direct sparse LDLT Cholesky factorizations without square root. + * + * This class provides a LDL^T Cholesky factorizations without square root of sparse matrices that are + * selfadjoint and positive definite. The factorization allows for solving A.X = B where + * X and B can be either dense or sparse. + * + * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization + * such that the factorized matrix is P A P^-1. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * \sa class SimplicialLLT + */ +template<typename _MatrixType, int _UpLo> + class SimplicialLDLT : public SimplicialCholeskyBase<SimplicialLDLT<_MatrixType,_UpLo> > +{ +public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef SimplicialCholeskyBase<SimplicialLDLT> Base; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType; + typedef Matrix<Scalar,Dynamic,1> VectorType; + typedef internal::traits<SimplicialLDLT> Traits; + typedef typename Traits::MatrixL MatrixL; + typedef typename Traits::MatrixU MatrixU; +public: + /** Default constructor */ + SimplicialLDLT() : Base() {} + + /** Constructs and performs the LLT factorization of \a matrix */ + SimplicialLDLT(const MatrixType& matrix) + : Base(matrix) {} + + /** \returns a vector expression of the diagonal D */ + inline const VectorType vectorD() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); + return Base::m_diag; + } + /** \returns an expression of the factor L */ + inline const MatrixL matrixL() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); + return Traits::getL(Base::m_matrix); + } + + /** \returns an expression of the factor U (= L^*) */ + inline const MatrixU matrixU() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); + return Traits::getU(Base::m_matrix); + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + SimplicialLDLT& compute(const MatrixType& matrix) + { + Base::template compute<true>(matrix); + return *this; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& a) + { + Base::analyzePattern(a, true); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& a) + { + Base::template factorize<true>(a); + } + + /** \returns the determinant of the underlying matrix from the current factorization */ + Scalar determinant() const + { + return Base::m_diag.prod(); + } +}; + +/** \deprecated use SimplicialLDLT or class SimplicialLLT + * \ingroup SparseCholesky_Module + * \class SimplicialCholesky + * + * \sa class SimplicialLDLT, class SimplicialLLT + */ +template<typename _MatrixType, int _UpLo> + class SimplicialCholesky : public SimplicialCholeskyBase<SimplicialCholesky<_MatrixType,_UpLo> > +{ +public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef SimplicialCholeskyBase<SimplicialCholesky> Base; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType; + typedef Matrix<Scalar,Dynamic,1> VectorType; + typedef internal::traits<SimplicialCholesky> Traits; + typedef internal::traits<SimplicialLDLT<MatrixType,UpLo> > LDLTTraits; + typedef internal::traits<SimplicialLLT<MatrixType,UpLo> > LLTTraits; + public: + SimplicialCholesky() : Base(), m_LDLT(true) {} + + SimplicialCholesky(const MatrixType& matrix) + : Base(), m_LDLT(true) + { + compute(matrix); + } + + SimplicialCholesky& setMode(SimplicialCholeskyMode mode) + { + switch(mode) + { + case SimplicialCholeskyLLT: + m_LDLT = false; + break; + case SimplicialCholeskyLDLT: + m_LDLT = true; + break; + default: + break; + } + + return *this; + } + + inline const VectorType vectorD() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized"); + return Base::m_diag; + } + inline const CholMatrixType rawMatrix() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized"); + return Base::m_matrix; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + SimplicialCholesky& compute(const MatrixType& matrix) + { + if(m_LDLT) + Base::template compute<true>(matrix); + else + Base::template compute<false>(matrix); + return *this; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& a) + { + Base::analyzePattern(a, m_LDLT); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& a) + { + if(m_LDLT) + Base::template factorize<true>(a); + else + Base::template factorize<false>(a); + } + + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const + { + eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(Base::m_matrix.rows()==b.rows()); + + if(Base::m_info!=Success) + return; + + if(Base::m_P.size()>0) + dest = Base::m_P * b; + else + dest = b; + + if(Base::m_matrix.nonZeros()>0) // otherwise L==I + { + if(m_LDLT) + LDLTTraits::getL(Base::m_matrix).solveInPlace(dest); + else + LLTTraits::getL(Base::m_matrix).solveInPlace(dest); + } + + if(Base::m_diag.size()>0) + dest = Base::m_diag.asDiagonal().inverse() * dest; + + if (Base::m_matrix.nonZeros()>0) // otherwise I==I + { + if(m_LDLT) + LDLTTraits::getU(Base::m_matrix).solveInPlace(dest); + else + LLTTraits::getU(Base::m_matrix).solveInPlace(dest); + } + + if(Base::m_P.size()>0) + dest = Base::m_Pinv * dest; + } + + Scalar determinant() const + { + if(m_LDLT) + { + return Base::m_diag.prod(); + } + else + { + Scalar detL = Diagonal<const CholMatrixType>(Base::m_matrix).prod(); + return internal::abs2(detL); + } + } + + protected: + bool m_LDLT; +}; + +template<typename Derived> +void SimplicialCholeskyBase<Derived>::ordering(const MatrixType& a, CholMatrixType& ap) +{ + eigen_assert(a.rows()==a.cols()); + const Index size = a.rows(); + // TODO allows to configure the permutation + // Note that amd compute the inverse permutation + { + CholMatrixType C; + C = a.template selfadjointView<UpLo>(); + // remove diagonal entries: + // seems not to be needed + // C.prune(keep_diag()); + internal::minimum_degree_ordering(C, m_Pinv); + } + + if(m_Pinv.size()>0) + m_P = m_Pinv.inverse(); + else + m_P.resize(0); + + ap.resize(size,size); + ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P); +} + +template<typename Derived> +void SimplicialCholeskyBase<Derived>::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT) +{ + const Index size = ap.rows(); + m_matrix.resize(size, size); + m_parent.resize(size); + m_nonZerosPerCol.resize(size); + + ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0); + + for(Index k = 0; k < size; ++k) + { + /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */ + m_parent[k] = -1; /* parent of k is not yet known */ + tags[k] = k; /* mark node k as visited */ + m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */ + for(typename CholMatrixType::InnerIterator it(ap,k); it; ++it) + { + Index i = it.index(); + if(i < k) + { + /* follow path from i to root of etree, stop at flagged node */ + for(; tags[i] != k; i = m_parent[i]) + { + /* find parent of i if not yet determined */ + if (m_parent[i] == -1) + m_parent[i] = k; + m_nonZerosPerCol[i]++; /* L (k,i) is nonzero */ + tags[i] = k; /* mark i as visited */ + } + } + } + } + + /* construct Lp index array from m_nonZerosPerCol column counts */ + Index* Lp = m_matrix.outerIndexPtr(); + Lp[0] = 0; + for(Index k = 0; k < size; ++k) + Lp[k+1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1); + + m_matrix.resizeNonZeros(Lp[size]); + + m_isInitialized = true; + m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; +} + + +template<typename Derived> +template<bool DoLDLT> +void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + eigen_assert(ap.rows()==ap.cols()); + const Index size = ap.rows(); + eigen_assert(m_parent.size()==size); + eigen_assert(m_nonZerosPerCol.size()==size); + + const Index* Lp = m_matrix.outerIndexPtr(); + Index* Li = m_matrix.innerIndexPtr(); + Scalar* Lx = m_matrix.valuePtr(); + + ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0); + ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0); + ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0); + + bool ok = true; + m_diag.resize(DoLDLT ? size : 0); + + for(Index k = 0; k < size; ++k) + { + // compute nonzero pattern of kth row of L, in topological order + y[k] = 0.0; // Y(0:k) is now all zero + Index top = size; // stack for pattern is empty + tags[k] = k; // mark node k as visited + m_nonZerosPerCol[k] = 0; // count of nonzeros in column k of L + for(typename MatrixType::InnerIterator it(ap,k); it; ++it) + { + Index i = it.index(); + if(i <= k) + { + y[i] += internal::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */ + Index len; + for(len = 0; tags[i] != k; i = m_parent[i]) + { + pattern[len++] = i; /* L(k,i) is nonzero */ + tags[i] = k; /* mark i as visited */ + } + while(len > 0) + pattern[--top] = pattern[--len]; + } + } + + /* compute numerical values kth row of L (a sparse triangular solve) */ + + RealScalar d = internal::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k) + y[k] = 0.0; + for(; top < size; ++top) + { + Index i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */ + Scalar yi = y[i]; /* get and clear Y(i) */ + y[i] = 0.0; + + /* the nonzero entry L(k,i) */ + Scalar l_ki; + if(DoLDLT) + l_ki = yi / m_diag[i]; + else + yi = l_ki = yi / Lx[Lp[i]]; + + Index p2 = Lp[i] + m_nonZerosPerCol[i]; + Index p; + for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p) + y[Li[p]] -= internal::conj(Lx[p]) * yi; + d -= internal::real(l_ki * internal::conj(yi)); + Li[p] = k; /* store L(k,i) in column form of L */ + Lx[p] = l_ki; + ++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */ + } + if(DoLDLT) + { + m_diag[k] = d; + if(d == RealScalar(0)) + { + ok = false; /* failure, D(k,k) is zero */ + break; + } + } + else + { + Index p = Lp[k] + m_nonZerosPerCol[k]++; + Li[p] = k ; /* store L(k,k) = sqrt (d) in column k */ + if(d <= RealScalar(0)) { + ok = false; /* failure, matrix is not positive definite */ + break; + } + Lx[p] = internal::sqrt(d) ; + } + } + + m_info = ok ? Success : NumericalIssue; + m_factorizationIsOk = true; +} + +namespace internal { + +template<typename Derived, typename Rhs> +struct solve_retval<SimplicialCholeskyBase<Derived>, Rhs> + : solve_retval_base<SimplicialCholeskyBase<Derived>, Rhs> +{ + typedef SimplicialCholeskyBase<Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec().derived()._solve(rhs(),dst); + } +}; + +template<typename Derived, typename Rhs> +struct sparse_solve_retval<SimplicialCholeskyBase<Derived>, Rhs> + : sparse_solve_retval_base<SimplicialCholeskyBase<Derived>, Rhs> +{ + typedef SimplicialCholeskyBase<Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec().derived()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SIMPLICIAL_CHOLESKY_H diff --git a/extern/Eigen3/Eigen/src/Sparse/AmbiVector.h b/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h index 2ea8ba3096b..6cfaadbaa9a 100644 --- a/extern/Eigen3/Eigen/src/Sparse/AmbiVector.h +++ b/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h @@ -3,28 +3,17 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_AMBIVECTOR_H #define EIGEN_AMBIVECTOR_H +namespace Eigen { + +namespace internal { + /** \internal * Hybrid sparse/dense vector class designed for intensive read-write operations. * @@ -299,7 +288,7 @@ class AmbiVector<_Scalar,_Index>::Iterator * In practice, all coefficients having a magnitude smaller than \a epsilon * are skipped. */ - Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*NumTraits<RealScalar>::dummy_precision()) + Iterator(const AmbiVector& vec, RealScalar epsilon = 0) : m_vector(vec) { m_epsilon = epsilon; @@ -315,7 +304,7 @@ class AmbiVector<_Scalar,_Index>::Iterator { ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer); m_currentEl = m_vector.m_llStart; - while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<m_epsilon) + while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<=m_epsilon) m_currentEl = llElements[m_currentEl].next; if (m_currentEl<0) { @@ -375,5 +364,8 @@ class AmbiVector<_Scalar,_Index>::Iterator bool m_isDense; // mode of the vector }; +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_AMBIVECTOR_H diff --git a/extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h b/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h index b3bde272ec2..85a998aff10 100644 --- a/extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h +++ b/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h @@ -3,29 +3,19 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPRESSED_STORAGE_H #define EIGEN_COMPRESSED_STORAGE_H -/** Stores a sparse set of values as a list of values and a list of indices. +namespace Eigen { + +namespace internal { + +/** \internal + * Stores a sparse set of values as a list of values and a list of indices. * */ template<typename _Scalar,typename _Index> @@ -218,8 +208,8 @@ class CompressedStorage Index* newIndices = new Index[size]; size_t copySize = (std::min)(size, m_size); // copy - memcpy(newValues, m_values, copySize * sizeof(Scalar)); - memcpy(newIndices, m_indices, copySize * sizeof(Index)); + internal::smart_copy(m_values, m_values+copySize, newValues); + internal::smart_copy(m_indices, m_indices+copySize, newIndices); // delete old stuff delete[] m_values; delete[] m_indices; @@ -236,4 +226,8 @@ class CompressedStorage }; +} // end namespace internal + +} // end namespace Eigen + #endif // EIGEN_COMPRESSED_STORAGE_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h new file mode 100644 index 00000000000..16b5e1dba6c --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h @@ -0,0 +1,245 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H +#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H + +namespace Eigen { + +namespace internal { + +template<typename Lhs, typename Rhs, typename ResultType> +static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) +{ + typedef typename remove_all<Lhs>::type::Scalar Scalar; + typedef typename remove_all<Lhs>::type::Index Index; + + // make sure to call innerSize/outerSize since we fake the storage order. + Index rows = lhs.innerSize(); + Index cols = rhs.outerSize(); + eigen_assert(lhs.outerSize() == rhs.innerSize()); + + std::vector<bool> mask(rows,false); + Matrix<Scalar,Dynamic,1> values(rows); + Matrix<Index,Dynamic,1> indices(rows); + + // estimate the number of non zero entries + // given a rhs column containing Y non zeros, we assume that the respective Y columns + // of the lhs differs in average of one non zeros, thus the number of non zeros for + // the product of a rhs column with the lhs is X+Y where X is the average number of non zero + // per column of the lhs. + // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) + Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); + + res.setZero(); + res.reserve(Index(estimated_nnz_prod)); + // we compute each column of the result, one after the other + for (Index j=0; j<cols; ++j) + { + + res.startVec(j); + Index nnz = 0; + for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt) + { + Scalar y = rhsIt.value(); + Index k = rhsIt.index(); + for (typename Lhs::InnerIterator lhsIt(lhs, k); lhsIt; ++lhsIt) + { + Index i = lhsIt.index(); + Scalar x = lhsIt.value(); + if(!mask[i]) + { + mask[i] = true; + values[i] = x * y; + indices[nnz] = i; + ++nnz; + } + else + values[i] += x * y; + } + } + + // unordered insertion + for(int k=0; k<nnz; ++k) + { + int i = indices[k]; + res.insertBackByOuterInnerUnordered(j,i) = values[i]; + mask[i] = false; + } + +#if 0 + // alternative ordered insertion code: + + int t200 = rows/(log2(200)*1.39); + int t = (rows*100)/139; + + // FIXME reserve nnz non zeros + // FIXME implement fast sort algorithms for very small nnz + // if the result is sparse enough => use a quick sort + // otherwise => loop through the entire vector + // In order to avoid to perform an expensive log2 when the + // result is clearly very sparse we use a linear bound up to 200. + //if((nnz<200 && nnz<t200) || nnz * log2(nnz) < t) + //res.startVec(j); + if(true) + { + if(nnz>1) std::sort(indices.data(),indices.data()+nnz); + for(int k=0; k<nnz; ++k) + { + int i = indices[k]; + res.insertBackByOuterInner(j,i) = values[i]; + mask[i] = false; + } + } + else + { + // dense path + for(int i=0; i<rows; ++i) + { + if(mask[i]) + { + mask[i] = false; + res.insertBackByOuterInner(j,i) = values[i]; + } + } + } +#endif + + } + res.finalize(); +} + + +} // end namespace internal + +namespace internal { + +template<typename Lhs, typename Rhs, typename ResultType, + int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit, + int RhsStorageOrder = traits<Rhs>::Flags&RowMajorBit, + int ResStorageOrder = traits<ResultType>::Flags&RowMajorBit> +struct conservative_sparse_sparse_product_selector; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor> +{ + typedef typename remove_all<Lhs>::type LhsCleaned; + typedef typename LhsCleaned::Scalar Scalar; + + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; + typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; + ColMajorMatrix resCol(lhs.rows(),rhs.cols()); + internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol); + // sort the non zeros: + RowMajorMatrix resRow(resCol); + res = resRow; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,ColMajor> +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; + RowMajorMatrix rhsRow = rhs; + RowMajorMatrix resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl<RowMajorMatrix,Lhs,RowMajorMatrix>(rhsRow, lhs, resRow); + res = resRow; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,RowMajor,ColMajor> +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; + RowMajorMatrix lhsRow = lhs; + RowMajorMatrix resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl<Rhs,RowMajorMatrix,RowMajorMatrix>(rhs, lhsRow, resRow); + res = resRow; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor> +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; + RowMajorMatrix resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow); + res = resRow; + } +}; + + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor> +{ + typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; + + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; + ColMajorMatrix resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol); + res = resCol; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,RowMajor> +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; + ColMajorMatrix lhsCol = lhs; + ColMajorMatrix resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl<ColMajorMatrix,Rhs,ColMajorMatrix>(lhsCol, rhs, resCol); + res = resCol; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,RowMajor,RowMajor> +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; + ColMajorMatrix rhsCol = rhs; + ColMajorMatrix resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl<Lhs,ColMajorMatrix,ColMajorMatrix>(lhs, rhsCol, resCol); + res = resCol; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor> +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; + typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; + RowMajorMatrix resRow(lhs.rows(),rhs.cols()); + internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow); + // sort the non zeros: + ColMajorMatrix resCol(resRow); + res = resCol; + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/CoreIterators.h b/extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h index b4beaeee69e..6da4683d2c2 100644 --- a/extern/Eigen3/Eigen/src/Sparse/CoreIterators.h +++ b/extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h @@ -3,32 +3,20 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COREITERATORS_H #define EIGEN_COREITERATORS_H +namespace Eigen { + /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core */ -/** \class InnerIterator +/** \ingroup SparseCore_Module + * \class InnerIterator * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression * * todo @@ -68,4 +56,6 @@ template<typename Derived> class DenseBase<Derived>::InnerIterator const Index m_end; }; +} // end namespace Eigen + #endif // EIGEN_COREITERATORS_H diff --git a/extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h b/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h index 31a431fb224..93cd4832dea 100644 --- a/extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h +++ b/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MAPPED_SPARSEMATRIX_H #define EIGEN_MAPPED_SPARSEMATRIX_H +namespace Eigen { + /** \class MappedSparseMatrix * * \brief Sparse matrix @@ -46,9 +33,9 @@ class MappedSparseMatrix { public: EIGEN_SPARSE_PUBLIC_INTERFACE(MappedSparseMatrix) + enum { IsRowMajor = Base::IsRowMajor }; protected: - enum { IsRowMajor = Base::IsRowMajor }; Index m_outerSize; Index m_innerSize; @@ -63,18 +50,17 @@ class MappedSparseMatrix inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } inline Index innerSize() const { return m_innerSize; } inline Index outerSize() const { return m_outerSize; } - inline Index innerNonZeros(Index j) const { return m_outerIndex[j+1]-m_outerIndex[j]; } //---------------------------------------- // direct access interface - inline const Scalar* _valuePtr() const { return m_values; } - inline Scalar* _valuePtr() { return m_values; } + inline const Scalar* valuePtr() const { return m_values; } + inline Scalar* valuePtr() { return m_values; } - inline const Index* _innerIndexPtr() const { return m_innerIndices; } - inline Index* _innerIndexPtr() { return m_innerIndices; } + inline const Index* innerIndexPtr() const { return m_innerIndices; } + inline Index* innerIndexPtr() { return m_innerIndices; } - inline const Index* _outerIndexPtr() const { return m_outerIndex; } - inline Index* _outerIndexPtr() { return m_outerIndex; } + inline const Index* outerIndexPtr() const { return m_outerIndex; } + inline Index* outerIndexPtr() { return m_outerIndex; } //---------------------------------------- inline Scalar coeff(Index row, Index col) const @@ -112,6 +98,7 @@ class MappedSparseMatrix } class InnerIterator; + class ReverseInnerIterator; /** \returns the number of non zero coefficients */ inline Index nonZeros() const { return m_nnz; } @@ -132,23 +119,17 @@ class MappedSparseMatrix<Scalar,_Flags,_Index>::InnerIterator InnerIterator(const MappedSparseMatrix& mat, Index outer) : m_matrix(mat), m_outer(outer), - m_id(mat._outerIndexPtr()[outer]), + m_id(mat.outerIndexPtr()[outer]), m_start(m_id), - m_end(mat._outerIndexPtr()[outer+1]) - {} - - template<unsigned int Added, unsigned int Removed> - InnerIterator(const Flagged<MappedSparseMatrix,Added,Removed>& mat, Index outer) - : m_matrix(mat._expression()), m_id(m_matrix._outerIndexPtr()[outer]), - m_start(m_id), m_end(m_matrix._outerIndexPtr()[outer+1]) + m_end(mat.outerIndexPtr()[outer+1]) {} inline InnerIterator& operator++() { m_id++; return *this; } - inline Scalar value() const { return m_matrix._valuePtr()[m_id]; } - inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix._valuePtr()[m_id]); } + inline Scalar value() const { return m_matrix.valuePtr()[m_id]; } + inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id]); } - inline Index index() const { return m_matrix._innerIndexPtr()[m_id]; } + inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; } inline Index row() const { return IsRowMajor ? m_outer : index(); } inline Index col() const { return IsRowMajor ? index() : m_outer; } @@ -162,4 +143,37 @@ class MappedSparseMatrix<Scalar,_Flags,_Index>::InnerIterator const Index m_end; }; +template<typename Scalar, int _Flags, typename _Index> +class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator +{ + public: + ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer) + : m_matrix(mat), + m_outer(outer), + m_id(mat.outerIndexPtr()[outer+1]), + m_start(mat.outerIndexPtr()[outer]), + m_end(m_id) + {} + + inline ReverseInnerIterator& operator--() { m_id--; return *this; } + + inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; } + inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id-1]); } + + inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); } + + protected: + const MappedSparseMatrix& m_matrix; + const Index m_outer; + Index m_id; + const Index m_start; + const Index m_end; +}; + +} // end namespace Eigen + #endif // EIGEN_MAPPED_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseAssign.h b/extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h index e69de29bb2d..e69de29bb2d 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseAssign.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseBlock.h b/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h index 8079c999994..eefd8070251 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseBlock.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_BLOCK_H #define EIGEN_SPARSE_BLOCK_H +namespace Eigen { + namespace internal { template<typename MatrixType, int Size> struct traits<SparseInnerVectorSet<MatrixType, Size> > @@ -65,6 +52,17 @@ class SparseInnerVectorSet : internal::no_assignment_operator, protected: Index m_outer; }; + class ReverseInnerIterator: public MatrixType::ReverseInnerIterator + { + public: + inline ReverseInnerIterator(const SparseInnerVectorSet& xpr, Index outer) + : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) + {} + inline Index row() const { return IsRowMajor ? m_outer : this->index(); } + inline Index col() const { return IsRowMajor ? this->index() : m_outer; } + protected: + Index m_outer; + }; inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize) : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize) @@ -101,15 +99,16 @@ class SparseInnerVectorSet : internal::no_assignment_operator, const internal::variable_if_dynamic<Index, Size> m_outerSize; }; + /*************************************************************************** -* specialisation for DynamicSparseMatrix +* specialisation for SparseMatrix ***************************************************************************/ -template<typename _Scalar, int _Options, int Size> -class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> - : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> > +template<typename _Scalar, int _Options, typename _Index, int Size> +class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> + : public SparseMatrixBase<SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> > { - typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType; + typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType; public: enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor }; @@ -126,98 +125,11 @@ class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> protected: Index m_outer; }; - - inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize) - : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize) - { - eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) ); - } - - inline SparseInnerVectorSet(const MatrixType& matrix, Index outer) - : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size) - { - eigen_assert(Size!=Dynamic); - eigen_assert( (outer>=0) && (outer<matrix.outerSize()) ); - } - - template<typename OtherDerived> - inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other) - { - if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit)) - { - // need to transpose => perform a block evaluation followed by a big swap - DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other); - *this = aux.markAsRValue(); - } - else - { - // evaluate/copy vector per vector - for (Index j=0; j<m_outerSize.value(); ++j) - { - SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j)); - m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data()); - } - } - return *this; - } - - inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other) - { - return operator=<SparseInnerVectorSet>(other); - } - - Index nonZeros() const - { - Index count = 0; - for (Index j=0; j<m_outerSize.value(); ++j) - count += m_matrix._data()[m_outerStart+j].size(); - return count; - } - - const Scalar& lastCoeff() const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet); - eigen_assert(m_matrix.data()[m_outerStart].size()>0); - return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1); - } - -// template<typename Sparse> -// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other) -// { -// return *this; -// } - - EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } - - protected: - - const typename MatrixType::Nested m_matrix; - Index m_outerStart; - const internal::variable_if_dynamic<Index, Size> m_outerSize; - -}; - - -/*************************************************************************** -* specialisation for SparseMatrix -***************************************************************************/ - -template<typename _Scalar, int _Options, typename _Index, int Size> -class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> - : public SparseMatrixBase<SparseInnerVectorSet<SparseMatrix<_Scalar, _Options>, Size> > -{ - typedef SparseMatrix<_Scalar, _Options> MatrixType; - public: - - enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor }; - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet) - class InnerIterator: public MatrixType::InnerIterator + class ReverseInnerIterator: public MatrixType::ReverseInnerIterator { public: - inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer) - : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) + inline ReverseInnerIterator(const SparseInnerVectorSet& xpr, Index outer) + : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) {} inline Index row() const { return IsRowMajor ? m_outer : this->index(); } inline Index col() const { return IsRowMajor ? this->index() : m_outer; } @@ -243,19 +155,19 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> { typedef typename internal::remove_all<typename MatrixType::Nested>::type _NestedMatrixType; _NestedMatrixType& matrix = const_cast<_NestedMatrixType&>(m_matrix);; - // This assignement is slow if this vector set not empty + // This assignement is slow if this vector set is not empty // and/or it is not at the end of the nonzeros of the underlying matrix. // 1 - eval to a temporary to avoid transposition and/or aliasing issues SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, Index> tmp(other); // 2 - let's check whether there is enough allocated memory - Index nnz = tmp.nonZeros(); - Index nnz_previous = nonZeros(); - Index free_size = matrix.data().allocatedSize() - nnz_previous; - std::size_t nnz_head = m_outerStart==0 ? 0 : matrix._outerIndexPtr()[m_outerStart]; - std::size_t tail = m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()]; - std::size_t nnz_tail = matrix.nonZeros() - tail; + Index nnz = tmp.nonZeros(); + Index nnz_previous = nonZeros(); + Index free_size = Index(matrix.data().allocatedSize()) + nnz_previous; + Index nnz_head = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart]; + Index tail = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]; + Index nnz_tail = matrix.nonZeros() - tail; if(nnz>free_size) { @@ -298,15 +210,15 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> // update outer index pointers Index p = nnz_head; - for(Index k=1; k<m_outerSize.value(); ++k) + for(Index k=0; k<m_outerSize.value(); ++k) { - matrix._outerIndexPtr()[m_outerStart+k] = p; + matrix.outerIndexPtr()[m_outerStart+k] = p; p += tmp.innerVector(k).nonZeros(); } std::ptrdiff_t offset = nnz - nnz_previous; for(Index k = m_outerStart + m_outerSize.value(); k<=matrix.outerSize(); ++k) { - matrix._outerIndexPtr()[k] += offset; + matrix.outerIndexPtr()[k] += offset; } return *this; @@ -317,32 +229,40 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> return operator=<SparseInnerVectorSet>(other); } - inline const Scalar* _valuePtr() const - { return m_matrix._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; } - inline Scalar* _valuePtr() - { return m_matrix.const_cast_derived()._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; } + inline const Scalar* valuePtr() const + { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } + inline Scalar* valuePtr() + { return m_matrix.const_cast_derived().valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - inline const Index* _innerIndexPtr() const - { return m_matrix._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; } - inline Index* _innerIndexPtr() - { return m_matrix.const_cast_derived()._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; } + inline const Index* innerIndexPtr() const + { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } + inline Index* innerIndexPtr() + { return m_matrix.const_cast_derived().innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - inline const Index* _outerIndexPtr() const - { return m_matrix._outerIndexPtr() + m_outerStart; } - inline Index* _outerIndexPtr() - { return m_matrix.const_cast_derived()._outerIndexPtr() + m_outerStart; } + inline const Index* outerIndexPtr() const + { return m_matrix.outerIndexPtr() + m_outerStart; } + inline Index* outerIndexPtr() + { return m_matrix.const_cast_derived().outerIndexPtr() + m_outerStart; } Index nonZeros() const { - return std::size_t(m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()]) - - std::size_t(m_matrix._outerIndexPtr()[m_outerStart]); + if(m_matrix.isCompressed()) + return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]) + - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]); + else if(m_outerSize.value()==0) + return 0; + else + return Map<const Matrix<Index,Size,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); } const Scalar& lastCoeff() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet); eigen_assert(nonZeros()>0); - return m_matrix._valuePtr()[m_matrix._outerIndexPtr()[m_outerStart+1]-1]; + if(m_matrix.isCompressed()) + return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1]; + else + return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1]; } // template<typename Sparse> @@ -356,7 +276,7 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; Index m_outerStart; const internal::variable_if_dynamic<Index, Size> m_outerSize; @@ -412,11 +332,9 @@ template<typename Derived> const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(Index outer) const { return SparseInnerVectorSet<Derived,1>(derived(), outer); } -//---------- - /** \returns the i-th row of the matrix \c *this. For row-major matrix only. */ template<typename Derived> -SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(Index start, Index size) +SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleRows(Index start, Index size) { EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES); return innerVectors(start, size); @@ -425,7 +343,7 @@ SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(Index s /** \returns the i-th row of the matrix \c *this. For row-major matrix only. * (read-only version) */ template<typename Derived> -const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(Index start, Index size) const +const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleRows(Index start, Index size) const { EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES); return innerVectors(start, size); @@ -433,7 +351,7 @@ const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(I /** \returns the i-th column of the matrix \c *this. For column-major matrix only. */ template<typename Derived> -SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(Index start, Index size) +SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleCols(Index start, Index size) { EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); return innerVectors(start, size); @@ -442,12 +360,14 @@ SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(Index s /** \returns the i-th column of the matrix \c *this. For column-major matrix only. * (read-only version) */ template<typename Derived> -const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(Index start, Index size) const +const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleCols(Index start, Index size) const { EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); return innerVectors(start, size); } + + /** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this * is col-major (resp. row-major). */ @@ -462,4 +382,6 @@ template<typename Derived> const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const { return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); } +} // end namespace Eigen + #endif // EIGEN_SPARSE_BLOCK_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h index cde5bbc0300..d5f97f78fc9 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H #define EIGEN_SPARSE_CWISE_BINARY_OP_H +namespace Eigen { + // Here we have to handle 3 cases: // 1 - sparse op dense // 2 - dense op sparse @@ -63,8 +50,18 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse> { public: class InnerIterator; + class ReverseInnerIterator; typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived; EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + CwiseBinaryOpImpl() + { + typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind; + typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind; + EIGEN_STATIC_ASSERT(( + (!internal::is_same<LhsStorageKind,RhsStorageKind>::value) + || ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))), + THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH); + } }; template<typename BinaryOp, typename Lhs, typename Rhs> @@ -76,7 +73,7 @@ class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator typedef internal::sparse_cwise_binary_op_inner_iterator_selector< BinaryOp,Lhs,Rhs, InnerIterator> Base; - EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer) + EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename CwiseBinaryOpImpl::Index outer) : Base(binOp.derived(),outer) {} }; @@ -246,7 +243,7 @@ class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; } protected: - const RhsNested m_rhs; + RhsNested m_rhs; LhsIterator m_lhsIter; const BinaryFunc m_functor; const Index m_outer; @@ -298,16 +295,6 @@ class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, * Implementation of SparseMatrixBase and SparseCwise functions/operators ***************************************************************************/ -// template<typename Derived> -// template<typename OtherDerived> -// EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_difference_op<typename internal::traits<Derived>::Scalar>, -// Derived, OtherDerived> -// SparseMatrixBase<Derived>::operator-(const SparseMatrixBase<OtherDerived> &other) const -// { -// return CwiseBinaryOp<internal::scalar_difference_op<Scalar>, -// Derived, OtherDerived>(derived(), other.derived()); -// } - template<typename Derived> template<typename OtherDerived> EIGEN_STRONG_INLINE Derived & @@ -316,14 +303,6 @@ SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &othe return *this = derived() - other.derived(); } -// template<typename Derived> -// template<typename OtherDerived> -// EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_sum_op<typename internal::traits<Derived>::Scalar>, Derived, OtherDerived> -// SparseMatrixBase<Derived>::operator+(const SparseMatrixBase<OtherDerived> &other) const -// { -// return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); -// } - template<typename Derived> template<typename OtherDerived> EIGEN_STRONG_INLINE Derived & @@ -332,14 +311,6 @@ SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& othe return *this = derived() + other.derived(); } -// template<typename ExpressionType> -// template<typename OtherDerived> -// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE -// SparseCwise<ExpressionType>::operator*(const SparseMatrixBase<OtherDerived> &other) const -// { -// return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); -// } - template<typename Derived> template<typename OtherDerived> EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE @@ -348,28 +319,6 @@ SparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) c return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived()); } -// template<typename ExpressionType> -// template<typename OtherDerived> -// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op) -// SparseCwise<ExpressionType>::operator/(const SparseMatrixBase<OtherDerived> &other) const -// { -// return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived()); -// } -// -// template<typename ExpressionType> -// template<typename OtherDerived> -// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op) -// SparseCwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const -// { -// return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived()); -// } - -// template<typename ExpressionType> -// template<typename OtherDerived> -// inline ExpressionType& SparseCwise<ExpressionType>::operator*=(const SparseMatrixBase<OtherDerived> &other) -// { -// return m_matrix.const_cast_derived() = _expression() * other.derived(); -// } - +} // end namespace Eigen #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h new file mode 100644 index 00000000000..5a50c780303 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h @@ -0,0 +1,163 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H +#define EIGEN_SPARSE_CWISE_UNARY_OP_H + +namespace Eigen { + +template<typename UnaryOp, typename MatrixType> +class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse> + : public SparseMatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> > +{ + public: + + class InnerIterator; + class ReverseInnerIterator; + + typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + + protected: + typedef typename internal::traits<Derived>::_XprTypeNested _MatrixTypeNested; + typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; + typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; +}; + +template<typename UnaryOp, typename MatrixType> +class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator + : public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator +{ + typedef typename CwiseUnaryOpImpl::Scalar Scalar; + typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { Base::operator++(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } + + protected: + const UnaryOp m_functor; + private: + typename CwiseUnaryOpImpl::Scalar& valueRef(); +}; + +template<typename UnaryOp, typename MatrixType> +class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::ReverseInnerIterator + : public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator +{ + typedef typename CwiseUnaryOpImpl::Scalar Scalar; + typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() + { Base::operator--(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } + + protected: + const UnaryOp m_functor; + private: + typename CwiseUnaryOpImpl::Scalar& valueRef(); +}; + +template<typename ViewOp, typename MatrixType> +class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse> + : public SparseMatrixBase<CwiseUnaryView<ViewOp, MatrixType> > +{ + public: + + class InnerIterator; + class ReverseInnerIterator; + + typedef CwiseUnaryView<ViewOp, MatrixType> Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + + protected: + typedef typename internal::traits<Derived>::_MatrixTypeNested _MatrixTypeNested; + typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; + typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; +}; + +template<typename ViewOp, typename MatrixType> +class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator + : public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator +{ + typedef typename CwiseUnaryViewImpl::Scalar Scalar; + typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { Base::operator++(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } + + protected: + const ViewOp m_functor; +}; + +template<typename ViewOp, typename MatrixType> +class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::ReverseInnerIterator + : public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator +{ + typedef typename CwiseUnaryViewImpl::Scalar Scalar; + typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() + { Base::operator--(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } + + protected: + const ViewOp m_functor; +}; + +template<typename Derived> +EIGEN_STRONG_INLINE Derived& +SparseMatrixBase<Derived>::operator*=(const Scalar& other) +{ + for (Index j=0; j<outerSize(); ++j) + for (typename Derived::InnerIterator i(derived(),j); i; ++i) + i.valueRef() *= other; + return derived(); +} + +template<typename Derived> +EIGEN_STRONG_INLINE Derived& +SparseMatrixBase<Derived>::operator/=(const Scalar& other) +{ + for (Index j=0; j<outerSize(); ++j) + for (typename Derived::InnerIterator i(derived(),j); i; ++i) + i.valueRef() /= other; + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_CWISE_UNARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseDenseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h index 0f77aa5be99..6f32940d6c1 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseDenseProduct.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEDENSEPRODUCT_H #define EIGEN_SPARSEDENSEPRODUCT_H +namespace Eigen { + template<typename Lhs, typename Rhs, int InnerSize> struct SparseDenseProductReturnType { typedef SparseTimeDenseProduct<Lhs,Rhs> Type; @@ -149,6 +136,102 @@ struct traits<SparseTimeDenseProduct<Lhs,Rhs> > typedef Dense StorageKind; typedef MatrixXpr XprKind; }; + +template<typename SparseLhsType, typename DenseRhsType, typename DenseResType, + int LhsStorageOrder = ((SparseLhsType::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor, + bool ColPerCol = ((DenseRhsType::Flags&RowMajorBit)==0) || DenseRhsType::ColsAtCompileTime==1> +struct sparse_time_dense_product_impl; + +template<typename SparseLhsType, typename DenseRhsType, typename DenseResType> +struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, RowMajor, true> +{ + typedef typename internal::remove_all<SparseLhsType>::type Lhs; + typedef typename internal::remove_all<DenseRhsType>::type Rhs; + typedef typename internal::remove_all<DenseResType>::type Res; + typedef typename Lhs::Index Index; + typedef typename Lhs::InnerIterator LhsInnerIterator; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index c=0; c<rhs.cols(); ++c) + { + int n = lhs.outerSize(); + for(Index j=0; j<n; ++j) + { + typename Res::Scalar tmp(0); + for(LhsInnerIterator it(lhs,j); it ;++it) + tmp += it.value() * rhs.coeff(it.index(),c); + res.coeffRef(j,c) = alpha * tmp; + } + } + } +}; + +template<typename SparseLhsType, typename DenseRhsType, typename DenseResType> +struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, ColMajor, true> +{ + typedef typename internal::remove_all<SparseLhsType>::type Lhs; + typedef typename internal::remove_all<DenseRhsType>::type Rhs; + typedef typename internal::remove_all<DenseResType>::type Res; + typedef typename Lhs::InnerIterator LhsInnerIterator; + typedef typename Lhs::Index Index; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index c=0; c<rhs.cols(); ++c) + { + for(Index j=0; j<lhs.outerSize(); ++j) + { + typename Res::Scalar rhs_j = alpha * rhs.coeff(j,c); + for(LhsInnerIterator it(lhs,j); it ;++it) + res.coeffRef(it.index(),c) += it.value() * rhs_j; + } + } + } +}; + +template<typename SparseLhsType, typename DenseRhsType, typename DenseResType> +struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, RowMajor, false> +{ + typedef typename internal::remove_all<SparseLhsType>::type Lhs; + typedef typename internal::remove_all<DenseRhsType>::type Rhs; + typedef typename internal::remove_all<DenseResType>::type Res; + typedef typename Lhs::InnerIterator LhsInnerIterator; + typedef typename Lhs::Index Index; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index j=0; j<lhs.outerSize(); ++j) + { + typename Res::RowXpr res_j(res.row(j)); + for(LhsInnerIterator it(lhs,j); it ;++it) + res_j += (alpha*it.value()) * rhs.row(it.index()); + } + } +}; + +template<typename SparseLhsType, typename DenseRhsType, typename DenseResType> +struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, ColMajor, false> +{ + typedef typename internal::remove_all<SparseLhsType>::type Lhs; + typedef typename internal::remove_all<DenseRhsType>::type Rhs; + typedef typename internal::remove_all<DenseResType>::type Res; + typedef typename Lhs::InnerIterator LhsInnerIterator; + typedef typename Lhs::Index Index; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index j=0; j<lhs.outerSize(); ++j) + { + typename Rhs::ConstRowXpr rhs_j(rhs.row(j)); + for(LhsInnerIterator it(lhs,j); it ;++it) + res.row(it.index()) += (alpha*it.value()) * rhs_j; + } + } +}; + +template<typename SparseLhsType, typename DenseRhsType, typename DenseResType,typename AlphaType> +inline void sparse_time_dense_product(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const AlphaType& alpha) +{ + sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType>::run(lhs, rhs, res, alpha); +} + } // end namespace internal template<typename Lhs, typename Rhs> @@ -163,21 +246,7 @@ class SparseTimeDenseProduct template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const { - typedef typename internal::remove_all<Lhs>::type _Lhs; - typedef typename internal::remove_all<Rhs>::type _Rhs; - typedef typename _Lhs::InnerIterator LhsInnerIterator; - enum { LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit }; - for(Index j=0; j<m_lhs.outerSize(); ++j) - { - typename Rhs::Scalar rhs_j = alpha * m_rhs.coeff(LhsIsRowMajor ? 0 : j,0); - typename Dest::RowXpr dest_j(dest.row(LhsIsRowMajor ? j : 0)); - for(LhsInnerIterator it(m_lhs,j); it ;++it) - { - if(LhsIsRowMajor) dest_j += (alpha*it.value()) * m_rhs.row(it.index()); - else if(Rhs::ColsAtCompileTime==1) dest.coeffRef(it.index()) += it.value() * rhs_j; - else dest.row(it.index()) += (alpha*it.value()) * m_rhs.row(j); - } - } + internal::sparse_time_dense_product(m_lhs, m_rhs, dest, alpha); } private: @@ -207,12 +276,10 @@ class DenseTimeSparseProduct template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const { - typedef typename internal::remove_all<Rhs>::type _Rhs; - typedef typename _Rhs::InnerIterator RhsInnerIterator; - enum { RhsIsRowMajor = (_Rhs::Flags&RowMajorBit)==RowMajorBit }; - for(Index j=0; j<m_rhs.outerSize(); ++j) - for(RhsInnerIterator i(m_rhs,j); i; ++i) - dest.col(RhsIsRowMajor ? i.index() : j) += (alpha*i.value()) * m_lhs.col(RhsIsRowMajor ? j : i.index()); + Transpose<const _LhsNested> lhs_t(m_lhs); + Transpose<const _RhsNested> rhs_t(m_rhs); + Transpose<Dest> dest_t(dest); + internal::sparse_time_dense_product(rhs_t, lhs_t, dest_t, alpha); } private: @@ -228,4 +295,6 @@ SparseMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) cons return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); } +} // end namespace Eigen + #endif // EIGEN_SPARSEDENSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h index fb9a29c051b..095bf6863fc 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H #define EIGEN_SPARSE_DIAGONAL_PRODUCT_H +namespace Eigen { + // The product of a diagonal matrix with a sparse matrix can be easily // implemented using expression template. // We have two consider very different cases: @@ -192,4 +179,6 @@ SparseMatrixBase<Derived>::operator*(const DiagonalBase<OtherDerived> &other) co return SparseDiagonalProduct<Derived,OtherDerived>(this->derived(), other.derived()); } +} // end namespace Eigen + #endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseDot.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h index 1f10f71a402..5c4a593dc01 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseDot.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_DOT_H #define EIGEN_SPARSE_DOT_H +namespace Eigen { + template<typename Derived> template<typename OtherDerived> typename internal::traits<Derived>::Scalar @@ -40,7 +27,7 @@ SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const eigen_assert(other.size()>0 && "you are using a non initialized vector"); typename Derived::InnerIterator i(derived(),0); - Scalar res = 0; + Scalar res(0); while (i) { res += internal::conj(i.value()) * other.coeff(i.index()); @@ -62,9 +49,17 @@ SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) cons eigen_assert(size() == other.size()); - typename Derived::InnerIterator i(derived(),0); - typename OtherDerived::InnerIterator j(other.derived(),0); - Scalar res = 0; + typedef typename Derived::Nested Nested; + typedef typename OtherDerived::Nested OtherNested; + typedef typename internal::remove_all<Nested>::type NestedCleaned; + typedef typename internal::remove_all<OtherNested>::type OtherNestedCleaned; + + const Nested nthis(derived()); + const OtherNested nother(other.derived()); + + typename NestedCleaned::InnerIterator i(nthis,0); + typename OtherNestedCleaned::InnerIterator j(nother,0); + Scalar res(0); while (i && j) { if (i.index()==j.index()) @@ -94,4 +89,6 @@ SparseMatrixBase<Derived>::norm() const return internal::sqrt(squaredNorm()); } +} // end namespace Eigen + #endif // EIGEN_SPARSE_DOT_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h b/extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h new file mode 100644 index 00000000000..45f36e9eb90 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h @@ -0,0 +1,26 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_FUZZY_H +#define EIGEN_SPARSE_FUZZY_H + +// template<typename Derived> +// template<typename OtherDerived> +// bool SparseMatrixBase<Derived>::isApprox( +// const OtherDerived& other, +// typename NumTraits<Scalar>::Real prec +// ) const +// { +// const typename internal::nested<Derived,2>::type nested(derived()); +// const typename internal::nested<OtherDerived,2>::type otherNested(other.derived()); +// return (nested - otherNested).cwise().abs2().sum() +// <= prec * prec * (std::min)(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum()); +// } + +#endif // EIGEN_SPARSE_FUZZY_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h new file mode 100644 index 00000000000..efb774f031b --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h @@ -0,0 +1,1116 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSEMATRIX_H +#define EIGEN_SPARSEMATRIX_H + +namespace Eigen { + +/** \ingroup SparseCore_Module + * + * \class SparseMatrix + * + * \brief A versatible sparse matrix representation + * + * This class implements a more versatile variants of the common \em compressed row/column storage format. + * Each colmun's (resp. row) non zeros are stored as a pair of value with associated row (resp. colmiun) index. + * All the non zeros are stored in a single large buffer. Unlike the \em compressed format, there might be extra + * space inbetween the nonzeros of two successive colmuns (resp. rows) such that insertion of new non-zero + * can be done with limited memory reallocation and copies. + * + * A call to the function makeCompressed() turns the matrix into the standard \em compressed format + * compatible with many library. + * + * More details on this storage sceheme are given in the \ref TutorialSparse "manual pages". + * + * \tparam _Scalar the scalar type, i.e. the type of the coefficients + * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility + * is RowMajor. The default is 0 which means column-major. + * \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN. + */ + +namespace internal { +template<typename _Scalar, int _Options, typename _Index> +struct traits<SparseMatrix<_Scalar, _Options, _Index> > +{ + typedef _Scalar Scalar; + typedef _Index Index; + typedef Sparse StorageKind; + typedef MatrixXpr XprKind; + enum { + RowsAtCompileTime = Dynamic, + ColsAtCompileTime = Dynamic, + MaxRowsAtCompileTime = Dynamic, + MaxColsAtCompileTime = Dynamic, + Flags = _Options | NestByRefBit | LvalueBit, + CoeffReadCost = NumTraits<Scalar>::ReadCost, + SupportedAccessPatterns = InnerRandomAccessPattern + }; +}; + +template<typename _Scalar, int _Options, typename _Index, int DiagIndex> +struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> > +{ + typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType; + typedef typename nested<MatrixType>::type MatrixTypeNested; + typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; + + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef _Index Index; + typedef MatrixXpr XprKind; + + enum { + RowsAtCompileTime = Dynamic, + ColsAtCompileTime = 1, + MaxRowsAtCompileTime = Dynamic, + MaxColsAtCompileTime = 1, + Flags = 0, + CoeffReadCost = _MatrixTypeNested::CoeffReadCost*10 + }; +}; + +} // end namespace internal + +template<typename _Scalar, int _Options, typename _Index> +class SparseMatrix + : public SparseMatrixBase<SparseMatrix<_Scalar, _Options, _Index> > +{ + public: + EIGEN_SPARSE_PUBLIC_INTERFACE(SparseMatrix) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) + + typedef MappedSparseMatrix<Scalar,Flags> Map; + using Base::IsRowMajor; + typedef internal::CompressedStorage<Scalar,Index> Storage; + enum { + Options = _Options + }; + + protected: + + typedef SparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix; + + Index m_outerSize; + Index m_innerSize; + Index* m_outerIndex; + Index* m_innerNonZeros; // optional, if null then the data is compressed + Storage m_data; + + Eigen::Map<Matrix<Index,Dynamic,1> > innerNonZeros() { return Eigen::Map<Matrix<Index,Dynamic,1> >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } + const Eigen::Map<const Matrix<Index,Dynamic,1> > innerNonZeros() const { return Eigen::Map<const Matrix<Index,Dynamic,1> >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } + + public: + + /** \returns whether \c *this is in compressed form. */ + inline bool isCompressed() const { return m_innerNonZeros==0; } + + /** \returns the number of rows of the matrix */ + inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } + /** \returns the number of columns of the matrix */ + inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } + + /** \returns the number of rows (resp. columns) of the matrix if the storage order column major (resp. row major) */ + inline Index innerSize() const { return m_innerSize; } + /** \returns the number of columns (resp. rows) of the matrix if the storage order column major (resp. row major) */ + inline Index outerSize() const { return m_outerSize; } + + /** \returns a const pointer to the array of values. + * This function is aimed at interoperability with other libraries. + * \sa innerIndexPtr(), outerIndexPtr() */ + inline const Scalar* valuePtr() const { return &m_data.value(0); } + /** \returns a non-const pointer to the array of values. + * This function is aimed at interoperability with other libraries. + * \sa innerIndexPtr(), outerIndexPtr() */ + inline Scalar* valuePtr() { return &m_data.value(0); } + + /** \returns a const pointer to the array of inner indices. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), outerIndexPtr() */ + inline const Index* innerIndexPtr() const { return &m_data.index(0); } + /** \returns a non-const pointer to the array of inner indices. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), outerIndexPtr() */ + inline Index* innerIndexPtr() { return &m_data.index(0); } + + /** \returns a const pointer to the array of the starting positions of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), innerIndexPtr() */ + inline const Index* outerIndexPtr() const { return m_outerIndex; } + /** \returns a non-const pointer to the array of the starting positions of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), innerIndexPtr() */ + inline Index* outerIndexPtr() { return m_outerIndex; } + + /** \returns a const pointer to the array of the number of non zeros of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \warning it returns the null pointer 0 in compressed mode */ + inline const Index* innerNonZeroPtr() const { return m_innerNonZeros; } + /** \returns a non-const pointer to the array of the number of non zeros of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \warning it returns the null pointer 0 in compressed mode */ + inline Index* innerNonZeroPtr() { return m_innerNonZeros; } + + /** \internal */ + inline Storage& data() { return m_data; } + /** \internal */ + inline const Storage& data() const { return m_data; } + + /** \returns the value of the matrix at position \a i, \a j + * This function returns Scalar(0) if the element is an explicit \em zero */ + inline Scalar coeff(Index row, Index col) const + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1]; + return m_data.atInRange(m_outerIndex[outer], end, inner); + } + + /** \returns a non-const reference to the value of the matrix at position \a i, \a j + * + * If the element does not exist then it is inserted via the insert(Index,Index) function + * which itself turns the matrix into a non compressed form if that was not the case. + * + * This is a O(log(nnz_j)) operation (binary search) plus the cost of insert(Index,Index) + * function if the element does not already exist. + */ + inline Scalar& coeffRef(Index row, Index col) + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + Index start = m_outerIndex[outer]; + Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1]; + eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); + if(end<=start) + return insert(row,col); + const Index p = m_data.searchLowerIndex(start,end-1,inner); + if((p<end) && (m_data.index(p)==inner)) + return m_data.value(p); + else + return insert(row,col); + } + + /** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col. + * The non zero coefficient must \b not already exist. + * + * If the matrix \c *this is in compressed mode, then \c *this is turned into uncompressed + * mode while reserving room for 2 non zeros per inner vector. It is strongly recommended to first + * call reserve(const SizesType &) to reserve a more appropriate number of elements per + * inner vector that better match your scenario. + * + * This function performs a sorted insertion in O(1) if the elements of each inner vector are + * inserted in increasing inner index order, and in O(nnz_j) for a random insertion. + * + */ + EIGEN_DONT_INLINE Scalar& insert(Index row, Index col) + { + if(isCompressed()) + { + reserve(VectorXi::Constant(outerSize(), 2)); + } + return insertUncompressed(row,col); + } + + public: + + class InnerIterator; + class ReverseInnerIterator; + + /** Removes all non zeros but keep allocated memory */ + inline void setZero() + { + m_data.clear(); + memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); + if(m_innerNonZeros) + memset(m_innerNonZeros, 0, (m_outerSize)*sizeof(Index)); + } + + /** \returns the number of non zero coefficients */ + inline Index nonZeros() const + { + if(m_innerNonZeros) + return innerNonZeros().sum(); + return static_cast<Index>(m_data.size()); + } + + /** Preallocates \a reserveSize non zeros. + * + * Precondition: the matrix must be in compressed mode. */ + inline void reserve(Index reserveSize) + { + eigen_assert(isCompressed() && "This function does not make sense in non compressed mode."); + m_data.reserve(reserveSize); + } + + #ifdef EIGEN_PARSED_BY_DOXYGEN + /** Preallocates \a reserveSize[\c j] non zeros for each column (resp. row) \c j. + * + * This function turns the matrix in non-compressed mode */ + template<class SizesType> + inline void reserve(const SizesType& reserveSizes); + #else + template<class SizesType> + inline void reserve(const SizesType& reserveSizes, const typename SizesType::value_type& enableif = typename SizesType::value_type()) + { + EIGEN_UNUSED_VARIABLE(enableif); + reserveInnerVectors(reserveSizes); + } + template<class SizesType> + inline void reserve(const SizesType& reserveSizes, const typename SizesType::Scalar& enableif = + #if (!defined(_MSC_VER)) || (_MSC_VER>=1500) // MSVC 2005 fails to compile with this typename + typename + #endif + SizesType::Scalar()) + { + EIGEN_UNUSED_VARIABLE(enableif); + reserveInnerVectors(reserveSizes); + } + #endif // EIGEN_PARSED_BY_DOXYGEN + protected: + template<class SizesType> + inline void reserveInnerVectors(const SizesType& reserveSizes) + { + + if(isCompressed()) + { + std::size_t totalReserveSize = 0; + // turn the matrix into non-compressed mode + m_innerNonZeros = new Index[m_outerSize]; + + // temporarily use m_innerSizes to hold the new starting points. + Index* newOuterIndex = m_innerNonZeros; + + Index count = 0; + for(Index j=0; j<m_outerSize; ++j) + { + newOuterIndex[j] = count; + count += reserveSizes[j] + (m_outerIndex[j+1]-m_outerIndex[j]); + totalReserveSize += reserveSizes[j]; + } + m_data.reserve(totalReserveSize); + std::ptrdiff_t previousOuterIndex = m_outerIndex[m_outerSize]; + for(std::ptrdiff_t j=m_outerSize-1; j>=0; --j) + { + ptrdiff_t innerNNZ = previousOuterIndex - m_outerIndex[j]; + for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i) + { + m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); + m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); + } + previousOuterIndex = m_outerIndex[j]; + m_outerIndex[j] = newOuterIndex[j]; + m_innerNonZeros[j] = innerNNZ; + } + m_outerIndex[m_outerSize] = m_outerIndex[m_outerSize-1] + m_innerNonZeros[m_outerSize-1] + reserveSizes[m_outerSize-1]; + + m_data.resize(m_outerIndex[m_outerSize]); + } + else + { + Index* newOuterIndex = new Index[m_outerSize+1]; + Index count = 0; + for(Index j=0; j<m_outerSize; ++j) + { + newOuterIndex[j] = count; + Index alreadyReserved = (m_outerIndex[j+1]-m_outerIndex[j]) - m_innerNonZeros[j]; + Index toReserve = std::max<std::ptrdiff_t>(reserveSizes[j], alreadyReserved); + count += toReserve + m_innerNonZeros[j]; + } + newOuterIndex[m_outerSize] = count; + + m_data.resize(count); + for(ptrdiff_t j=m_outerSize-1; j>=0; --j) + { + std::ptrdiff_t offset = newOuterIndex[j] - m_outerIndex[j]; + if(offset>0) + { + std::ptrdiff_t innerNNZ = m_innerNonZeros[j]; + for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i) + { + m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); + m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); + } + } + } + + std::swap(m_outerIndex, newOuterIndex); + delete[] newOuterIndex; + } + + } + public: + + //--- low level purely coherent filling --- + + /** \internal + * \returns a reference to the non zero coefficient at position \a row, \a col assuming that: + * - the nonzero does not already exist + * - the new coefficient is the last one according to the storage order + * + * Before filling a given inner vector you must call the statVec(Index) function. + * + * After an insertion session, you should call the finalize() function. + * + * \sa insert, insertBackByOuterInner, startVec */ + inline Scalar& insertBack(Index row, Index col) + { + return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); + } + + /** \internal + * \sa insertBack, startVec */ + inline Scalar& insertBackByOuterInner(Index outer, Index inner) + { + eigen_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)"); + eigen_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)<inner) && "Invalid ordered insertion (invalid inner index)"); + Index p = m_outerIndex[outer+1]; + ++m_outerIndex[outer+1]; + m_data.append(0, inner); + return m_data.value(p); + } + + /** \internal + * \warning use it only if you know what you are doing */ + inline Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner) + { + Index p = m_outerIndex[outer+1]; + ++m_outerIndex[outer+1]; + m_data.append(0, inner); + return m_data.value(p); + } + + /** \internal + * \sa insertBack, insertBackByOuterInner */ + inline void startVec(Index outer) + { + eigen_assert(m_outerIndex[outer]==int(m_data.size()) && "You must call startVec for each inner vector sequentially"); + eigen_assert(m_outerIndex[outer+1]==0 && "You must call startVec for each inner vector sequentially"); + m_outerIndex[outer+1] = m_outerIndex[outer]; + } + + /** \internal + * Must be called after inserting a set of non zero entries using the low level compressed API. + */ + inline void finalize() + { + if(isCompressed()) + { + Index size = static_cast<Index>(m_data.size()); + Index i = m_outerSize; + // find the last filled column + while (i>=0 && m_outerIndex[i]==0) + --i; + ++i; + while (i<=m_outerSize) + { + m_outerIndex[i] = size; + ++i; + } + } + } + + //--- + + template<typename InputIterators> + void setFromTriplets(const InputIterators& begin, const InputIterators& end); + + void sumupDuplicates(); + + //--- + + /** \internal + * same as insert(Index,Index) except that the indices are given relative to the storage order */ + EIGEN_DONT_INLINE Scalar& insertByOuterInner(Index j, Index i) + { + return insert(IsRowMajor ? j : i, IsRowMajor ? i : j); + } + + /** Turns the matrix into the \em compressed format. + */ + void makeCompressed() + { + if(isCompressed()) + return; + + Index oldStart = m_outerIndex[1]; + m_outerIndex[1] = m_innerNonZeros[0]; + for(Index j=1; j<m_outerSize; ++j) + { + Index nextOldStart = m_outerIndex[j+1]; + std::ptrdiff_t offset = oldStart - m_outerIndex[j]; + if(offset>0) + { + for(Index k=0; k<m_innerNonZeros[j]; ++k) + { + m_data.index(m_outerIndex[j]+k) = m_data.index(oldStart+k); + m_data.value(m_outerIndex[j]+k) = m_data.value(oldStart+k); + } + } + m_outerIndex[j+1] = m_outerIndex[j] + m_innerNonZeros[j]; + oldStart = nextOldStart; + } + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + m_data.resize(m_outerIndex[m_outerSize]); + m_data.squeeze(); + } + + /** Suppresses all nonzeros which are \b much \b smaller \b than \a reference under the tolerence \a epsilon */ + void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) + { + prune(default_prunning_func(reference,epsilon)); + } + + /** Turns the matrix into compressed format, and suppresses all nonzeros which do not satisfy the predicate \a keep. + * The functor type \a KeepFunc must implement the following function: + * \code + * bool operator() (const Index& row, const Index& col, const Scalar& value) const; + * \endcode + * \sa prune(Scalar,RealScalar) + */ + template<typename KeepFunc> + void prune(const KeepFunc& keep = KeepFunc()) + { + // TODO optimize the uncompressed mode to avoid moving and allocating the data twice + // TODO also implement a unit test + makeCompressed(); + + Index k = 0; + for(Index j=0; j<m_outerSize; ++j) + { + Index previousStart = m_outerIndex[j]; + m_outerIndex[j] = k; + Index end = m_outerIndex[j+1]; + for(Index i=previousStart; i<end; ++i) + { + if(keep(IsRowMajor?j:m_data.index(i), IsRowMajor?m_data.index(i):j, m_data.value(i))) + { + m_data.value(k) = m_data.value(i); + m_data.index(k) = m_data.index(i); + ++k; + } + } + } + m_outerIndex[m_outerSize] = k; + m_data.resize(k,0); + } + + /** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero. + * \sa resizeNonZeros(Index), reserve(), setZero() + */ + void resize(Index rows, Index cols) + { + const Index outerSize = IsRowMajor ? rows : cols; + m_innerSize = IsRowMajor ? cols : rows; + m_data.clear(); + if (m_outerSize != outerSize || m_outerSize==0) + { + delete[] m_outerIndex; + m_outerIndex = new Index [outerSize+1]; + m_outerSize = outerSize; + } + if(m_innerNonZeros) + { + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + } + memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); + } + + /** \internal + * Resize the nonzero vector to \a size */ + void resizeNonZeros(Index size) + { + // TODO remove this function + m_data.resize(size); + } + + /** \returns a const expression of the diagonal coefficients */ + const Diagonal<const SparseMatrix> diagonal() const { return *this; } + + /** Default constructor yielding an empty \c 0 \c x \c 0 matrix */ + inline SparseMatrix() + : m_outerSize(-1), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + resize(0, 0); + } + + /** Constructs a \a rows \c x \a cols empty matrix */ + inline SparseMatrix(Index rows, Index cols) + : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + resize(rows, cols); + } + + /** Constructs a sparse matrix from the sparse expression \a other */ + template<typename OtherDerived> + inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other) + : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + *this = other.derived(); + } + + /** Copy constructor (it performs a deep copy) */ + inline SparseMatrix(const SparseMatrix& other) + : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + *this = other.derived(); + } + + /** Swaps the content of two sparse matrices of the same type. + * This is a fast operation that simply swaps the underlying pointers and parameters. */ + inline void swap(SparseMatrix& other) + { + //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); + std::swap(m_outerIndex, other.m_outerIndex); + std::swap(m_innerSize, other.m_innerSize); + std::swap(m_outerSize, other.m_outerSize); + std::swap(m_innerNonZeros, other.m_innerNonZeros); + m_data.swap(other.m_data); + } + + inline SparseMatrix& operator=(const SparseMatrix& other) + { + if (other.isRValue()) + { + swap(other.const_cast_derived()); + } + else + { + initAssignment(other); + if(other.isCompressed()) + { + memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); + m_data = other.m_data; + } + else + { + Base::operator=(other); + } + } + return *this; + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template<typename Lhs, typename Rhs> + inline SparseMatrix& operator=(const SparseSparseProduct<Lhs,Rhs>& product) + { return Base::operator=(product); } + + template<typename OtherDerived> + inline SparseMatrix& operator=(const ReturnByValue<OtherDerived>& other) + { return Base::operator=(other.derived()); } + + template<typename OtherDerived> + inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other) + { return Base::operator=(other.derived()); } + #endif + + template<typename OtherDerived> + EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other) + { + initAssignment(other.derived()); + const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + if (needToTranspose) + { + // two passes algorithm: + // 1 - compute the number of coeffs per dest inner vector + // 2 - do the actual copy/eval + // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed + typedef typename internal::nested<OtherDerived,2>::type OtherCopy; + typedef typename internal::remove_all<OtherCopy>::type _OtherCopy; + OtherCopy otherCopy(other.derived()); + + Eigen::Map<Matrix<Index, Dynamic, 1> > (m_outerIndex,outerSize()).setZero(); + // pass 1 + // FIXME the above copy could be merged with that pass + for (Index j=0; j<otherCopy.outerSize(); ++j) + for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) + ++m_outerIndex[it.index()]; + + // prefix sum + Index count = 0; + VectorXi positions(outerSize()); + for (Index j=0; j<outerSize(); ++j) + { + Index tmp = m_outerIndex[j]; + m_outerIndex[j] = count; + positions[j] = count; + count += tmp; + } + m_outerIndex[outerSize()] = count; + // alloc + m_data.resize(count); + // pass 2 + for (Index j=0; j<otherCopy.outerSize(); ++j) + { + for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) + { + Index pos = positions[it.index()]++; + m_data.index(pos) = j; + m_data.value(pos) = it.value(); + } + } + return *this; + } + else + { + // there is no special optimization + return Base::operator=(other.derived()); + } + } + + friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m) + { + EIGEN_DBG_SPARSE( + s << "Nonzero entries:\n"; + if(m.isCompressed()) + for (Index i=0; i<m.nonZeros(); ++i) + s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") "; + else + for (Index i=0; i<m.outerSize(); ++i) + { + int p = m.m_outerIndex[i]; + int pe = m.m_outerIndex[i]+m.m_innerNonZeros[i]; + Index k=p; + for (; k<pe; ++k) + s << "(" << m.m_data.value(k) << "," << m.m_data.index(k) << ") "; + for (; k<m.m_outerIndex[i+1]; ++k) + s << "(_,_) "; + } + s << std::endl; + s << std::endl; + s << "Outer pointers:\n"; + for (Index i=0; i<m.outerSize(); ++i) + s << m.m_outerIndex[i] << " "; + s << " $" << std::endl; + if(!m.isCompressed()) + { + s << "Inner non zeros:\n"; + for (Index i=0; i<m.outerSize(); ++i) + s << m.m_innerNonZeros[i] << " "; + s << " $" << std::endl; + } + s << std::endl; + ); + s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m); + return s; + } + + /** Destructor */ + inline ~SparseMatrix() + { + delete[] m_outerIndex; + delete[] m_innerNonZeros; + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** Overloaded for performance */ + Scalar sum() const; +#endif + +# ifdef EIGEN_SPARSEMATRIX_PLUGIN +# include EIGEN_SPARSEMATRIX_PLUGIN +# endif + +protected: + + template<typename Other> + void initAssignment(const Other& other) + { + resize(other.rows(), other.cols()); + if(m_innerNonZeros) + { + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + } + } + + /** \internal + * \sa insert(Index,Index) */ + EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col) + { + eigen_assert(isCompressed()); + + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + Index previousOuter = outer; + if (m_outerIndex[outer+1]==0) + { + // we start a new inner vector + while (previousOuter>=0 && m_outerIndex[previousOuter]==0) + { + m_outerIndex[previousOuter] = static_cast<Index>(m_data.size()); + --previousOuter; + } + m_outerIndex[outer+1] = m_outerIndex[outer]; + } + + // here we have to handle the tricky case where the outerIndex array + // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g., + // the 2nd inner vector... + bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) + && (size_t(m_outerIndex[outer+1]) == m_data.size()); + + size_t startId = m_outerIndex[outer]; + // FIXME let's make sure sizeof(long int) == sizeof(size_t) + size_t p = m_outerIndex[outer+1]; + ++m_outerIndex[outer+1]; + + float reallocRatio = 1; + if (m_data.allocatedSize()<=m_data.size()) + { + // if there is no preallocated memory, let's reserve a minimum of 32 elements + if (m_data.size()==0) + { + m_data.reserve(32); + } + else + { + // we need to reallocate the data, to reduce multiple reallocations + // we use a smart resize algorithm based on the current filling ratio + // in addition, we use float to avoid integers overflows + float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1); + reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size()); + // furthermore we bound the realloc ratio to: + // 1) reduce multiple minor realloc when the matrix is almost filled + // 2) avoid to allocate too much memory when the matrix is almost empty + reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f); + } + } + m_data.resize(m_data.size()+1,reallocRatio); + + if (!isLastVec) + { + if (previousOuter==-1) + { + // oops wrong guess. + // let's correct the outer offsets + for (Index k=0; k<=(outer+1); ++k) + m_outerIndex[k] = 0; + Index k=outer+1; + while(m_outerIndex[k]==0) + m_outerIndex[k++] = 1; + while (k<=m_outerSize && m_outerIndex[k]!=0) + m_outerIndex[k++]++; + p = 0; + --k; + k = m_outerIndex[k]-1; + while (k>0) + { + m_data.index(k) = m_data.index(k-1); + m_data.value(k) = m_data.value(k-1); + k--; + } + } + else + { + // we are not inserting into the last inner vec + // update outer indices: + Index j = outer+2; + while (j<=m_outerSize && m_outerIndex[j]!=0) + m_outerIndex[j++]++; + --j; + // shift data of last vecs: + Index k = m_outerIndex[j]-1; + while (k>=Index(p)) + { + m_data.index(k) = m_data.index(k-1); + m_data.value(k) = m_data.value(k-1); + k--; + } + } + } + + while ( (p > startId) && (m_data.index(p-1) > inner) ) + { + m_data.index(p) = m_data.index(p-1); + m_data.value(p) = m_data.value(p-1); + --p; + } + + m_data.index(p) = inner; + return (m_data.value(p) = 0); + } + + /** \internal + * A vector object that is equal to 0 everywhere but v at the position i */ + class SingletonVector + { + Index m_index; + Index m_value; + public: + typedef Index value_type; + SingletonVector(Index i, Index v) + : m_index(i), m_value(v) + {} + + Index operator[](Index i) const { return i==m_index ? m_value : 0; } + }; + + /** \internal + * \sa insert(Index,Index) */ + EIGEN_DONT_INLINE Scalar& insertUncompressed(Index row, Index col) + { + eigen_assert(!isCompressed()); + + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + std::ptrdiff_t room = m_outerIndex[outer+1] - m_outerIndex[outer]; + std::ptrdiff_t innerNNZ = m_innerNonZeros[outer]; + if(innerNNZ>=room) + { + // this inner vector is full, we need to reallocate the whole buffer :( + reserve(SingletonVector(outer,std::max<std::ptrdiff_t>(2,innerNNZ))); + } + + Index startId = m_outerIndex[outer]; + Index p = startId + m_innerNonZeros[outer]; + while ( (p > startId) && (m_data.index(p-1) > inner) ) + { + m_data.index(p) = m_data.index(p-1); + m_data.value(p) = m_data.value(p-1); + --p; + } + + m_innerNonZeros[outer]++; + + m_data.index(p) = inner; + return (m_data.value(p) = 0); + } + +public: + /** \internal + * \sa insert(Index,Index) */ + inline Scalar& insertBackUncompressed(Index row, Index col) + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + eigen_assert(!isCompressed()); + eigen_assert(m_innerNonZeros[outer]<=(m_outerIndex[outer+1] - m_outerIndex[outer])); + + Index p = m_outerIndex[outer] + m_innerNonZeros[outer]; + m_innerNonZeros[outer]++; + m_data.index(p) = inner; + return (m_data.value(p) = 0); + } + +private: + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); + } + + struct default_prunning_func { + default_prunning_func(Scalar ref, RealScalar eps) : reference(ref), epsilon(eps) {} + inline bool operator() (const Index&, const Index&, const Scalar& value) const + { + return !internal::isMuchSmallerThan(value, reference, epsilon); + } + Scalar reference; + RealScalar epsilon; + }; +}; + +template<typename Scalar, int _Options, typename _Index> +class SparseMatrix<Scalar,_Options,_Index>::InnerIterator +{ + public: + InnerIterator(const SparseMatrix& mat, Index outer) + : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]) + { + if(mat.isCompressed()) + m_end = mat.m_outerIndex[outer+1]; + else + m_end = m_id + mat.m_innerNonZeros[outer]; + } + + inline InnerIterator& operator++() { m_id++; return *this; } + + inline const Scalar& value() const { return m_values[m_id]; } + inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id]); } + + inline Index index() const { return m_indices[m_id]; } + inline Index outer() const { return m_outer; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + inline operator bool() const { return (m_id < m_end); } + + protected: + const Scalar* m_values; + const Index* m_indices; + const Index m_outer; + Index m_id; + Index m_end; +}; + +template<typename Scalar, int _Options, typename _Index> +class SparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator +{ + public: + ReverseInnerIterator(const SparseMatrix& mat, Index outer) + : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_start(mat.m_outerIndex[outer]) + { + if(mat.isCompressed()) + m_id = mat.m_outerIndex[outer+1]; + else + m_id = m_start + mat.m_innerNonZeros[outer]; + } + + inline ReverseInnerIterator& operator--() { --m_id; return *this; } + + inline const Scalar& value() const { return m_values[m_id-1]; } + inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id-1]); } + + inline Index index() const { return m_indices[m_id-1]; } + inline Index outer() const { return m_outer; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + inline operator bool() const { return (m_id > m_start); } + + protected: + const Scalar* m_values; + const Index* m_indices; + const Index m_outer; + Index m_id; + const Index m_start; +}; + +namespace internal { + +template<typename InputIterator, typename SparseMatrixType> +void set_from_triplets(const InputIterator& begin, const InputIterator& end, SparseMatrixType& mat, int Options = 0) +{ + EIGEN_UNUSED_VARIABLE(Options); + enum { IsRowMajor = SparseMatrixType::IsRowMajor }; + typedef typename SparseMatrixType::Scalar Scalar; + typedef typename SparseMatrixType::Index Index; + SparseMatrix<Scalar,IsRowMajor?ColMajor:RowMajor> trMat(mat.rows(),mat.cols()); + + // pass 1: count the nnz per inner-vector + VectorXi wi(trMat.outerSize()); + wi.setZero(); + for(InputIterator it(begin); it!=end; ++it) + wi(IsRowMajor ? it->col() : it->row())++; + + // pass 2: insert all the elements into trMat + trMat.reserve(wi); + for(InputIterator it(begin); it!=end; ++it) + trMat.insertBackUncompressed(it->row(),it->col()) = it->value(); + + // pass 3: + trMat.sumupDuplicates(); + + // pass 4: transposed copy -> implicit sorting + mat = trMat; +} + +} + + +/** Fill the matrix \c *this with the list of \em triplets defined by the iterator range \a begin - \b. + * + * A \em triplet is a tuple (i,j,value) defining a non-zero element. + * The input list of triplets does not have to be sorted, and can contains duplicated elements. + * In any case, the result is a \b sorted and \b compressed sparse matrix where the duplicates have been summed up. + * This is a \em O(n) operation, with \em n the number of triplet elements. + * The initial contents of \c *this is destroyed. + * The matrix \c *this must be properly resized beforehand using the SparseMatrix(Index,Index) constructor, + * or the resize(Index,Index) method. The sizes are not extracted from the triplet list. + * + * The \a InputIterators value_type must provide the following interface: + * \code + * Scalar value() const; // the value + * Scalar row() const; // the row index i + * Scalar col() const; // the column index j + * \endcode + * See for instance the Eigen::Triplet template class. + * + * Here is a typical usage example: + * \code + typedef Triplet<double> T; + std::vector<T> tripletList; + triplets.reserve(estimation_of_entries); + for(...) + { + // ... + tripletList.push_back(T(i,j,v_ij)); + } + SparseMatrixType m(rows,cols); + m.setFromTriplets(tripletList.begin(), tripletList.end()); + // m is ready to go! + * \endcode + * + * \warning The list of triplets is read multiple times (at least twice). Therefore, it is not recommended to define + * an abstract iterator over a complex data-structure that would be expensive to evaluate. The triplets should rather + * be explicitely stored into a std::vector for instance. + */ +template<typename Scalar, int _Options, typename _Index> +template<typename InputIterators> +void SparseMatrix<Scalar,_Options,_Index>::setFromTriplets(const InputIterators& begin, const InputIterators& end) +{ + internal::set_from_triplets(begin, end, *this); +} + +/** \internal */ +template<typename Scalar, int _Options, typename _Index> +void SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates() +{ + eigen_assert(!isCompressed()); + // TODO, in practice we should be able to use m_innerNonZeros for that task + VectorXi wi(innerSize()); + wi.fill(-1); + Index count = 0; + // for each inner-vector, wi[inner_index] will hold the position of first element into the index/value buffers + for(int j=0; j<outerSize(); ++j) + { + Index start = count; + Index oldEnd = m_outerIndex[j]+m_innerNonZeros[j]; + for(Index k=m_outerIndex[j]; k<oldEnd; ++k) + { + Index i = m_data.index(k); + if(wi(i)>=start) + { + // we already meet this entry => accumulate it + m_data.value(wi(i)) += m_data.value(k); + } + else + { + m_data.value(count) = m_data.value(k); + m_data.index(count) = m_data.index(k); + wi(i) = count; + ++count; + } + } + m_outerIndex[j] = start; + } + m_outerIndex[m_outerSize] = count; + + // turn the matrix into compressed form + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + m_data.resize(m_outerIndex[m_outerSize]); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h index c01981bc935..9a1258097fe 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h @@ -1,31 +1,18 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEMATRIXBASE_H #define EIGEN_SPARSEMATRIXBASE_H -/** \ingroup Sparse_Module +namespace Eigen { + +/** \ingroup SparseCore_Module * * \class SparseMatrixBase * @@ -44,6 +31,9 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> typedef typename internal::packet_traits<Scalar>::type PacketScalar; typedef typename internal::traits<Derived>::StorageKind StorageKind; typedef typename internal::traits<Derived>::Index Index; + typedef typename internal::add_const_on_value_type_if_arithmetic< + typename internal::packet_traits<Scalar>::type + >::type PacketReturnType; typedef SparseMatrixBase StorageBaseType; typedef EigenBase<Derived> Base; @@ -54,8 +44,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> other.derived().evalTo(derived()); return derived(); } - -// using Base::operator=; enum { @@ -107,15 +95,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> #endif }; - /* \internal the return type of MatrixBase::conjugate() */ -// typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, -// const SparseCwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Derived>, -// const Derived& -// >::type ConjugateReturnType; - /* \internal the return type of MatrixBase::real() */ -// typedef SparseCwiseUnaryOp<internal::scalar_real_op<Scalar>, Derived> RealReturnType; - /* \internal the return type of MatrixBase::imag() */ -// typedef SparseCwiseUnaryOp<internal::scalar_imag_op<Scalar>, Derived> ImagReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >, @@ -125,16 +104,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainObject; -#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase -# include "../plugins/CommonCwiseUnaryOps.h" -# include "../plugins/CommonCwiseBinaryOps.h" -# include "../plugins/MatrixCwiseUnaryOps.h" -# include "../plugins/MatrixCwiseBinaryOps.h" -# ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN -# include EIGEN_SPARSEMATRIXBASE_PLUGIN -# endif -# undef EIGEN_CURRENT_STORAGE_BASE_CLASS -#undef EIGEN_CURRENT_STORAGE_BASE_CLASS #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is the "real scalar" type; if the \a Scalar type is already real numbers @@ -162,12 +131,24 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); } #endif // not EIGEN_PARSED_BY_DOXYGEN - /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN +# include EIGEN_SPARSEMATRIXBASE_PLUGIN +# endif +# undef EIGEN_CURRENT_STORAGE_BASE_CLASS +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + + /** \returns the number of rows. \sa cols() */ inline Index rows() const { return derived().rows(); } - /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ + /** \returns the number of columns. \sa rows() */ inline Index cols() const { return derived().cols(); } /** \returns the number of coefficients, which is \a rows()*cols(). - * \sa rows(), cols(), SizeAtCompileTime. */ + * \sa rows(), cols(). */ inline Index size() const { return rows() * cols(); } /** \returns the number of nonzero coefficients which is in practice the number * of stored coefficients. */ @@ -188,29 +169,64 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> Derived& markAsRValue() { m_isRValue = true; return derived(); } SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } + + template<typename OtherDerived> + Derived& operator=(const ReturnByValue<OtherDerived>& other) + { + other.evalTo(derived()); + return derived(); + } + + + template<typename OtherDerived> + inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other) + { + return assign(other.derived()); + } + inline Derived& operator=(const Derived& other) { -// std::cout << "Derived& operator=(const Derived& other)\n"; // if (other.isRValue()) // derived().swap(other.const_cast_derived()); // else - this->operator=<Derived>(other); - return derived(); + return assign(other.derived()); } - + + protected: + template<typename OtherDerived> - Derived& operator=(const ReturnByValue<OtherDerived>& other) + inline Derived& assign(const OtherDerived& other) { - other.evalTo(derived()); + const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); + if ((!transpose) && other.isRValue()) + { + // eval without temporary + derived().resize(other.rows(), other.cols()); + derived().setZero(); + derived().reserve((std::max)(this->rows(),this->cols())*2); + for (Index j=0; j<outerSize; ++j) + { + derived().startVec(j); + for (typename OtherDerived::InnerIterator it(other, j); it; ++it) + { + Scalar v = it.value(); + derived().insertBackByOuterInner(j,it.index()) = v; + } + } + derived().finalize(); + } + else + { + assignGeneric(other); + } return derived(); } - template<typename OtherDerived> inline void assignGeneric(const OtherDerived& other) { -// std::cout << "Derived& operator=(const MatrixBase<OtherDerived>& other)\n"; //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && @@ -230,8 +246,7 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) { Scalar v = it.value(); - if (v!=Scalar(0)) - temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; + temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; } } temp.finalize(); @@ -239,54 +254,23 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> derived() = temp.markAsRValue(); } - - template<typename OtherDerived> - inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other) - { -// std::cout << typeid(OtherDerived).name() << "\n"; -// std::cout << Flags << " " << OtherDerived::Flags << "\n"; - const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); -// std::cout << "eval transpose = " << transpose << "\n"; - const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); - if ((!transpose) && other.isRValue()) - { - // eval without temporary - derived().resize(other.rows(), other.cols()); - derived().setZero(); - derived().reserve((std::max)(this->rows(),this->cols())*2); - for (Index j=0; j<outerSize; ++j) - { - derived().startVec(j); - for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) - { - Scalar v = it.value(); - if (v!=Scalar(0)) - derived().insertBackByOuterInner(j,it.index()) = v; - } - } - derived().finalize(); - } - else - { - assignGeneric(other.derived()); - } - return derived(); - } + public: template<typename Lhs, typename Rhs> inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product); - template<typename Lhs, typename Rhs> - inline void _experimentalNewProduct(const Lhs& lhs, const Rhs& rhs); - friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) { + typedef typename Derived::Nested Nested; + typedef typename internal::remove_all<Nested>::type NestedCleaned; + if (Flags&RowMajorBit) { - for (Index row=0; row<m.outerSize(); ++row) + const Nested nm(m.derived()); + for (Index row=0; row<nm.outerSize(); ++row) { Index col = 0; - for (typename Derived::InnerIterator it(m.derived(), row); it; ++it) + for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it) { for ( ; col<it.index(); ++col) s << "0 "; @@ -300,9 +284,10 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> } else { + const Nested nm(m.derived()); if (m.cols() == 1) { Index row = 0; - for (typename Derived::InnerIterator it(m.derived(), 0); it; ++it) + for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it) { for ( ; row<it.index(); ++row) s << "0" << std::endl; @@ -314,31 +299,18 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> } else { - SparseMatrix<Scalar, RowMajorBit> trans = m.derived(); - s << trans; + SparseMatrix<Scalar, RowMajorBit> trans = m; + s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit> >&>(trans); } } return s; } -// const SparseCwiseUnaryOp<internal::scalar_opposite_op<typename internal::traits<Derived>::Scalar>,Derived> operator-() const; - -// template<typename OtherDerived> -// const CwiseBinaryOp<internal::scalar_sum_op<typename internal::traits<Derived>::Scalar>, Derived, OtherDerived> -// operator+(const SparseMatrixBase<OtherDerived> &other) const; - -// template<typename OtherDerived> -// const CwiseBinaryOp<internal::scalar_difference_op<typename internal::traits<Derived>::Scalar>, Derived, OtherDerived> -// operator-(const SparseMatrixBase<OtherDerived> &other) const; - template<typename OtherDerived> Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); template<typename OtherDerived> Derived& operator-=(const SparseMatrixBase<OtherDerived>& other); -// template<typename Lhs,typename Rhs> -// Derived& operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProduct>, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other); - Derived& operator*=(const Scalar& other); Derived& operator/=(const Scalar& other); @@ -358,16 +330,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE cwiseProduct(const MatrixBase<OtherDerived> &other) const; -// const SparseCwiseUnaryOp<internal::scalar_multiple_op<typename internal::traits<Derived>::Scalar>, Derived> -// operator*(const Scalar& scalar) const; -// const SparseCwiseUnaryOp<internal::scalar_quotient1_op<typename internal::traits<Derived>::Scalar>, Derived> -// operator/(const Scalar& scalar) const; - -// inline friend const SparseCwiseUnaryOp<internal::scalar_multiple_op<typename internal::traits<Derived>::Scalar>, Derived> -// operator*(const Scalar& scalar, const SparseMatrixBase& matrix) -// { return matrix*scalar; } - - // sparse * sparse template<typename OtherDerived> const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type @@ -394,6 +356,12 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> template<typename OtherDerived> const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type operator*(const MatrixBase<OtherDerived> &other) const; + + /** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */ + SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const + { + return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm); + } template<typename OtherDerived> Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); @@ -407,8 +375,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> // deprecated template<typename OtherDerived> void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const; -// template<typename OtherDerived> -// void solveTriangularInPlace(SparseMatrixBase<OtherDerived>& other) const; #endif // EIGEN2_SUPPORT template<int Mode> @@ -421,12 +387,9 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const; RealScalar squaredNorm() const; RealScalar norm() const; -// const PlainObject normalized() const; -// void normalize(); Transpose<Derived> transpose() { return derived(); } const Transpose<const Derived> transpose() const { return derived(); } - // void transposeInPlace(); const AdjointReturnType adjoint() const { return transpose(); } // sub-vector @@ -442,77 +405,14 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> const SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size) const; SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size); const SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size) const; + + SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size); + const SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size) const; + SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size); + const SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size) const; SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize); const SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize) const; -// typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols); -// const typename BlockReturnType<Derived>::Type -// block(int startRow, int startCol, int blockRows, int blockCols) const; -// -// typename BlockReturnType<Derived>::SubVectorType segment(int start, int size); -// const typename BlockReturnType<Derived>::SubVectorType segment(int start, int size) const; -// -// typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size); -// const typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size) const; -// -// typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size); -// const typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size) const; -// -// template<int BlockRows, int BlockCols> -// typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol); -// template<int BlockRows, int BlockCols> -// const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const; - -// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType start(void); -// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType start() const; - -// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType end(); -// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType end() const; - -// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType segment(int start); -// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType segment(int start) const; - -// Diagonal<Derived> diagonal(); -// const Diagonal<Derived> diagonal() const; - -// template<unsigned int Mode> Part<Derived, Mode> part(); -// template<unsigned int Mode> const Part<Derived, Mode> part() const; - - -// static const ConstantReturnType Constant(int rows, int cols, const Scalar& value); -// static const ConstantReturnType Constant(int size, const Scalar& value); -// static const ConstantReturnType Constant(const Scalar& value); - -// template<typename CustomNullaryOp> -// static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(int rows, int cols, const CustomNullaryOp& func); -// template<typename CustomNullaryOp> -// static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(int size, const CustomNullaryOp& func); -// template<typename CustomNullaryOp> -// static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(const CustomNullaryOp& func); - -// static const ConstantReturnType Zero(int rows, int cols); -// static const ConstantReturnType Zero(int size); -// static const ConstantReturnType Zero(); -// static const ConstantReturnType Ones(int rows, int cols); -// static const ConstantReturnType Ones(int size); -// static const ConstantReturnType Ones(); -// static const IdentityReturnType Identity(); -// static const IdentityReturnType Identity(int rows, int cols); -// static const BasisReturnType Unit(int size, int i); -// static const BasisReturnType Unit(int i); -// static const BasisReturnType UnitX(); -// static const BasisReturnType UnitY(); -// static const BasisReturnType UnitZ(); -// static const BasisReturnType UnitW(); - -// const DiagonalMatrix<Derived> asDiagonal() const; - -// Derived& setConstant(const Scalar& value); -// Derived& setZero(); -// Derived& setOnes(); -// Derived& setRandom(); -// Derived& setIdentity(); - /** \internal use operator= */ template<typename DenseDerived> void evalTo(MatrixBase<DenseDerived>& dst) const @@ -537,37 +437,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> bool isApprox(const MatrixBase<OtherDerived>& other, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const { return toDense().isApprox(other,prec); } -// bool isMuchSmallerThan(const RealScalar& other, -// RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// template<typename OtherDerived> -// bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other, -// RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; - -// bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// bool isIdentity(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// bool isDiagonal(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; - -// bool isUpper(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// bool isLower(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; - -// template<typename OtherDerived> -// bool isOrthogonal(const MatrixBase<OtherDerived>& other, -// RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; -// bool isUnitary(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; - -// template<typename OtherDerived> -// inline bool operator==(const MatrixBase<OtherDerived>& other) const -// { return (cwise() == other).all(); } - -// template<typename OtherDerived> -// inline bool operator!=(const MatrixBase<OtherDerived>& other) const -// { return (cwise() != other).any(); } - - -// template<typename NewType> -// const SparseCwiseUnaryOp<internal::scalar_cast_op<typename internal::traits<Derived>::Scalar, NewType>, Derived> cast() const; /** \returns the matrix or vector obtained by evaluating this expression. * @@ -577,130 +446,13 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> inline const typename internal::eval<Derived>::type eval() const { return typename internal::eval<Derived>::type(derived()); } -// template<typename OtherDerived> -// void swap(MatrixBase<OtherDerived> const & other); - -// template<unsigned int Added> -// const SparseFlagged<Derived, Added, 0> marked() const; -// const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit> lazy() const; - - /** \returns number of elements to skip to pass from one row (resp. column) to another - * for a row-major (resp. column-major) matrix. - * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data - * of the underlying matrix. - */ -// inline int stride(void) const { return derived().stride(); } - -// FIXME -// ConjugateReturnType conjugate() const; -// const RealReturnType real() const; -// const ImagReturnType imag() const; - -// template<typename CustomUnaryOp> -// const SparseCwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const; - -// template<typename CustomBinaryOp, typename OtherDerived> -// const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> -// binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const; - - Scalar sum() const; -// Scalar trace() const; - -// typename internal::traits<Derived>::Scalar minCoeff() const; -// typename internal::traits<Derived>::Scalar maxCoeff() const; - -// typename internal::traits<Derived>::Scalar minCoeff(int* row, int* col = 0) const; -// typename internal::traits<Derived>::Scalar maxCoeff(int* row, int* col = 0) const; - -// template<typename BinaryOp> -// typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type -// redux(const BinaryOp& func) const; - -// template<typename Visitor> -// void visit(Visitor& func) const; - - -// const SparseCwise<Derived> cwise() const; -// SparseCwise<Derived> cwise(); - -// inline const WithFormat<Derived> format(const IOFormat& fmt) const; - -/////////// Array module /////////// - /* - bool all(void) const; - bool any(void) const; - - const VectorwiseOp<Derived,Horizontal> rowwise() const; - const VectorwiseOp<Derived,Vertical> colwise() const; - - static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(int rows, int cols); - static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(int size); - static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(); - - template<typename ThenDerived,typename ElseDerived> - const Select<Derived,ThenDerived,ElseDerived> - select(const MatrixBase<ThenDerived>& thenMatrix, - const MatrixBase<ElseDerived>& elseMatrix) const; - - template<typename ThenDerived> - inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> - select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const; - - template<typename ElseDerived> - inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > - select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const; - - template<int p> RealScalar lpNorm() const; - */ - - -// template<typename OtherDerived> -// Scalar dot(const MatrixBase<OtherDerived>& other) const -// { -// EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) -// EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) -// EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), -// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) -// -// eigen_assert(derived().size() == other.size()); -// // short version, but the assembly looks more complicated because -// // of the CwiseBinaryOp iterator complexity -// // return res = (derived().cwise() * other.derived().conjugate()).sum(); -// -// // optimized, generic version -// typename Derived::InnerIterator i(derived(),0); -// typename OtherDerived::InnerIterator j(other.derived(),0); -// Scalar res = 0; -// while (i && j) -// { -// if (i.index()==j.index()) -// { -// // std::cerr << i.value() << " * " << j.value() << "\n"; -// res += i.value() * internal::conj(j.value()); -// ++i; ++j; -// } -// else if (i.index()<j.index()) -// ++i; -// else -// ++j; -// } -// return res; -// } -// -// Scalar sum() const -// { -// Scalar res = 0; -// for (typename Derived::InnerIterator iter(*this,0); iter; ++iter) -// { -// res += iter.value(); -// } -// return res; -// } protected: bool m_isRValue; }; +} // end namespace Eigen + #endif // EIGEN_SPARSEMATRIXBASE_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h b/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h new file mode 100644 index 00000000000..b897b7595b5 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h @@ -0,0 +1,148 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_PERMUTATION_H +#define EIGEN_SPARSE_PERMUTATION_H + +// This file implements sparse * permutation products + +namespace Eigen { + +namespace internal { + +template<typename PermutationType, typename MatrixType, int Side, bool Transposed> +struct traits<permut_sparsematrix_product_retval<PermutationType, MatrixType, Side, Transposed> > +{ + typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; + typedef typename MatrixTypeNestedCleaned::Scalar Scalar; + typedef typename MatrixTypeNestedCleaned::Index Index; + enum { + SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, + MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight + }; + + typedef typename internal::conditional<MoveOuter, + SparseMatrix<Scalar,SrcStorageOrder,Index>, + SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,Index> >::type ReturnType; +}; + +template<typename PermutationType, typename MatrixType, int Side, bool Transposed> +struct permut_sparsematrix_product_retval + : public ReturnByValue<permut_sparsematrix_product_retval<PermutationType, MatrixType, Side, Transposed> > +{ + typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; + typedef typename MatrixTypeNestedCleaned::Scalar Scalar; + typedef typename MatrixTypeNestedCleaned::Index Index; + + enum { + SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, + MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight + }; + + permut_sparsematrix_product_retval(const PermutationType& perm, const MatrixType& matrix) + : m_permutation(perm), m_matrix(matrix) + {} + + inline int rows() const { return m_matrix.rows(); } + inline int cols() const { return m_matrix.cols(); } + + template<typename Dest> inline void evalTo(Dest& dst) const + { + if(MoveOuter) + { + SparseMatrix<Scalar,SrcStorageOrder,Index> tmp(m_matrix.rows(), m_matrix.cols()); + VectorXi sizes(m_matrix.outerSize()); + for(Index j=0; j<m_matrix.outerSize(); ++j) + { + Index jp = m_permutation.indices().coeff(j); + sizes[((Side==OnTheLeft) ^ Transposed) ? jp : j] = m_matrix.innerVector(((Side==OnTheRight) ^ Transposed) ? jp : j).size(); + } + tmp.reserve(sizes); + for(Index j=0; j<m_matrix.outerSize(); ++j) + { + Index jp = m_permutation.indices().coeff(j); + Index jsrc = ((Side==OnTheRight) ^ Transposed) ? jp : j; + Index jdst = ((Side==OnTheLeft) ^ Transposed) ? jp : j; + for(typename MatrixTypeNestedCleaned::InnerIterator it(m_matrix,jsrc); it; ++it) + tmp.insertByOuterInner(jdst,it.index()) = it.value(); + } + dst = tmp; + } + else + { + SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,Index> tmp(m_matrix.rows(), m_matrix.cols()); + VectorXi sizes(tmp.outerSize()); + sizes.setZero(); + PermutationMatrix<Dynamic,Dynamic,Index> perm; + if((Side==OnTheLeft) ^ Transposed) + perm = m_permutation; + else + perm = m_permutation.transpose(); + + for(Index j=0; j<m_matrix.outerSize(); ++j) + for(typename MatrixTypeNestedCleaned::InnerIterator it(m_matrix,j); it; ++it) + sizes[perm.indices().coeff(it.index())]++; + tmp.reserve(sizes); + for(Index j=0; j<m_matrix.outerSize(); ++j) + for(typename MatrixTypeNestedCleaned::InnerIterator it(m_matrix,j); it; ++it) + tmp.insertByOuterInner(perm.indices().coeff(it.index()),j) = it.value(); + dst = tmp; + } + } + + protected: + const PermutationType& m_permutation; + typename MatrixType::Nested m_matrix; +}; + +} + + + +/** \returns the matrix with the permutation applied to the columns + */ +template<typename SparseDerived, typename PermDerived> +inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, false> +operator*(const SparseMatrixBase<SparseDerived>& matrix, const PermutationBase<PermDerived>& perm) +{ + return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, false>(perm, matrix.derived()); +} + +/** \returns the matrix with the permutation applied to the rows + */ +template<typename SparseDerived, typename PermDerived> +inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, false> +operator*( const PermutationBase<PermDerived>& perm, const SparseMatrixBase<SparseDerived>& matrix) +{ + return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, false>(perm, matrix.derived()); +} + + + +/** \returns the matrix with the inverse permutation applied to the columns. + */ +template<typename SparseDerived, typename PermDerived> +inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, true> +operator*(const SparseMatrixBase<SparseDerived>& matrix, const Transpose<PermutationBase<PermDerived> >& tperm) +{ + return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, true>(tperm.nestedPermutation(), matrix.derived()); +} + +/** \returns the matrix with the inverse permutation applied to the rows. + */ +template<typename SparseDerived, typename PermDerived> +inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, true> +operator*(const Transpose<PermutationBase<PermDerived> >& tperm, const SparseMatrixBase<SparseDerived>& matrix) +{ + return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, true>(tperm.nestedPermutation(), matrix.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h index 1c1f54706ac..6a555b83434 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseProduct.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEPRODUCT_H #define EIGEN_SPARSEPRODUCT_H +namespace Eigen { + template<typename Lhs, typename Rhs> struct SparseSparseProductReturnType { @@ -38,11 +25,11 @@ struct SparseSparseProductReturnType typedef typename internal::conditional<TransposeLhs, SparseMatrix<Scalar,0>, - const typename internal::nested<Lhs,Rhs::RowsAtCompileTime>::type>::type LhsNested; + typename internal::nested<Lhs,Rhs::RowsAtCompileTime>::type>::type LhsNested; typedef typename internal::conditional<TransposeRhs, SparseMatrix<Scalar,0>, - const typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type>::type RhsNested; + typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type>::type RhsNested; typedef SparseSparseProduct<LhsNested, RhsNested> Type; }; @@ -106,9 +93,42 @@ class SparseSparseProduct : internal::no_assignment_operator, template<typename Lhs, typename Rhs> EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) + : m_lhs(lhs), m_rhs(rhs), m_tolerance(0), m_conservative(true) + { + init(); + } + + template<typename Lhs, typename Rhs> + EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, RealScalar tolerance) + : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false) + { + init(); + } + + SparseSparseProduct pruned(Scalar reference = 0, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) const + { + return SparseSparseProduct(m_lhs,m_rhs,internal::abs(reference)*epsilon); + } + + template<typename Dest> + void evalTo(Dest& result) const + { + if(m_conservative) + internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result); + else + internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance); + } + + EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } + + EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } + EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } + + protected: + void init() { - eigen_assert(lhs.cols() == rhs.rows()); + eigen_assert(m_lhs.cols() == m_rhs.rows()); enum { ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic @@ -127,15 +147,40 @@ class SparseSparseProduct : internal::no_assignment_operator, EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) } - EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } - - EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } - EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } - - protected: LhsNested m_lhs; RhsNested m_rhs; + RealScalar m_tolerance; + bool m_conservative; }; +// sparse = sparse * sparse +template<typename Derived> +template<typename Lhs, typename Rhs> +inline Derived& SparseMatrixBase<Derived>::operator=(const SparseSparseProduct<Lhs,Rhs>& product) +{ + product.evalTo(derived()); + return derived(); +} + +/** \returns an expression of the product of two sparse matrices. + * By default a conservative product preserving the symbolic non zeros is performed. + * The automatic pruning of the small values can be achieved by calling the pruned() function + * in which case a totally different product algorithm is employed: + * \code + * C = (A*B).pruned(); // supress numerical zeros (exact) + * C = (A*B).pruned(ref); + * C = (A*B).pruned(ref,epsilon); + * \endcode + * where \c ref is a meaningful non zero reference value. + * */ +template<typename Derived> +template<typename OtherDerived> +inline const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type +SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const +{ + return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); +} + +} // end namespace Eigen + #endif // EIGEN_SPARSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseRedux.h b/extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h index afc49de7aad..f3da93a71d4 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseRedux.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h @@ -3,34 +3,21 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEREDUX_H #define EIGEN_SPARSEREDUX_H +namespace Eigen { + template<typename Derived> typename internal::traits<Derived>::Scalar SparseMatrixBase<Derived>::sum() const { eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix"); - Scalar res = 0; + Scalar res(0); for (Index j=0; j<outerSize(); ++j) for (typename Derived::InnerIterator iter(derived(),j); iter; ++iter) res += iter.value(); @@ -53,4 +40,6 @@ SparseVector<_Scalar,_Options,_Index>::sum() const return Matrix<Scalar,1,Dynamic>::Map(&m_data.value(0), m_data.size()).sum(); } +} // end namespace Eigen + #endif // EIGEN_SPARSEREDUX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h index d82044c789c..86ec0a6c5e2 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h @@ -3,30 +3,17 @@ // // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_SELFADJOINTVIEW_H #define EIGEN_SPARSE_SELFADJOINTVIEW_H -/** \class SparseSelfAdjointView - * +namespace Eigen { + +/** \ingroup SparseCore_Module + * \class SparseSelfAdjointView * * \brief Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix. * @@ -45,9 +32,6 @@ class SparseSelfAdjointTimeDenseProduct; template<typename Lhs, typename Rhs, int UpLo> class DenseTimeSparseSelfAdjointProduct; -template<typename MatrixType,int UpLo> -class SparseSymmetricPermutationProduct; - namespace internal { template<typename MatrixType, unsigned int UpLo> @@ -106,9 +90,6 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView * * \returns a reference to \c *this * - * Note that it is faster to set alpha=0 than initializing the matrix to zero - * and then keep the default value alpha=1. - * * To perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply * call this function with u.adjoint(). */ @@ -116,21 +97,21 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView SparseSelfAdjointView& rankUpdate(const SparseMatrixBase<DerivedU>& u, Scalar alpha = Scalar(1)); /** \internal triggered by sparse_matrix = SparseSelfadjointView; */ - template<typename DestScalar> void evalTo(SparseMatrix<DestScalar>& _dest) const + template<typename DestScalar,int StorageOrder> void evalTo(SparseMatrix<DestScalar,StorageOrder,Index>& _dest) const { internal::permute_symm_to_fullsymm<UpLo>(m_matrix, _dest); } - template<typename DestScalar> void evalTo(DynamicSparseMatrix<DestScalar>& _dest) const + template<typename DestScalar> void evalTo(DynamicSparseMatrix<DestScalar,ColMajor,Index>& _dest) const { // TODO directly evaluate into _dest; - SparseMatrix<DestScalar> tmp(_dest.rows(),_dest.cols()); + SparseMatrix<DestScalar,ColMajor,Index> tmp(_dest.rows(),_dest.cols()); internal::permute_symm_to_fullsymm<UpLo>(m_matrix, tmp); _dest = tmp; } - /** \returns an expression of P^-1 H P */ - SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo> twistedBy(const PermutationMatrix<Dynamic>& perm) const + /** \returns an expression of P H P^-1 */ + SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const { return SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo>(m_matrix, perm); } @@ -141,6 +122,20 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView permutedMatrix.evalTo(*this); return *this; } + + + SparseSelfAdjointView& operator=(const SparseSelfAdjointView& src) + { + PermutationMatrix<Dynamic> pnull; + return *this = src.twistedBy(pnull); + } + + template<typename SrcMatrixType,unsigned int SrcUpLo> + SparseSelfAdjointView& operator=(const SparseSelfAdjointView<SrcMatrixType,SrcUpLo>& src) + { + PermutationMatrix<Dynamic> pnull; + return *this = src.twistedBy(pnull); + } // const SparseLLT<PlainObject, UpLo> llt() const; @@ -148,7 +143,7 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; mutable VectorI m_countPerRow; mutable VectorI m_countPerCol; }; @@ -230,12 +225,15 @@ class SparseSelfAdjointTimeDenseProduct for (Index j=0; j<m_lhs.outerSize(); ++j) { LhsInnerIterator i(m_lhs,j); - if (ProcessSecondHalf && i && (i.index()==j)) + if (ProcessSecondHalf) { - dest.row(j) += i.value() * m_rhs.row(j); - ++i; + while (i && i.index()<j) ++i; + if(i && i.index()==j) + { + dest.row(j) += i.value() * m_rhs.row(j); + ++i; + } } - Block<Dest,1,Dest::ColsAtCompileTime> dest_j(dest.row(LhsIsRowMajor ? j : 0)); for(; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i) { Index a = LhsIsRowMajor ? j : i.index(); @@ -300,7 +298,7 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix<typename Matri enum { StorageOrderMatch = int(Dest::IsRowMajor) == int(MatrixType::IsRowMajor) }; - eigen_assert(perm==0); + Index size = mat.rows(); VectorI count; count.resize(size); @@ -312,10 +310,14 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix<typename Matri for(typename MatrixType::InnerIterator it(mat,j); it; ++it) { Index i = it.index(); + Index r = it.row(); + Index c = it.col(); Index ip = perm ? perm[i] : i; - if(i==j) + if(UpLo==(Upper|Lower)) + count[StorageOrderMatch ? jp : ip]++; + else if(r==c) count[ip]++; - else if((UpLo==Lower && i>j) || (UpLo==Upper && i<j)) + else if(( UpLo==Lower && r>c) || ( UpLo==Upper && r<c)) { count[ip]++; count[jp]++; @@ -325,49 +327,65 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix<typename Matri Index nnz = count.sum(); // reserve space - dest.reserve(nnz); - dest._outerIndexPtr()[0] = 0; + dest.resizeNonZeros(nnz); + dest.outerIndexPtr()[0] = 0; for(Index j=0; j<size; ++j) - dest._outerIndexPtr()[j+1] = dest._outerIndexPtr()[j] + count[j]; + dest.outerIndexPtr()[j+1] = dest.outerIndexPtr()[j] + count[j]; for(Index j=0; j<size; ++j) - count[j] = dest._outerIndexPtr()[j]; + count[j] = dest.outerIndexPtr()[j]; // copy data for(Index j = 0; j<size; ++j) { - Index jp = perm ? perm[j] : j; for(typename MatrixType::InnerIterator it(mat,j); it; ++it) { Index i = it.index(); + Index r = it.row(); + Index c = it.col(); + + Index jp = perm ? perm[j] : j; Index ip = perm ? perm[i] : i; - if(i==j) + + if(UpLo==(Upper|Lower)) + { + Index k = count[StorageOrderMatch ? jp : ip]++; + dest.innerIndexPtr()[k] = StorageOrderMatch ? ip : jp; + dest.valuePtr()[k] = it.value(); + } + else if(r==c) { - int k = count[ip]++; - dest._innerIndexPtr()[k] = ip; - dest._valuePtr()[k] = it.value(); + Index k = count[ip]++; + dest.innerIndexPtr()[k] = ip; + dest.valuePtr()[k] = it.value(); } - else if((UpLo==Lower && i>j) || (UpLo==Upper && i<j)) + else if(( (UpLo&Lower)==Lower && r>c) || ( (UpLo&Upper)==Upper && r<c)) { - int k = count[jp]++; - dest._innerIndexPtr()[k] = ip; - dest._valuePtr()[k] = it.value(); + if(!StorageOrderMatch) + std::swap(ip,jp); + Index k = count[jp]++; + dest.innerIndexPtr()[k] = ip; + dest.valuePtr()[k] = it.value(); k = count[ip]++; - dest._innerIndexPtr()[k] = jp; - dest._valuePtr()[k] = internal::conj(it.value()); + dest.innerIndexPtr()[k] = jp; + dest.valuePtr()[k] = internal::conj(it.value()); } } } } -template<int SrcUpLo,int DstUpLo,typename MatrixType,int DestOrder> -void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DestOrder,typename MatrixType::Index>& _dest, const typename MatrixType::Index* perm) +template<int _SrcUpLo,int _DstUpLo,typename MatrixType,int DstOrder> +void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DstOrder,typename MatrixType::Index>& _dest, const typename MatrixType::Index* perm) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; - typedef SparseMatrix<Scalar,DestOrder,Index> Dest; - Dest& dest(_dest.derived()); + SparseMatrix<Scalar,DstOrder,Index>& dest(_dest.derived()); typedef Matrix<Index,Dynamic,1> VectorI; - //internal::conj_if<SrcUpLo!=DstUpLo> cj; + enum { + SrcOrder = MatrixType::IsRowMajor ? RowMajor : ColMajor, + StorageOrderMatch = int(SrcOrder) == int(DstOrder), + DstUpLo = DstOrder==RowMajor ? (_DstUpLo==Upper ? Lower : Upper) : _DstUpLo, + SrcUpLo = SrcOrder==RowMajor ? (_SrcUpLo==Upper ? Lower : Upper) : _SrcUpLo + }; Index size = mat.rows(); VectorI count(size); @@ -379,37 +397,40 @@ void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixTyp for(typename MatrixType::InnerIterator it(mat,j); it; ++it) { Index i = it.index(); - if((SrcUpLo==Lower && i<j) || (SrcUpLo==Upper && i>j)) + if((int(SrcUpLo)==int(Lower) && i<j) || (int(SrcUpLo)==int(Upper) && i>j)) continue; Index ip = perm ? perm[i] : i; - count[DstUpLo==Lower ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; + count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; } } - dest._outerIndexPtr()[0] = 0; + dest.outerIndexPtr()[0] = 0; for(Index j=0; j<size; ++j) - dest._outerIndexPtr()[j+1] = dest._outerIndexPtr()[j] + count[j]; - dest.resizeNonZeros(dest._outerIndexPtr()[size]); + dest.outerIndexPtr()[j+1] = dest.outerIndexPtr()[j] + count[j]; + dest.resizeNonZeros(dest.outerIndexPtr()[size]); for(Index j=0; j<size; ++j) - count[j] = dest._outerIndexPtr()[j]; + count[j] = dest.outerIndexPtr()[j]; for(Index j = 0; j<size; ++j) { - Index jp = perm ? perm[j] : j; + for(typename MatrixType::InnerIterator it(mat,j); it; ++it) { Index i = it.index(); - if((SrcUpLo==Lower && i<j) || (SrcUpLo==Upper && i>j)) + if((int(SrcUpLo)==int(Lower) && i<j) || (int(SrcUpLo)==int(Upper) && i>j)) continue; + Index jp = perm ? perm[j] : j; Index ip = perm? perm[i] : i; - Index k = count[DstUpLo==Lower ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; - dest._innerIndexPtr()[k] = DstUpLo==Lower ? (std::max)(ip,jp) : (std::min)(ip,jp); - if((DstUpLo==Lower && ip<jp) || (DstUpLo==Upper && ip>jp)) - dest._valuePtr()[k] = conj(it.value()); + Index k = count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; + dest.innerIndexPtr()[k] = int(DstUpLo)==int(Lower) ? (std::max)(ip,jp) : (std::min)(ip,jp); + + if(!StorageOrderMatch) std::swap(ip,jp); + if( ((int(DstUpLo)==int(Lower) && ip<jp) || (int(DstUpLo)==int(Upper) && ip>jp))) + dest.valuePtr()[k] = conj(it.value()); else - dest._valuePtr()[k] = it.value(); + dest.valuePtr()[k] = it.value(); } } } @@ -420,10 +441,12 @@ template<typename MatrixType,int UpLo> class SparseSymmetricPermutationProduct : public EigenBase<SparseSymmetricPermutationProduct<MatrixType,UpLo> > { - typedef PermutationMatrix<Dynamic> Perm; public: typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; + protected: + typedef PermutationMatrix<Dynamic,Dynamic,Index> Perm; + public: typedef Matrix<Index,Dynamic,1> VectorI; typedef typename MatrixType::Nested MatrixTypeNested; typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested; @@ -435,7 +458,8 @@ class SparseSymmetricPermutationProduct inline Index rows() const { return m_matrix.rows(); } inline Index cols() const { return m_matrix.cols(); } - template<typename DestScalar> void evalTo(SparseMatrix<DestScalar>& _dest) const + template<typename DestScalar, int Options, typename DstIndex> + void evalTo(SparseMatrix<DestScalar,Options,DstIndex>& _dest) const { internal::permute_symm_to_fullsymm<UpLo>(m_matrix,_dest,m_perm.indices().data()); } @@ -446,9 +470,11 @@ class SparseSymmetricPermutationProduct } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; const Perm& m_perm; }; +} // end namespace Eigen + #endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h new file mode 100644 index 00000000000..2438ac573d0 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h @@ -0,0 +1,149 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H +#define EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H + +namespace Eigen { + +namespace internal { + + +// perform a pseudo in-place sparse * sparse product assuming all matrices are col major +template<typename Lhs, typename Rhs, typename ResultType> +static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, typename ResultType::RealScalar tolerance) +{ + // return sparse_sparse_product_with_pruning_impl2(lhs,rhs,res); + + typedef typename remove_all<Lhs>::type::Scalar Scalar; + typedef typename remove_all<Lhs>::type::Index Index; + + // make sure to call innerSize/outerSize since we fake the storage order. + Index rows = lhs.innerSize(); + Index cols = rhs.outerSize(); + //int size = lhs.outerSize(); + eigen_assert(lhs.outerSize() == rhs.innerSize()); + + // allocate a temporary buffer + AmbiVector<Scalar,Index> tempVector(rows); + + // estimate the number of non zero entries + // given a rhs column containing Y non zeros, we assume that the respective Y columns + // of the lhs differs in average of one non zeros, thus the number of non zeros for + // the product of a rhs column with the lhs is X+Y where X is the average number of non zero + // per column of the lhs. + // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) + Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); + + // mimics a resizeByInnerOuter: + if(ResultType::IsRowMajor) + res.resize(cols, rows); + else + res.resize(rows, cols); + + res.reserve(estimated_nnz_prod); + double ratioColRes = double(estimated_nnz_prod)/double(lhs.rows()*rhs.cols()); + for (Index j=0; j<cols; ++j) + { + // FIXME: + //double ratioColRes = (double(rhs.innerVector(j).nonZeros()) + double(lhs.nonZeros())/double(lhs.cols()))/double(lhs.rows()); + // let's do a more accurate determination of the nnz ratio for the current column j of res + tempVector.init(ratioColRes); + tempVector.setZero(); + for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt) + { + // FIXME should be written like this: tmp += rhsIt.value() * lhs.col(rhsIt.index()) + tempVector.restart(); + Scalar x = rhsIt.value(); + for (typename Lhs::InnerIterator lhsIt(lhs, rhsIt.index()); lhsIt; ++lhsIt) + { + tempVector.coeffRef(lhsIt.index()) += lhsIt.value() * x; + } + } + res.startVec(j); + for (typename AmbiVector<Scalar,Index>::Iterator it(tempVector,tolerance); it; ++it) + res.insertBackByOuterInner(j,it.index()) = it.value(); + } + res.finalize(); +} + +template<typename Lhs, typename Rhs, typename ResultType, + int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit, + int RhsStorageOrder = traits<Rhs>::Flags&RowMajorBit, + int ResStorageOrder = traits<ResultType>::Flags&RowMajorBit> +struct sparse_sparse_product_with_pruning_selector; + +template<typename Lhs, typename Rhs, typename ResultType> +struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor> +{ + typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; + typedef typename ResultType::RealScalar RealScalar; + + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + typename remove_all<ResultType>::type _res(res.rows(), res.cols()); + internal::sparse_sparse_product_with_pruning_impl<Lhs,Rhs,ResultType>(lhs, rhs, _res, tolerance); + res.swap(_res); + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor> +{ + typedef typename ResultType::RealScalar RealScalar; + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + // we need a col-major matrix to hold the result + typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType; + SparseTemporaryType _res(res.rows(), res.cols()); + internal::sparse_sparse_product_with_pruning_impl<Lhs,Rhs,SparseTemporaryType>(lhs, rhs, _res, tolerance); + res = _res; + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor> +{ + typedef typename ResultType::RealScalar RealScalar; + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + // let's transpose the product to get a column x column product + typename remove_all<ResultType>::type _res(res.rows(), res.cols()); + internal::sparse_sparse_product_with_pruning_impl<Rhs,Lhs,ResultType>(rhs, lhs, _res, tolerance); + res.swap(_res); + } +}; + +template<typename Lhs, typename Rhs, typename ResultType> +struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor> +{ + typedef typename ResultType::RealScalar RealScalar; + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; + ColMajorMatrix colLhs(lhs); + ColMajorMatrix colRhs(rhs); + internal::sparse_sparse_product_with_pruning_impl<ColMajorMatrix,ColMajorMatrix,ResultType>(colLhs, colRhs, res, tolerance); + + // let's transpose the product to get a column x column product +// typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType; +// SparseTemporaryType _res(res.cols(), res.rows()); +// sparse_sparse_product_with_pruning_impl<Rhs,Lhs,SparseTemporaryType>(rhs, lhs, _res); +// res = _res.transpose(); + } +}; + +// NOTE the 2 others cases (col row *) must never occur since they are caught +// by ProductReturnType which transforms it to (col col *) by evaluating rhs. + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h b/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h index 2aea2fa32c7..273f9de688f 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSETRANSPOSE_H #define EIGEN_SPARSETRANSPOSE_H +namespace Eigen { + template<typename MatrixType> class TransposeImpl<MatrixType,Sparse> : public SparseMatrixBase<Transpose<MatrixType> > { @@ -39,17 +26,21 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Sparse> inline Index nonZeros() const { return derived().nestedExpression().nonZeros(); } }; +// NOTE: VC10 trigger an ICE if don't put typename TransposeImpl<MatrixType,Sparse>:: in front of Index, +// a typedef typename TransposeImpl<MatrixType,Sparse>::Index Index; +// does not fix the issue. +// An alternative is to define the nested class in the parent class itself. template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::InnerIterator : public _MatrixTypeNested::InnerIterator { typedef typename _MatrixTypeNested::InnerIterator Base; public: - EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, Index outer) + EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl<MatrixType,Sparse>::Index outer) : Base(trans.derived().nestedExpression(), outer) {} - inline Index row() const { return Base::col(); } - inline Index col() const { return Base::row(); } + inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); } + inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); } }; template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInnerIterator @@ -58,11 +49,13 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInn typedef typename _MatrixTypeNested::ReverseInnerIterator Base; public: - EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, Index outer) + EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl<MatrixType,Sparse>::Index outer) : Base(xpr.derived().nestedExpression(), outer) {} - inline Index row() const { return Base::col(); } - inline Index col() const { return Base::row(); } + inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); } + inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); } }; +} // end namespace Eigen + #endif // EIGEN_SPARSETRANSPOSE_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h new file mode 100644 index 00000000000..477e4bd94b0 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h @@ -0,0 +1,164 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_TRIANGULARVIEW_H +#define EIGEN_SPARSE_TRIANGULARVIEW_H + +namespace Eigen { + +namespace internal { + +template<typename MatrixType, int Mode> +struct traits<SparseTriangularView<MatrixType,Mode> > +: public traits<MatrixType> +{}; + +} // namespace internal + +template<typename MatrixType, int Mode> class SparseTriangularView + : public SparseMatrixBase<SparseTriangularView<MatrixType,Mode> > +{ + enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit)) + || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)), + SkipLast = !SkipFirst, + HasUnitDiag = (Mode&UnitDiag) ? 1 : 0 + }; + + public: + + EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView) + + class InnerIterator; + class ReverseInnerIterator; + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + typedef typename MatrixType::Nested MatrixTypeNested; + typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef; + typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; + + inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {} + + /** \internal */ + inline const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } + + template<typename OtherDerived> + typename internal::plain_matrix_type_column_major<OtherDerived>::type + solve(const MatrixBase<OtherDerived>& other) const; + + template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const; + template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const; + + protected: + MatrixTypeNested m_matrix; +}; + +template<typename MatrixType, int Mode> +class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator +{ + typedef typename MatrixTypeNestedCleaned::InnerIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer) + : Base(view.nestedExpression(), outer), m_returnOne(false) + { + if(SkipFirst) + { + while((*this) && (HasUnitDiag ? this->index()<=outer : this->index()<outer)) + Base::operator++(); + if(HasUnitDiag) + m_returnOne = true; + } + else if(HasUnitDiag && ((!Base::operator bool()) || Base::index()>=Base::outer())) + { + if((!SkipFirst) && Base::operator bool()) + Base::operator++(); + m_returnOne = true; + } + } + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { + if(HasUnitDiag && m_returnOne) + m_returnOne = false; + else + { + Base::operator++(); + if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer())) + { + if((!SkipFirst) && Base::operator bool()) + Base::operator++(); + m_returnOne = true; + } + } + return *this; + } + + inline Index row() const { return Base::row(); } + inline Index col() const { return Base::col(); } + inline Index index() const + { + if(HasUnitDiag && m_returnOne) return Base::outer(); + else return Base::index(); + } + inline Scalar value() const + { + if(HasUnitDiag && m_returnOne) return Scalar(1); + else return Base::value(); + } + + EIGEN_STRONG_INLINE operator bool() const + { + if(HasUnitDiag && m_returnOne) + return true; + return (SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() <= this->outer())); + } + protected: + bool m_returnOne; +}; + +template<typename MatrixType, int Mode> +class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator +{ + typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer) + : Base(view.nestedExpression(), outer) + { + eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal"); + if(SkipLast) + while((*this) && this->index()>outer) + --(*this); + } + + EIGEN_STRONG_INLINE InnerIterator& operator--() + { Base::operator--(); return *this; } + + inline Index row() const { return Base::row(); } + inline Index col() const { return Base::col(); } + + EIGEN_STRONG_INLINE operator bool() const + { + return SkipLast ? Base::operator bool() : (Base::operator bool() && this->index() >= this->outer()); + } +}; + +template<typename Derived> +template<int Mode> +inline const SparseTriangularView<Derived, Mode> +SparseMatrixBase<Derived>::triangularView() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseUtil.h b/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h index db9ae98e7a0..6062a086ff7 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseUtil.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEUTIL_H #define EIGEN_SPARSEUTIL_H +namespace Eigen { + #ifdef NDEBUG #define EIGEN_DBG_SPARSE(X) #else @@ -58,22 +45,22 @@ EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) #define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \ typedef BaseClass Base; \ - typedef typename Eigen::internal::traits<Derived>::Scalar Scalar; \ + typedef typename Eigen::internal::traits<Derived >::Scalar Scalar; \ typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ - typedef typename Eigen::internal::nested<Derived>::type Nested; \ - typedef typename Eigen::internal::traits<Derived>::StorageKind StorageKind; \ - typedef typename Eigen::internal::traits<Derived>::Index Index; \ - enum { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \ - ColsAtCompileTime = Eigen::internal::traits<Derived>::ColsAtCompileTime, \ - Flags = Eigen::internal::traits<Derived>::Flags, \ - CoeffReadCost = Eigen::internal::traits<Derived>::CoeffReadCost, \ + typedef typename Eigen::internal::nested<Derived >::type Nested; \ + typedef typename Eigen::internal::traits<Derived >::StorageKind StorageKind; \ + typedef typename Eigen::internal::traits<Derived >::Index Index; \ + enum { RowsAtCompileTime = Eigen::internal::traits<Derived >::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::internal::traits<Derived >::ColsAtCompileTime, \ + Flags = Eigen::internal::traits<Derived >::Flags, \ + CoeffReadCost = Eigen::internal::traits<Derived >::CoeffReadCost, \ SizeAtCompileTime = Base::SizeAtCompileTime, \ IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ using Base::derived; \ using Base::const_cast_derived; #define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \ - _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived>) + _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived >) const int CoherentAccessPattern = 0x1; const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern; @@ -100,20 +87,43 @@ template<typename Lhs, typename Rhs, bool Transpose> class SparseDenseOuterProdu template<typename Lhs, typename Rhs> struct SparseSparseProductReturnType; template<typename Lhs, typename Rhs, int InnerSize = internal::traits<Lhs>::ColsAtCompileTime> struct DenseSparseProductReturnType; template<typename Lhs, typename Rhs, int InnerSize = internal::traits<Lhs>::ColsAtCompileTime> struct SparseDenseProductReturnType; +template<typename MatrixType,int UpLo> class SparseSymmetricPermutationProduct; namespace internal { +template<typename T,int Rows,int Cols> struct sparse_eval; + template<typename T> struct eval<T,Sparse> -{ + : public sparse_eval<T, traits<T>::RowsAtCompileTime,traits<T>::ColsAtCompileTime> +{}; + +template<typename T,int Cols> struct sparse_eval<T,1,Cols> { typedef typename traits<T>::Scalar _Scalar; - enum { - _Flags = traits<T>::Flags - }; + enum { _Flags = traits<T>::Flags| RowMajorBit }; + public: + typedef SparseVector<_Scalar, _Flags> type; +}; +template<typename T,int Rows> struct sparse_eval<T,Rows,1> { + typedef typename traits<T>::Scalar _Scalar; + enum { _Flags = traits<T>::Flags & (~RowMajorBit) }; + public: + typedef SparseVector<_Scalar, _Flags> type; +}; + +template<typename T,int Rows,int Cols> struct sparse_eval { + typedef typename traits<T>::Scalar _Scalar; + enum { _Flags = traits<T>::Flags }; public: typedef SparseMatrix<_Scalar, _Flags> type; }; +template<typename T> struct sparse_eval<T,1,1> { + typedef typename traits<T>::Scalar _Scalar; + public: + typedef Matrix<_Scalar, 1, 1> type; +}; + template<typename T> struct plain_matrix_type<T,Sparse> { typedef typename traits<T>::Scalar _Scalar; @@ -127,4 +137,37 @@ template<typename T> struct plain_matrix_type<T,Sparse> } // end namespace internal +/** \ingroup SparseCore_Module + * + * \class Triplet + * + * \brief A small structure to hold a non zero as a triplet (i,j,value). + * + * \sa SparseMatrix::setFromTriplets() + */ +template<typename Scalar, typename Index=unsigned int> +class Triplet +{ +public: + Triplet() : m_row(0), m_col(0), m_value(0) {} + + Triplet(const Index& i, const Index& j, const Scalar& v = Scalar(0)) + : m_row(i), m_col(j), m_value(v) + {} + + /** \returns the row index of the element */ + const Index& row() const { return m_row; } + + /** \returns the column index of the element */ + const Index& col() const { return m_col; } + + /** \returns the value of the element */ + const Scalar& value() const { return m_value; } +protected: + Index m_row, m_col; + Scalar m_value; +}; + +} // end namespace Eigen + #endif // EIGEN_SPARSEUTIL_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseVector.h b/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h index ce4bb51a27e..c952f654038 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseVector.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h @@ -3,29 +3,17 @@ // // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEVECTOR_H #define EIGEN_SPARSEVECTOR_H -/** \class SparseVector +namespace Eigen { + +/** \ingroup SparseCore_Module + * \class SparseVector * * \brief a sparse vector class * @@ -46,13 +34,13 @@ struct traits<SparseVector<_Scalar, _Options, _Index> > typedef Sparse StorageKind; typedef MatrixXpr XprKind; enum { - IsColVector = _Options & RowMajorBit ? 0 : 1, + IsColVector = (_Options & RowMajorBit) ? 0 : 1, RowsAtCompileTime = IsColVector ? Dynamic : 1, ColsAtCompileTime = IsColVector ? 1 : Dynamic, MaxRowsAtCompileTime = RowsAtCompileTime, MaxColsAtCompileTime = ColsAtCompileTime, - Flags = _Options | NestByRefBit | LvalueBit, + Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit), CoeffReadCost = NumTraits<Scalar>::ReadCost, SupportedAccessPatterns = InnerRandomAccessPattern }; @@ -67,7 +55,6 @@ class SparseVector EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector) EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=) EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=) -// EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, =) protected: public: @@ -79,11 +66,11 @@ class SparseVector Options = _Options }; - CompressedStorage<Scalar,Index> m_data; + internal::CompressedStorage<Scalar,Index> m_data; Index m_size; - CompressedStorage<Scalar,Index>& _data() { return m_data; } - CompressedStorage<Scalar,Index>& _data() const { return m_data; } + internal::CompressedStorage<Scalar,Index>& _data() { return m_data; } + internal::CompressedStorage<Scalar,Index>& _data() const { return m_data; } public: @@ -91,13 +78,12 @@ class SparseVector EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; } EIGEN_STRONG_INLINE Index innerSize() const { return m_size; } EIGEN_STRONG_INLINE Index outerSize() const { return 1; } - EIGEN_STRONG_INLINE Index innerNonZeros(Index j) const { eigen_assert(j==0); return m_size; } - EIGEN_STRONG_INLINE const Scalar* _valuePtr() const { return &m_data.value(0); } - EIGEN_STRONG_INLINE Scalar* _valuePtr() { return &m_data.value(0); } + EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); } + EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); } - EIGEN_STRONG_INLINE const Index* _innerIndexPtr() const { return &m_data.index(0); } - EIGEN_STRONG_INLINE Index* _innerIndexPtr() { return &m_data.index(0); } + EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); } + EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); } inline Scalar coeff(Index row, Index col) const { @@ -126,6 +112,7 @@ class SparseVector public: class InnerIterator; + class ReverseInnerIterator; inline void setZero() { m_data.clear(); } @@ -134,11 +121,13 @@ class SparseVector inline void startVec(Index outer) { + EIGEN_UNUSED_VARIABLE(outer); eigen_assert(outer==0); } inline Scalar& insertBackByOuterInner(Index outer, Index inner) { + EIGEN_UNUSED_VARIABLE(outer); eigen_assert(outer==0); return insertBack(inner); } @@ -158,7 +147,7 @@ class SparseVector Scalar& insert(Index i) { Index startId = 0; - Index p = m_data.size() - 1; + Index p = Index(m_data.size()) - 1; // TODO smart realloc m_data.resize(p+2,1); @@ -206,13 +195,6 @@ class SparseVector inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); } template<typename OtherDerived> - inline SparseVector(const MatrixBase<OtherDerived>& other) - : m_size(0) - { - *this = other.derived(); - } - - template<typename OtherDerived> inline SparseVector(const SparseMatrixBase<OtherDerived>& other) : m_size(0) { @@ -249,9 +231,9 @@ class SparseVector inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other) { if (int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime)) - return Base::operator=(other.transpose()); + return assign(other.transpose()); else - return Base::operator=(other); + return assign(other); } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -262,56 +244,6 @@ class SparseVector } #endif -// const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); -// if (needToTranspose) -// { -// // two passes algorithm: -// // 1 - compute the number of coeffs per dest inner vector -// // 2 - do the actual copy/eval -// // Since each coeff of the rhs has to be evaluated twice, let's evauluate it if needed -// typedef typename internal::nested<OtherDerived,2>::type OtherCopy; -// OtherCopy otherCopy(other.derived()); -// typedef typename internal::remove_all<OtherCopy>::type _OtherCopy; -// -// resize(other.rows(), other.cols()); -// Eigen::Map<VectorXi>(m_outerIndex,outerSize()).setZero(); -// // pass 1 -// // FIXME the above copy could be merged with that pass -// for (int j=0; j<otherCopy.outerSize(); ++j) -// for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) -// ++m_outerIndex[it.index()]; -// -// // prefix sum -// int count = 0; -// VectorXi positions(outerSize()); -// for (int j=0; j<outerSize(); ++j) -// { -// int tmp = m_outerIndex[j]; -// m_outerIndex[j] = count; -// positions[j] = count; -// count += tmp; -// } -// m_outerIndex[outerSize()] = count; -// // alloc -// m_data.resize(count); -// // pass 2 -// for (int j=0; j<otherCopy.outerSize(); ++j) -// for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) -// { -// int pos = positions[it.index()]++; -// m_data.index(pos) = j; -// m_data.value(pos) = it.value(); -// } -// -// return *this; -// } -// else -// { -// // there is no special optimization -// return SparseMatrixBase<SparseMatrix>::operator=(other.derived()); -// } -// } - friend std::ostream & operator << (std::ostream & s, const SparseVector& m) { for (Index i=0; i<m.nonZeros(); ++i) @@ -320,28 +252,6 @@ class SparseVector return s; } - // this specialized version does not seems to be faster -// Scalar dot(const SparseVector& other) const -// { -// int i=0, j=0; -// Scalar res = 0; -// asm("#begindot"); -// while (i<nonZeros() && j<other.nonZeros()) -// { -// if (m_data.index(i)==other.m_data.index(j)) -// { -// res += m_data.value(i) * internal::conj(other.m_data.value(j)); -// ++i; ++j; -// } -// else if (m_data.index(i)<other.m_data.index(j)) -// ++i; -// else -// ++j; -// } -// asm("#enddot"); -// return res; -// } - /** Destructor */ inline ~SparseVector() {} @@ -390,6 +300,33 @@ class SparseVector # ifdef EIGEN_SPARSEVECTOR_PLUGIN # include EIGEN_SPARSEVECTOR_PLUGIN # endif + +protected: + template<typename OtherDerived> + EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other) + { + const OtherDerived& other(_other.derived()); + const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + if(needToTranspose) + { + Index size = other.size(); + Index nnz = other.nonZeros(); + resize(size); + reserve(nnz); + for(Index i=0; i<size; ++i) + { + typename OtherDerived::InnerIterator it(other, i); + if(it) + insert(i) = it.value(); + } + return *this; + } + else + { + // there is no special optimization + return Base::operator=(other); + } + } }; template<typename Scalar, int _Options, typename _Index> @@ -399,18 +336,14 @@ class SparseVector<Scalar,_Options,_Index>::InnerIterator InnerIterator(const SparseVector& vec, Index outer=0) : m_data(vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size())) { + EIGEN_UNUSED_VARIABLE(outer); eigen_assert(outer==0); } - InnerIterator(const CompressedStorage<Scalar,Index>& data) + InnerIterator(const internal::CompressedStorage<Scalar,Index>& data) : m_data(data), m_id(0), m_end(static_cast<Index>(m_data.size())) {} - template<unsigned int Added, unsigned int Removed> - InnerIterator(const Flagged<SparseVector,Added,Removed>& vec, Index ) - : m_data(vec._expression().m_data), m_id(0), m_end(m_data.size()) - {} - inline InnerIterator& operator++() { m_id++; return *this; } inline Scalar value() const { return m_data.value(m_id); } @@ -423,9 +356,43 @@ class SparseVector<Scalar,_Options,_Index>::InnerIterator inline operator bool() const { return (m_id < m_end); } protected: - const CompressedStorage<Scalar,Index>& m_data; + const internal::CompressedStorage<Scalar,Index>& m_data; Index m_id; const Index m_end; }; +template<typename Scalar, int _Options, typename _Index> +class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator +{ + public: + ReverseInnerIterator(const SparseVector& vec, Index outer=0) + : m_data(vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0) + { + EIGEN_UNUSED_VARIABLE(outer); + eigen_assert(outer==0); + } + + ReverseInnerIterator(const internal::CompressedStorage<Scalar,Index>& data) + : m_data(data), m_id(static_cast<Index>(m_data.size())), m_start(0) + {} + + inline ReverseInnerIterator& operator--() { m_id--; return *this; } + + inline Scalar value() const { return m_data.value(m_id-1); } + inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id-1)); } + + inline Index index() const { return m_data.index(m_id-1); } + inline Index row() const { return IsColVector ? index() : 0; } + inline Index col() const { return IsColVector ? 0 : index(); } + + inline operator bool() const { return (m_id > m_start); } + + protected: + const internal::CompressedStorage<Scalar,Index>& m_data; + Index m_id; + const Index m_start; +}; + +} // end namespace Eigen + #endif // EIGEN_SPARSEVECTOR_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseView.h index 24306561098..8b0b9ea0304 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseView.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseView.h @@ -1,31 +1,18 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010 Daniel Lowengrub <lowdanie@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEVIEW_H #define EIGEN_SPARSEVIEW_H +namespace Eigen { + namespace internal { template<typename MatrixType> @@ -61,7 +48,7 @@ public: inline Index outerSize() const { return m_matrix.outerSize(); } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; Scalar m_reference; typename NumTraits<Scalar>::Real m_epsilon; }; @@ -92,10 +79,10 @@ protected: private: void incrementToNonZero() { - while(internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon) && (bool(*this))) - { - IterBase::operator++(); - } + while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon)) + { + IterBase::operator++(); + } } }; @@ -106,4 +93,6 @@ const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& m_refere return SparseView<Derived>(derived(), m_reference, m_epsilon); } +} // end namespace Eigen + #endif diff --git a/extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h b/extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h index 62bb8bb44c9..cb8ad82b4f6 100644 --- a/extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h +++ b/extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSETRIANGULARSOLVER_H #define EIGEN_SPARSETRIANGULARSOLVER_H +namespace Eigen { + namespace internal { template<typename Lhs, typename Rhs, int Mode, @@ -48,7 +35,7 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,RowMajor> for(int i=0; i<lhs.rows(); ++i) { Scalar tmp = other.coeff(i,col); - Scalar lastVal = 0; + Scalar lastVal(0); int lastIndex = 0; for(typename Lhs::InnerIterator it(lhs, i); it; ++it) { @@ -82,8 +69,17 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,RowMajor> for(int i=lhs.rows()-1 ; i>=0 ; --i) { Scalar tmp = other.coeff(i,col); + Scalar l_ii = 0; typename Lhs::InnerIterator it(lhs, i); - if (it && it.index() == i) + while(it && it.index()<i) + ++it; + if(!(Mode & UnitDiag)) + { + eigen_assert(it && it.index()==i); + l_ii = it.value(); + ++it; + } + else if (it && it.index() == i) ++it; for(; it; ++it) { @@ -93,11 +89,7 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,RowMajor> if (Mode & UnitDiag) other.coeffRef(i,col) = tmp; else - { - typename Lhs::InnerIterator it(lhs, i); - eigen_assert(it && it.index() == i); - other.coeffRef(i,col) = tmp/it.value(); - } + other.coeffRef(i,col) = tmp/l_ii; } } } @@ -118,9 +110,11 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,ColMajor> if (tmp!=Scalar(0)) // optimization when other is actually sparse { typename Lhs::InnerIterator it(lhs, i); + while(it && it.index()<i) + ++it; if(!(Mode & UnitDiag)) { - eigen_assert(it.index()==i); + eigen_assert(it && it.index()==i); tmp /= it.value(); } if (it && it.index()==i) @@ -149,9 +143,12 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,ColMajor> { if(!(Mode & UnitDiag)) { - // FIXME lhs.coeff(i,i) might not be always efficient while it must simply be the - // last element of the column ! - other.coeffRef(i,col) /= lhs.innerVector(i).lastCoeff(); + // TODO replace this by a binary search. make sure the binary search is safe for partially sorted elements + typename Lhs::ReverseInnerIterator it(lhs, i); + while(it && it.index()!=i) + --it; + eigen_assert(it && it.index()==i); + other.coeffRef(i,col) /= it.value(); } typename Lhs::InnerIterator it(lhs, i); for(; it && it.index()<i; ++it) @@ -168,10 +165,8 @@ template<typename ExpressionType,int Mode> template<typename OtherDerived> void SparseTriangularView<ExpressionType,Mode>::solveInPlace(MatrixBase<OtherDerived>& other) const { - eigen_assert(m_matrix.cols() == m_matrix.rows()); - eigen_assert(m_matrix.cols() == other.rows()); - eigen_assert(!(Mode & ZeroDiag)); - eigen_assert((Mode & (Upper|Lower)) != 0); + eigen_assert(m_matrix.cols() == m_matrix.rows() && m_matrix.cols() == other.rows()); + eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit }; @@ -295,10 +290,8 @@ template<typename ExpressionType,int Mode> template<typename OtherDerived> void SparseTriangularView<ExpressionType,Mode>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const { - eigen_assert(m_matrix.cols() == m_matrix.rows()); - eigen_assert(m_matrix.cols() == other.rows()); - eigen_assert(!(Mode & ZeroDiag)); - eigen_assert((Mode & (Upper|Lower)) != 0); + eigen_assert(m_matrix.cols() == m_matrix.rows() && m_matrix.cols() == other.rows()); + eigen_assert( (!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); // enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit }; @@ -336,4 +329,6 @@ SparseMatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other } #endif // EIGEN2_SUPPORT +} // end namespace Eigen + #endif // EIGEN_SPARSETRIANGULARSOLVER_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h b/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h index 6f12c106dbc..4ee8e5c10a5 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDDEQUE_H #define EIGEN_STDDEQUE_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdList.h b/extern/Eigen3/Eigen/src/StlSupport/StdList.h index d329a0b2dc5..627381ecec0 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdList.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdList.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDLIST_H #define EIGEN_STDLIST_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h index 27d6ab539f9..40a9abefa82 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDVECTOR_H #define EIGEN_STDVECTOR_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/details.h b/extern/Eigen3/Eigen/src/StlSupport/details.h index 397c8ef8581..d8debc7c4f8 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/details.h +++ b/extern/Eigen3/Eigen/src/StlSupport/details.h @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STL_DETAILS_H #define EIGEN_STL_DETAILS_H diff --git a/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h b/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h new file mode 100644 index 00000000000..11fb014dd93 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h @@ -0,0 +1,1025 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SUPERLUSUPPORT_H +#define EIGEN_SUPERLUSUPPORT_H + +namespace Eigen { + +#define DECL_GSSVX(PREFIX,FLOATTYPE,KEYTYPE) \ + extern "C" { \ + typedef struct { FLOATTYPE for_lu; FLOATTYPE total_needed; int expansions; } PREFIX##mem_usage_t; \ + extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, \ + char *, FLOATTYPE *, FLOATTYPE *, SuperMatrix *, SuperMatrix *, \ + void *, int, SuperMatrix *, SuperMatrix *, \ + FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, \ + PREFIX##mem_usage_t *, SuperLUStat_t *, int *); \ + } \ + inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, \ + int *perm_c, int *perm_r, int *etree, char *equed, \ + FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ + SuperMatrix *U, void *work, int lwork, \ + SuperMatrix *B, SuperMatrix *X, \ + FLOATTYPE *recip_pivot_growth, \ + FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, \ + SuperLUStat_t *stats, int *info, KEYTYPE) { \ + PREFIX##mem_usage_t mem_usage; \ + PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, \ + U, work, lwork, B, X, recip_pivot_growth, rcond, \ + ferr, berr, &mem_usage, stats, info); \ + return mem_usage.for_lu; /* bytes used by the factor storage */ \ + } + +DECL_GSSVX(s,float,float) +DECL_GSSVX(c,float,std::complex<float>) +DECL_GSSVX(d,double,double) +DECL_GSSVX(z,double,std::complex<double>) + +#ifdef MILU_ALPHA +#define EIGEN_SUPERLU_HAS_ILU +#endif + +#ifdef EIGEN_SUPERLU_HAS_ILU + +// similarly for the incomplete factorization using gsisx +#define DECL_GSISX(PREFIX,FLOATTYPE,KEYTYPE) \ + extern "C" { \ + extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, \ + char *, FLOATTYPE *, FLOATTYPE *, SuperMatrix *, SuperMatrix *, \ + void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, FLOATTYPE *, \ + PREFIX##mem_usage_t *, SuperLUStat_t *, int *); \ + } \ + inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, \ + int *perm_c, int *perm_r, int *etree, char *equed, \ + FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ + SuperMatrix *U, void *work, int lwork, \ + SuperMatrix *B, SuperMatrix *X, \ + FLOATTYPE *recip_pivot_growth, \ + FLOATTYPE *rcond, \ + SuperLUStat_t *stats, int *info, KEYTYPE) { \ + PREFIX##mem_usage_t mem_usage; \ + PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, \ + U, work, lwork, B, X, recip_pivot_growth, rcond, \ + &mem_usage, stats, info); \ + return mem_usage.for_lu; /* bytes used by the factor storage */ \ + } + +DECL_GSISX(s,float,float) +DECL_GSISX(c,float,std::complex<float>) +DECL_GSISX(d,double,double) +DECL_GSISX(z,double,std::complex<double>) + +#endif + +template<typename MatrixType> +struct SluMatrixMapHelper; + +/** \internal + * + * A wrapper class for SuperLU matrices. It supports only compressed sparse matrices + * and dense matrices. Supernodal and other fancy format are not supported by this wrapper. + * + * This wrapper class mainly aims to avoids the need of dynamic allocation of the storage structure. + */ +struct SluMatrix : SuperMatrix +{ + SluMatrix() + { + Store = &storage; + } + + SluMatrix(const SluMatrix& other) + : SuperMatrix(other) + { + Store = &storage; + storage = other.storage; + } + + SluMatrix& operator=(const SluMatrix& other) + { + SuperMatrix::operator=(static_cast<const SuperMatrix&>(other)); + Store = &storage; + storage = other.storage; + return *this; + } + + struct + { + union {int nnz;int lda;}; + void *values; + int *innerInd; + int *outerInd; + } storage; + + void setStorageType(Stype_t t) + { + Stype = t; + if (t==SLU_NC || t==SLU_NR || t==SLU_DN) + Store = &storage; + else + { + eigen_assert(false && "storage type not supported"); + Store = 0; + } + } + + template<typename Scalar> + void setScalarType() + { + if (internal::is_same<Scalar,float>::value) + Dtype = SLU_S; + else if (internal::is_same<Scalar,double>::value) + Dtype = SLU_D; + else if (internal::is_same<Scalar,std::complex<float> >::value) + Dtype = SLU_C; + else if (internal::is_same<Scalar,std::complex<double> >::value) + Dtype = SLU_Z; + else + { + eigen_assert(false && "Scalar type not supported by SuperLU"); + } + } + + template<typename MatrixType> + static SluMatrix Map(MatrixBase<MatrixType>& _mat) + { + MatrixType& mat(_mat.derived()); + eigen_assert( ((MatrixType::Flags&RowMajorBit)!=RowMajorBit) && "row-major dense matrices are not supported by SuperLU"); + SluMatrix res; + res.setStorageType(SLU_DN); + res.setScalarType<typename MatrixType::Scalar>(); + res.Mtype = SLU_GE; + + res.nrow = mat.rows(); + res.ncol = mat.cols(); + + res.storage.lda = MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride(); + res.storage.values = mat.data(); + return res; + } + + template<typename MatrixType> + static SluMatrix Map(SparseMatrixBase<MatrixType>& mat) + { + SluMatrix res; + if ((MatrixType::Flags&RowMajorBit)==RowMajorBit) + { + res.setStorageType(SLU_NR); + res.nrow = mat.cols(); + res.ncol = mat.rows(); + } + else + { + res.setStorageType(SLU_NC); + res.nrow = mat.rows(); + res.ncol = mat.cols(); + } + + res.Mtype = SLU_GE; + + res.storage.nnz = mat.nonZeros(); + res.storage.values = mat.derived().valuePtr(); + res.storage.innerInd = mat.derived().innerIndexPtr(); + res.storage.outerInd = mat.derived().outerIndexPtr(); + + res.setScalarType<typename MatrixType::Scalar>(); + + // FIXME the following is not very accurate + if (MatrixType::Flags & Upper) + res.Mtype = SLU_TRU; + if (MatrixType::Flags & Lower) + res.Mtype = SLU_TRL; + + eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU"); + + return res; + } +}; + +template<typename Scalar, int Rows, int Cols, int Options, int MRows, int MCols> +struct SluMatrixMapHelper<Matrix<Scalar,Rows,Cols,Options,MRows,MCols> > +{ + typedef Matrix<Scalar,Rows,Cols,Options,MRows,MCols> MatrixType; + static void run(MatrixType& mat, SluMatrix& res) + { + eigen_assert( ((Options&RowMajor)!=RowMajor) && "row-major dense matrices is not supported by SuperLU"); + res.setStorageType(SLU_DN); + res.setScalarType<Scalar>(); + res.Mtype = SLU_GE; + + res.nrow = mat.rows(); + res.ncol = mat.cols(); + + res.storage.lda = mat.outerStride(); + res.storage.values = mat.data(); + } +}; + +template<typename Derived> +struct SluMatrixMapHelper<SparseMatrixBase<Derived> > +{ + typedef Derived MatrixType; + static void run(MatrixType& mat, SluMatrix& res) + { + if ((MatrixType::Flags&RowMajorBit)==RowMajorBit) + { + res.setStorageType(SLU_NR); + res.nrow = mat.cols(); + res.ncol = mat.rows(); + } + else + { + res.setStorageType(SLU_NC); + res.nrow = mat.rows(); + res.ncol = mat.cols(); + } + + res.Mtype = SLU_GE; + + res.storage.nnz = mat.nonZeros(); + res.storage.values = mat.valuePtr(); + res.storage.innerInd = mat.innerIndexPtr(); + res.storage.outerInd = mat.outerIndexPtr(); + + res.setScalarType<typename MatrixType::Scalar>(); + + // FIXME the following is not very accurate + if (MatrixType::Flags & Upper) + res.Mtype = SLU_TRU; + if (MatrixType::Flags & Lower) + res.Mtype = SLU_TRL; + + eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU"); + } +}; + +namespace internal { + +template<typename MatrixType> +SluMatrix asSluMatrix(MatrixType& mat) +{ + return SluMatrix::Map(mat); +} + +/** View a Super LU matrix as an Eigen expression */ +template<typename Scalar, int Flags, typename Index> +MappedSparseMatrix<Scalar,Flags,Index> map_superlu(SluMatrix& sluMat) +{ + eigen_assert((Flags&RowMajor)==RowMajor && sluMat.Stype == SLU_NR + || (Flags&ColMajor)==ColMajor && sluMat.Stype == SLU_NC); + + Index outerSize = (Flags&RowMajor)==RowMajor ? sluMat.ncol : sluMat.nrow; + + return MappedSparseMatrix<Scalar,Flags,Index>( + sluMat.nrow, sluMat.ncol, sluMat.storage.outerInd[outerSize], + sluMat.storage.outerInd, sluMat.storage.innerInd, reinterpret_cast<Scalar*>(sluMat.storage.values) ); +} + +} // end namespace internal + +/** \ingroup SuperLUSupport_Module + * \class SuperLUBase + * \brief The base class for the direct and incomplete LU factorization of SuperLU + */ +template<typename _MatrixType, typename Derived> +class SuperLUBase : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix<Scalar,Dynamic,1> Vector; + typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType; + typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType; + typedef SparseMatrix<Scalar> LUMatrixType; + + public: + + SuperLUBase() {} + + ~SuperLUBase() + { + clearFactors(); + } + + Derived& derived() { return *static_cast<Derived*>(this); } + const Derived& derived() const { return *static_cast<const Derived*>(this); } + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + /** \returns a reference to the Super LU option object to configure the Super LU algorithms. */ + inline superlu_options_t& options() { return m_sluOptions; } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + void compute(const MatrixType& matrix) + { + derived().analyzePattern(matrix); + derived().factorize(matrix); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::solve_retval<SuperLUBase, Rhs> solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "SuperLU is not initialized."); + eigen_assert(rows()==b.rows() + && "SuperLU::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<SuperLUBase, Rhs>(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ +// template<typename Rhs> +// inline const internal::sparse_solve_retval<SuperLU, Rhs> solve(const SparseMatrixBase<Rhs>& b) const +// { +// eigen_assert(m_isInitialized && "SuperLU is not initialized."); +// eigen_assert(rows()==b.rows() +// && "SuperLU::solve(): invalid number of rows of the right hand side matrix b"); +// return internal::sparse_solve_retval<SuperLU, Rhs>(*this, b.derived()); +// } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& /*matrix*/) + { + m_isInitialized = true; + m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + template<typename Stream> + void dumpMemory(Stream& s) + {} + + protected: + + void initFactorization(const MatrixType& a) + { + set_default_options(&this->m_sluOptions); + + const int size = a.rows(); + m_matrix = a; + + m_sluA = internal::asSluMatrix(m_matrix); + clearFactors(); + + m_p.resize(size); + m_q.resize(size); + m_sluRscale.resize(size); + m_sluCscale.resize(size); + m_sluEtree.resize(size); + + // set empty B and X + m_sluB.setStorageType(SLU_DN); + m_sluB.setScalarType<Scalar>(); + m_sluB.Mtype = SLU_GE; + m_sluB.storage.values = 0; + m_sluB.nrow = 0; + m_sluB.ncol = 0; + m_sluB.storage.lda = size; + m_sluX = m_sluB; + + m_extractedDataAreDirty = true; + } + + void init() + { + m_info = InvalidInput; + m_isInitialized = false; + m_sluL.Store = 0; + m_sluU.Store = 0; + } + + void extractData() const; + + void clearFactors() + { + if(m_sluL.Store) + Destroy_SuperNode_Matrix(&m_sluL); + if(m_sluU.Store) + Destroy_CompCol_Matrix(&m_sluU); + + m_sluL.Store = 0; + m_sluU.Store = 0; + + memset(&m_sluL,0,sizeof m_sluL); + memset(&m_sluU,0,sizeof m_sluU); + } + + // cached data to reduce reallocation, etc. + mutable LUMatrixType m_l; + mutable LUMatrixType m_u; + mutable IntColVectorType m_p; + mutable IntRowVectorType m_q; + + mutable LUMatrixType m_matrix; // copy of the factorized matrix + mutable SluMatrix m_sluA; + mutable SuperMatrix m_sluL, m_sluU; + mutable SluMatrix m_sluB, m_sluX; + mutable SuperLUStat_t m_sluStat; + mutable superlu_options_t m_sluOptions; + mutable std::vector<int> m_sluEtree; + mutable Matrix<RealScalar,Dynamic,1> m_sluRscale, m_sluCscale; + mutable Matrix<RealScalar,Dynamic,1> m_sluFerr, m_sluBerr; + mutable char m_sluEqued; + + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; + mutable bool m_extractedDataAreDirty; + + private: + SuperLUBase(SuperLUBase& ) { } +}; + + +/** \ingroup SuperLUSupport_Module + * \class SuperLU + * \brief A sparse direct LU factorization and solver based on the SuperLU library + * + * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization + * using the SuperLU library. The sparse matrix A must be squared and invertible. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename _MatrixType> +class SuperLU : public SuperLUBase<_MatrixType,SuperLU<_MatrixType> > +{ + public: + typedef SuperLUBase<_MatrixType,SuperLU> Base; + typedef _MatrixType MatrixType; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; + typedef typename Base::Index Index; + typedef typename Base::IntRowVectorType IntRowVectorType; + typedef typename Base::IntColVectorType IntColVectorType; + typedef typename Base::LUMatrixType LUMatrixType; + typedef TriangularView<LUMatrixType, Lower|UnitDiag> LMatrixType; + typedef TriangularView<LUMatrixType, Upper> UMatrixType; + + public: + + SuperLU() : Base() { init(); } + + SuperLU(const MatrixType& matrix) : Base() + { + Base::init(); + compute(matrix); + } + + ~SuperLU() + { + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + m_info = InvalidInput; + m_isInitialized = false; + Base::analyzePattern(matrix); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix); + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const; + #endif // EIGEN_PARSED_BY_DOXYGEN + + inline const LMatrixType& matrixL() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_l; + } + + inline const UMatrixType& matrixU() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_u; + } + + inline const IntColVectorType& permutationP() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_p; + } + + inline const IntRowVectorType& permutationQ() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_q; + } + + Scalar determinant() const; + + protected: + + using Base::m_matrix; + using Base::m_sluOptions; + using Base::m_sluA; + using Base::m_sluB; + using Base::m_sluX; + using Base::m_p; + using Base::m_q; + using Base::m_sluEtree; + using Base::m_sluEqued; + using Base::m_sluRscale; + using Base::m_sluCscale; + using Base::m_sluL; + using Base::m_sluU; + using Base::m_sluStat; + using Base::m_sluFerr; + using Base::m_sluBerr; + using Base::m_l; + using Base::m_u; + + using Base::m_analysisIsOk; + using Base::m_factorizationIsOk; + using Base::m_extractedDataAreDirty; + using Base::m_isInitialized; + using Base::m_info; + + void init() + { + Base::init(); + + set_default_options(&this->m_sluOptions); + m_sluOptions.PrintStat = NO; + m_sluOptions.ConditionNumber = NO; + m_sluOptions.Trans = NOTRANS; + m_sluOptions.ColPerm = COLAMD; + } + + + private: + SuperLU(SuperLU& ) { } +}; + +template<typename MatrixType> +void SuperLU<MatrixType>::factorize(const MatrixType& a) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + if(!m_analysisIsOk) + { + m_info = InvalidInput; + return; + } + + this->initFactorization(a); + + int info = 0; + RealScalar recip_pivot_growth, rcond; + RealScalar ferr, berr; + + StatInit(&m_sluStat); + SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], + &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &ferr, &berr, + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + + m_extractedDataAreDirty = true; + + // FIXME how to better check for errors ??? + m_info = info == 0 ? Success : NumericalIssue; + m_factorizationIsOk = true; +} + +template<typename MatrixType> +template<typename Rhs,typename Dest> +void SuperLU<MatrixType>::_solve(const MatrixBase<Rhs> &b, MatrixBase<Dest>& x) const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or analyzePattern()/factorize()"); + + const int size = m_matrix.rows(); + const int rhsCols = b.cols(); + eigen_assert(size==b.rows()); + + m_sluOptions.Trans = NOTRANS; + m_sluOptions.Fact = FACTORED; + m_sluOptions.IterRefine = NOREFINE; + + + m_sluFerr.resize(rhsCols); + m_sluBerr.resize(rhsCols); + m_sluB = SluMatrix::Map(b.const_cast_derived()); + m_sluX = SluMatrix::Map(x.derived()); + + typename Rhs::PlainObject b_cpy; + if(m_sluEqued!='N') + { + b_cpy = b; + m_sluB = SluMatrix::Map(b_cpy.const_cast_derived()); + } + + StatInit(&m_sluStat); + int info = 0; + RealScalar recip_pivot_growth, rcond; + SuperLU_gssvx(&m_sluOptions, &m_sluA, + m_q.data(), m_p.data(), + &m_sluEtree[0], &m_sluEqued, + &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &m_sluFerr[0], &m_sluBerr[0], + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + m_info = info==0 ? Success : NumericalIssue; +} + +// the code of this extractData() function has been adapted from the SuperLU's Matlab support code, +// +// Copyright (c) 1994 by Xerox Corporation. All rights reserved. +// +// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY +// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. +// +template<typename MatrixType, typename Derived> +void SuperLUBase<MatrixType,Derived>::extractData() const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for extracting factors, you must first call either compute() or analyzePattern()/factorize()"); + if (m_extractedDataAreDirty) + { + int upper; + int fsupc, istart, nsupr; + int lastl = 0, lastu = 0; + SCformat *Lstore = static_cast<SCformat*>(m_sluL.Store); + NCformat *Ustore = static_cast<NCformat*>(m_sluU.Store); + Scalar *SNptr; + + const int size = m_matrix.rows(); + m_l.resize(size,size); + m_l.resizeNonZeros(Lstore->nnz); + m_u.resize(size,size); + m_u.resizeNonZeros(Ustore->nnz); + + int* Lcol = m_l.outerIndexPtr(); + int* Lrow = m_l.innerIndexPtr(); + Scalar* Lval = m_l.valuePtr(); + + int* Ucol = m_u.outerIndexPtr(); + int* Urow = m_u.innerIndexPtr(); + Scalar* Uval = m_u.valuePtr(); + + Ucol[0] = 0; + Ucol[0] = 0; + + /* for each supernode */ + for (int k = 0; k <= Lstore->nsuper; ++k) + { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + upper = 1; + + /* for each column in the supernode */ + for (int j = fsupc; j < L_FST_SUPC(k+1); ++j) + { + SNptr = &((Scalar*)Lstore->nzval)[L_NZ_START(j)]; + + /* Extract U */ + for (int i = U_NZ_START(j); i < U_NZ_START(j+1); ++i) + { + Uval[lastu] = ((Scalar*)Ustore->nzval)[i]; + /* Matlab doesn't like explicit zero. */ + if (Uval[lastu] != 0.0) + Urow[lastu++] = U_SUB(i); + } + for (int i = 0; i < upper; ++i) + { + /* upper triangle in the supernode */ + Uval[lastu] = SNptr[i]; + /* Matlab doesn't like explicit zero. */ + if (Uval[lastu] != 0.0) + Urow[lastu++] = L_SUB(istart+i); + } + Ucol[j+1] = lastu; + + /* Extract L */ + Lval[lastl] = 1.0; /* unit diagonal */ + Lrow[lastl++] = L_SUB(istart + upper - 1); + for (int i = upper; i < nsupr; ++i) + { + Lval[lastl] = SNptr[i]; + /* Matlab doesn't like explicit zero. */ + if (Lval[lastl] != 0.0) + Lrow[lastl++] = L_SUB(istart+i); + } + Lcol[j+1] = lastl; + + ++upper; + } /* for j ... */ + + } /* for k ... */ + + // squeeze the matrices : + m_l.resizeNonZeros(lastl); + m_u.resizeNonZeros(lastu); + + m_extractedDataAreDirty = false; + } +} + +template<typename MatrixType> +typename SuperLU<MatrixType>::Scalar SuperLU<MatrixType>::determinant() const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for computing the determinant, you must first call either compute() or analyzePattern()/factorize()"); + + if (m_extractedDataAreDirty) + this->extractData(); + + Scalar det = Scalar(1); + for (int j=0; j<m_u.cols(); ++j) + { + if (m_u.outerIndexPtr()[j+1]-m_u.outerIndexPtr()[j] > 0) + { + int lastId = m_u.outerIndexPtr()[j+1]-1; + eigen_assert(m_u.innerIndexPtr()[lastId]<=j); + if (m_u.innerIndexPtr()[lastId]==j) + det *= m_u.valuePtr()[lastId]; + } + } + if(m_sluEqued!='N') + return det/m_sluRscale.prod()/m_sluCscale.prod(); + else + return det; +} + +#ifdef EIGEN_PARSED_BY_DOXYGEN +#define EIGEN_SUPERLU_HAS_ILU +#endif + +#ifdef EIGEN_SUPERLU_HAS_ILU + +/** \ingroup SuperLUSupport_Module + * \class SuperILU + * \brief A sparse direct \b incomplete LU factorization and solver based on the SuperLU library + * + * This class allows to solve for an approximate solution of A.X = B sparse linear problems via an incomplete LU factorization + * using the SuperLU library. This class is aimed to be used as a preconditioner of the iterative linear solvers. + * + * \warning This class requires SuperLU 4 or later. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers, class ConjugateGradient, class BiCGSTAB + */ + +template<typename _MatrixType> +class SuperILU : public SuperLUBase<_MatrixType,SuperILU<_MatrixType> > +{ + public: + typedef SuperLUBase<_MatrixType,SuperILU> Base; + typedef _MatrixType MatrixType; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; + typedef typename Base::Index Index; + + public: + + SuperILU() : Base() { init(); } + + SuperILU(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~SuperILU() + { + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + Base::analyzePattern(matrix); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix); + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template<typename Rhs,typename Dest> + void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const; + #endif // EIGEN_PARSED_BY_DOXYGEN + + protected: + + using Base::m_matrix; + using Base::m_sluOptions; + using Base::m_sluA; + using Base::m_sluB; + using Base::m_sluX; + using Base::m_p; + using Base::m_q; + using Base::m_sluEtree; + using Base::m_sluEqued; + using Base::m_sluRscale; + using Base::m_sluCscale; + using Base::m_sluL; + using Base::m_sluU; + using Base::m_sluStat; + using Base::m_sluFerr; + using Base::m_sluBerr; + using Base::m_l; + using Base::m_u; + + using Base::m_analysisIsOk; + using Base::m_factorizationIsOk; + using Base::m_extractedDataAreDirty; + using Base::m_isInitialized; + using Base::m_info; + + void init() + { + Base::init(); + + ilu_set_default_options(&m_sluOptions); + m_sluOptions.PrintStat = NO; + m_sluOptions.ConditionNumber = NO; + m_sluOptions.Trans = NOTRANS; + m_sluOptions.ColPerm = MMD_AT_PLUS_A; + + // no attempt to preserve column sum + m_sluOptions.ILU_MILU = SILU; + // only basic ILU(k) support -- no direct control over memory consumption + // better to use ILU_DropRule = DROP_BASIC | DROP_AREA + // and set ILU_FillFactor to max memory growth + m_sluOptions.ILU_DropRule = DROP_BASIC; + m_sluOptions.ILU_DropTol = NumTraits<Scalar>::dummy_precision()*10; + } + + private: + SuperILU(SuperILU& ) { } +}; + +template<typename MatrixType> +void SuperILU<MatrixType>::factorize(const MatrixType& a) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + if(!m_analysisIsOk) + { + m_info = InvalidInput; + return; + } + + this->initFactorization(a); + + int info = 0; + RealScalar recip_pivot_growth, rcond; + + StatInit(&m_sluStat); + SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], + &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + + // FIXME how to better check for errors ??? + m_info = info == 0 ? Success : NumericalIssue; + m_factorizationIsOk = true; +} + +template<typename MatrixType> +template<typename Rhs,typename Dest> +void SuperILU<MatrixType>::_solve(const MatrixBase<Rhs> &b, MatrixBase<Dest>& x) const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or analyzePattern()/factorize()"); + + const int size = m_matrix.rows(); + const int rhsCols = b.cols(); + eigen_assert(size==b.rows()); + + m_sluOptions.Trans = NOTRANS; + m_sluOptions.Fact = FACTORED; + m_sluOptions.IterRefine = NOREFINE; + + m_sluFerr.resize(rhsCols); + m_sluBerr.resize(rhsCols); + m_sluB = SluMatrix::Map(b.const_cast_derived()); + m_sluX = SluMatrix::Map(x.derived()); + + typename Rhs::PlainObject b_cpy; + if(m_sluEqued!='N') + { + b_cpy = b; + m_sluB = SluMatrix::Map(b_cpy.const_cast_derived()); + } + + int info = 0; + RealScalar recip_pivot_growth, rcond; + + StatInit(&m_sluStat); + SuperLU_gsisx(&m_sluOptions, &m_sluA, + m_q.data(), m_p.data(), + &m_sluEtree[0], &m_sluEqued, + &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + + m_info = info==0 ? Success : NumericalIssue; +} +#endif + +namespace internal { + +template<typename _MatrixType, typename Derived, typename Rhs> +struct solve_retval<SuperLUBase<_MatrixType,Derived>, Rhs> + : solve_retval_base<SuperLUBase<_MatrixType,Derived>, Rhs> +{ + typedef SuperLUBase<_MatrixType,Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec().derived()._solve(rhs(),dst); + } +}; + +template<typename _MatrixType, typename Derived, typename Rhs> +struct sparse_solve_retval<SuperLUBase<_MatrixType,Derived>, Rhs> + : sparse_solve_retval_base<SuperLUBase<_MatrixType,Derived>, Rhs> +{ + typedef SuperLUBase<_MatrixType,Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec().derived()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SUPERLUSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h b/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h new file mode 100644 index 00000000000..f01720362de --- /dev/null +++ b/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -0,0 +1,431 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_UMFPACKSUPPORT_H +#define EIGEN_UMFPACKSUPPORT_H + +namespace Eigen { + +/* TODO extract L, extract U, compute det, etc... */ + +// generic double/complex<double> wrapper functions: + +inline void umfpack_free_numeric(void **Numeric, double) +{ umfpack_di_free_numeric(Numeric); *Numeric = 0; } + +inline void umfpack_free_numeric(void **Numeric, std::complex<double>) +{ umfpack_zi_free_numeric(Numeric); *Numeric = 0; } + +inline void umfpack_free_symbolic(void **Symbolic, double) +{ umfpack_di_free_symbolic(Symbolic); *Symbolic = 0; } + +inline void umfpack_free_symbolic(void **Symbolic, std::complex<double>) +{ umfpack_zi_free_symbolic(Symbolic); *Symbolic = 0; } + +inline int umfpack_symbolic(int n_row,int n_col, + const int Ap[], const int Ai[], const double Ax[], void **Symbolic, + const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]) +{ + return umfpack_di_symbolic(n_row,n_col,Ap,Ai,Ax,Symbolic,Control,Info); +} + +inline int umfpack_symbolic(int n_row,int n_col, + const int Ap[], const int Ai[], const std::complex<double> Ax[], void **Symbolic, + const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]) +{ + return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Control,Info); +} + +inline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[], + void *Symbolic, void **Numeric, + const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO]) +{ + return umfpack_di_numeric(Ap,Ai,Ax,Symbolic,Numeric,Control,Info); +} + +inline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex<double> Ax[], + void *Symbolic, void **Numeric, + const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO]) +{ + return umfpack_zi_numeric(Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info); +} + +inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[], + double X[], const double B[], void *Numeric, + const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) +{ + return umfpack_di_solve(sys,Ap,Ai,Ax,X,B,Numeric,Control,Info); +} + +inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::complex<double> Ax[], + std::complex<double> X[], const std::complex<double> B[], void *Numeric, + const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) +{ + return umfpack_zi_solve(sys,Ap,Ai,&internal::real_ref(Ax[0]),0,&internal::real_ref(X[0]),0,&internal::real_ref(B[0]),0,Numeric,Control,Info); +} + +inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double) +{ + return umfpack_di_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric); +} + +inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, std::complex<double>) +{ + return umfpack_zi_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric); +} + +inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui[], double Ux[], + int P[], int Q[], double Dx[], int *do_recip, double Rs[], void *Numeric) +{ + return umfpack_di_get_numeric(Lp,Lj,Lx,Up,Ui,Ux,P,Q,Dx,do_recip,Rs,Numeric); +} + +inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex<double> Lx[], int Up[], int Ui[], std::complex<double> Ux[], + int P[], int Q[], std::complex<double> Dx[], int *do_recip, double Rs[], void *Numeric) +{ + double& lx0_real = internal::real_ref(Lx[0]); + double& ux0_real = internal::real_ref(Ux[0]); + double& dx0_real = internal::real_ref(Dx[0]); + return umfpack_zi_get_numeric(Lp,Lj,Lx?&lx0_real:0,0,Up,Ui,Ux?&ux0_real:0,0,P,Q, + Dx?&dx0_real:0,0,do_recip,Rs,Numeric); +} + +inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO]) +{ + return umfpack_di_get_determinant(Mx,Ex,NumericHandle,User_Info); +} + +inline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO]) +{ + double& mx_real = internal::real_ref(*Mx); + return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info); +} + +/** \ingroup UmfPackSupport_Module + * \brief A sparse LU factorization and solver based on UmfPack + * + * This class allows to solve for A.X = B sparse linear problems via a LU factorization + * using the UmfPack library. The sparse matrix A must be squared and full rank. + * The vectors or matrices X and B can be either dense or sparse. + * + * \WARNING The input matrix A should be in a \b compressed and \b column-major form. + * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix. + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers + */ +template<typename _MatrixType> +class UmfPackLU : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix<Scalar,Dynamic,1> Vector; + typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType; + typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType; + typedef SparseMatrix<Scalar> LUMatrixType; + typedef SparseMatrix<Scalar,ColMajor,int> UmfpackMatrixType; + + public: + + UmfPackLU() { init(); } + + UmfPackLU(const MatrixType& matrix) + { + init(); + compute(matrix); + } + + ~UmfPackLU() + { + if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); + if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); + } + + inline Index rows() const { return m_copyMatrix.rows(); } + inline Index cols() const { return m_copyMatrix.cols(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + inline const LUMatrixType& matrixL() const + { + if (m_extractedDataAreDirty) extractData(); + return m_l; + } + + inline const LUMatrixType& matrixU() const + { + if (m_extractedDataAreDirty) extractData(); + return m_u; + } + + inline const IntColVectorType& permutationP() const + { + if (m_extractedDataAreDirty) extractData(); + return m_p; + } + + inline const IntRowVectorType& permutationQ() const + { + if (m_extractedDataAreDirty) extractData(); + return m_q; + } + + /** Computes the sparse Cholesky decomposition of \a matrix + * Note that the matrix should be column-major, and in compressed format for best performance. + * \sa SparseMatrix::makeCompressed(). + */ + void compute(const MatrixType& matrix) + { + analyzePattern(matrix); + factorize(matrix); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template<typename Rhs> + inline const internal::solve_retval<UmfPackLU, Rhs> solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "UmfPackLU is not initialized."); + eigen_assert(rows()==b.rows() + && "UmfPackLU::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval<UmfPackLU, Rhs>(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ +// template<typename Rhs> +// inline const internal::sparse_solve_retval<UmfPAckLU, Rhs> solve(const SparseMatrixBase<Rhs>& b) const +// { +// eigen_assert(m_isInitialized && "UmfPAckLU is not initialized."); +// eigen_assert(rows()==b.rows() +// && "UmfPAckLU::solve(): invalid number of rows of the right hand side matrix b"); +// return internal::sparse_solve_retval<UmfPAckLU, Rhs>(*this, b.derived()); +// } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize(), compute() + */ + void analyzePattern(const MatrixType& matrix) + { + if(m_symbolic) + umfpack_free_symbolic(&m_symbolic,Scalar()); + if(m_numeric) + umfpack_free_numeric(&m_numeric,Scalar()); + + grapInput(matrix); + + int errorCode = 0; + errorCode = umfpack_symbolic(matrix.rows(), matrix.cols(), m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + &m_symbolic, 0, 0); + + m_isInitialized = true; + m_info = errorCode ? InvalidInput : Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed. + * + * \sa analyzePattern(), compute() + */ + void factorize(const MatrixType& matrix) + { + eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()"); + if(m_numeric) + umfpack_free_numeric(&m_numeric,Scalar()); + + grapInput(matrix); + + int errorCode; + errorCode = umfpack_numeric(m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + m_symbolic, &m_numeric, 0, 0); + + m_info = errorCode ? NumericalIssue : Success; + m_factorizationIsOk = true; + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template<typename BDerived,typename XDerived> + bool _solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const; + #endif + + Scalar determinant() const; + + void extractData() const; + + protected: + + + void init() + { + m_info = InvalidInput; + m_isInitialized = false; + m_numeric = 0; + m_symbolic = 0; + m_outerIndexPtr = 0; + m_innerIndexPtr = 0; + m_valuePtr = 0; + } + + void grapInput(const MatrixType& mat) + { + m_copyMatrix.resize(mat.rows(), mat.cols()); + if( ((MatrixType::Flags&RowMajorBit)==RowMajorBit) || sizeof(typename MatrixType::Index)!=sizeof(int) || !mat.isCompressed() ) + { + // non supported input -> copy + m_copyMatrix = mat; + m_outerIndexPtr = m_copyMatrix.outerIndexPtr(); + m_innerIndexPtr = m_copyMatrix.innerIndexPtr(); + m_valuePtr = m_copyMatrix.valuePtr(); + } + else + { + m_outerIndexPtr = mat.outerIndexPtr(); + m_innerIndexPtr = mat.innerIndexPtr(); + m_valuePtr = mat.valuePtr(); + } + } + + // cached data to reduce reallocation, etc. + mutable LUMatrixType m_l; + mutable LUMatrixType m_u; + mutable IntColVectorType m_p; + mutable IntRowVectorType m_q; + + UmfpackMatrixType m_copyMatrix; + const Scalar* m_valuePtr; + const int* m_outerIndexPtr; + const int* m_innerIndexPtr; + void* m_numeric; + void* m_symbolic; + + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; + mutable bool m_extractedDataAreDirty; + + private: + UmfPackLU(UmfPackLU& ) { } +}; + + +template<typename MatrixType> +void UmfPackLU<MatrixType>::extractData() const +{ + if (m_extractedDataAreDirty) + { + // get size of the data + int lnz, unz, rows, cols, nz_udiag; + umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar()); + + // allocate data + m_l.resize(rows,(std::min)(rows,cols)); + m_l.resizeNonZeros(lnz); + + m_u.resize((std::min)(rows,cols),cols); + m_u.resizeNonZeros(unz); + + m_p.resize(rows); + m_q.resize(cols); + + // extract + umfpack_get_numeric(m_l.outerIndexPtr(), m_l.innerIndexPtr(), m_l.valuePtr(), + m_u.outerIndexPtr(), m_u.innerIndexPtr(), m_u.valuePtr(), + m_p.data(), m_q.data(), 0, 0, 0, m_numeric); + + m_extractedDataAreDirty = false; + } +} + +template<typename MatrixType> +typename UmfPackLU<MatrixType>::Scalar UmfPackLU<MatrixType>::determinant() const +{ + Scalar det; + umfpack_get_determinant(&det, 0, m_numeric, 0); + return det; +} + +template<typename MatrixType> +template<typename BDerived,typename XDerived> +bool UmfPackLU<MatrixType>::_solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const +{ + const int rhsCols = b.cols(); + eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet"); + eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet"); + + int errorCode; + for (int j=0; j<rhsCols; ++j) + { + errorCode = umfpack_solve(UMFPACK_A, + m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + &x.col(j).coeffRef(0), &b.const_cast_derived().col(j).coeffRef(0), m_numeric, 0, 0); + if (errorCode!=0) + return false; + } + + return true; +} + + +namespace internal { + +template<typename _MatrixType, typename Rhs> +struct solve_retval<UmfPackLU<_MatrixType>, Rhs> + : solve_retval_base<UmfPackLU<_MatrixType>, Rhs> +{ + typedef UmfPackLU<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template<typename _MatrixType, typename Rhs> +struct sparse_solve_retval<UmfPackLU<_MatrixType>, Rhs> + : sparse_solve_retval_base<UmfPackLU<_MatrixType>, Rhs> +{ + typedef UmfPackLU<_MatrixType> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template<typename Dest> void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_UMFPACKSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/misc/Image.h b/extern/Eigen3/Eigen/src/misc/Image.h index 19b3e08cbfd..75c5f433a8a 100644 --- a/extern/Eigen3/Eigen/src/misc/Image.h +++ b/extern/Eigen3/Eigen/src/misc/Image.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MISC_IMAGE_H #define EIGEN_MISC_IMAGE_H +namespace Eigen { + namespace internal { /** \class image_retval_base @@ -92,4 +79,6 @@ template<typename _DecompositionType> struct image_retval_base image_retval(const DecompositionType& dec, const MatrixType& originalMatrix) \ : Base(dec, originalMatrix) {} +} // end namespace Eigen + #endif // EIGEN_MISC_IMAGE_H diff --git a/extern/Eigen3/Eigen/src/misc/Kernel.h b/extern/Eigen3/Eigen/src/misc/Kernel.h index 0115970e8eb..b9e1518fd49 100644 --- a/extern/Eigen3/Eigen/src/misc/Kernel.h +++ b/extern/Eigen3/Eigen/src/misc/Kernel.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MISC_KERNEL_H #define EIGEN_MISC_KERNEL_H +namespace Eigen { + namespace internal { /** \class kernel_retval_base @@ -89,4 +76,6 @@ template<typename _DecompositionType> struct kernel_retval_base using Base::cols; \ kernel_retval(const DecompositionType& dec) : Base(dec) {} +} // end namespace Eigen + #endif // EIGEN_MISC_KERNEL_H diff --git a/extern/Eigen3/Eigen/src/misc/Solve.h b/extern/Eigen3/Eigen/src/misc/Solve.h index b7cbcadb392..7f70d60afbd 100644 --- a/extern/Eigen3/Eigen/src/misc/Solve.h +++ b/extern/Eigen3/Eigen/src/misc/Solve.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MISC_SOLVE_H #define EIGEN_MISC_SOLVE_H +namespace Eigen { + namespace internal { /** \class solve_retval_base @@ -66,7 +53,7 @@ template<typename _DecompositionType, typename Rhs> struct solve_retval_base protected: const DecompositionType& m_dec; - const typename Rhs::Nested m_rhs; + typename Rhs::Nested m_rhs; }; } // end namespace internal @@ -84,4 +71,6 @@ template<typename _DecompositionType, typename Rhs> struct solve_retval_base solve_retval(const DecompositionType& dec, const Rhs& rhs) \ : Base(dec, rhs) {} +} // end namespace Eigen + #endif // EIGEN_MISC_SOLVE_H diff --git a/extern/Eigen3/Eigen/src/misc/SparseSolve.h b/extern/Eigen3/Eigen/src/misc/SparseSolve.h new file mode 100644 index 00000000000..272c4a479d7 --- /dev/null +++ b/extern/Eigen3/Eigen/src/misc/SparseSolve.h @@ -0,0 +1,111 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_SOLVE_H +#define EIGEN_SPARSE_SOLVE_H + +namespace Eigen { + +namespace internal { + +template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval_base; +template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval; + +template<typename DecompositionType, typename Rhs> +struct traits<sparse_solve_retval_base<DecompositionType, Rhs> > +{ + typedef typename DecompositionType::MatrixType MatrixType; + typedef SparseMatrix<typename Rhs::Scalar, Rhs::Options, typename Rhs::Index> ReturnType; +}; + +template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval_base + : public ReturnByValue<sparse_solve_retval_base<_DecompositionType, Rhs> > +{ + typedef typename remove_all<typename Rhs::Nested>::type RhsNestedCleaned; + typedef _DecompositionType DecompositionType; + typedef ReturnByValue<sparse_solve_retval_base> Base; + typedef typename Base::Index Index; + + sparse_solve_retval_base(const DecompositionType& dec, const Rhs& rhs) + : m_dec(dec), m_rhs(rhs) + {} + + inline Index rows() const { return m_dec.cols(); } + inline Index cols() const { return m_rhs.cols(); } + inline const DecompositionType& dec() const { return m_dec; } + inline const RhsNestedCleaned& rhs() const { return m_rhs; } + + template<typename Dest> inline void evalTo(Dest& dst) const + { + static_cast<const sparse_solve_retval<DecompositionType,Rhs>*>(this)->evalTo(dst); + } + + protected: + const DecompositionType& m_dec; + typename Rhs::Nested m_rhs; +}; + +#define EIGEN_MAKE_SPARSE_SOLVE_HELPERS(DecompositionType,Rhs) \ + typedef typename DecompositionType::MatrixType MatrixType; \ + typedef typename MatrixType::Scalar Scalar; \ + typedef typename MatrixType::RealScalar RealScalar; \ + typedef typename MatrixType::Index Index; \ + typedef Eigen::internal::sparse_solve_retval_base<DecompositionType,Rhs> Base; \ + using Base::dec; \ + using Base::rhs; \ + using Base::rows; \ + using Base::cols; \ + sparse_solve_retval(const DecompositionType& dec, const Rhs& rhs) \ + : Base(dec, rhs) {} + + + +template<typename DecompositionType, typename Rhs, typename Guess> struct solve_retval_with_guess; + +template<typename DecompositionType, typename Rhs, typename Guess> +struct traits<solve_retval_with_guess<DecompositionType, Rhs, Guess> > +{ + typedef typename DecompositionType::MatrixType MatrixType; + typedef Matrix<typename Rhs::Scalar, + MatrixType::ColsAtCompileTime, + Rhs::ColsAtCompileTime, + Rhs::PlainObject::Options, + MatrixType::MaxColsAtCompileTime, + Rhs::MaxColsAtCompileTime> ReturnType; +}; + +template<typename DecompositionType, typename Rhs, typename Guess> struct solve_retval_with_guess + : public ReturnByValue<solve_retval_with_guess<DecompositionType, Rhs, Guess> > +{ + typedef typename DecompositionType::Index Index; + + solve_retval_with_guess(const DecompositionType& dec, const Rhs& rhs, const Guess& guess) + : m_dec(dec), m_rhs(rhs), m_guess(guess) + {} + + inline Index rows() const { return m_dec.cols(); } + inline Index cols() const { return m_rhs.cols(); } + + template<typename Dest> inline void evalTo(Dest& dst) const + { + dst = m_guess; + m_dec._solveWithGuess(m_rhs,dst); + } + + protected: + const DecompositionType& m_dec; + const typename Rhs::Nested m_rhs; + const typename Guess::Nested m_guess; +}; + +} // namepsace internal + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_SOLVE_H diff --git a/extern/Eigen3/Eigen/src/misc/blas.h b/extern/Eigen3/Eigen/src/misc/blas.h new file mode 100644 index 00000000000..6fce99ed5c4 --- /dev/null +++ b/extern/Eigen3/Eigen/src/misc/blas.h @@ -0,0 +1,658 @@ +#ifndef BLAS_H +#define BLAS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define BLASFUNC(FUNC) FUNC##_ + +#ifdef __WIN64__ +typedef long long BLASLONG; +typedef unsigned long long BLASULONG; +#else +typedef long BLASLONG; +typedef unsigned long BLASULONG; +#endif + +int BLASFUNC(xerbla)(const char *, int *info, int); + +float BLASFUNC(sdot) (int *, float *, int *, float *, int *); +float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *); + +double BLASFUNC(dsdot) (int *, float *, int *, float *, int *); +double BLASFUNC(ddot) (int *, double *, int *, double *, int *); +double BLASFUNC(qdot) (int *, double *, int *, double *, int *); + +int BLASFUNC(cdotuw) (int *, float *, int *, float *, int *, float*); +int BLASFUNC(cdotcw) (int *, float *, int *, float *, int *, float*); +int BLASFUNC(zdotuw) (int *, double *, int *, double *, int *, double*); +int BLASFUNC(zdotcw) (int *, double *, int *, double *, int *, double*); + +int BLASFUNC(saxpy) (int *, float *, float *, int *, float *, int *); +int BLASFUNC(daxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(qaxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(caxpy) (int *, float *, float *, int *, float *, int *); +int BLASFUNC(zaxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(xaxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(caxpyc)(int *, float *, float *, int *, float *, int *); +int BLASFUNC(zaxpyc)(int *, double *, double *, int *, double *, int *); +int BLASFUNC(xaxpyc)(int *, double *, double *, int *, double *, int *); + +int BLASFUNC(scopy) (int *, float *, int *, float *, int *); +int BLASFUNC(dcopy) (int *, double *, int *, double *, int *); +int BLASFUNC(qcopy) (int *, double *, int *, double *, int *); +int BLASFUNC(ccopy) (int *, float *, int *, float *, int *); +int BLASFUNC(zcopy) (int *, double *, int *, double *, int *); +int BLASFUNC(xcopy) (int *, double *, int *, double *, int *); + +int BLASFUNC(sswap) (int *, float *, int *, float *, int *); +int BLASFUNC(dswap) (int *, double *, int *, double *, int *); +int BLASFUNC(qswap) (int *, double *, int *, double *, int *); +int BLASFUNC(cswap) (int *, float *, int *, float *, int *); +int BLASFUNC(zswap) (int *, double *, int *, double *, int *); +int BLASFUNC(xswap) (int *, double *, int *, double *, int *); + +float BLASFUNC(sasum) (int *, float *, int *); +float BLASFUNC(scasum)(int *, float *, int *); +double BLASFUNC(dasum) (int *, double *, int *); +double BLASFUNC(qasum) (int *, double *, int *); +double BLASFUNC(dzasum)(int *, double *, int *); +double BLASFUNC(qxasum)(int *, double *, int *); + +int BLASFUNC(isamax)(int *, float *, int *); +int BLASFUNC(idamax)(int *, double *, int *); +int BLASFUNC(iqamax)(int *, double *, int *); +int BLASFUNC(icamax)(int *, float *, int *); +int BLASFUNC(izamax)(int *, double *, int *); +int BLASFUNC(ixamax)(int *, double *, int *); + +int BLASFUNC(ismax) (int *, float *, int *); +int BLASFUNC(idmax) (int *, double *, int *); +int BLASFUNC(iqmax) (int *, double *, int *); +int BLASFUNC(icmax) (int *, float *, int *); +int BLASFUNC(izmax) (int *, double *, int *); +int BLASFUNC(ixmax) (int *, double *, int *); + +int BLASFUNC(isamin)(int *, float *, int *); +int BLASFUNC(idamin)(int *, double *, int *); +int BLASFUNC(iqamin)(int *, double *, int *); +int BLASFUNC(icamin)(int *, float *, int *); +int BLASFUNC(izamin)(int *, double *, int *); +int BLASFUNC(ixamin)(int *, double *, int *); + +int BLASFUNC(ismin)(int *, float *, int *); +int BLASFUNC(idmin)(int *, double *, int *); +int BLASFUNC(iqmin)(int *, double *, int *); +int BLASFUNC(icmin)(int *, float *, int *); +int BLASFUNC(izmin)(int *, double *, int *); +int BLASFUNC(ixmin)(int *, double *, int *); + +float BLASFUNC(samax) (int *, float *, int *); +double BLASFUNC(damax) (int *, double *, int *); +double BLASFUNC(qamax) (int *, double *, int *); +float BLASFUNC(scamax)(int *, float *, int *); +double BLASFUNC(dzamax)(int *, double *, int *); +double BLASFUNC(qxamax)(int *, double *, int *); + +float BLASFUNC(samin) (int *, float *, int *); +double BLASFUNC(damin) (int *, double *, int *); +double BLASFUNC(qamin) (int *, double *, int *); +float BLASFUNC(scamin)(int *, float *, int *); +double BLASFUNC(dzamin)(int *, double *, int *); +double BLASFUNC(qxamin)(int *, double *, int *); + +float BLASFUNC(smax) (int *, float *, int *); +double BLASFUNC(dmax) (int *, double *, int *); +double BLASFUNC(qmax) (int *, double *, int *); +float BLASFUNC(scmax) (int *, float *, int *); +double BLASFUNC(dzmax) (int *, double *, int *); +double BLASFUNC(qxmax) (int *, double *, int *); + +float BLASFUNC(smin) (int *, float *, int *); +double BLASFUNC(dmin) (int *, double *, int *); +double BLASFUNC(qmin) (int *, double *, int *); +float BLASFUNC(scmin) (int *, float *, int *); +double BLASFUNC(dzmin) (int *, double *, int *); +double BLASFUNC(qxmin) (int *, double *, int *); + +int BLASFUNC(sscal) (int *, float *, float *, int *); +int BLASFUNC(dscal) (int *, double *, double *, int *); +int BLASFUNC(qscal) (int *, double *, double *, int *); +int BLASFUNC(cscal) (int *, float *, float *, int *); +int BLASFUNC(zscal) (int *, double *, double *, int *); +int BLASFUNC(xscal) (int *, double *, double *, int *); +int BLASFUNC(csscal)(int *, float *, float *, int *); +int BLASFUNC(zdscal)(int *, double *, double *, int *); +int BLASFUNC(xqscal)(int *, double *, double *, int *); + +float BLASFUNC(snrm2) (int *, float *, int *); +float BLASFUNC(scnrm2)(int *, float *, int *); + +double BLASFUNC(dnrm2) (int *, double *, int *); +double BLASFUNC(qnrm2) (int *, double *, int *); +double BLASFUNC(dznrm2)(int *, double *, int *); +double BLASFUNC(qxnrm2)(int *, double *, int *); + +int BLASFUNC(srot) (int *, float *, int *, float *, int *, float *, float *); +int BLASFUNC(drot) (int *, double *, int *, double *, int *, double *, double *); +int BLASFUNC(qrot) (int *, double *, int *, double *, int *, double *, double *); +int BLASFUNC(csrot) (int *, float *, int *, float *, int *, float *, float *); +int BLASFUNC(zdrot) (int *, double *, int *, double *, int *, double *, double *); +int BLASFUNC(xqrot) (int *, double *, int *, double *, int *, double *, double *); + +int BLASFUNC(srotg) (float *, float *, float *, float *); +int BLASFUNC(drotg) (double *, double *, double *, double *); +int BLASFUNC(qrotg) (double *, double *, double *, double *); +int BLASFUNC(crotg) (float *, float *, float *, float *); +int BLASFUNC(zrotg) (double *, double *, double *, double *); +int BLASFUNC(xrotg) (double *, double *, double *, double *); + +int BLASFUNC(srotmg)(float *, float *, float *, float *, float *); +int BLASFUNC(drotmg)(double *, double *, double *, double *, double *); + +int BLASFUNC(srotm) (int *, float *, int *, float *, int *, float *); +int BLASFUNC(drotm) (int *, double *, int *, double *, int *, double *); +int BLASFUNC(qrotm) (int *, double *, int *, double *, int *, double *); + +/* Level 2 routines */ + +int BLASFUNC(sger)(int *, int *, float *, float *, int *, + float *, int *, float *, int *); +int BLASFUNC(dger)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(qger)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(cgeru)(int *, int *, float *, float *, int *, + float *, int *, float *, int *); +int BLASFUNC(cgerc)(int *, int *, float *, float *, int *, + float *, int *, float *, int *); +int BLASFUNC(zgeru)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(zgerc)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(xgeru)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(xgerc)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); + +int BLASFUNC(sgemv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(cgemv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(strsv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(dtrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(qtrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(ctrsv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(ztrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(xtrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); + +int BLASFUNC(stpsv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(dtpsv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(qtpsv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(ctpsv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(ztpsv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(xtpsv) (char *, char *, char *, int *, double *, double *, int *); + +int BLASFUNC(strmv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(dtrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(qtrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(ctrmv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(ztrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(xtrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); + +int BLASFUNC(stpmv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(dtpmv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(qtpmv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(ctpmv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(ztpmv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(xtpmv) (char *, char *, char *, int *, double *, double *, int *); + +int BLASFUNC(stbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(dtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(qtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(ctbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(ztbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(xtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); + +int BLASFUNC(stbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(dtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(qtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(ctbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(ztbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(xtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); + +int BLASFUNC(ssymv) (char *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(csymv) (char *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(sspmv) (char *, int *, float *, float *, + float *, int *, float *, float *, int *); +int BLASFUNC(dspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(qspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(cspmv) (char *, int *, float *, float *, + float *, int *, float *, float *, int *); +int BLASFUNC(zspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(xspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); + +int BLASFUNC(ssyr) (char *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(dsyr) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(qsyr) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(csyr) (char *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(zsyr) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(xsyr) (char *, int *, double *, double *, int *, + double *, int *); + +int BLASFUNC(ssyr2) (char *, int *, float *, + float *, int *, float *, int *, float *, int *); +int BLASFUNC(dsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(qsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(csyr2) (char *, int *, float *, + float *, int *, float *, int *, float *, int *); +int BLASFUNC(zsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(xsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); + +int BLASFUNC(sspr) (char *, int *, float *, float *, int *, + float *); +int BLASFUNC(dspr) (char *, int *, double *, double *, int *, + double *); +int BLASFUNC(qspr) (char *, int *, double *, double *, int *, + double *); +int BLASFUNC(cspr) (char *, int *, float *, float *, int *, + float *); +int BLASFUNC(zspr) (char *, int *, double *, double *, int *, + double *); +int BLASFUNC(xspr) (char *, int *, double *, double *, int *, + double *); + +int BLASFUNC(sspr2) (char *, int *, float *, + float *, int *, float *, int *, float *); +int BLASFUNC(dspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(qspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(cspr2) (char *, int *, float *, + float *, int *, float *, int *, float *); +int BLASFUNC(zspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(xspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); + +int BLASFUNC(cher) (char *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(zher) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(xher) (char *, int *, double *, double *, int *, + double *, int *); + +int BLASFUNC(chpr) (char *, int *, float *, float *, int *, float *); +int BLASFUNC(zhpr) (char *, int *, double *, double *, int *, double *); +int BLASFUNC(xhpr) (char *, int *, double *, double *, int *, double *); + +int BLASFUNC(cher2) (char *, int *, float *, + float *, int *, float *, int *, float *, int *); +int BLASFUNC(zher2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(xher2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); + +int BLASFUNC(chpr2) (char *, int *, float *, + float *, int *, float *, int *, float *); +int BLASFUNC(zhpr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(xhpr2) (char *, int *, double *, + double *, int *, double *, int *, double *); + +int BLASFUNC(chemv) (char *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhemv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhemv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(chpmv) (char *, int *, float *, float *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhpmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhpmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); + +int BLASFUNC(snorm)(char *, int *, int *, float *, int *); +int BLASFUNC(dnorm)(char *, int *, int *, double *, int *); +int BLASFUNC(cnorm)(char *, int *, int *, float *, int *); +int BLASFUNC(znorm)(char *, int *, int *, double *, int *); + +int BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +/* Level 3 routines */ + +int BLASFUNC(sgemm)(char *, char *, int *, int *, int *, float *, + float *, int *, float *, int *, float *, float *, int *); +int BLASFUNC(dgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(qgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(cgemm)(char *, char *, int *, int *, int *, float *, + float *, int *, float *, int *, float *, float *, int *); +int BLASFUNC(zgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(xgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); + +int BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *, + float *, int *, float *, int *, float *, float *, int *); +int BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); + +int BLASFUNC(sge2mm)(char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *, + float *, float *, int *); +int BLASFUNC(dge2mm)(char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *, + double *, double *, int *); +int BLASFUNC(cge2mm)(char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *, + float *, float *, int *); +int BLASFUNC(zge2mm)(char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *, + double *, double *, int *); + +int BLASFUNC(strsm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(dtrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(qtrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(ctrsm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(ztrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(xtrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); + +int BLASFUNC(strmm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(dtrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(qtrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(ctrmm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(ztrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(xtrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); + +int BLASFUNC(ssymm)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(csymm)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(ssyrk)(char *, char *, int *, int *, float *, float *, int *, + float *, float *, int *); +int BLASFUNC(dsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(qsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(csyrk)(char *, char *, int *, int *, float *, float *, int *, + float *, float *, int *); +int BLASFUNC(zsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(xsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); + +int BLASFUNC(ssyr2k)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(qsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(csyr2k)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(xsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); + +int BLASFUNC(chemm)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhemm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhemm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(cherk)(char *, char *, int *, int *, float *, float *, int *, + float *, float *, int *); +int BLASFUNC(zherk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(xherk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); + +int BLASFUNC(cher2k)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zher2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(xher2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(cher2m)(char *, char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zher2m)(char *, char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(xher2m)(char *, char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); + +int BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *, + double *, int *); + +int BLASFUNC(sgema)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(dgema)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); +int BLASFUNC(cgema)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(zgema)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); + +int BLASFUNC(sgems)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(dgems)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); +int BLASFUNC(cgems)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(zgems)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); + +int BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *); + +int BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *); + +int BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *); +int BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *); +int BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *); +int BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *); +int BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *); +int BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *); + +int BLASFUNC(sgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(dgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); +int BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); +int BLASFUNC(cgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(zgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); +int BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); + +int BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double*, int *, int *); +int BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double*, int *, int *); +int BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double*, int *, int *); +int BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double*, int *, int *); + +int BLASFUNC(spotf2)(char *, int *, float *, int *, int *); +int BLASFUNC(dpotf2)(char *, int *, double *, int *, int *); +int BLASFUNC(qpotf2)(char *, int *, double *, int *, int *); +int BLASFUNC(cpotf2)(char *, int *, float *, int *, int *); +int BLASFUNC(zpotf2)(char *, int *, double *, int *, int *); +int BLASFUNC(xpotf2)(char *, int *, double *, int *, int *); + +int BLASFUNC(spotrf)(char *, int *, float *, int *, int *); +int BLASFUNC(dpotrf)(char *, int *, double *, int *, int *); +int BLASFUNC(qpotrf)(char *, int *, double *, int *, int *); +int BLASFUNC(cpotrf)(char *, int *, float *, int *, int *); +int BLASFUNC(zpotrf)(char *, int *, double *, int *, int *); +int BLASFUNC(xpotrf)(char *, int *, double *, int *, int *); + +int BLASFUNC(slauu2)(char *, int *, float *, int *, int *); +int BLASFUNC(dlauu2)(char *, int *, double *, int *, int *); +int BLASFUNC(qlauu2)(char *, int *, double *, int *, int *); +int BLASFUNC(clauu2)(char *, int *, float *, int *, int *); +int BLASFUNC(zlauu2)(char *, int *, double *, int *, int *); +int BLASFUNC(xlauu2)(char *, int *, double *, int *, int *); + +int BLASFUNC(slauum)(char *, int *, float *, int *, int *); +int BLASFUNC(dlauum)(char *, int *, double *, int *, int *); +int BLASFUNC(qlauum)(char *, int *, double *, int *, int *); +int BLASFUNC(clauum)(char *, int *, float *, int *, int *); +int BLASFUNC(zlauum)(char *, int *, double *, int *, int *); +int BLASFUNC(xlauum)(char *, int *, double *, int *, int *); + +int BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *); + +int BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *); + +int BLASFUNC(spotri)(char *, int *, float *, int *, int *); +int BLASFUNC(dpotri)(char *, int *, double *, int *, int *); +int BLASFUNC(qpotri)(char *, int *, double *, int *, int *); +int BLASFUNC(cpotri)(char *, int *, float *, int *, int *); +int BLASFUNC(zpotri)(char *, int *, double *, int *, int *); +int BLASFUNC(xpotri)(char *, int *, double *, int *, int *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h index 7d509e78f3a..5b979ebf89d 100644 --- a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -29,6 +29,16 @@ operator/(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const */ EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op) +/** \returns an expression of the coefficient-wise min of \c *this and scalar \a other + * + * \sa max() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const ConstantReturnType> +(min)(const Scalar &other) const +{ + return (min)(Derived::PlainObject::Constant(rows(), cols(), other)); +} + /** \returns an expression of the coefficient-wise max of \c *this and \a other * * Example: \include Cwise_max.cpp @@ -38,6 +48,16 @@ EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op) */ EIGEN_MAKE_CWISE_BINARY_OP(max,internal::scalar_max_op) +/** \returns an expression of the coefficient-wise max of \c *this and scalar \a other + * + * \sa min() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const ConstantReturnType> +(max)(const Scalar &other) const +{ + return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); +} + /** \returns an expression of the coefficient-wise \< operator of *this and \a other * * Example: \include Cwise_less.cpp @@ -141,3 +161,39 @@ operator-(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS<Derived>& { return (-other) + scalar; } + +/** \returns an expression of the coefficient-wise && operator of *this and \a other + * + * \warning this operator is for expression of bool only. + * + * Example: \include Cwise_boolean_and.cpp + * Output: \verbinclude Cwise_boolean_and.out + * + * \sa operator||(), select() + */ +template<typename OtherDerived> +inline const CwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived> +operator&&(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + EIGEN_STATIC_ASSERT((internal::is_same<bool,Scalar>::value && internal::is_same<bool,typename OtherDerived::Scalar>::value), + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); + return CwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>(derived(),other.derived()); +} + +/** \returns an expression of the coefficient-wise || operator of *this and \a other + * + * \warning this operator is for expression of bool only. + * + * Example: \include Cwise_boolean_or.cpp + * Output: \verbinclude Cwise_boolean_or.out + * + * \sa operator&&(), select() + */ +template<typename OtherDerived> +inline const CwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived> +operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + EIGEN_STATIC_ASSERT((internal::is_same<bool,Scalar>::value && internal::is_same<bool,typename OtherDerived::Scalar>::value), + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); + return CwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>(derived(),other.derived()); +} diff --git a/extern/Eigen3/Eigen/src/plugins/BlockMethods.h b/extern/Eigen3/Eigen/src/plugins/BlockMethods.h index 4eba933388a..ef224001a54 100644 --- a/extern/Eigen3/Eigen/src/plugins/BlockMethods.h +++ b/extern/Eigen3/Eigen/src/plugins/BlockMethods.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCKMETHODS_H #define EIGEN_BLOCKMETHODS_H diff --git a/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h index 8f7765e72bd..688d2244088 100644 --- a/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing common coefficient wise functions. diff --git a/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h b/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h index 941d5153c59..08e931aaddd 100644 --- a/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing common coefficient wise functions. diff --git a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h index 35183f91f80..3a737df7b86 100644 --- a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing matrix specifics coefficient wise functions. @@ -91,6 +76,16 @@ cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const return CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); } +/** \returns an expression of the coefficient-wise min of *this and scalar \a other + * + * \sa class CwiseBinaryOp, min() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const ConstantReturnType> +cwiseMin(const Scalar &other) const +{ + return cwiseMin(Derived::PlainObject::Constant(rows(), cols(), other)); +} + /** \returns an expression of the coefficient-wise max of *this and \a other * * Example: \include MatrixBase_cwiseMax.cpp @@ -105,6 +100,17 @@ cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const return CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); } +/** \returns an expression of the coefficient-wise max of *this and scalar \a other + * + * \sa class CwiseBinaryOp, min() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const ConstantReturnType> +cwiseMax(const Scalar &other) const +{ + return cwiseMax(Derived::PlainObject::Constant(rows(), cols(), other)); +} + + /** \returns an expression of the coefficient-wise quotient of *this and \a other * * Example: \include MatrixBase_cwiseQuotient.cpp diff --git a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h index a3d9a0e1465..0cf0640bae6 100644 --- a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, 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. -// -// Eigen 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 Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see <http://www.gnu.org/licenses/>. +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing matrix specifics coefficient wise functions. diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 602372f6ff7..38be34add75 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -28,14 +28,14 @@ set(INC . - ../Eigen3 - third_party/ssba - third_party/ldl/Include ../colamd/Include third_party/ceres/include ) set(INC_SYS + ../Eigen3 + third_party/ssba + third_party/ldl/Include ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ) diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh index 3f877508c46..1e386ec8096 100755 --- a/extern/libmv/bundle.sh +++ b/extern/libmv/bundle.sh @@ -124,14 +124,14 @@ cat > CMakeLists.txt << EOF set(INC . - ../Eigen3 - third_party/ssba - third_party/ldl/Include ../colamd/Include third_party/ceres/include ) set(INC_SYS + ../Eigen3 + third_party/ssba + third_party/ldl/Include \${PNG_INCLUDE_DIR} \${ZLIB_INCLUDE_DIRS} ) diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt index 0ce8e273f4a..e2f06d74646 100644 --- a/extern/libmv/third_party/ceres/CMakeLists.txt +++ b/extern/libmv/third_party/ceres/CMakeLists.txt @@ -28,13 +28,13 @@ set(INC . - ../../../Eigen3 include internal ../gflags ) set(INC_SYS + ../../../Eigen3 ) set(SRC diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh index 902fce5f398..ccf6d0aca16 100755 --- a/extern/libmv/third_party/ceres/bundle.sh +++ b/extern/libmv/third_party/ceres/bundle.sh @@ -117,13 +117,13 @@ cat > CMakeLists.txt << EOF set(INC . - ../../../Eigen3 include internal ../gflags ) set(INC_SYS + ../../../Eigen3 ) set(SRC diff --git a/intern/bsp/CMakeLists.txt b/intern/bsp/CMakeLists.txt index 136c168bdb8..e3907c5273d 100644 --- a/intern/bsp/CMakeLists.txt +++ b/intern/bsp/CMakeLists.txt @@ -29,11 +29,10 @@ set(INC ../guardedalloc ../memutil ../moto/include - ../../extern/carve/include ) set(INC_SYS - + ../../extern/carve/include ) set(SRC diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 38daf790955..7562ee0a0a5 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -41,6 +41,7 @@ endif() if(WITH_CYCLES_OSL) add_definitions(-DWITH_OSL) + include_directories(${OSL_INCLUDES}) endif() if(WITH_CYCLES_PARTIO) diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 87a238e508c..5de9d71b8cc 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -591,6 +591,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug if(string_iequals(in->name, attr.name())) { switch(in->type) { case SHADER_SOCKET_FLOAT: + case SHADER_SOCKET_INT: xml_read_float(&in->value.x, node, attr.name()); break; case SHADER_SOCKET_COLOR: diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 0fadfa0afc8..5c68b7f2cb4 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -136,7 +136,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ) cls.blur_glossy = FloatProperty( name="Filter Glossy", - description="Adaptively blur glossy shaders after blurry bounces, to reduce noise at the cost of accuracy", + description="Adaptively blur glossy shaders after blurry bounces, " + "to reduce noise at the cost of accuracy", min=0.0, max=10.0, default=0.0, ) @@ -230,7 +231,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.sample_clamp = FloatProperty( name="Clamp", - description="If non-zero, the maximum value for a sample, higher values will be scaled down to avoid too much noise and slow convergence at the cost of accuracy", + description="If non-zero, the maximum value for a sample, " + "higher values will be scaled down to avoid too " + "much noise and slow convergence at the cost of accuracy", min=0.0, max=1e8, default=0.0, ) @@ -244,7 +247,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.preview_start_resolution = IntProperty( name="Start Resolution", - description="Resolution to start rendering preview at, progressively increasing it to the full viewport size", + description="Resolution to start rendering preview at, " + "progressively increasing it to the full viewport size", min=8, max=16384, default=64, ) @@ -284,6 +288,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Cache last built BVH to disk for faster re-render if no geometry changed", default=False, ) + cls.use_progressive_refine = BoolProperty( + name="Progressive Refine", + description="Instead of rendering each tile until it is finished, " + "refine the whole image progressively. " + "This renders somewhat slower, " + "but time can be saved by manually stopping the render when the noise is low enough", + default=False, + ) @classmethod def unregister(cls): @@ -369,12 +381,15 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup): ) cls.sample_as_light = BoolProperty( name="Sample as Lamp", - description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources", + description="Use direct light sampling for this material, " + "disabling may reduce overall noise for large " + "objects that emit little light compared to other light sources", default=True, ) cls.homogeneous_volume = BoolProperty( name="Homogeneous Volume", - description="When using volume rendering, assume volume has the same density everywhere, for faster rendering", + description="When using volume rendering, assume volume has the same density everywhere, " + "for faster rendering", default=False, ) @@ -418,12 +433,14 @@ class CyclesWorldSettings(bpy.types.PropertyGroup): ) cls.sample_as_light = BoolProperty( name="Sample as Lamp", - description="Use direct light sampling for the environment, enabling for non-solid colors is recommended", + description="Use direct light sampling for the environment, " + "enabling for non-solid colors is recommended", default=False, ) cls.sample_map_resolution = IntProperty( name="Map Resolution", - description="Importance map size is resolution x resolution; higher values potentially produce less noise, at the cost of memory and speed", + description="Importance map size is resolution x resolution; " + "higher values potentially produce less noise, at the cost of memory and speed", min=4, max=8096, default=256, ) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4f4b0371839..f125740efd5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -134,10 +134,6 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): bl_label = "Motion Blur" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - return False - def draw_header(self, context): rd = context.scene.render @@ -202,6 +198,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.prop(rd, "parts_x", text="X") sub.prop(rd, "parts_y", text="Y") + sub.prop(cscene, "use_progressive_refine") + subsub = sub.column() subsub.enabled = not rd.use_border subsub.prop(rd, "use_save_buffers") diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index e16677336d5..000d412ab28 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -425,12 +425,26 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp BL::RegionView3D b_rv3d, int width, int height) { BL::RenderSettings r = b_scene.render(); - - if(!r.use_border()) - return; + bool is_camera_view; /* camera view? */ - if(!(b_rv3d && b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA)) + is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA; + + if(!is_camera_view) { + /* for non-camera view check whether render border is enabled for viewport + * and if so use border from 3d viewport + * assume viewport has got correctly clamped border already + */ + if(b_v3d.use_render_border()) { + bcam->border_left = b_v3d.render_border_min_x(); + bcam->border_right = b_v3d.render_border_max_x(); + bcam->border_bottom = b_v3d.render_border_min_y(); + bcam->border_top = b_v3d.render_border_max_y(); + + return; + } + } + else if(!r.use_border()) return; BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); @@ -504,14 +518,20 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int blender_camera_sync(scene->camera, &bcam, width, height); } -BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height) +BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height) { BufferParams params; + bool use_border = false; params.full_width = width; params.full_height = height; - if(b_scene.render().use_border()) { + if(b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA) + use_border = b_v3d.use_render_border(); + else + use_border = b_scene.render().use_border(); + + if(use_border) { /* border render */ params.full_x = cam->border_left*width; params.full_y = cam->border_bottom*height; diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 9764f24a893..7055cf981c7 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -33,6 +33,28 @@ CCL_NAMESPACE_BEGIN /* Find/Add */ +static float3 tangent_from_triangle(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2) +{ + float3 duv1 = tx2 - tx0; + float3 duv2 = tx2 - tx1; + float3 dp1 = v2 - v0; + float3 dp2 = v2 - v1; + float det = duv1[0] * duv2[1] - duv1[1] * duv2[0]; + + if(det != 0.0f) { + return normalize(dp1 * duv2[1] - dp2 * duv1[1]); + } + else { + /* give back a sane default, using a valid edge as a fallback */ + float3 edge = v1 - v0; + + if(len(edge) == 0.0f) + edge = v2 - v0; + + return normalize(edge); + } +} + static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders) { /* create vertices */ @@ -67,27 +89,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< nverts.push_back(n); } - /* create generated coordinates. todo: we should actually get the orco - * coordinates from modifiers, for now we use texspace loc/size which - * is available in the api. */ - if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { - Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); - float3 loc = get_float3(b_mesh.texspace_location()); - float3 size = get_float3(b_mesh.texspace_size()); - - if(size.x != 0.0f) size.x = 0.5f/size.x; - if(size.y != 0.0f) size.y = 0.5f/size.y; - if(size.z != 0.0f) size.z = 0.5f/size.z; - - loc = loc*size - make_float3(0.5f, 0.5f, 0.5f); - - float3 *fdata = attr->data_float3(); - size_t i = 0; - - for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) - fdata[i++] = get_float3(v->co())*size - loc; - } - /* create vertex color attributes */ { BL::Mesh::tessface_vertex_colors_iterator l; @@ -157,6 +158,86 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< } } } + + /* create texcoord-based tangent attributes */ + if(mesh->need_attribute(scene, ATTR_STD_TANGENT)) { + BL::Mesh::tessface_uv_textures_iterator l; + + for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { + if(!l->active_render()) + continue; + + Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent")); + + /* compute average tangents per vertex */ + float3 *tangents = attr->data_float3(); + memset(tangents, 0, sizeof(float3)*mesh->verts.size()); + + BL::MeshTextureFaceLayer::data_iterator t; + + size_t fi = 0; /* face index */ + b_mesh.tessfaces.begin(f); + for(l->data.begin(t); t != l->data.end() && f != b_mesh.tessfaces.end(); ++t, ++fi, ++f) { + int4 vi = get_int4(f->vertices_raw()); + + float3 tx0 = get_float3(t->uv1()); + float3 tx1 = get_float3(t->uv2()); + float3 tx2 = get_float3(t->uv3()); + + float3 v0 = mesh->verts[vi[0]]; + float3 v1 = mesh->verts[vi[1]]; + float3 v2 = mesh->verts[vi[2]]; + + /* calculate tangent for the triangle; + * get vertex positions, and find change in position with respect + * to the texture coords in the first texture coord dimension */ + float3 tangent0 = tangent_from_triangle(v0, v1, v2, tx0, tx1, tx2); + + if(nverts[fi] == 4) { + /* quad tangent */ + float3 tx3 = get_float3(t->uv4()); + float3 v3 = mesh->verts[vi[3]]; + float3 tangent1 = tangent_from_triangle(v0, v2, v3, tx0, tx2, tx3); + + tangents[vi[0]] += 0.5f*(tangent0 + tangent1); + tangents[vi[1]] += tangent0; + tangents[vi[2]] += 0.5f*(tangent0 + tangent1); + tangents[vi[3]] += tangent1; + } + else { + /* triangle tangent */ + tangents[vi[0]] += tangent0; + tangents[vi[1]] += tangent0; + tangents[vi[2]] += tangent0; + } + } + + /* normalize tangent vectors */ + for(int i = 0; i < mesh->verts.size(); i++) + tangents[i] = normalize(tangents[i]); + } + } + + /* create generated coordinates. todo: we should actually get the orco + * coordinates from modifiers, for now we use texspace loc/size which + * is available in the api. */ + if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { + Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); + float3 loc = get_float3(b_mesh.texspace_location()); + float3 size = get_float3(b_mesh.texspace_size()); + + if(size.x != 0.0f) size.x = 0.5f/size.x; + if(size.y != 0.0f) size.y = 0.5f/size.y; + if(size.z != 0.0f) size.z = 0.5f/size.z; + + loc = loc*size - make_float3(0.5f, 0.5f, 0.5f); + + float3 *generated = attr->data_float3(); + size_t i = 0; + + for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) + generated[i++] = get_float3(v->co())*size - loc; + } } static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, const vector<uint>& used_shaders) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 27301026d35..6de2b0f08fa 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -17,12 +17,14 @@ */ #include "camera.h" +#include "integrator.h" #include "graph.h" #include "light.h" #include "mesh.h" #include "object.h" #include "scene.h" #include "nodes.h" +#include "particles.h" #include "shader.h" #include "blender_sync.h" @@ -227,7 +229,9 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject object->use_motion = true; } - sync_mesh_motion(b_ob, object->mesh, motion); + /* mesh deformation blur not supported yet */ + if(!scene->integrator->motion_blur) + sync_mesh_motion(b_ob, object->mesh, motion); } return; @@ -304,6 +308,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) mesh_map.pre_sync(); object_map.pre_sync(); mesh_synced.clear(); + particle_system_map.pre_sync(); } /* object loop */ @@ -337,8 +342,19 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) Transform tfm = get_transform(b_dup->matrix()); BL::Object b_dup_ob = b_dup->object(); bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); + bool emitter_hide = false; + + if(b_dup_ob.is_duplicator()) { + emitter_hide = true; /* duplicators hidden by default */ + + /* check if we should render or hide particle emitter */ + BL::Object::particle_systems_iterator b_psys; + for(b_dup_ob.particle_systems.begin(b_psys); b_psys != b_dup_ob.particle_systems.end(); ++b_psys) + if(b_psys->settings().use_render_emitter()) + emitter_hide = false; + } - if(!(b_dup->hide() || dup_hide)) { + if(!(b_dup->hide() || dup_hide || emitter_hide)) { sync_object(*b_ob, b_index, *b_dup, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); } @@ -348,11 +364,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) object_free_duplilist(*b_ob); } - /* check if we should render or hide particle emitter */ + + /* sync particles and check if we should render or hide particle emitter */ BL::Object::particle_systems_iterator b_psys; - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) + for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { + if(!motion) + sync_particles(*b_ob, *b_psys); + if(b_psys->settings().use_render_emitter()) hide = false; + } if(!hide) { /* object itself */ @@ -379,6 +400,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) scene->mesh_manager->tag_update(scene); if(object_map.post_sync()) scene->object_manager->tag_update(scene); + if(particle_system_map.post_sync()) + scene->particle_system_manager->tag_update(scene); mesh_synced.clear(); } } @@ -393,6 +416,8 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) if(b_override) b_cam = b_override; + Camera prevcam = *(scene->camera); + /* go back and forth one frame */ int frame = b_scene.frame_current(); @@ -408,6 +433,10 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) } scene_frame_set(b_scene, frame); + + /* tag camera for motion update */ + if(scene->camera->motion_modified(prevcam)) + scene->camera->tag_update(); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index f309960fc55..c4c6d2f79a3 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -51,7 +51,7 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_PATH: { /* for strand rendering */ BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } break; @@ -60,10 +60,10 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_OBJECT: { BL::Object b_dupli_ob = b_psys.settings().dupli_object(); - if (b_dupli_ob) { + if(b_dupli_ob) { BL::ID key = (BKE_object_is_modified(b_dupli_ob))? b_dupli_ob: b_dupli_ob.data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } } @@ -72,12 +72,12 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_GROUP: { BL::Group b_dupli_group = b_psys.settings().dupli_group(); - if (b_dupli_group) { + if(b_dupli_group) { BL::Group::objects_iterator b_gob; for (b_dupli_group.objects.begin(b_gob); b_gob != b_dupli_group.objects.end(); ++b_gob) { BL::ID key = (BKE_object_is_modified(*b_gob))? *b_gob: b_gob->data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } } @@ -109,38 +109,43 @@ static bool use_particle_system(BL::ParticleSystem b_psys) return true; } -static bool use_particle(BL::Particle b_pa) +static bool use_particle(BL::Particle b_pa, bool preview, bool show_unborn, bool use_dead) { - return b_pa.is_exist() && b_pa.is_visible() && - (b_pa.alive_state()==BL::Particle::alive_state_ALIVE || b_pa.alive_state()==BL::Particle::alive_state_DYING); + return b_pa.is_exist() && (!preview || b_pa.is_visible()) && + (b_pa.alive_state() != BL::Particle::alive_state_UNBORN || show_unborn) && + (b_pa.alive_state() != BL::Particle::alive_state_DEAD || use_dead); } -static int psys_count_particles(BL::ParticleSystem b_psys) +static int psys_count_particles(BL::ParticleSystem b_psys, bool preview) { - int tot = 0; BL::ParticleSystem::particles_iterator b_pa; - for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) { - if(use_particle(*b_pa)) - ++tot; - } - return tot; + bool show_unborn = b_psys.settings().show_unborn(); + bool use_dead = b_psys.settings().use_dead(); + int num = 0; + + for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) + if(use_particle(*b_pa, preview, show_unborn, use_dead)) + ++num; + + return num; } int BlenderSync::object_count_particles(BL::Object b_ob) { - int tot = 0; BL::Object::particle_systems_iterator b_psys; - for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { - if (use_particle_system(*b_psys)) - tot += psys_count_particles(*b_psys); - } - return tot; + int num = 0; + + for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) + if(use_particle_system(*b_psys)) + num += psys_count_particles(*b_psys, preview); + + return num; } void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) { /* depending on settings the psys may not even be rendered */ - if (!use_particle_system(b_psys)) + if(!use_particle_system(b_psys)) return; /* key to lookup particle system */ @@ -155,15 +160,19 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) bool need_update = psys_need_update(b_psys); - if (object_updated || need_update) { - int tot = psys_count_particles(b_psys); + if(object_updated || need_update) { + bool show_unborn = b_psys.settings().show_unborn(); + bool use_dead = b_psys.settings().use_dead(); + + int num = psys_count_particles(b_psys, preview); psys->particles.clear(); - psys->particles.reserve(tot); + psys->particles.reserve(num); - int index = 0; BL::ParticleSystem::particles_iterator b_pa; + int index = 0; + for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) { - if(use_particle(*b_pa)) { + if(use_particle(*b_pa, preview, show_unborn, use_dead)) { Particle pa; pa.index = index; @@ -185,34 +194,4 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) } } -void BlenderSync::sync_particle_systems() -{ - /* layer data */ - uint scene_layer = render_layer.scene_layer; - - particle_system_map.pre_sync(); - - /* object loop */ - BL::Scene::objects_iterator b_ob; - BL::Scene b_sce = b_scene; - - for(; b_sce; b_sce = b_sce.background_set()) { - for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) { - bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render(); - uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), render_layer.use_localview, object_is_light(*b_ob)); - hide = hide || !(ob_layer & scene_layer); - - if(!hide) { - BL::Object::particle_systems_iterator b_psys; - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) - sync_particles(*b_ob, *b_psys); - } - } - } - - /* handle removed data and modified pointers */ - if(particle_system_map.post_sync()) - scene->particle_system_manager->tag_update(scene); -} - CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 7b80c520e72..3fdd4418eb6 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -105,7 +105,7 @@ void BlenderSession::create_session() sync->sync_camera(b_engine.camera_override(), width, height); /* set buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } @@ -239,7 +239,7 @@ void BlenderSession::render() /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); /* render each layer */ BL::RenderSettings r = b_scene.render(); @@ -399,7 +399,7 @@ void BlenderSession::synchronize() /* reset if needed */ if(scene->need_reset()) { - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } } @@ -437,7 +437,7 @@ bool BlenderSession::draw(int w, int h) /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, w, h); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, w, h); session->reset(buffer_params, session_params.samples); } @@ -447,7 +447,7 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); return !session->draw(buffer_params); } @@ -466,9 +466,12 @@ void BlenderSession::get_progress(float& progress, double& total_time) session->progress.get_tile(tile, total_time, tile_time); sample = session->progress.get_sample(); - samples_per_tile = session->tile_manager.state.num_samples; + samples_per_tile = session->params.samples; - progress = ((float)sample/(float)(tile_total * samples_per_tile)); + if(samples_per_tile) + progress = ((float)sample/(float)(tile_total * samples_per_tile)); + else + progress = 0.0; } void BlenderSession::update_status_progress() diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index b6d5cc623bb..db34a9fe9aa 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -80,6 +80,8 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) switch (b_type) { case BL::NodeSocket::type_VALUE: return SHADER_SOCKET_FLOAT; + case BL::NodeSocket::type_INT: + return SHADER_SOCKET_INT; case BL::NodeSocket::type_VECTOR: return SHADER_SOCKET_VECTOR; case BL::NodeSocket::type_RGBA: @@ -89,7 +91,6 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) case BL::NodeSocket::type_BOOLEAN: case BL::NodeSocket::type_MESH: - case BL::NodeSocket::type_INT: default: return SHADER_SOCKET_FLOAT; } @@ -104,6 +105,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock) input->set(value_sock.default_value()); break; } + case SHADER_SOCKET_INT: { + BL::NodeSocketIntNone value_sock(sock); + input->set((float)value_sock.default_value()); + break; + } case SHADER_SOCKET_COLOR: { BL::NodeSocketRGBA rgba_sock(sock); input->set(get_float3(rgba_sock.default_value())); @@ -315,6 +321,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph node = new HoldoutNode(); break; } + case BL::ShaderNode::type_BSDF_ANISOTROPIC: { + node = new WardBsdfNode(); + break; + } case BL::ShaderNode::type_BSDF_DIFFUSE: { node = new DiffuseBsdfNode(); break; @@ -398,6 +408,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph node = new ParticleInfoNode(); break; } + case BL::ShaderNode::type_BUMP: { + node = new BumpNode(); + break; + } case BL::ShaderNode::type_TEX_IMAGE: { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index b4990eb815a..24a561116ec 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -17,6 +17,7 @@ */ #include "background.h" +#include "camera.h" #include "film.h" #include "../render/filter.h" #include "graph.h" @@ -141,7 +142,6 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const sync_film(); sync_shaders(); sync_objects(b_v3d); - sync_particle_systems(); sync_motion(b_v3d, b_override); } @@ -149,6 +149,9 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const void BlenderSync::sync_integrator() { +#ifdef __CAMERA_MOTION__ + BL::RenderSettings r = b_scene.render(); +#endif PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); experimental = (RNA_enum_get(&cscene, "feature_set") != 0); @@ -175,7 +178,12 @@ void BlenderSync::sync_integrator() integrator->layer_flag = render_layer.layer; integrator->sample_clamp = get_float(cscene, "sample_clamp"); -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ + if(integrator->motion_blur != r.use_motion_blur()) { + scene->object_manager->tag_update(scene); + scene->camera->tag_update(); + } + integrator->motion_blur = (!preview && r.use_motion_blur()); #endif @@ -377,8 +385,14 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use params.reset_timeout = get_float(cscene, "debug_reset_timeout"); params.text_timeout = get_float(cscene, "debug_text_timeout"); + params.progressive_refine = get_boolean(cscene, "use_progressive_refine"); + if(background) { - params.progressive = false; + if(params.progressive_refine) + params.progressive = true; + else + params.progressive = false; + params.start_resolution = INT_MAX; } else diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index ce563087b4a..36cd5e684a7 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -63,7 +63,7 @@ public: static SceneParams get_scene_params(BL::Scene b_scene, bool background); static SessionParams get_session_params(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, BL::Scene b_scene, bool background); static bool get_session_pause(BL::Scene b_scene, bool background); - static BufferParams get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height); + static BufferParams get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height); private: /* sync */ @@ -77,7 +77,6 @@ private: void sync_world(); void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); void sync_shaders(); - void sync_particle_systems(); void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt index ba5c3785eac..cbbd23fcff8 100644 --- a/intern/cycles/bvh/CMakeLists.txt +++ b/intern/cycles/bvh/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../util ../device ) + set(INC_SYS ) diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index 1d7c6ef4be3..0071bbe5cdc 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../util ../render ) + set(INC_SYS ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_PATH} diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 4c54671b0d0..b727a83d024 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -135,8 +135,10 @@ public: void thread_path_trace(DeviceTask& task) { - if(task_pool.cancelled()) - return; + if(task_pool.cancelled()) { + if(task.need_finish_queue == false) + return; + } #ifdef WITH_OSL if(kernel_osl_use(kg)) @@ -154,8 +156,10 @@ public: #ifdef WITH_OPTIMIZED_KERNEL if(system_cpu_support_optimized()) { for(int sample = start_sample; sample < end_sample; sample++) { - if (task.get_cancel() || task_pool.cancelled()) - break; + if (task.get_cancel() || task_pool.cancelled()) { + if(task.need_finish_queue == false) + break; + } for(int y = tile.y; y < tile.y + tile.h; y++) { for(int x = tile.x; x < tile.x + tile.w; x++) { @@ -173,8 +177,10 @@ public: #endif { for(int sample = start_sample; sample < end_sample; sample++) { - if (task.get_cancel() || task_pool.cancelled()) - break; + if (task.get_cancel() || task_pool.cancelled()) { + if(task.need_finish_queue == false) + break; + } for(int y = tile.y; y < tile.y + tile.h; y++) { for(int x = tile.x; x < tile.x + tile.w; x++) { @@ -191,8 +197,10 @@ public: task.release_tile(tile); - if(task_pool.cancelled()) - break; + if(task_pool.cancelled()) { + if(task.need_finish_queue == false) + break; + } } #ifdef WITH_OSL diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index c8dcfdc2f3d..04b4cb0950a 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -837,8 +837,10 @@ public: int end_sample = tile.start_sample + tile.num_samples; for(int sample = start_sample; sample < end_sample; sample++) { - if (task->get_cancel()) - break; + if (task->get_cancel()) { + if(task->need_finish_queue == false) + break; + } path_trace(tile, sample); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 673ffdf79fd..aa4f17ea325 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -686,8 +686,10 @@ public: int end_sample = tile.start_sample + tile.num_samples; for(int sample = start_sample; sample < end_sample; sample++) { - if (task->get_cancel()) - break; + if (task->get_cancel()) { + if(task->need_finish_queue == false) + break; + } path_trace(tile, sample); diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h index cfb3d8d988e..8ca8b88ea49 100644 --- a/intern/cycles/device/device_task.h +++ b/intern/cycles/device/device_task.h @@ -65,6 +65,7 @@ public: boost::function<void(RenderTile&)> release_tile; boost::function<bool(void)> get_cancel; + bool need_finish_queue; protected: double last_update_time; }; diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index df8a9b1d5b4..6ba25881910 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -5,7 +5,9 @@ set(INC osl svm ) + set(INC_SYS + ) set(SRC @@ -31,13 +33,11 @@ set(SRC_HEADERS kernel_globals.h kernel_light.h kernel_math.h - kernel_mbvh.h kernel_montecarlo.h kernel_object.h kernel_passes.h kernel_path.h kernel_projection.h - kernel_qbvh.h kernel_random.h kernel_shader.h kernel_textures.h @@ -46,17 +46,17 @@ set(SRC_HEADERS ) set(SRC_SVM_HEADERS - svm/bsdf.h - svm/bsdf_ashikhmin_velvet.h - svm/bsdf_diffuse.h - svm/bsdf_oren_nayar.h - svm/bsdf_microfacet.h - svm/bsdf_reflection.h - svm/bsdf_refraction.h - svm/bsdf_transparent.h - svm/bsdf_ward.h - svm/bsdf_westin.h - svm/emissive.h + closure/bsdf.h + closure/bsdf_ashikhmin_velvet.h + closure/bsdf_microfacet.h + closure/bsdf_reflection.h + closure/bsdf_refraction.h + closure/bsdf_transparent.h + closure/bsdf_ward.h + closure/bsdf_westin.h + closure/emissive.h + closure/volume.h + svm/svm.h svm/svm_attribute.h svm/svm_bsdf.h @@ -92,7 +92,6 @@ set(SRC_SVM_HEADERS svm/svm_value.h svm/svm_voronoi.h svm/svm_wave.h - svm/volume.h ) set(SRC_UTIL_HEADERS diff --git a/intern/cycles/kernel/svm/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index cfb6321a918..cfb6321a918 100644 --- a/intern/cycles/kernel/svm/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h index 40249dbe9c6..016fd73204e 100644 --- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h @@ -35,37 +35,34 @@ CCL_NAMESPACE_BEGIN -typedef struct BsdfAshikhminVelvetClosure { - //float3 m_N; - float m_invsigma2; -} BsdfAshikhminVelvetClosure; - -__device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, ShaderClosure *sc, float sigma) +__device int bsdf_ashikhmin_velvet_setup(ShaderClosure *sc) { + float sigma = sc->data0; sigma = fmaxf(sigma, 0.01f); float m_invsigma2 = 1.0f/(sigma * sigma); sc->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; sc->data0 = m_invsigma2; + + return SD_BSDF|SD_BSDF_HAS_EVAL; } __device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invsigma2 = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float3 H = normalize(omega_in + I); - float cosNH = dot(m_N, H); + float cosNH = dot(N, H); float cosHO = fabsf(dot(I, H)); if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f)) @@ -93,32 +90,27 @@ __device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const S return make_float3(0, 0, 0); } -__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_invsigma2 = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; // we are viewing the surface from above - send a ray out with uniform // distribution over the hemisphere - sample_uniform_hemisphere(m_N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) > 0) { - float3 H = normalize(*omega_in + sd->I); + if(dot(Ng, *omega_in) > 0) { + float3 H = normalize(*omega_in + I); - float cosNI = dot(m_N, *omega_in); - float cosNO = dot(m_N, sd->I); - float cosNH = dot(m_N, H); - float cosHO = fabsf(dot(sd->I, H)); + float cosNI = dot(N, *omega_in); + float cosNO = dot(N, I); + float cosNH = dot(N, H); + float cosHO = fabsf(dot(I, H)); if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) { float cosNHdivHO = cosNH / cosHO; @@ -140,8 +132,8 @@ __device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClos #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the retroreflective bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h index edf8dd93341..88b40e3d479 100644 --- a/intern/cycles/kernel/svm/bsdf_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse.h @@ -37,52 +37,43 @@ CCL_NAMESPACE_BEGIN /* DIFFUSE */ -typedef struct BsdfDiffuseClosure { - //float3 m_N; -} BsdfDiffuseClosure; - -__device void bsdf_diffuse_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_diffuse_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DIFFUSE_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; + return SD_BSDF|SD_BSDF_HAS_EVAL; } __device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float3 m_N = sd->N; + float3 N = sc->N; - float cos_pi = fmaxf(dot(m_N, omega_in), 0.0f) * M_1_PI_F; + float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; return make_float3(cos_pi, cos_pi, cos_pi); } -__device float3 bsdf_diffuse_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_diffuse_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - float3 m_N = sd->N; + float3 N = sc->N; // distribution over the hemisphere - sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf); + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) > 0.0f) { + if(dot(Ng, *omega_in) > 0.0f) { *eval = make_float3(*pdf, *pdf, *pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif @@ -95,52 +86,48 @@ __device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, /* TRANSLUCENT */ -typedef struct BsdfTranslucentClosure { - //float3 m_N; -} BsdfTranslucentClosure; - -__device void bsdf_translucent_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_translucent_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSLUCENT_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; + return SD_BSDF|SD_BSDF_HAS_EVAL; } __device void bsdf_translucent_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float3 m_N = sd->N; + float3 N = sc->N; - float cos_pi = fmaxf(-dot(m_N, omega_in), 0.0f) * M_1_PI_F; + float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; return make_float3 (cos_pi, cos_pi, cos_pi); } -__device float bsdf_translucent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_translucent_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_translucent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - float3 m_N = sd->N; + float3 N = sc->N; // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere - sample_cos_hemisphere (-m_N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) < 0) { + sample_cos_hemisphere (-N, randu, randv, omega_in, pdf); + if(dot(Ng, *omega_in) < 0) { *eval = make_float3(*pdf, *pdf, *pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= -125.0f; *domega_in_dy *= -125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index d8f0310bd02..f671e858481 100644 --- a/intern/cycles/kernel/svm/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -37,31 +37,39 @@ CCL_NAMESPACE_BEGIN /* GGX */ -typedef struct BsdfMicrofacetGGXClosure { - //float3 m_N; - float m_ag; - float m_eta; -} BsdfMicrofacetGGXClosure; - __device_inline float safe_sqrtf(float f) { return sqrtf(max(f, 0.0f)); } -__device void bsdf_microfacet_ggx_setup(ShaderData *sd, ShaderClosure *sc, float ag, float eta, bool refractive) +__device int bsdf_microfacet_ggx_setup(ShaderClosure *sc) { + float ag = sc->data0; + float eta = sc->data1; + float m_ag = clamp(ag, 1e-4f, 1.0f); float m_eta = eta; sc->data0 = m_ag; sc->data1 = m_eta; + sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID; - if(refractive) - sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - else - sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +} - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +__device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc) +{ + float ag = sc->data0; + float eta = sc->data1; + + float m_ag = clamp(ag, 1e-4f, 1.0f); + float m_eta = eta; + + sc->data0 = m_ag; + sc->data1 = m_eta; + sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) @@ -71,23 +79,23 @@ __device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) sc->data0 = m_ag; } -__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ag = sc->data0; //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sd->N; + float3 N = sc->N; if(m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNI > 0 && cosNO > 0) { // get half vector float3 Hr = normalize(omega_in + I); // eq. 20: (F*G*D)/(4*in*on) // eq. 33: first we calculate D(m) with m=Hr: float alpha2 = m_ag * m_ag; - float cosThetaM = dot(m_N, Hr); + float cosThetaM = dot(N, Hr); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -108,16 +116,16 @@ __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const Sha return make_float3 (0, 0, 0); } -__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ag = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sd->N; + float3 N = sc->N; if(!m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO <= 0 || cosNI >= 0) return make_float3 (0, 0, 0); // vectors on same side -- not possible // compute half-vector of the refraction (eq. 16) @@ -128,7 +136,7 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh float cosHI = dot(Ht, omega_in); // eq. 33: first we calculate D(m) with m=Ht: float alpha2 = m_ag * m_ag; - float cosThetaM = dot(m_N, Ht); + float cosThetaM = dot(N, Ht); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -144,21 +152,16 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh return make_float3 (out, out, out); } -__device float bsdf_microfacet_ggx_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_ag = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sd->N; + float3 N = sc->N; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { - float3 X, Y, Z = m_N; + float3 X, Y, Z = N; make_orthonormals(Z, &X, &Y); // generate a random microfacet normal m // eq. 35,36: @@ -173,11 +176,11 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur (sinf(phiM) * sinThetaM) * Y + cosThetaM * Z; if(!m_refractive) { - float cosMO = dot(m, sd->I); + float cosMO = dot(m, I); if(cosMO > 0) { // eq. 39 - compute actual reflected direction - *omega_in = 2 * cosMO * m - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { + *omega_in = 2 * cosMO * m - I; + if(dot(Ng, *omega_in) > 0) { // microfacet normal is visible to this ray // eq. 33 float cosThetaM2 = cosThetaM * cosThetaM; @@ -190,7 +193,7 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf *pdf = pm * 0.25f / cosMO; // eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 34: now calculate G1(i,m) and G1(o,m) float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); @@ -199,8 +202,8 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur float out = (G * D) * 0.25f / cosNO; *eval = make_float3(out, out, out); #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx; - *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy; + *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; + *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; // Since there is some blur to this reflection, make the // derivatives a bit bigger. In theory this varies with the // roughness but the exact relationship is complex and @@ -219,9 +222,9 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, m, sd->I, &R, &T, + fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ - sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy, + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); @@ -238,14 +241,14 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur // eq. 24 float pm = D * cosThetaM; // eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 34: now calculate G1(i,m) and G1(o,m) float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); float G = G1o * G1i; // eq. 21 float cosHI = dot(m, *omega_in); - float cosHO = dot(m, sd->I); + float cosHO = dot(m, I); float Ht2 = m_eta * cosHI + cosHO; Ht2 *= Ht2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); @@ -268,26 +271,32 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur /* BECKMANN */ -typedef struct BsdfMicrofacetBeckmannClosure { - //float3 m_N; - float m_ab; - float m_eta; -} BsdfMicrofacetBeckmannClosure; - -__device void bsdf_microfacet_beckmann_setup(ShaderData *sd, ShaderClosure *sc, float ab, float eta, bool refractive) +__device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc) { + float ab = sc->data0; + float eta = sc->data1; float m_ab = clamp(ab, 1e-4f, 1.0f); float m_eta = eta; sc->data0 = m_ab; sc->data1 = m_eta; - if(refractive) - sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - else - sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +} + +__device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc) +{ + float ab = sc->data0; + float eta = sc->data1; + float m_ab = clamp(ab, 1e-4f, 1.0f); + float m_eta = eta; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; + sc->data0 = m_ab; + sc->data1 = m_eta; + + sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness) @@ -297,23 +306,23 @@ __device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness) sc->data0 = m_ab; } -__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ab = sc->data0; //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sd->N; + float3 N = sc->N; if(m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { // get half vector float3 Hr = normalize(omega_in + I); // eq. 20: (F*G*D)/(4*in*on) // eq. 25: first we calculate D(m) with m=Hr: float alpha2 = m_ab * m_ab; - float cosThetaM = dot(m_N, Hr); + float cosThetaM = dot(N, Hr); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -336,16 +345,16 @@ __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, cons return make_float3 (0, 0, 0); } -__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ab = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sd->N; + float3 N = sc->N; if(!m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO <= 0 || cosNI >= 0) return make_float3 (0, 0, 0); // compute half-vector of the refraction (eq. 16) @@ -356,7 +365,7 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con float cosHI = dot(Ht, omega_in); // eq. 33: first we calculate D(m) with m=Ht: float alpha2 = m_ab * m_ab; - float cosThetaM = dot(m_N, Ht); + float cosThetaM = dot(N, Ht); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -374,21 +383,16 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con return make_float3 (out, out, out); } -__device float bsdf_microfacet_beckmann_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_ab = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sd->N; + float3 N = sc->N; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { - float3 X, Y, Z = m_N; + float3 X, Y, Z = N; make_orthonormals(Z, &X, &Y); // generate a random microfacet normal m // eq. 35,36: @@ -404,11 +408,11 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC cosThetaM * Z; if(!m_refractive) { - float cosMO = dot(m, sd->I); + float cosMO = dot(m, I); if(cosMO > 0) { // eq. 39 - compute actual reflected direction - *omega_in = 2 * cosMO * m - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { + *omega_in = 2 * cosMO * m - I; + if(dot(Ng, *omega_in) > 0) { // microfacet normal is visible to this ray // eq. 25 float cosThetaM2 = cosThetaM * cosThetaM; @@ -422,7 +426,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf *pdf = pm * 0.25f / cosMO; // Eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 26, 27: now calculate G1(i,m) and G1(o,m) float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); @@ -433,8 +437,8 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float out = (G * D) * 0.25f / cosNO; *eval = make_float3(out, out, out); #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx; - *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy; + *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; + *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; // Since there is some blur to this reflection, make the // derivatives a bit bigger. In theory this varies with the // roughness but the exact relationship is complex and @@ -453,9 +457,9 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, m, sd->I, &R, &T, + fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ - sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy, + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); @@ -474,7 +478,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC // eq. 24 float pm = D * cosThetaM; // eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 26, 27: now calculate G1(i,m) and G1(o,m) float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); @@ -483,7 +487,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float G = G1o * G1i; // eq. 21 float cosHI = dot(m, *omega_in); - float cosHO = dot(m, sd->I); + float cosHO = dot(m, I); float Ht2 = m_eta * cosHI + cosHO; Ht2 *= Ht2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); diff --git a/intern/cycles/kernel/svm/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h index a7edccdc423..066937da6eb 100644 --- a/intern/cycles/kernel/svm/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h @@ -21,11 +21,6 @@ CCL_NAMESPACE_BEGIN -typedef struct BsdfOrenNayarClosure { - float m_a; - float m_b; -} BsdfOrenNayarClosure; - __device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, float3 v, float3 l) { float nl = max(dot(n, l), 0.0f); @@ -38,10 +33,11 @@ __device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, return make_float3(is, is, is); } -__device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sigma) +__device int bsdf_oren_nayar_setup(ShaderClosure *sc) { + float sigma = sc->data0; + sc->type = CLOSURE_BSDF_OREN_NAYAR_ID; - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; sigma = clamp(sigma, 0.0f, 1.0f); @@ -49,17 +45,19 @@ __device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sig sc->data0 = 1.0f * div; sc->data1 = sigma * div; + + return SD_BSDF | SD_BSDF_HAS_EVAL; } __device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - if (dot(sd->N, omega_in) > 0.0f) { + if (dot(sc->N, omega_in) > 0.0f) { *pdf = 0.5f * M_1_PI_F; - return bsdf_oren_nayar_get_intensity(sc, sd->N, I, omega_in); + return bsdf_oren_nayar_get_intensity(sc, sc->N, I, omega_in); } else { *pdf = 0.0f; @@ -67,27 +65,22 @@ __device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderC } } -__device float3 bsdf_oren_nayar_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_oren_nayar_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_oren_nayar_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - sample_uniform_hemisphere(sd->N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf); - if (dot(sd->Ng, *omega_in) > 0.0f) { - *eval = bsdf_oren_nayar_get_intensity(sc, sd->N, sd->I, *omega_in); + if (dot(Ng, *omega_in) > 0.0f) { + *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the bounce - *domega_in_dx = (2.0f * dot(sd->N, sd->dI.dx)) * sd->N - sd->dI.dx; - *domega_in_dy = (2.0f * dot(sd->N, sd->dI.dy)) * sd->N - sd->dI.dy; + *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx; + *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h index 09b4e0e48f0..9356f950d98 100644 --- a/intern/cycles/kernel/svm/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -37,48 +37,39 @@ CCL_NAMESPACE_BEGIN /* REFLECTION */ -typedef struct BsdfReflectionClosure { - //float3 m_N; -} BsdfReflectionClosure; - -__device void bsdf_reflection_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_reflection_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_REFLECTION_ID; - sd->flag |= SD_BSDF; + return SD_BSDF; } __device void bsdf_reflection_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_reflection_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_reflection_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_reflection_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_reflection_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { //const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data; - float3 m_N = sd->N; + float3 N = sc->N; // only one direction is possible - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { - *omega_in = (2 * cosNO) * m_N - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { + *omega_in = (2 * cosNO) * N - I; + if(dot(Ng, *omega_in) > 0) { #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(m_N, sd->dI.dx) * m_N - sd->dI.dx; - *domega_in_dy = 2 * dot(m_N, sd->dI.dy) * m_N - sd->dI.dy; + *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; + *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; #endif *pdf = 1; *eval = make_float3(1, 1, 1); diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h index c9c268999c0..ef79d6cc259 100644 --- a/intern/cycles/kernel/svm/bsdf_refraction.h +++ b/intern/cycles/kernel/closure/bsdf_refraction.h @@ -37,50 +37,39 @@ CCL_NAMESPACE_BEGIN /* REFRACTION */ -typedef struct BsdfRefractionClosure { - float m_eta; -} BsdfRefractionClosure; - -__device void bsdf_refraction_setup(ShaderData *sd, ShaderClosure *sc, float eta) +__device int bsdf_refraction_setup(ShaderClosure *sc) { - sc->data0 = eta; - sc->type = CLOSURE_BSDF_REFRACTION_ID; - sd->flag |= SD_BSDF; + return SD_BSDF; } __device void bsdf_refraction_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_refraction_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_refraction_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_refraction_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_refraction_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_refraction_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_eta = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; float3 R, T; #ifdef __RAY_DIFFERENTIALS__ float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, m_N, sd->I, &R, &T, + fresnel_dielectric(m_eta, N, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ - sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy, + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); diff --git a/intern/cycles/kernel/svm/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h index 511836cdfa2..81bc7690b50 100644 --- a/intern/cycles/kernel/svm/bsdf_transparent.h +++ b/intern/cycles/kernel/closure/bsdf_transparent.h @@ -35,38 +35,33 @@ CCL_NAMESPACE_BEGIN -__device void bsdf_transparent_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_transparent_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSPARENT_ID; - sd->flag |= SD_BSDF; + return SD_BSDF; } __device void bsdf_transparent_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_transparent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_transparent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_transparent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_transparent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { // only one direction is possible - *omega_in = -sd->I; + *omega_in = -I; #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = -sd->dI.dx; - *domega_in_dy = -sd->dI.dy; + *domega_in_dx = -dIdx; + *domega_in_dy = -dIdy; #endif *pdf = 1; *eval = make_float3(1, 1, 1); diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h index 6ae45948a73..9c81548a2c3 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/closure/bsdf_ward.h @@ -37,23 +37,19 @@ CCL_NAMESPACE_BEGIN /* WARD */ -typedef struct BsdfWardClosure { - //float3 m_N; - //float3 m_T; - float m_ax; - float m_ay; -} BsdfWardClosure; - -__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float3 T, float ax, float ay) +__device int bsdf_ward_setup(ShaderClosure *sc) { - float m_ax = clamp(ax, 1e-5f, 1.0f); - float m_ay = clamp(ay, 1e-5f, 1.0f); + float ax = sc->data0; + float ay = sc->data1; + + float m_ax = clamp(ax, 1e-4f, 1.0f); + float m_ay = clamp(ay, 1e-4f, 1.0f); sc->data0 = m_ax; sc->data1 = m_ay; sc->type = CLOSURE_BSDF_WARD_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_ward_blur(ShaderClosure *sc, float roughness) @@ -62,25 +58,25 @@ __device void bsdf_ward_blur(ShaderClosure *sc, float roughness) sc->data1 = fmaxf(roughness, sc->data1); } -__device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ward_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ax = sc->data0; float m_ay = sc->data1; - float3 m_N = sd->N; - float3 m_T = normalize(sd->dPdu); + float3 N = sc->N; + float3 T = sc->T; - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNI > 0 && cosNO > 0) { // get half vector and get x,y basis on the surface for anisotropy float3 H = normalize(omega_in + I); // normalize needed for pdf float3 X, Y; - make_orthonormals_tangent(m_N, m_T, &X, &Y); + make_orthonormals_tangent(N, T, &X, &Y); // eq. 4 float dotx = dot(H, X) / m_ax; float doty = dot(H, Y) / m_ay; - float dotn = dot(H, m_N); + float dotn = dot(H, N); float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); float denom = (4 * M_PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI)); float exp_val = expf(-exp_arg); @@ -90,31 +86,27 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *pdf = exp_val / denom; return make_float3 (out, out, out); } + return make_float3 (0, 0, 0); } -__device float3 bsdf_ward_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ward_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_ward_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_ward_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_ax = sc->data0; float m_ay = sc->data1; - float3 m_N = sd->N; - float3 m_T = normalize(sd->dPdu); + float3 N = sc->N; + float3 T = sc->T; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { // get x,y basis on the surface for anisotropy float3 X, Y; - make_orthonormals_tangent(m_N, m_T, &X, &Y); + make_orthonormals_tangent(N, T, &X, &Y); // generate random angles for the half vector // eq. 7 (taking care around discontinuities to keep //ttoutput angle in the right quadrant) @@ -166,12 +158,12 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo float doty = h.y / m_ay; float dotn = h.z; // transform to world space - h = h.x * X + h.y * Y + h.z * m_N; + h = h.x * X + h.y * Y + h.z * N; // generate the final sample - float oh = dot(h, sd->I); - *omega_in = 2.0f * oh * h - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { - float cosNI = dot(m_N, *omega_in); + float oh = dot(h, I); + *omega_in = 2.0f * oh * h - I; + if(dot(Ng, *omega_in) > 0) { + float cosNI = dot(N, *omega_in); if(cosNI > 0) { // eq. 9 float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); @@ -182,8 +174,8 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo float power = cosNI * expf(-exp_arg) / denom; *eval = make_float3(power, power, power); #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; // Since there is some blur to this reflection, make the // derivatives a bit bigger. In theory this varies with the // roughness but the exact relationship is complex and diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h index 3e7c27f44a4..968173208b4 100644 --- a/intern/cycles/kernel/svm/bsdf_westin.h +++ b/intern/cycles/kernel/closure/bsdf_westin.h @@ -37,19 +37,16 @@ CCL_NAMESPACE_BEGIN /* WESTIN BACKSCATTER */ -typedef struct BsdfWestinBackscatterClosure { - //float3 m_N; - float m_invroughness; -} BsdfWestinBackscatterClosure; - -__device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness) +__device int bsdf_westin_backscatter_setup(ShaderClosure *sc) { + float roughness = sc->data0; roughness = clamp(roughness, 1e-5f, 1.0f); float m_invroughness = 1.0f/roughness; sc->type = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; sc->data0 = m_invroughness; + + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness) @@ -59,14 +56,14 @@ __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness) sc->data0 = m_invroughness; } -__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invroughness = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; // pdf is implicitly 0 (no indirect sampling) - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float cosine = dot(I, omega_in); *pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; @@ -76,40 +73,35 @@ __device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const return make_float3 (0, 0, 0); } -__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_invroughness = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = sd->dI.dx; - *domega_in_dy = sd->dI.dy; + *domega_in_dx = dIdx; + *domega_in_dy = dIdy; #endif float3 T, B; - make_orthonormals (sd->I, &T, &B); + make_orthonormals (I, &T, &B); float phi = 2 * M_PI_F * randu; float cosTheta = powf(randv, 1 / (m_invroughness + 1)); float sinTheta2 = 1 - cosTheta * cosTheta; float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; *omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + - (cosTheta) * sd->I; - if(dot(sd->Ng, *omega_in) > 0) + (cosTheta) * I; + if(dot(Ng, *omega_in) > 0) { // common terms for pdf and eval - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // make sure the direction we chose is still in the right hemisphere if(cosNI > 0) { @@ -132,30 +124,26 @@ __device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderCl /* WESTIN SHEEN */ -typedef struct BsdfWestinSheenClosure { - //float3 m_N; - float m_edginess; -} BsdfWestinSheenClosure; - -__device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess) +__device int bsdf_westin_sheen_setup(ShaderClosure *sc) { + float edginess = sc->data0; sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; sc->data0 = edginess; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_sheen_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_edginess = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; // pdf is implicitly 0 (no indirect sampling) - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float sinNO2 = 1 - cosNO * cosNO; *pdf = cosNI * M_1_PI_F; @@ -165,34 +153,29 @@ __device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const Shade return make_float3 (0, 0, 0); } -__device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_sheen_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - -__device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_westin_sheen_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_edginess = sc->data0; - float3 m_N = sd->N; + float3 N = sc->N; // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere - sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) > 0) { + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + if(dot(Ng, *omega_in) > 0) { // TODO: account for sheen when sampling - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); float sinNO2 = 1 - cosNO * cosNO; float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0; *eval = make_float3(westin, westin, westin); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/emissive.h b/intern/cycles/kernel/closure/emissive.h index 9a906f82963..cbf9d9a4efb 100644 --- a/intern/cycles/kernel/svm/emissive.h +++ b/intern/cycles/kernel/closure/emissive.h @@ -34,15 +34,21 @@ CCL_NAMESPACE_BEGIN /* EMISSION CLOSURE */ -/// Return the probability distribution function in the direction I, -/// given the parameters and the light's surface normal. This MUST match -/// the PDF computed by sample(). +/* return the probability distribution function in the direction I, + * given the parameters and the light's surface normal. This MUST match + * the PDF computed by sample(). */ __device float emissive_pdf(const float3 Ng, const float3 I) { float cosNO = fabsf(dot(Ng, I)); return (cosNO > 0.0f)? 1.0f: 0.0f; } +__device void emissive_sample(const float3 Ng, float randu, float randv, + float3 *omega_out, float *pdf) +{ + /* todo: not implemented and used yet */ +} + __device float3 emissive_eval(const float3 Ng, const float3 I) { float res = emissive_pdf(Ng, I); diff --git a/intern/cycles/kernel/svm/volume.h b/intern/cycles/kernel/closure/volume.h index 10e9c5de352..734f9111ab6 100644 --- a/intern/cycles/kernel/svm/volume.h +++ b/intern/cycles/kernel/closure/volume.h @@ -23,44 +23,46 @@ CCL_NAMESPACE_BEGIN /* ISOTROPIC VOLUME CLOSURE */ -__device void volume_isotropic_setup(ShaderData *sd, ShaderClosure *sc, float density) +__device int volume_isotropic_setup(ShaderClosure *sc, float density) { sc->type = CLOSURE_VOLUME_ISOTROPIC_ID; - sd->flag |= SD_VOLUME; sc->data0 = density; + + return SD_VOLUME; } -__device float3 volume_isotropic_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_isotropic_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { return make_float3(1.0f, 1.0f, 1.0f); } /* TRANSPARENT VOLUME CLOSURE */ -__device void volume_transparent_setup(ShaderData *sd, ShaderClosure *sc, float density) +__device int volume_transparent_setup(ShaderClosure *sc, float density) { sc->type = CLOSURE_VOLUME_TRANSPARENT_ID; - sd->flag |= SD_VOLUME; sc->data0 = density; + + return SD_VOLUME; } -__device float3 volume_transparent_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { return make_float3(1.0f, 1.0f, 1.0f); } /* VOLUME CLOSURE */ -__device float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { float3 eval; switch(sc->type) { case CLOSURE_VOLUME_ISOTROPIC_ID: - eval = volume_isotropic_eval_phase(sd, sc, omega_in, omega_out); + eval = volume_isotropic_eval_phase(sc, omega_in, omega_out); break; case CLOSURE_VOLUME_TRANSPARENT_ID: - eval = volume_transparent_eval_phase(sd, sc, omega_in, omega_out); + eval = volume_transparent_eval_phase(sc, omega_in, omega_out); break; default: eval = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h index 115de2fdbdb..2774f5e924b 100644 --- a/intern/cycles/kernel/kernel_attribute.h +++ b/intern/cycles/kernel/kernel_attribute.h @@ -59,7 +59,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id) attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset); /* return result */ - return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : attr_map.z; + return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; } } diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index 34a44af8b8d..e3c8b796e9c 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -57,7 +57,7 @@ __device_inline float3 bvh_inverse_direction(float3 dir) __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) { - Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, ray->P); @@ -75,7 +75,7 @@ __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) { if(*t != FLT_MAX) { - Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); *t *= len(transform_direction(&tfm, 1.0f/(*idir))); } @@ -83,6 +83,35 @@ __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray * *idir = bvh_inverse_direction(ray->D); } +#ifdef __OBJECT_MOTION__ +__device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax) +{ + Transform itfm; + *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + + *P = transform_point(&itfm, ray->P); + + float3 dir = transform_direction(&itfm, ray->D); + + float len; + dir = normalize_len(dir, &len); + + *idir = bvh_inverse_direction(dir); + + if(*t != FLT_MAX) + *t *= len; +} + +__device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax) +{ + if(*t != FLT_MAX) + *t *= len(transform_direction(tfm, 1.0f/(*idir))); + + *P = ray->P; + *idir = bvh_inverse_direction(ray->D); +} +#endif + /* intersect two bounding boxes */ __device_inline void bvh_node_intersect(KernelGlobals *kg, bool *traverseChild0, bool *traverseChild1, @@ -176,7 +205,7 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise } } -__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) +__device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) { /* traversal stack in CUDA thread-local memory */ int traversalStack[BVH_STACK_SIZE]; @@ -268,7 +297,6 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui else { /* instance push */ object = kernel_tex_fetch(__prim_object, -primAddr-1); - bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax); ++stackPtr; @@ -296,6 +324,140 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui return (isect->prim != ~0); } +#ifdef __OBJECT_MOTION__ +__device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) +{ + /* traversal stack in CUDA thread-local memory */ + int traversalStack[BVH_STACK_SIZE]; + traversalStack[0] = ENTRYPOINT_SENTINEL; + + /* traversal variables in registers */ + int stackPtr = 0; + int nodeAddr = kernel_data.bvh.root; + + /* ray parameters in registers */ + const float tmax = ray->t; + float3 P = ray->P; + float3 idir = bvh_inverse_direction(ray->D); + int object = ~0; + + Transform ob_tfm; + + isect->t = tmax; + isect->object = ~0; + isect->prim = ~0; + isect->u = 0.0f; + isect->v = 0.0f; + + /* traversal loop */ + do { + do + { + /* traverse internal nodes */ + while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) + { + bool traverseChild0, traverseChild1, closestChild1; + int nodeAddrChild1; + + bvh_node_intersect(kg, &traverseChild0, &traverseChild1, + &closestChild1, &nodeAddr, &nodeAddrChild1, + P, idir, isect->t, visibility, nodeAddr); + + if(traverseChild0 != traverseChild1) { + /* one child was intersected */ + if(traverseChild1) { + nodeAddr = nodeAddrChild1; + } + } + else { + if(!traverseChild0) { + /* neither child was intersected */ + nodeAddr = traversalStack[stackPtr]; + --stackPtr; + } + else { + /* both children were intersected, push the farther one */ + if(closestChild1) { + int tmp = nodeAddr; + nodeAddr = nodeAddrChild1; + nodeAddrChild1 = tmp; + } + + ++stackPtr; + traversalStack[stackPtr] = nodeAddrChild1; + } + } + } + + /* if node is leaf, fetch triangle list */ + if(nodeAddr < 0) { + float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1)); + int primAddr = __float_as_int(leaf.x); + + if(primAddr >= 0) { + int primAddr2 = __float_as_int(leaf.y); + + /* pop */ + nodeAddr = traversalStack[stackPtr]; + --stackPtr; + + /* triangle intersection */ + while(primAddr < primAddr2) { + /* intersect ray against triangle */ + bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); + + /* shadow ray early termination */ + if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0) + return true; + + primAddr++; + } + } + else { + /* instance push */ + object = kernel_tex_fetch(__prim_object, -primAddr-1); + bvh_instance_motion_push(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax); + + ++stackPtr; + traversalStack[stackPtr] = ENTRYPOINT_SENTINEL; + + nodeAddr = kernel_tex_fetch(__object_node, object); + } + } + } while(nodeAddr != ENTRYPOINT_SENTINEL); + + if(stackPtr >= 0) { + kernel_assert(object != ~0); + + /* instance pop */ + bvh_instance_motion_pop(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax); + object = ~0; + nodeAddr = traversalStack[stackPtr]; + --stackPtr; + } + } while(nodeAddr != ENTRYPOINT_SENTINEL); + + return (isect->prim != ~0); +} +#endif + +__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) +{ +#ifdef __OBJECT_MOTION__ +#if !defined(__KERNEL_CUDA__) || (__CUDA_ARCH__ >= 210) + if(kernel_data.bvh.have_motion) + return bvh_intersect_motion(kg, ray, visibility, isect); + else + return bvh_intersect(kg, ray, visibility, isect); +#else + /* todo: fix cuda sm 2.0 motion blur */ + return bvh_intersect(kg, ray, visibility, isect); +#endif +#else + return bvh_intersect(kg, ray, visibility, isect); +#endif +} + __device_inline float3 ray_offset(float3 P, float3 Ng) { #ifdef __INTERSECTION_REFINE__ @@ -349,10 +511,10 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co #ifdef __INTERSECTION_REFINE__ if(isect->object != ~0) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_itfm; #else - Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); #endif P = transform_point(&tfm, P); @@ -370,10 +532,10 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co P = P + D*rt; if(isect->object != ~0) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_tfm; #else - Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); #endif P = transform_point(&tfm, P); diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 7fa987197c9..1b2fe8c56ee 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -63,7 +63,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float /* transform ray from camera to world */ Transform cameratoworld = kernel_data.cam.cameratoworld; -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); #endif @@ -106,7 +106,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa /* transform ray from camera to world */ Transform cameratoworld = kernel_data.cam.cameratoworld; -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); #endif @@ -180,7 +180,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra /* transform ray from camera to world */ Transform cameratoworld = kernel_data.cam.cameratoworld; -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); #endif @@ -212,12 +212,12 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo float raster_x = x + kernel_tex_interp(__filter_table, filter_u, FILTER_TABLE_SIZE); float raster_y = y + kernel_tex_interp(__filter_table, filter_v, FILTER_TABLE_SIZE); -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ /* motion blur */ if(kernel_data.cam.shuttertime == 0.0f) ray->time = TIME_INVALID; else - ray->time = 0.5f + (time - 0.5f)*kernel_data.cam.shuttertime; + ray->time = 0.5f + 0.5f*(time - 0.5f)*kernel_data.cam.shuttertime; #endif /* sample */ diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h index 6461a1eea38..a55f7a7fd75 100644 --- a/intern/cycles/kernel/kernel_displace.h +++ b/intern/cycles/kernel/kernel_displace.h @@ -47,6 +47,9 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou ray.P = make_float3(0.0f, 0.0f, 0.0f); ray.D = equirectangular_to_direction(u, v); ray.t = 0.0f; +#ifdef __CAMERA_MOTION__ + ray.time = 0.5f; +#endif #ifdef __RAY_DIFFERENTIALS__ ray.dD.dx = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 53d53b4bedd..6d650a0158d 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -32,8 +32,15 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, Ray ray; ray.D = ls->D; ray.P = ls->P; + ray.t = 1.0f; +#ifdef __OBJECT_MOTION__ + ray.time = time; +#endif ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f); ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f); +#ifdef __CAMERA_MOTION__ + ray.time = time; +#endif shader_setup_from_background(kg, &sd, &ray); eval = shader_eval_background(kg, &sd, 0); } diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 1084415d0cf..2791b3abbb6 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -301,8 +301,13 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, #ifdef __INSTANCING__ /* instance transform */ if(ls->object >= 0) { - Transform tfm = object_fetch_transform(kg, ls->object, time, OBJECT_TRANSFORM); - Transform itfm = object_fetch_transform(kg, ls->object, time, OBJECT_INVERSE_TRANSFORM); +#ifdef __OBJECT_MOTION__ + Transform itfm; + Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); +#else + Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); + Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); +#endif ls->P = transform_point(&tfm, ls->P); ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng)); diff --git a/intern/cycles/kernel/kernel_mbvh.h b/intern/cycles/kernel/kernel_mbvh.h deleted file mode 100644 index ccbd3d069b4..00000000000 --- a/intern/cycles/kernel/kernel_mbvh.h +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * 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. - */ - -CCL_NAMESPACE_BEGIN - -#define MBVH_OBJECT_SENTINEL 0x76543210 -#define MBVH_NODE_SIZE 8 -#define MBVH_STACK_SIZE 1024 -#define MBVH_RAY_STACK_SIZE 10000 - -typedef struct MBVHTask { - int node; - int index; - int num; - int object; -} MBVHTask; - -typedef struct MVBHRay { - float3 P; - float u; - float3 idir; - float v; - float t; - int index; - int object; - - float3 origP; - float3 origD; - float tmax; -} MBVHRay; - -__device float3 mbvh_inverse_direction(float3 dir) -{ - // Avoid divide by zero (ooeps = exp2f(-80.0f)) - float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f; - float3 idir; - - idir.x = 1.0f / (fabsf(dir.x) > ooeps ? dir.x : copysignf(ooeps, dir.x)); - idir.y = 1.0f / (fabsf(dir.y) > ooeps ? dir.y : copysignf(ooeps, dir.y)); - idir.z = 1.0f / (fabsf(dir.z) > ooeps ? dir.z : copysignf(ooeps, dir.z)); - - return idir; -} - -__device void mbvh_instance_push(KernelGlobals *kg, int object, MBVHRay *ray) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - - ray->P = transform_point(&tfm, ray->origP); - - float3 dir = ray->origD; - - if(ray->t != ray->tmax) dir *= ray->t; - - dir = transform_direction(&tfm, dir); - ray->idir = mbvh_inverse_direction(normalize(dir)); - - if(ray->t != ray->tmax) ray->t = len(dir); -} - -__device void mbvh_instance_pop(KernelGlobals *kg, int object, MBVHRay *ray) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - - if(ray->t != ray->tmax) - ray->t = len(transform_direction(&tfm, (1.0f/(ray->idir)) * (ray->t))); - - ray->P = ray->origP; - ray->idir = mbvh_inverse_direction(ray->origD); -} - -/* Sven Woop's algorithm */ -__device void mbvh_triangle_intersect(KernelGlobals *kg, MBVHRay *ray, int object, int triAddr) -{ - float3 P = ray->P; - float3 idir = ray->idir; - - /* compute and check intersection t-value */ - float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+0); - float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+1); - float3 dir = 1.0f/idir; - - float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z; - float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z); - float t = Oz * invDz; - - if(t > 0.0f && t < ray->t) { - /* compute and check barycentric u */ - float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z; - float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z; - float u = Ox + t*Dx; - - if(u >= 0.0f) { - /* compute and check barycentric v */ - float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+2); - float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z; - float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z; - float v = Oy + t*Dy; - - if(v >= 0.0f && u + v <= 1.0f) { - /* record intersection */ - ray->index = triAddr; - ray->object = object; - ray->u = u; - ray->v = v; - ray->t = t; - } - } - } -} - -__device void mbvh_node_intersect(KernelGlobals *kg, __m128 *traverseChild, - __m128 *tHit, float3 P, float3 idir, float t, int nodeAddr) -{ - /* X axis */ - const __m128 bminx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+0); - const __m128 t0x = _mm_mul_ps(_mm_sub_ps(bminx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - const __m128 bmaxx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+1); - const __m128 t1x = _mm_mul_ps(_mm_sub_ps(bmaxx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - - __m128 tmin = _mm_max_ps(_mm_min_ps(t0x, t1x), _mm_setzero_ps()); - __m128 tmax = _mm_min_ps(_mm_max_ps(t0x, t1x), _mm_set_ps1(t)); - - /* Y axis */ - const __m128 bminy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+2); - const __m128 t0y = _mm_mul_ps(_mm_sub_ps(bminy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - const __m128 bmaxy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+3); - const __m128 t1y = _mm_mul_ps(_mm_sub_ps(bmaxy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - - tmin = _mm_max_ps(_mm_min_ps(t0y, t1y), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0y, t1y), tmax); - - /* Z axis */ - const __m128 bminz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+4); - const __m128 t0z = _mm_mul_ps(_mm_sub_ps(bminz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - const __m128 bmaxz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+5); - const __m128 t1z = _mm_mul_ps(_mm_sub_ps(bmaxz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - - tmin = _mm_max_ps(_mm_min_ps(t0z, t1z), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0z, t1z), tmax); - - /* compare and get mask */ - *traverseChild = _mm_cmple_ps(tmin, tmax); - - /* get distance XXX probably wrong */ - *tHit = tmin; -} - -static void mbvh_sort_by_length(int id[4], float len[4]) -{ - for(int i = 1; i < 4; i++) { - int j = i - 1; - - while(j >= 0 && len[j] > len[j+1]) { - swap(len[j], len[j+1]); - swap(id[j], id[j+1]); - j--; - } - } -} - -__device void scene_intersect(KernelGlobals *kg, MBVHRay *rays, int numrays) -{ - /* traversal stacks */ - MBVHTask task_stack[MBVH_STACK_SIZE]; - int active_ray_stacks[4][MBVH_RAY_STACK_SIZE]; - int num_task, num_active[4] = {0, 0, 0, 0}; - __m128i one_mm = _mm_set1_epi32(1); - - /* push root node task on stack */ - task_stack[0].node = kernel_data.bvh.root; - task_stack[0].index = 0; - task_stack[0].num = numrays; - task_stack[0].object = ~0; - num_task = 1; - - /* push all rays in first SIMD lane */ - for(int i = 0; i < numrays; i++) - active_ray_stacks[0][i] = i; - num_active[0] = numrays; - - while(num_task >= 1) { - /* pop task */ - MBVHTask task = task_stack[--num_task]; - - if(task.node == MBVH_OBJECT_SENTINEL) { - /* instance pop */ - - /* pop rays from stack */ - num_active[task.index] -= task.num; - int ray_offset = num_active[task.index]; - - /* transform rays */ - for(int i = 0; i < task.num; i++) { - MBVHRay *ray = &rays[active_ray_stacks[task.index][ray_offset + i]]; - mbvh_instance_pop(kg, task.object, ray); - } - } - else if(task.node >= 0) { - /* inner node? */ - - /* pop rays from stack*/ - num_active[task.index] -= task.num; - int ray_offset = num_active[task.index]; - - /* initialze simd values */ - __m128i num_active_mm = _mm_load_si128((__m128i*)num_active); - __m128 len_mm = _mm_set_ps1(0.0f); - - for(int i = 0; i < task.num; i++) { - int rayid = active_ray_stacks[task.index][ray_offset + i]; - MVBHRay *ray = rays + rayid; - - /* intersect 4 QBVH node children */ - __m128 result; - __m128 thit; - - mbvh_node_intersect(kg, &result, &thit, ray->P, ray->idir, ray->t, task.node); - - /* update length for sorting */ - len_mm = _mm_add_ps(len_mm, _mm_and_ps(thit, result)); - - /* push rays on stack */ - for(int j = 0; j < 4; j++) - active_ray_stacks[j][num_active[j]] = rayid; - - /* update num active */ - __m128i resulti = _mm_and_si128(*((__m128i*)&result), one_mm); - num_active_mm = _mm_add_epi32(resulti, num_active_mm); - _mm_store_si128((__m128i*)num_active, num_active_mm); - } - - if(num_active[0] || num_active[1] || num_active[2] || num_active[3]) { - /* load child node addresses */ - float4 cnodes = kernel_tex_fetch(__bvh_nodes, task.node); - int child[4] = { - __float_as_int(cnodes.x), - __float_as_int(cnodes.y), - __float_as_int(cnodes.z), - __float_as_int(cnodes.w)}; - - /* sort nodes by average intersection distance */ - int ids[4] = {0, 1, 2, 3}; - float len[4]; - - _mm_store_ps(len, len_mm); - mbvh_sort_by_length(ids, len); - - /* push new tasks on stack */ - for(int j = 0; j < 4; j++) { - if(num_active[j]) { - int id = ids[j]; - - task_stack[num_task].node = child[id]; - task_stack[num_task].index = id; - task_stack[num_task].num = num_active[id]; - task_stack[num_task].object = task.object; - num_task++; - } - } - } - } - else { - /* fetch leaf node data */ - float4 leaf = kernel_tex_fetch(__bvh_nodes, (-task.node-1)*MBVH_NODE_SIZE+(MBVH_NODE_SIZE-2)); - int triAddr = __float_as_int(leaf.x); - int triAddr2 = __float_as_int(leaf.y); - - /* pop rays from stack*/ - num_active[task.index] -= task.num; - int ray_offset = num_active[task.index]; - - /* triangles */ - if(triAddr >= 0) { - int i, numq = (task.num >> 2) << 2; - - /* SIMD ray leaf intersection */ - for(i = 0; i < numq; i += 4) { - MBVHRay *ray4[4] = { - &rays[active_ray_stacks[task.index][ray_offset + i + 0]], - &rays[active_ray_stacks[task.index][ray_offset + i + 1]], - &rays[active_ray_stacks[task.index][ray_offset + i + 2]], - &rays[active_ray_stacks[task.index][ray_offset + i + 3]]}; - - /* load SoA */ - - while(triAddr < triAddr2) { - mbvh_triangle_intersect(ray4[0], task.object, task.node); - mbvh_triangle_intersect(ray4[1], task.object, task.node); - mbvh_triangle_intersect(ray4[2], task.object, task.node); - mbvh_triangle_intersect(ray4[3], task.object, task.node); - triAddr++; - - /* some shadow ray optim could be done by setting t=0 */ - } - - /* store AoS */ - } - - /* mono ray leaf intersection */ - for(; i < task.num; i++) { - MBVHRay *ray = &rays[active_ray_stacks[task.index][ray_offset + i]]; - - while(triAddr < triAddr2) { - mbvh_triangle_intersect(kg, ray, task.object, task.node); - triAddr++; - } - } - } - else { - /* instance push */ - int object = -triAddr-1; - int node = triAddr; - - /* push instance pop task */ - task_stack[num_task].node = MBVH_OBJECT_SENTINEL; - task_stack[num_task].index = task.index; - task_stack[num_task].num = task.num; - task_stack[num_task].object = object; - num_task++; - - num_active[task.index] += task.num; - - /* push node task */ - task_stack[num_task].node = node; - task_stack[num_task].index = task.index; - task_stack[num_task].num = task.num; - task_stack[num_task].object = object; - num_task++; - - for(int i = 0; i < task.num; i++) { - int rayid = active_ray_stacks[task.index][ray_offset + i]; - - /* push on stack for last task */ - active_ray_stacks[task.index][num_active[task.index]] = rayid; - num_active[task.index]++; - - /* transform ray */ - MBVHRay *ray = &rays[rayid]; - mbvh_instance_push(kg, object, ray); - } - } - } - } -} - -__device void mbvh_set_ray(MBVHRay *rays, int i, Ray *ray, float tmax) -{ - MBVHRay *mray = &rays[i]; - - /* ray parameters in registers */ - mray->P = ray->P; - mray->idir = mbvh_inverse_direction(ray->D); - mray->t = tmax; -} - -__device bool mbvh_get_intersection(MVBHRay *rays, int i, Intersection *isect, float tmax) -{ - MBVHRay *mray = &rays[i]; - - if(mray->t == tmax) - return false; - - isect->t = mray->t; - isect->u = mray->u; - isect->v = mray->v; - isect->index = mray->index; - isect->object = mray->object; - - return true; -} - -__device bool mbvh_get_shadow(MBVHRay *rays, int i, float tmax) -{ - return (rays[i].t == tmax); -} - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index d0b588a88d4..48d1aa64c9f 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -72,7 +72,7 @@ __device void to_unit_disk(float *x, float *y) __device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b) { - *b = cross(N, T); + *b = normalize(cross(N, T)); *a = cross(*b, N); } diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 01da5050c8d..2fa9443766e 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,107 +23,133 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_POST = 12, - OBJECT_DUPLI = 16 + OBJECT_TRANSFORM_MOTION_MID = 12, + OBJECT_TRANSFORM_MOTION_POST = 16, + OBJECT_DUPLI = 20 }; -__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type) +__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) { - Transform tfm; + int offset = object*OBJECT_SIZE + (int)type; -#ifdef __MOTION__ - /* if we do motion blur */ - if(sd->flag & SD_OBJECT_MOTION) { - /* fetch motion transforms */ - MotionTransform motion; + Transform tfm; + tfm.x = kernel_tex_fetch(__objects, offset + 0); + tfm.y = kernel_tex_fetch(__objects, offset + 1); + tfm.z = kernel_tex_fetch(__objects, offset + 2); + tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f); - motion.pre.x = have_motion; - motion.pre.y = kernel_tex_fetch(__objects, offset + 1); - motion.pre.z = kernel_tex_fetch(__objects, offset + 2); - motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + return tfm; +} - motion.post.x = kernel_tex_fetch(__objects, offset + 4); - motion.post.y = kernel_tex_fetch(__objects, offset + 5); - motion.post.z = kernel_tex_fetch(__objects, offset + 6); - motion.post.w = kernel_tex_fetch(__objects, offset + 7); +#ifdef __OBJECT_MOTION__ +__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time) +{ + MotionTransform motion; - /* interpolate (todo: do only once per object) */ - transform_motion_interpolate(&tfm, &motion, time); + int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; - /* invert */ - if(type == OBJECT_INVERSE_TRANSFORM) - tfm = transform_quick_inverse(tfm); + motion.pre.x = kernel_tex_fetch(__objects, offset + 0); + motion.pre.y = kernel_tex_fetch(__objects, offset + 1); + motion.pre.z = kernel_tex_fetch(__objects, offset + 2); + motion.pre.w = kernel_tex_fetch(__objects, offset + 3); - return tfm; - } -#endif + motion.mid.x = kernel_tex_fetch(__objects, offset + 4); + motion.mid.y = kernel_tex_fetch(__objects, offset + 5); + motion.mid.z = kernel_tex_fetch(__objects, offset + 6); + motion.mid.w = kernel_tex_fetch(__objects, offset + 7); - int offset = object*OBJECT_SIZE + (int)type; + motion.post.x = kernel_tex_fetch(__objects, offset + 8); + motion.post.y = kernel_tex_fetch(__objects, offset + 9); + motion.post.z = kernel_tex_fetch(__objects, offset + 10); + motion.post.w = kernel_tex_fetch(__objects, offset + 11); - tfm.x = kernel_tex_fetch(__objects, offset + 0); - tfm.y = kernel_tex_fetch(__objects, offset + 1); - tfm.z = kernel_tex_fetch(__objects, offset + 2); - tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f); + Transform tfm; + transform_motion_interpolate(&tfm, &motion, time); return tfm; } +__device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg, int object, float time, Transform *itfm) +{ + int object_flag = kernel_tex_fetch(__object_flag, object); + + if(object_flag & SD_OBJECT_MOTION) { + /* if we do motion blur */ + Transform tfm = object_fetch_transform_motion(kg, object, time); + + if(itfm) + *itfm = transform_quick_inverse(tfm); + + return tfm; + } + else { + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); + *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + + return tfm; + } +} +#endif + __device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *P = transform_point(&sd->ob_tfm, *P); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *P = transform_point(&tfm, *P); #endif } __device_inline void object_inverse_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *P = transform_point(&sd->ob_itfm, *P); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, *P); #endif } __device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *N = normalize(transform_direction_transposed(&sd->ob_tfm, *N)); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); #endif } __device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *N = normalize(transform_direction_transposed(&sd->ob_itfm, *N)); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); #endif } __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *D = transform_direction(&sd->ob_tfm, *D); #else - Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *D = transform_direction(&tfm, *D); #endif } __device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd) { -#ifdef __MOTION__ + if(sd->object == ~0) + return make_float3(0.0f, 0.0f, 0.0f); + +#ifdef __OBJECT_MOTION__ return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w); #else - Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); return make_float3(tfm.x.w, tfm.y.w, tfm.z.w); #endif } @@ -249,6 +275,5 @@ __device float3 particle_angular_velocity(KernelGlobals *kg, int particle) return make_float3(f3.z, f3.w, f4.x); } - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index d606c3d634a..817f254a5e5 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -343,7 +343,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, light_ray.P = ray_offset(sd.P, sd.Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -368,7 +368,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, BsdfEval L_light; bool is_lamp; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -520,7 +520,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray light_ray.P = ray_offset(sd.P, sd.Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -545,7 +545,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray BsdfEval L_light; bool is_lamp; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -728,7 +728,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam light_ray.P = ray_offset(sd.P, sd.Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -748,7 +748,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam BsdfEval L_light; bool is_lamp; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -867,7 +867,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam bsdf_ray.dP = sd.dP; bsdf_ray.dD = bsdf_domega_in; #endif -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ bsdf_ray.time = sd.time; #endif @@ -925,7 +925,7 @@ __device void kernel_path_trace(KernelGlobals *kg, float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U); float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V); -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ float time = path_rng(kg, &rng, sample, PRNG_TIME); #else float time = 0.0f; diff --git a/intern/cycles/kernel/kernel_qbvh.h b/intern/cycles/kernel/kernel_qbvh.h deleted file mode 100644 index 525b616921d..00000000000 --- a/intern/cycles/kernel/kernel_qbvh.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Adapted from code Copyright 2009-2010 NVIDIA Corporation - * Modifications Copyright 2011, Blender Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CCL_NAMESPACE_BEGIN - -/* - * "Persistent while-while kernel" used in: - * - * "Understanding the Efficiency of Ray Traversal on GPUs", - * Timo Aila and Samuli Laine, - * Proc. High-Performance Graphics 2009 - */ - -/* bottom-most stack entry, indicating the end of traversal */ - -#define ENTRYPOINT_SENTINEL 0x76543210 -/* 64 object BVH + 64 mesh BVH + 64 object node splitting */ -#define QBVH_STACK_SIZE 192 -#define QBVH_NODE_SIZE 8 -#define TRI_NODE_SIZE 3 - -__device_inline float3 qbvh_inverse_direction(float3 dir) -{ - // Avoid divide by zero (ooeps = exp2f(-80.0f)) - float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f; - float3 idir; - - idir.x = 1.0f/((fabsf(dir.x) > ooeps)? dir.x: copysignf(ooeps, dir.x)); - idir.y = 1.0f/((fabsf(dir.y) > ooeps)? dir.y: copysignf(ooeps, dir.y)); - idir.z = 1.0f/((fabsf(dir.z) > ooeps)? dir.z: copysignf(ooeps, dir.z)); - - return idir; -} - -__device_inline void qbvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - - *P = transform_point(&tfm, ray->P); - - float3 dir = transform_direction(&tfm, ray->D); - - float len; - dir = normalize_len(dir, &len); - - *idir = qbvh_inverse_direction(dir); - - if(*t != FLT_MAX) - *t *= len; -} - -__device_inline void qbvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - - if(*t != FLT_MAX) - *t *= len(transform_direction(&tfm, 1.0f/(*idir))); - - *P = ray->P; - *idir = qbvh_inverse_direction(ray->D); -} - -#ifdef __KERNEL_CPU__ - -__device_inline void qbvh_node_intersect(KernelGlobals *kg, int *traverseChild, - int nodeAddrChild[4], float3 P, float3 idir, float t, int nodeAddr) -{ - /* X axis */ - const __m128 bminx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+0); - const __m128 t0x = _mm_mul_ps(_mm_sub_ps(bminx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - const __m128 bmaxx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+1); - const __m128 t1x = _mm_mul_ps(_mm_sub_ps(bmaxx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - - __m128 tmin = _mm_max_ps(_mm_min_ps(t0x, t1x), _mm_setzero_ps()); - __m128 tmax = _mm_min_ps(_mm_max_ps(t0x, t1x), _mm_set_ps1(t)); - - /* Y axis */ - const __m128 bminy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+2); - const __m128 t0y = _mm_mul_ps(_mm_sub_ps(bminy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - const __m128 bmaxy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+3); - const __m128 t1y = _mm_mul_ps(_mm_sub_ps(bmaxy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - - tmin = _mm_max_ps(_mm_min_ps(t0y, t1y), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0y, t1y), tmax); - - /* Z axis */ - const __m128 bminz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+4); - const __m128 t0z = _mm_mul_ps(_mm_sub_ps(bminz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - const __m128 bmaxz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+5); - const __m128 t1z = _mm_mul_ps(_mm_sub_ps(bmaxz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - - tmin = _mm_max_ps(_mm_min_ps(t0z, t1z), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0z, t1z), tmax); - - /* compare and get mask */ - *traverseChild = _mm_movemask_ps(_mm_cmple_ps(tmin, tmax)); - - /* get node addresses */ - float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+6); - - nodeAddrChild[0] = __float_as_int(cnodes.x); - nodeAddrChild[1] = __float_as_int(cnodes.y); - nodeAddrChild[2] = __float_as_int(cnodes.z); - nodeAddrChild[3] = __float_as_int(cnodes.w); -} - -#else - -__device_inline bool qbvh_bb_intersect(float3 bmin, float3 bmax, float3 P, float3 idir, float t) -{ - float t0x = (bmin.x - P.x)*idir.x; - float t1x = (bmax.x - P.x)*idir.x; - float t0y = (bmin.y - P.y)*idir.y; - float t1y = (bmax.y - P.y)*idir.y; - float t0z = (bmin.z - P.z)*idir.z; - float t1z = (bmax.z - P.z)*idir.z; - - float minx = min(t0x, t1x); - float maxx = max(t0x, t1x); - float miny = min(t0y, t1y); - float maxy = max(t0y, t1y); - float minz = min(t0z, t1z); - float maxz = max(t0z, t1z); - - float tmin = max4(0.0f, minx, miny, minz); - float tmax = min4(t, maxx, maxy, maxz); - - return (tmin <= tmax); -} - -/* intersect four bounding boxes */ -__device_inline void qbvh_node_intersect(KernelGlobals *kg, int *traverseChild, - int nodeAddrChild[4], float3 P, float3 idir, float t, int nodeAddr) -{ - /* fetch node data */ - float4 minx = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+0); - float4 miny = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+2); - float4 minz = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+4); - float4 maxx = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+1); - float4 maxy = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+3); - float4 maxz = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+5); - - /* intersect bounding boxes */ - bool traverseChild0 = qbvh_bb_intersect(make_float3(minx.x, miny.x, minz.x), make_float3(maxx.x, maxy.x, maxz.x), P, idir, t); - bool traverseChild1 = qbvh_bb_intersect(make_float3(minx.y, miny.y, minz.y), make_float3(maxx.y, maxy.y, maxz.y), P, idir, t); - bool traverseChild2 = qbvh_bb_intersect(make_float3(minx.z, miny.z, minz.z), make_float3(maxx.z, maxy.z, maxz.z), P, idir, t); - bool traverseChild3 = qbvh_bb_intersect(make_float3(minx.w, miny.w, minz.w), make_float3(maxx.w, maxy.w, maxz.w), P, idir, t); - - *traverseChild = 0; - if(traverseChild0) *traverseChild |= 1; - if(traverseChild1) *traverseChild |= 2; - if(traverseChild2) *traverseChild |= 4; - if(traverseChild3) *traverseChild |= 8; - - /* get node addresses */ - float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+6); - - nodeAddrChild[0] = __float_as_int(cnodes.x); - nodeAddrChild[1] = __float_as_int(cnodes.y); - nodeAddrChild[2] = __float_as_int(cnodes.z); - nodeAddrChild[3] = __float_as_int(cnodes.w); -} - -#endif - -/* Sven Woop's algorithm */ -__device_inline void qbvh_triangle_intersect(KernelGlobals *kg, Intersection *isect, float3 P, float3 idir, int object, int triAddr) -{ - /* compute and check intersection t-value */ - float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0); - float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1); - float3 dir = 1.0f/idir; - - float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z; - float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z); - float t = Oz * invDz; - - if(t > 0.0f && t < isect->t) { - /* compute and check barycentric u */ - float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z; - float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z; - float u = Ox + t*Dx; - - if(u >= 0.0f) { - /* compute and check barycentric v */ - float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2); - float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z; - float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z; - float v = Oy + t*Dy; - - if(v >= 0.0f && u + v <= 1.0f) { - /* record intersection */ - isect->prim = triAddr; - isect->object = object; - isect->u = u; - isect->v = v; - isect->t = t; - } - } - } -} - -__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const bool isshadowray, Intersection *isect) -{ - /* traversal stack in CUDA thread-local memory */ - int traversalStack[QBVH_STACK_SIZE]; - traversalStack[0] = ENTRYPOINT_SENTINEL; - - /* traversal variables in registers */ - int stackPtr = 0; - int nodeAddr = kernel_data.bvh.root; - - /* ray parameters in registers */ - const float tmax = ray->t; - float3 P = ray->P; - float3 idir = qbvh_inverse_direction(ray->D); - int object = ~0; - - isect->t = tmax; - isect->object = ~0; - isect->prim = ~0; - isect->u = 0.0f; - isect->v = 0.0f; - - /* traversal loop */ - do { - do - { - /* traverse internal nodes */ - while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) - { - int traverseChild, nodeAddrChild[4]; - - qbvh_node_intersect(kg, &traverseChild, nodeAddrChild, - P, idir, isect->t, nodeAddr); - - if(traverseChild & 1) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[0]; - } - - if(traverseChild & 2) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[1]; - } - if(traverseChild & 4) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[2]; - } - - if(traverseChild & 8) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[3]; - } - - nodeAddr = traversalStack[stackPtr]; - --stackPtr; - } - - /* if node is leaf, fetch triangle list */ - if(nodeAddr < 0) { - float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*QBVH_NODE_SIZE+(QBVH_NODE_SIZE-2)); - int primAddr = __float_as_int(leaf.x); - -#ifdef __INSTANCING__ - if(primAddr >= 0) { -#endif - int primAddr2 = __float_as_int(leaf.y); - - /* pop */ - nodeAddr = traversalStack[stackPtr]; - --stackPtr; - - /* triangle intersection */ - while(primAddr < primAddr2) { - /* intersect ray against triangle */ - qbvh_triangle_intersect(kg, isect, P, idir, object, primAddr); - - /* shadow ray early termination */ - if(isshadowray && isect->prim != ~0) - return true; - - primAddr++; - } -#ifdef __INSTANCING__ - } - else { - /* instance push */ - object = kernel_tex_fetch(__prim_object, -primAddr-1); - - qbvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax); - - ++stackPtr; - traversalStack[stackPtr] = ENTRYPOINT_SENTINEL; - - nodeAddr = kernel_tex_fetch(__object_node, object); - } -#endif - } - } while(nodeAddr != ENTRYPOINT_SENTINEL); - -#ifdef __INSTANCING__ - if(stackPtr >= 0) { - kernel_assert(object != ~0); - - /* instance pop */ - qbvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax); - object = ~0; - nodeAddr = traversalStack[stackPtr]; - --stackPtr; - } -#endif - } while(nodeAddr != ENTRYPOINT_SENTINEL); - - return (isect->prim != ~0); -} - -__device_inline float3 ray_offset(float3 P, float3 Ng) -{ -#ifdef __INTERSECTION_REFINE__ - const float epsilon_f = 1e-5f; - const int epsilon_i = 32; - - float3 res; - - /* x component */ - if(fabsf(P.x) < epsilon_f) { - res.x = P.x + Ng.x*epsilon_f; - } - else { - uint ix = __float_as_uint(P.x); - ix += ((ix ^ __float_as_uint(Ng.x)) >> 31)? -epsilon_i: epsilon_i; - res.x = __uint_as_float(ix); - } - - /* y component */ - if(fabsf(P.y) < epsilon_f) { - res.y = P.y + Ng.y*epsilon_f; - } - else { - uint iy = __float_as_uint(P.y); - iy += ((iy ^ __float_as_uint(Ng.y)) >> 31)? -epsilon_i: epsilon_i; - res.y = __uint_as_float(iy); - } - - /* z component */ - if(fabsf(P.z) < epsilon_f) { - res.z = P.z + Ng.z*epsilon_f; - } - else { - uint iz = __float_as_uint(P.z); - iz += ((iz ^ __float_as_uint(Ng.z)) >> 31)? -epsilon_i: epsilon_i; - res.z = __uint_as_float(iz); - } - - return res; -#else - const float epsilon_f = 1e-4f; - return P + epsilon_f*Ng; -#endif -} - -__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection *isect, const Ray *ray) -{ - float3 P = ray->P; - float3 D = ray->D; - float t = isect->t; - -#ifdef __INTERSECTION_REFINE__ - if(isect->object != ~0) { - Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); - - P = transform_point(&tfm, P); - D = transform_direction(&tfm, D*t); - D = normalize_len(D, &t); - } - - P = P + D*t; - - float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0); - float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z; - float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z); - float rt = Oz * invDz; - - P = P + D*rt; - - if(isect->object != ~0) { - Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); - P = transform_point(&tfm, P); - } - - return P; -#else - return P + D*t; -#endif -} - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index b57e27bc8ed..86886a6a231 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -27,22 +27,36 @@ */ #ifdef __OSL__ - #include "osl_shader.h" - #endif -#include "svm/bsdf.h" -#include "svm/emissive.h" -#include "svm/volume.h" +#include "closure/bsdf.h" +#include "closure/emissive.h" +#include "closure/volume.h" + #include "svm/svm_bsdf.h" #include "svm/svm.h" - CCL_NAMESPACE_BEGIN /* ShaderData setup from incoming ray */ +#ifdef __OBJECT_MOTION__ +__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) +{ + /* note that this is a separate non-inlined function to work around crash + * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */ + if(sd->flag & SD_OBJECT_MOTION) { + sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time); + sd->ob_itfm= transform_quick_inverse(sd->ob_tfm); + } + else { + sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); + sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + } +} +#endif + __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { @@ -67,11 +81,12 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, sd->v = isect->v; #endif - /* matrices and time */ -#ifdef __MOTION__ - sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM); + sd->flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2); + sd->flag |= kernel_tex_fetch(__object_flag, sd->object); + /* matrices and time */ +#ifdef __OBJECT_MOTION__ + shader_setup_object_transforms(kg, sd, ray->time); sd->time = ray->time; #endif @@ -87,9 +102,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, if(sd->shader & SHADER_SMOOTH_NORMAL) sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); - sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); - sd->flag |= kernel_tex_fetch(__object_flag, sd->object); - #ifdef __DPDU__ /* dPdu/dPdv */ triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); @@ -171,11 +183,17 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, } #endif -#ifdef __MOTION__ - sd->time = time; + sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); + if(sd->object != -1) { + sd->flag |= kernel_tex_fetch(__object_flag, sd->object); - sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM); +#ifdef __OBJECT_MOTION__ + shader_setup_object_transforms(kg, sd, time); + } + + sd->time = time; +#else + } #endif /* smooth normal */ @@ -188,10 +206,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, #endif } - sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); - if(sd->object != -1) - sd->flag |= kernel_tex_fetch(__object_flag, sd->object); - #ifdef __DPDU__ /* dPdu/dPdv */ if(sd->prim == ~0) { @@ -275,7 +289,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData sd->I = -sd->P; sd->shader = kernel_data.background.shader; sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ sd->time = ray->time; #endif sd->ray_length = 0.0f; @@ -483,18 +497,22 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd, __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness) { -#ifndef __OSL__ #ifdef __MULTI_CLOSURE__ for(int i = 0; i< sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_BSDF(sc->type)) - svm_bsdf_blur(sc, roughness); + if(CLOSURE_IS_BSDF(sc->type)) { +#ifdef __OSL__ + if (kernel_osl_use(kg)) + OSLShader::bsdf_blur(sc, roughness); + else +#endif + svm_bsdf_blur(sc, roughness); + } } #else svm_bsdf_blur(&sd->closure, roughness); #endif -#endif } __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd) @@ -704,16 +722,16 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd, if(CLOSURE_IS_VOLUME(sc->type)) { #ifdef __OSL__ if (kernel_osl_use(kg)) - eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out); + eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out); else #endif - eval += volume_eval_phase(sd, sc, omega_in, omega_out); + eval += volume_eval_phase(sc, omega_in, omega_out); } } return eval; #else - return volume_eval_phase(sd, &sd->closure, omega_in, omega_out); + return volume_eval_phase(&sd->closure, omega_in, omega_out); #endif } diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h index f57c59a45eb..43cfa330724 100644 --- a/intern/cycles/kernel/kernel_triangle.h +++ b/intern/cycles/kernel/kernel_triangle.h @@ -201,10 +201,10 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd) * transformation was set match the world/object space of motion_pre/post */ Transform tfm; - tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_PRE); + tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE); motion_pre = transform_point(&tfm, motion_pre); - tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_POST); + tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST); motion_post = transform_point(&tfm, motion_post); float3 P; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 48e271a9f3f..c341269f4ca 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN /* constants */ -#define OBJECT_SIZE 18 +#define OBJECT_SIZE 22 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 @@ -108,11 +108,11 @@ CCL_NAMESPACE_BEGIN #define __PASSES__ #define __BACKGROUND_MIS__ #define __AO__ -//#define __MOTION__ +#define __CAMERA_MOTION__ +#define __OBJECT_MOTION__ #endif //#define __SOBOL_FULL_SCREEN__ -//#define __QBVH__ /* Shader Evaluation */ @@ -129,7 +129,7 @@ enum PathTraceDimension { PRNG_FILTER_V = 1, PRNG_LENS_U = 2, PRNG_LENS_V = 3, -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ PRNG_TIME = 4, PRNG_UNUSED = 5, PRNG_BASE_NUM = 6, @@ -370,6 +370,9 @@ typedef struct ShaderClosure { float data0; float data1; + float3 N; + float3 T; + } ShaderClosure; /* Shader Data @@ -426,13 +429,6 @@ typedef struct ShaderData { /* length of the ray being shaded */ float ray_length; -#ifdef __MOTION__ - /* object <-> world space transformations, cached to avoid - * re-interpolating them constantly for shading */ - Transform ob_tfm; - Transform ob_itfm; -#endif - #ifdef __RAY_DIFFERENTIALS__ /* differential of P. these are orthogonal to Ng, not N */ differential3 dP; @@ -448,6 +444,13 @@ typedef struct ShaderData { float3 dPdu, dPdv; #endif +#ifdef __OBJECT_MOTION__ + /* object <-> world space transformations, cached to avoid + * re-interpolating them constantly for shading */ + Transform ob_tfm; + Transform ob_itfm; +#endif + #ifdef __MULTI_CLOSURE__ /* Closure data, we store a fixed array of closures */ ShaderClosure closure[MAX_CLOSURE]; @@ -511,7 +514,9 @@ typedef struct KernelCamera { /* more matrices */ Transform screentoworld; Transform rastertoworld; - Transform ndctoworld; + /* work around cuda sm 2.0 crash, this seems to + * cross some limit in combination with motion + * Transform ndctoworld; */ Transform worldtoscreen; Transform worldtoraster; Transform worldtondc; @@ -627,7 +632,8 @@ typedef struct KernelBVH { /* root node */ int root; int attributes_map_stride; - int pad1, pad2; + int have_motion; + int pad2; } KernelBVH; typedef struct KernelData { diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 65d7a7ad53b..d6449b4349b 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -7,28 +7,17 @@ set(INC ../../util ../../device ) + set(INC_SYS + ) set(SRC background.cpp - bsdf_ashikhmin_velvet.cpp - bsdf_diffuse.cpp - bsdf_oren_nayar.cpp - bsdf_phong.cpp - bsdf_microfacet.cpp - bsdf_reflection.cpp - bsdf_refraction.cpp - bsdf_transparent.cpp - bsdf_ward.cpp - bsdf_westin.cpp - bssrdf.cpp - debug.cpp emissive.cpp osl_closures.cpp osl_services.cpp osl_shader.cpp - vol_subsurface.cpp ) set(HEADER_SRC diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 6290eed0af8..b6e9473b7bf 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -46,23 +46,16 @@ using namespace OSL; /// to return a color in background shaders. No methods, /// only the weight is taking into account /// -class GenericBackgroundClosure : public BackgroundClosure { +class GenericBackgroundClosure : public OSL::BackgroundClosure { public: GenericBackgroundClosure() {} void setup() {}; - size_t memsize() const { return sizeof(*this); } - const char *name() const { return "background"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } - + void print_on(std::ostream &out) const { out << name() << " ()"; } }; - /// Holdout closure /// /// This will be used by the shader to mark the @@ -75,17 +68,11 @@ public: HoldoutClosure () : ClosurePrimitive(Holdout) {} void setup() {}; - size_t memsize() const { return sizeof(*this); } - const char *name() const { return "holdout"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } + void print_on(std::ostream &out) const { out << name() << " ()"; } }; - ClosureParam *closure_background_params() { static ClosureParam params[] = { diff --git a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp deleted file mode 100644 index a1904d7f5d7..00000000000 --- a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class AshikhminVelvetClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_sigma; - float m_invsigma2; - - AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() - { - m_sigma = max(m_sigma, 0.01f); - m_invsigma2 = 1.0f / (m_sigma * m_sigma); - } - - bool mergeable(const ClosurePrimitive *other) const { - const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; - return m_N == comp->m_N && m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "ashikhmin_velvet"; } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_sigma; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f)) - return Color3(0, 0, 0); - - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = max(cosNHdivHO, 1e-5f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - - float out = 0.25f * (D * G) / cosNO; - - pdf = 0.5f * (float) M_1_PI; - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from above - send a ray out with uniform - // distribution over the hemisphere - sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) { - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = max(cosNHdivHO, 1e-5f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - - float power = 0.25f * (D * G) / cosNO; - - eval.setValue(power, power, power); - - // TODO: find a better approximation for the retroreflective bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } - else - pdf = 0; - } - else - pdf = 0; - return Labels::REFLECT; - } - -}; - - - -ClosureParam *bsdf_ashikhmin_velvet_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), - CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_diffuse.cpp deleted file mode 100644 index 1e06d3b583f..00000000000 --- a/intern/cycles/kernel/osl/bsdf_diffuse.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class DiffuseClosure : public BSDFClosure { -public: - Vec3 m_N; - - DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const DiffuseClosure *comp = (const DiffuseClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "diffuse"; } - - void print_on(std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = max(m_N.dot(omega_in), 0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3(cos_pi, cos_pi, cos_pi); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } - else - pdf = 0; - return Labels::REFLECT; - } -}; - - - -class TranslucentClosure : public BSDFClosure { -public: - Vec3 m_N; - - TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const TranslucentClosure *comp = (const TranslucentClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "translucent"; } - - void print_on(std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3(cos_pi, cos_pi, cos_pi); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(-m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) < 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= -125; - domega_in_dy *= -125; - } - else - pdf = 0; - return Labels::TRANSMIT; - } -}; - -ClosureParam *bsdf_diffuse_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DiffuseClosure) - }; - return params; -} - -ClosureParam *bsdf_translucent_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TranslucentClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure) -CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_microfacet.cpp b/intern/cycles/kernel/osl/bsdf_microfacet.cpp deleted file mode 100644 index 8446dbbe982..00000000000 --- a/intern/cycles/kernel/osl/bsdf_microfacet.cpp +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -#include "util_math.h" - -using namespace OSL; - -CCL_NAMESPACE_BEGIN - -// TODO: fresnel_dielectric is only used for derivatives, could be optimized - -// TODO: refactor these two classes so they share everything by the microfacet -// distribution terms - -// microfacet model with GGX facet distribution -// see http://www.graphics.cornell.edu/~bjw/microfacetbsdf.pdf -template <int Refractive = 0> -class MicrofacetGGXClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_ag; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; } - - void setup() - { - m_ag = clamp(m_ag, 1e-5f, 1.0f); - } - - bool mergeable(const ClosurePrimitive *other) const { - const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; - return m_N == comp->m_N && m_ag == comp->m_ag && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { - return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; - } - - void print_on(std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ag << ", "; - out << m_eta; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 33: first we calculate D(m) with m=Hr: - float alpha2 = m_ag * m_ag; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3(0, 0, 0); // vectors on same side -- not possible - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); - - float cosHI = Ht.dot(omega_in); - // eq. 33: first we calculate D(m) with m=Ht: - float alpha2 = m_ag * m_ag; - float cosThetaM = m_N.dot(Ht); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // probability - float invHt2 = 1 / ht.dot(ht); - pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3(out, out, out); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ag * m_ag; - float tanThetaM2 = alpha2 * randu / (1 - randu); - float cosThetaM = 1 / sqrtf(1 + tanThetaM2); - float sinThetaM = cosThetaM * sqrtf(tanThetaM2); - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } -}; - -// microfacet model with Beckmann facet distribution -// see http://www.graphics.cornell.edu/~bjw/microfacetbsdf.pdf -template <int Refractive = 0> -class MicrofacetBeckmannClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_ab; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { - } - - void setup() - { - m_ab = clamp(m_ab, 1e-5f, 1.0f); - } - - bool mergeable(const ClosurePrimitive *other) const { - const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; - return m_N == comp->m_N && m_ab == comp->m_ab && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } - - size_t memsize() const { - return sizeof(*this); - } - - const char *name() const { - return Refractive ? "microfacet_beckmann_refraction" - : "microfacet_beckmann"; - } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ab << ", "; - out << m_eta; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 25: first we calculate D(m) with m=Hr: - float alpha2 = m_ab * m_ab; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3(0, 0, 0); - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); - - float cosHI = Ht.dot(omega_in); - // eq. 33: first we calculate D(m) with m=Ht: - float alpha2 = m_ab * m_ab; - float cosThetaM = m_N.dot(Ht); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // probability - float invHt2 = 1 / ht.dot(ht); - pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3(out, out, out); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ab * m_ab; - float tanThetaM = sqrtf(-alpha2 * logf(1 - randu)); - float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM); - float sinThetaM = cosThetaM * tanThetaM; - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 25 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // Eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_microfacet_ggx_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) - }; - return params; -} - -ClosureParam *bsdf_microfacet_ggx_refraction_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_ag), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) - }; - return params; -} - -ClosureParam *bsdf_microfacet_beckmann_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) - }; - return params; -} - -ClosureParam *bsdf_microfacet_beckmann_refraction_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_ab), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>) -CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>) -CLOSURE_PREPARE(bsdf_microfacet_beckmann_prepare, MicrofacetBeckmannClosure<0>) -CLOSURE_PREPARE(bsdf_microfacet_beckmann_refraction_prepare, MicrofacetBeckmannClosure<1>) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp deleted file mode 100644 index 2a00100c256..00000000000 --- a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * 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. - */ - -#include <OpenImageIO/fmath.h> -#include <OSL/genclosure.h> -#include "osl_closures.h" -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - - -class OrenNayarClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_sigma; - float m_a, m_b; - - OrenNayarClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() { - m_sigma = clamp(m_sigma, 0.0f, 1.0f); - - float div = 1.0f / (M_PI + ((3.0f * M_PI - 4.0f) / 6.0f) * m_sigma); - - m_a = 1.0f * div; - m_b = m_sigma * div; - } - - bool mergeable(const ClosurePrimitive *other) const { - const OrenNayarClosure *comp = static_cast<const OrenNayarClosure *>(other); - return - m_N == comp->m_N && - m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { - return sizeof(*this); - } - - const char *name() const { - return "oren_nayar"; - } - - void print_on(std::ostream& out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_sigma; - out << ")"; - } - - float albedo(const Vec3& omega_out) const { - return 1.0f; - } - - Color3 eval_reflect(const Vec3& omega_out, const Vec3& omega_in, float& pdf) const { - if (m_N.dot(omega_in) > 0.0f) { - pdf = float(0.5 * M_1_PI); - float is = get_intensity(m_N, omega_out, omega_in); - return Color3(is, is, is); - } - else { - pdf = 0.0f; - return Color3(0.0f, 0.0f, 0.0f); - } - } - - Color3 eval_transmit(const Vec3& omega_out, const Vec3& omega_in, float& pdf) const { - return Color3(0.0f, 0.0f, 0.0f); - } - - ustring sample( - const Vec3& Ng, - const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy, - float randu, float randv, - Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, - float& pdf, Color3& eval - ) const { - sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - - if (Ng.dot(omega_in) > 0.0f) { - float is = get_intensity(m_N, omega_out, omega_in); - eval.setValue(is, is, is); - - // TODO: find a better approximation for the bounce - domega_in_dx = (2.0f * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2.0f * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125.0f; - domega_in_dy *= 125.0f; - } - else { - pdf = 0.0f; - } - - return Labels::REFLECT; - } - -private: - float get_intensity(Vec3 const& n, Vec3 const& v, Vec3 const& l) const { - float nl = max(n.dot(l), 0.0f); - float nv = max(n.dot(v), 0.0f); - float t = l.dot(v) - nl * nv; - - if (t > 0.0f) { - t /= max(nl, nv) + 1e-8f; - } - return nl * (m_a + m_b * t); - } -}; - -ClosureParam *bsdf_oren_nayar_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N), - CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(OrenNayarClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure) - - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_phong.cpp b/intern/cycles/kernel/osl/bsdf_phong.cpp deleted file mode 100644 index 1f430cc6f5d..00000000000 --- a/intern/cycles/kernel/osl/bsdf_phong.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2012, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> -#include "osl_closures.h" -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -// vanilla phong - leaks energy at grazing angles -// see Global Illumination Compendium entry (66) -class PhongClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_exponent; - PhongClosure() : BSDFClosure(Labels::GLOSSY) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const PhongClosure *comp = (const PhongClosure *)other; - return m_N == comp->m_N && m_exponent == comp->m_exponent && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "phong"; } - - void print_on (std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_exponent << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - if (cosNI > 0 && cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - float cosRI = R.dot(omega_in); - if (cosRI > 0) { - float common = 0.5f * (float) M_1_PI * powf(cosRI, m_exponent); - float out = cosNI * (m_exponent + 2) * common; - pdf = (m_exponent + 1) * common; - return Color3 (out, out, out); - } - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - Vec3 T, B; - make_orthonormals (R, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_exponent + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - ( cosTheta) * R; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - float common = 0.5f * (float) M_1_PI * powf(cosTheta, m_exponent); - pdf = (m_exponent + 1) * common; - float out = cosNI * (m_exponent + 2) * common; - eval.setValue(out, out, out); - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } -}; - - -class PhongRampClosure : public BSDFClosure { -public: - static const int MAXCOLORS = 8; - Vec3 m_N; - float m_exponent; - Color3 m_colors[MAXCOLORS]; - PhongRampClosure() : BSDFClosure(Labels::GLOSSY) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const PhongRampClosure *comp = (const PhongRampClosure *)other; - if (! (m_N == comp->m_N && m_exponent == comp->m_exponent && - BSDFClosure::mergeable(other))) - return false; - for (int i = 0; i < MAXCOLORS; ++i) - if (m_colors[i] != comp->m_colors[i]) - return false; - return true; - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "phong_ramp"; } - - void print_on (std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_exponent << ")"; - } - - Color3 get_color (float pos) const - { - float npos = pos * (float)(MAXCOLORS - 1); - int ipos = (int)npos; - if (ipos >= (MAXCOLORS - 1)) - return m_colors[MAXCOLORS - 1]; - float offset = npos - (float)ipos; - return m_colors[ipos] * (1.0f - offset) + m_colors[ipos+1] * offset; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - if (cosNI > 0 && cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - float cosRI = R.dot(omega_in); - if (cosRI > 0) { - float cosp = powf(cosRI, m_exponent); - float common = 0.5f * (float) M_1_PI * cosp; - float out = cosNI * (m_exponent + 2) * common; - pdf = (m_exponent + 1) * common; - return get_color(cosp) * out; - } - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - Vec3 T, B; - make_orthonormals (R, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_exponent + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - ( cosTheta) * R; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - float cosp = powf(cosTheta, m_exponent); - float common = 0.5f * (float) M_1_PI * cosp; - pdf = (m_exponent + 1) * common; - float out = cosNI * (m_exponent + 2) * common; - eval = get_color(cosp) * out; - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_phong_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(PhongClosure, m_N), - CLOSURE_FLOAT_PARAM (PhongClosure, m_exponent), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(PhongClosure) - }; - return params; -} - -ClosureParam *bsdf_phong_ramp_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM (PhongRampClosure, m_N), - CLOSURE_FLOAT_PARAM (PhongRampClosure, m_exponent), - CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, m_colors, PhongRampClosure::MAXCOLORS), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM (PhongRampClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_phong_prepare, PhongClosure) -CLOSURE_PREPARE(bsdf_phong_ramp_prepare, PhongRampClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_reflection.cpp b/intern/cycles/kernel/osl/bsdf_reflection.cpp deleted file mode 100644 index 1b85ec146d3..00000000000 --- a/intern/cycles/kernel/osl/bsdf_reflection.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class ReflectionClosure : public BSDFClosure { -public: - Vec3 m_N; // shading normal - ReflectionClosure() : BSDFClosure(Labels::SINGULAR) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const ReflectionClosure *comp = (const ReflectionClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "reflection"; } - - void print_on(std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - omega_in = (2 * cosNO) * m_N - omega_out; - if (Ng.dot(omega_in) > 0) { - domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx; - domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - } - } - return Labels::REFLECT; - } -}; - -ClosureParam *bsdf_reflection_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(ReflectionClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_refraction.cpp b/intern/cycles/kernel/osl/bsdf_refraction.cpp deleted file mode 100644 index 76ee53f7929..00000000000 --- a/intern/cycles/kernel/osl/bsdf_refraction.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class RefractionClosure : public BSDFClosure { -public: - Vec3 m_N; // shading normal - float m_eta; // ratio of indices of refraction (inside / outside) - RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) {} - - void setup() {} - - bool mergeable(const ClosurePrimitive *other) const { - const RefractionClosure *comp = (const RefractionClosure *)other; - return m_N == comp->m_N && m_eta == comp->m_eta && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "refraction"; } - - void print_on(std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_eta; - out << ")"; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - - fresnel_dielectric(m_eta, m_N, - omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - pdf = 1; - eval.setValue(1.0f, 1.0f, 1.0f); - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - } - - return Labels::TRANSMIT; - } -}; - -ClosureParam *bsdf_refraction_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), - CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(RefractionClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_transparent.cpp b/intern/cycles/kernel/osl/bsdf_transparent.cpp deleted file mode 100644 index 29cef8e192f..00000000000 --- a/intern/cycles/kernel/osl/bsdf_transparent.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class TransparentClosure : public BSDFClosure { -public: - TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) {} - - void setup() {} - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "transparent"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - omega_in = -omega_out; - domega_in_dx = -domega_out_dx; - domega_in_dy = -domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - return Labels::TRANSMIT; - } -}; - - - -ClosureParam *bsdf_transparent_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TransparentClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_ward.cpp b/intern/cycles/kernel/osl/bsdf_ward.cpp deleted file mode 100644 index 9d8d2fc4b76..00000000000 --- a/intern/cycles/kernel/osl/bsdf_ward.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -// anisotropic ward - leaks energy at grazing angles -// see http://www.graphics.cornell.edu/~bjw/wardnotes.pdf -class WardClosure : public BSDFClosure { -public: - Vec3 m_N; - Vec3 m_T; - float m_ax, m_ay; - WardClosure() : BSDFClosure(Labels::GLOSSY) {} - - void setup() - { - m_ax = clamp(m_ax, 1e-5f, 1.0f); - m_ay = clamp(m_ay, 1e-5f, 1.0f); - } - - bool mergeable(const ClosurePrimitive *other) const { - const WardClosure *comp = (const WardClosure *)other; - return m_N == comp->m_N && m_T == comp->m_T && - m_ax == comp->m_ax && m_ay == comp->m_ay && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "ward"; } - - void print_on(std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; - out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; - out << m_ax << ", " << m_ay << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector and get x,y basis on the surface for anisotropy - Vec3 H = omega_in + omega_out; - H.normalize(); // normalize needed for pdf - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // eq. 4 - float dotx = H.dot(X) / m_ax; - float doty = H.dot(Y) / m_ay; - float dotn = H.dot(m_N); - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float exp_val = expf(-exp_arg); - float out = cosNI * exp_val / denom; - float oh = H.dot(omega_out); - denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = exp_val / denom; - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // get x,y basis on the surface for anisotropy - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // generate random angles for the half vector - // eq. 7 (taking care around discontinuities to keep - // output angle in the right quadrant) - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alphaRatio = m_ay / m_ax; - float cosPhi, sinPhi; - if (randu < 0.25f) { - float val = 4 * randu; - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } - else if (randu < 0.5) { - float val = 1 - 4 * (0.5f - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = (float) M_PI - phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } - else if (randu < 0.75f) { - float val = 4 * (randu - 0.5f); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - //phi = (float) M_PI + phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } - else { - float val = 1 - 4 * (1 - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = 2 * (float) M_PI - phi; - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } - // eq. 6 - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay); - float tanTheta2 = -logf(1 - randv) / thetaDenom; - float cosTheta = 1 / sqrtf(1 + tanTheta2); - float sinTheta = cosTheta * sqrtf(tanTheta2); - - Vec3 h; // already normalized becaused expressed from spherical coordinates - h.x = sinTheta * cosPhi; - h.y = sinTheta * sinPhi; - h.z = cosTheta; - // compute terms that are easier in local space - float dotx = h.x / m_ax; - float doty = h.y / m_ay; - float dotn = h.z; - // transform to world space - h = h.x * X + h.y * Y + h.z * m_N; - // generate the final sample - float oh = h.dot(omega_out); - omega_in.x = 2 * oh * h.x - omega_out.x; - omega_in.y = 2 * oh * h.y - omega_out.y; - omega_in.z = 2 * oh * h.z - omega_out.z; - if (Ng.dot(omega_in) > 0) { - float cosNI = m_N.dot(omega_in); - if (cosNI > 0) { - // eq. 9 - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = expf(-exp_arg) / denom; - // compiler will reuse expressions already computed - denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float power = cosNI * expf(-exp_arg) / denom; - eval.setValue(power, power, power); - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - return Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_ward_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(WardClosure, m_N), - CLOSURE_VECTOR_PARAM(WardClosure, m_T), - CLOSURE_FLOAT_PARAM(WardClosure, m_ax), - CLOSURE_FLOAT_PARAM(WardClosure, m_ay), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WardClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_westin.cpp b/intern/cycles/kernel/osl/bsdf_westin.cpp deleted file mode 100644 index 6716376ad3e..00000000000 --- a/intern/cycles/kernel/osl/bsdf_westin.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class WestinBackscatterClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_roughness; - float m_invroughness; - WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) {} - - void setup() - { - m_roughness = clamp(m_roughness, 1e-5f, 1.0f); - m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; - } - - bool mergeable(const ClosurePrimitive *other) const { - const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; - return m_N == comp->m_N && m_roughness == comp->m_roughness && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "westin_backscatter"; } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_roughness; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float cosine = omega_out.dot(omega_in); - pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; - pdf *= 0.5f * float(M_1_PI); - return Color3(pdf, pdf, pdf); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - domega_in_dx = domega_out_dx; - domega_in_dy = domega_out_dy; - Vec3 T, B; - make_orthonormals(omega_out, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_invroughness + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - (cosTheta) * omega_out; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness); - pdf = (m_invroughness + 1) * pdf; - eval.setValue(pdf, pdf, pdf); - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } - -}; - - -class WestinSheenClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_edginess; -// float m_normalization; - WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const WestinSheenClosure *comp = (const WestinSheenClosure *)other; - return m_N == comp->m_N && m_edginess == comp->m_edginess && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "westin_sheen"; } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_edginess; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float sinNO2 = 1 - cosNO * cosNO; - pdf = cosNI * float(M_1_PI); - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - return Color3(westin, westin, westin); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - // TODO: account for sheen when sampling - float cosNO = m_N.dot(omega_out); - float sinNO2 = 1 - cosNO * cosNO; - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - eval.setValue(westin, westin, westin); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } - else { - pdf = 0; - } - return Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_westin_backscatter_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), - CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinBackscatterClosure) - }; - return params; -} - -ClosureParam *bsdf_westin_sheen_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), - CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinSheenClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure) -CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp deleted file mode 100644 index 889e8a54796..00000000000 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class BSSRDFCubicClosure : public BSSRDFClosure { -public: - Color3 m_radius; - Color3 m_scale; - float m_max_radius; - - template <typename T> - static inline T pow3(const T &x) { return x * x * x; } - - template <typename T> - static inline T pow5(const T &x) { T x2 = x * x; return x2 * x2 * x; } - - BSSRDFCubicClosure() {} - - void setup() - { - // pre-compute some terms - m_max_radius = 0; - for (int i = 0; i < 3; i++) { - m_scale[i] = m_radius[i] > 0 ? 4 / pow5(m_radius[i]) : 0; - m_max_radius = std::max(m_max_radius, m_radius[i]); - } - } - - bool mergeable(const ClosurePrimitive *other) const { - const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; - return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "bssrdf_cubic"; } - - void print_on(std::ostream &out) const - { - out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" - << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; - } - - Color3 eval(float r) const - { - return Color3((r < m_radius.x) ? pow3(m_radius.x - r) * m_scale.x : 0, - (r < m_radius.y) ? pow3(m_radius.y - r) * m_scale.y : 0, - (r < m_radius.z) ? pow3(m_radius.z - r) * m_scale.z : 0); - } - - float max_radius() const - { - return m_max_radius; - } -}; - - - -ClosureParam *closure_bssrdf_cubic_params() -{ - static ClosureParam params[] = { - CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) - }; - return params; -} - -CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/debug.cpp b/intern/cycles/kernel/osl/debug.cpp deleted file mode 100644 index ee5fb30371a..00000000000 --- a/intern/cycles/kernel/osl/debug.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -/// Debug closure -/// -/// This is going to be used for mask AOV's and similar -/// purposes. A tag (string) is always associated with -/// this closure, that "selects: the channel where the -/// weight should be sent. - -class DebugClosure : public ClosurePrimitive { -public: - ustring m_tag; - - DebugClosure () : ClosurePrimitive(Debug) {} - - bool mergeable(const ClosurePrimitive *other) const { - const DebugClosure *comp = (const DebugClosure *)other; - return m_tag == comp->m_tag && - ClosurePrimitive::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "debug"; } - - void print_on(std::ostream &out) const { - out << name() << " (\"" << m_tag.c_str() << "\")"; - } - -}; - -ClosureParam *closure_debug_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_PARAM(DebugClosure, m_tag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DebugClosure) - }; - return params; -} - -CLOSURE_PREPARE(closure_debug_prepare, DebugClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 3ee57cbe6b6..37e3e37c00a 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -36,6 +36,9 @@ #include "osl_closures.h" +#include "kernel_types.h" +#include "closure/emissive.h" + CCL_NAMESPACE_BEGIN using namespace OSL; @@ -52,51 +55,34 @@ public: GenericEmissiveClosure() { } void setup() {} - size_t memsize() const { return sizeof(*this); } - const char *name() const { return "emission"; } - void print_on(std::ostream &out) const { + void print_on(std::ostream &out) const + { out << name() << "()"; } Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const { - float cosNO = fabsf(Ng.dot(omega_out)); - float res = cosNO > 0 ? 1.0f : 0.0f; - return Color3(res, res, res); + float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out)); + return TO_COLOR3(result); } void sample(const Vec3 &Ng, float randu, float randv, Vec3 &omega_out, float &pdf) const { - // We don't do anything sophisticated here for the step - // We just sample the whole cone uniformly to the cosine - Vec3 T, B; - make_orthonormals(Ng, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = sqrtf(1.0f - 1.0f * randv); - float sinTheta = sqrtf(1.0f - cosTheta * cosTheta); - omega_out = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - cosTheta * Ng; - pdf = 1.0f / float(M_PI); + float3 omega_out_; + emissive_sample(TO_FLOAT3(Ng), randu, randv, &omega_out_, &pdf); + omega_out = TO_VEC3(omega_out_); } - /// Return the probability distribution function in the direction omega_out, - /// given the parameters and the light's surface normal. This MUST match - /// the PDF computed by sample(). - float pdf(const Vec3 &Ng, - const Vec3 &omega_out) const + float pdf(const Vec3 &Ng, const Vec3 &omega_out) const { - float cosNO = Ng.dot(omega_out); - return cosNO > 0 ? 1.0f : 0.0f; + return emissive_pdf(TO_FLOAT3(Ng), TO_FLOAT3(omega_out)); } }; - - ClosureParam *closure_emission_params() { static ClosureParam params[] = { diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index 541076f84c9..2c459fd714b 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRC_OSL node_combine_rgb.osl node_convert_from_color.osl node_convert_from_float.osl + node_convert_from_int.osl node_convert_from_normal.osl node_convert_from_point.osl node_convert_from_vector.osl @@ -29,7 +30,9 @@ set(SRC_OSL node_hsv.osl node_image_texture.osl node_invert.osl + node_layer_weight.osl node_light_path.osl + node_light_falloff.osl node_magic_texture.osl node_mapping.osl node_math.osl @@ -86,7 +89,7 @@ foreach(_file ${SRC_OSL}) unset(_OSO_FILE) endforeach() -add_custom_target(shader ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS}) +add_custom_target(cycles_osl_shaders ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS}) # CMAKE_CURRENT_SOURCE_DIR is already included in OSO paths delayed_install("" "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader) diff --git a/intern/cycles/kernel/osl/nodes/node_attribute.osl b/intern/cycles/kernel/osl/nodes/node_attribute.osl index d273d0c68d7..8e7c846d1a3 100644 --- a/intern/cycles/kernel/osl/nodes/node_attribute.osl +++ b/intern/cycles/kernel/osl/nodes/node_attribute.osl @@ -29,12 +29,12 @@ shader node_attribute( Vector = point(Color); getattribute(name, Fac); - if(bump_offset == "dx") { + if (bump_offset == "dx") { Color += Dx(Color); Vector += Dx(Vector); Fac += Dx(Fac); } - else if(bump_offset == "dy") { + else if (bump_offset == "dy") { Color += Dy(Color); Vector += Dy(Vector); Fac += Dy(Fac); diff --git a/intern/cycles/kernel/osl/nodes/node_background.osl b/intern/cycles/kernel/osl/nodes/node_background.osl index 69f8d85a82e..b51a1685294 100644 --- a/intern/cycles/kernel/osl/nodes/node_background.osl +++ b/intern/cycles/kernel/osl/nodes/node_background.osl @@ -23,6 +23,6 @@ shader node_background( float Strength = 1.0, output closure color Background = background()) { - Background = Color*Strength*background(); + Background = Color * Strength * background(); } diff --git a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl b/intern/cycles/kernel/osl/nodes/node_brick_texture.osl index 4daceb4018e..478d9457001 100644 --- a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_brick_texture.osl @@ -40,21 +40,21 @@ float brick(point p, float mortar_size, float bias, rownum = (int)floor(p[1] / row_height); - if(offset_frequency && squash_frequency) { - brick_width *= ((int)(rownum) % squash_frequency ) ? 1.0 : squash_amount; /* squash */ - offset = ((int)(rownum) % offset_frequency ) ? 0 : (brick_width*offset_amount); /* offset */ + if (offset_frequency && squash_frequency) { + brick_width *= ((int)(rownum) % squash_frequency) ? 1.0 : squash_amount; /* squash */ + offset = ((int)(rownum) % offset_frequency) ? 0 : (brick_width * offset_amount); /* offset */ } - bricknum = (int)floor((p[0]+offset) / brick_width); + bricknum = (int)floor((p[0] + offset) / brick_width); - x = (p[0]+offset) - brick_width*bricknum; - y = p[1] - row_height*rownum; + x = (p[0] + offset) - brick_width * bricknum; + y = p[1] - row_height * rownum; tint = clamp((brick_noise((rownum << 16) + (bricknum & 65535)) + bias), 0.0, 1.0); return (x < mortar_size || y < mortar_size || - x > (brick_width - mortar_size) || - y > (row_height - mortar_size)) ? 1.0 : 0.0; + x > (brick_width - mortar_size) || + y > (row_height - mortar_size)) ? 1.0 : 0.0; } shader node_brick_texture( @@ -77,10 +77,10 @@ shader node_brick_texture( float tint = 0.0; color Col = Color1; - Fac = brick(Vector*Scale, MortarSize, Bias, BrickWidth, RowHeight, + Fac = brick(Vector * Scale, MortarSize, Bias, BrickWidth, RowHeight, Offset, OffsetFrequency, Squash, SquashFrequency, tint); - if(Fac != 1.0) { + if (Fac != 1.0) { float facm = 1.0 - tint; Col[0] = facm * (Color1[0]) + tint * Color2[0]; @@ -89,6 +89,5 @@ shader node_brick_texture( } Color = (Fac == 1.0) ? Mortar: Col; - } diff --git a/intern/cycles/kernel/osl/nodes/node_brightness.osl b/intern/cycles/kernel/osl/nodes/node_brightness.osl index 4f19a20f736..8e9f5c9c796 100644 --- a/intern/cycles/kernel/osl/nodes/node_brightness.osl +++ b/intern/cycles/kernel/osl/nodes/node_brightness.osl @@ -24,7 +24,7 @@ shader node_brightness( float Contrast = 0.0, output color ColorOut = color(0.8, 0.8, 0.8)) { - float delta = Contrast * (1.0/200.0); + float delta = Contrast * (1.0 / 200.0); float a = 1.0 - delta * 2.0; float b; @@ -32,13 +32,13 @@ shader node_brightness( float bright_factor = Brightness / 100.0; /* - * The algorithm is by Werner D. Streidt - * (http://visca.com/ffactory/archives/5-99/msg00021.html) - * Extracted of OpenCV demhist.c - */ + * The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ if (Contrast > 0.0) { - a = (a < 0.0 ? 1.0/a : 0.0); + a = (a < 0.0 ? 1.0 / a : 0.0); b = a * (bright_factor - delta); } else { diff --git a/intern/cycles/kernel/osl/nodes/node_bump.osl b/intern/cycles/kernel/osl/nodes/node_bump.osl index a3849e70f98..dbc554e0a72 100644 --- a/intern/cycles/kernel/osl/nodes/node_bump.osl +++ b/intern/cycles/kernel/osl/nodes/node_bump.osl @@ -18,7 +18,7 @@ #include "stdosl.h" -/* "Bump Mapping Unparametrized Surfaces on the GPU" +/* "Bump Mapping Unparameterized Surfaces on the GPU" * Morten S. Mikkelsen, 2010 */ surface node_bump( @@ -37,10 +37,10 @@ surface node_bump( vector Ry = cross(N, dPdx); float det = dot(dPdx, Rx); - vector surfgrad = dx*Rx + dy*Ry; + vector surfgrad = dx * Rx + dy * Ry; surfgrad *= 0.1; /* todo: remove this factor */ - Normal = normalize(abs(det)*N - sign(det)*surfgrad); + Normal = normalize(abs(det) * N - sign(det) * surfgrad); } diff --git a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl b/intern/cycles/kernel/osl/nodes/node_checker_texture.osl index e92d7be34fc..577caf308ff 100644 --- a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_checker_texture.osl @@ -23,15 +23,15 @@ float checker(point p) { - p[0] = (p[0] + 0.00001)*0.9999; - p[1] = (p[1] + 0.00001)*0.9999; - p[2] = (p[2] + 0.00001)*0.9999; + p[0] = (p[0] + 0.00001) * 0.9999; + p[1] = (p[1] + 0.00001) * 0.9999; + p[2] = (p[2] + 0.00001) * 0.9999; int xi = (int)fabs(floor(p[0])); int yi = (int)fabs(floor(p[1])); int zi = (int)fabs(floor(p[2])); - if((xi % 2 == yi % 2) == (zi % 2)) { + if ((xi % 2 == yi % 2) == (zi % 2)) { return 1.0; } else { @@ -47,8 +47,8 @@ shader node_checker_texture( output float Fac = 0.0, output color Color = color(0.0, 0.0, 0.0)) { - Fac = checker(Vector*Scale); - if(Fac == 1.0) { + Fac = checker(Vector * Scale); + if (Fac == 1.0) { Color = Color1; } else { diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl index 97356139c48..2884c772414 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl @@ -21,11 +21,13 @@ shader node_convert_from_color( color Color = color(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { - Val = Color[0]*0.2126 + Color[1]*0.7152 + Color[2]*0.0722; + Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722; + ValInt = (int)(Color[0]*0.2126 + Color[1]*0.7152 + Color[2]*0.0722); Vector = vector(Color[0], Color[1], Color[2]); Point = point(Color[0], Color[1], Color[2]); Normal = normal(Color[0], Color[1], Color[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl index 00e78f3bab4..4466fbae3a6 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl @@ -20,11 +20,13 @@ shader node_convert_from_float( float Val = 0.0, + output int ValInt = 0, output color Color = color(0.0, 0.0, 0.0), output vector Vector = vector(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { + ValInt = (int)Val; Color = color(Val, Val, Val); Vector = vector(Val, Val, Val); Point = point(Val, Val, Val); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl new file mode 100644 index 00000000000..060d4184fa6 --- /dev/null +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl @@ -0,0 +1,36 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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. + */ + +#include "stdosl.h" + +shader node_convert_from_int( + int ValInt = 0, + output float Val = 0.0, + output color Color = color(0.0, 0.0, 0.0), + output vector Vector = vector(0.0, 0.0, 0.0), + output point Point = point(0.0, 0.0, 0.0), + output normal Normal = normal(0.0, 0.0, 0.0)) +{ + float f = (float)ValInt; + Val = f; + Color = color(f, f, f); + Vector = vector(f, f, f); + Point = point(f, f, f); + Normal = normal(f, f, f); +} + diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl index 0bb9092591d..419e93e1518 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl @@ -21,11 +21,13 @@ shader node_convert_from_normal( normal Normal = normal(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), output color Color = color(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0)) { - Val = (Normal[0] + Normal[1] + Normal[2])*(1.0/3.0); + Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0); + ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0)); Vector = vector(Normal[0], Normal[1], Normal[2]); Color = color(Normal[0], Normal[1], Normal[2]); Point = point(Normal[0], Normal[1], Normal[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl index e66d6a864d6..cedd200f088 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl @@ -21,11 +21,13 @@ shader node_convert_from_point( point Point = point(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), output color Color = color(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { - Val = (Point[0] + Point[1] + Point[2])*(1.0/3.0); + Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0); + ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0)); Vector = vector(Point[0], Point[1], Point[2]); Color = color(Point[0], Point[1], Point[2]); Normal = normal(Point[0], Point[1], Point[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl index 37ba9582cad..a9f43a40074 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl @@ -21,11 +21,13 @@ shader node_convert_from_vector( vector Vector = vector(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output color Color = color(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { - Val = (Vector[0] + Vector[1] + Vector[2])*(1.0/3.0); + Val = (Vector[0] + Vector[1] + Vector[2]) * (1.0 / 3.0); + ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0)); Color = color(Vector[0], Vector[1], Vector[2]); Point = point(Vector[0], Vector[1], Vector[2]); Normal = normal(Vector[0], Vector[1], Vector[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl index 6075b7c93f3..d6dc17316e8 100644 --- a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl @@ -24,7 +24,7 @@ shader node_diffuse_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - if(Roughness == 0.0) + if (Roughness == 0.0) BSDF = Color * diffuse(Normal); else BSDF = Color * oren_nayar(Normal, Roughness); diff --git a/intern/cycles/kernel/osl/nodes/node_emission.osl b/intern/cycles/kernel/osl/nodes/node_emission.osl index 8bfd1af173a..7ad0f9f7760 100644 --- a/intern/cycles/kernel/osl/nodes/node_emission.osl +++ b/intern/cycles/kernel/osl/nodes/node_emission.osl @@ -24,9 +24,9 @@ shader node_emission( float Strength = 1.0, output closure color Emission = emission()) { - if(TotalPower) - Emission = ((Strength/surfacearea())*Color)*emission(); + if (TotalPower) + Emission = ((Strength / surfacearea()) * Color) * emission(); else - Emission = (Strength*Color)*emission(); + Emission = (Strength * Color) * emission(); } diff --git a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl b/intern/cycles/kernel/osl/nodes/node_environment_texture.osl index 3ad806781eb..bad62e56ab4 100644 --- a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_environment_texture.osl @@ -28,7 +28,7 @@ shader node_environment_texture( { Color = (color)environment(filename, Vector, "alpha", Alpha); - if(color_space == "sRGB") + if (color_space == "sRGB") Color = color_srgb_to_scene_linear(Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.osl b/intern/cycles/kernel/osl/nodes/node_fresnel.osl index 3af4448b43f..e8d8e945f98 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.osl +++ b/intern/cycles/kernel/osl/nodes/node_fresnel.osl @@ -25,7 +25,7 @@ shader node_fresnel( output float Fac = 0.0) { float f = max(IOR, 1.0 + 1e-5); - float eta = backfacing()? 1.0/f: f; + float eta = backfacing() ? 1.0 / f: f; Fac = fresnel_dielectric(I, Normal, eta); } diff --git a/intern/cycles/kernel/osl/nodes/node_geometry.osl b/intern/cycles/kernel/osl/nodes/node_geometry.osl index 9efc2a75c64..a3831cbec9c 100644 --- a/intern/cycles/kernel/osl/nodes/node_geometry.osl +++ b/intern/cycles/kernel/osl/nodes/node_geometry.osl @@ -38,11 +38,11 @@ shader node_geometry( Parametric = point(u, v, 0.0); Backfacing = backfacing(); - if(bump_offset == "dx") { + if (bump_offset == "dx") { Position += Dx(Position); Parametric += Dx(Parametric); } - else if(bump_offset == "dy") { + else if (bump_offset == "dy") { Position += Dy(Position); Parametric += Dy(Parametric); } diff --git a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl index 52743669c99..f3fcce572cf 100644 --- a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl @@ -28,14 +28,16 @@ shader node_glass_bsdf( output closure color BSDF = diffuse(Normal)) { float f = max(IOR, 1.0 + 1e-5); - float eta = backfacing()? 1.0/f: f; + float eta = backfacing() ? 1.0 / f: f; float Fr = fresnel_dielectric(I, Normal, eta); - if(distribution == "Sharp") - BSDF = Color*(Fr*reflection(Normal) + (1.0-Fr)*refraction(Normal, eta)); - else if(distribution == "Beckmann") - BSDF = Color*(Fr*microfacet_beckmann(Normal, Roughness, eta) + (1.0-Fr)*microfacet_beckmann_refraction(Normal, Roughness, eta)); - else if(distribution == "GGX") - BSDF = Color*(Fr*microfacet_ggx(Normal, Roughness, eta) + (1.0-Fr)*microfacet_ggx_refraction(Normal, Roughness, eta)); + if (distribution == "Sharp") + BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta)); + else if (distribution == "Beckmann") + BSDF = Color * (Fr * microfacet_beckmann(Normal, Roughness, eta) + + (1.0 - Fr) * microfacet_beckmann_refraction(Normal, Roughness, eta)); + else if (distribution == "GGX") + BSDF = Color * (Fr * microfacet_ggx(Normal, Roughness, eta) + + (1.0 - Fr) * microfacet_ggx_refraction(Normal, Roughness, eta)); } diff --git a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl index 3890630e8a2..48d61ea0ab5 100644 --- a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl @@ -26,12 +26,12 @@ shader node_glossy_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - if(distribution == "Sharp") - BSDF = Color*reflection(Normal); - else if(distribution == "Beckmann") - BSDF = Color*microfacet_beckmann(Normal, Roughness, 1.0); - else if(distribution == "GGX") - BSDF = Color*microfacet_ggx(Normal, Roughness, 1.0); + if (distribution == "Sharp") + BSDF = Color * reflection(Normal); + else if (distribution == "Beckmann") + BSDF = Color * microfacet_beckmann(Normal, Roughness, 1.0); + else if (distribution == "GGX") + BSDF = Color * microfacet_ggx(Normal, Roughness, 1.0); } diff --git a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl b/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl index e0cbc2cc569..ae7cfa51f59 100644 --- a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl @@ -31,31 +31,31 @@ float gradient(point p, string type) float result = 0.0; - if(type == "Linear") { + if (type == "Linear") { result = x; } - else if(type == "Quadratic") { + else if (type == "Quadratic") { float r = max(x, 0.0); - result = r*r; + result = r * r; } - else if(type == "Easing") { + else if (type == "Easing") { float r = min(max(x, 0.0), 1.0); - float t = r*r; + float t = r * r; - result = (3.0*t - 2.0*t*r); + result = (3.0 * t - 2.0 * t * r); } - else if(type == "Diagonal") { - result = (x + y)/2.0; + else if (type == "Diagonal") { + result = (x + y) / 2.0; } - else if(type == "Radial") { - result = atan2(y, x)/(2.0*M_PI) + 0.5; + else if (type == "Radial") { + result = atan2(y, x) / (2.0 * M_PI) + 0.5; } else { - float r = max(1.0 - sqrt(x*x + y*y + z*z), 0.0); + float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0); - if(type == "Quadratic Sphere") - result = r*r; - else if(type == "Spherical") + if (type == "Quadratic Sphere") + result = r * r; + else if (type == "Spherical") result = r; } diff --git a/intern/cycles/kernel/osl/nodes/node_image_texture.osl b/intern/cycles/kernel/osl/nodes/node_image_texture.osl index 38126401d76..e005f1f4245 100644 --- a/intern/cycles/kernel/osl/nodes/node_image_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_image_texture.osl @@ -26,9 +26,9 @@ shader node_image_texture( output color Color = color(0.0, 0.0, 0.0), output float Alpha = 1.0) { - Color = (color)texture(filename, Vector[0], 1.0-Vector[1], "wrap", "periodic", "alpha", Alpha); + Color = (color)texture(filename, Vector[0], 1.0 - Vector[1], "wrap", "periodic", "alpha", Alpha); - if(color_space == "sRGB") + if (color_space == "sRGB") Color = color_srgb_to_scene_linear(Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl index d834819ef3a..3ea57f71786 100644 --- a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl +++ b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl @@ -19,24 +19,28 @@ #include "stdosl.h" #include "node_fresnel.h" -shader node_blend_weight( - float Blend = 0.3, +shader node_layer_weight( + float Blend = 0.5, normal Normal = N, output float Fresnel = 0.0, output float Facing = 0.0) { - float f = max(1.0 - Blend, 1e-5); - Fresnel = fresnel_dielectric(I, Normal, backfacing()? f: 1.0/f); + float blend = Blend; + /* Fresnel */ + float eta = max(1.0 - Blend, 1e-5); + eta = backfacing() ? eta : 1.0 / eta; + Fresnel = fresnel_dielectric(I, Normal, eta); + + /* Facing */ Facing = abs(dot(I, Normal)); - if(Blend != 0.5) { - Blend = clamp(Blend, 0.0, 1.0); - Blend = (Blend < 0.5)? 2.0*Blend: 0.5/(1.0 - Blend); + if (blend != 0.5) { + blend = clamp(blend, 0.0, 1.0 - 1e-5); + blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); - Facing = powf(Facing, Blend); + Facing = pow(Facing, blend); } Facing = 1.0 - Facing; } - diff --git a/intern/cycles/kernel/osl/nodes/node_light_falloff.osl b/intern/cycles/kernel/osl/nodes/node_light_falloff.osl new file mode 100644 index 00000000000..fd68594a1d8 --- /dev/null +++ b/intern/cycles/kernel/osl/nodes/node_light_falloff.osl @@ -0,0 +1,46 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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. + */ + +#include "stdosl.h" + +shader node_light_falloff( + float Strength = 0.0, + float Smooth = 0.0, + output float Quadratic = 0.0, + output float Linear = 0.0, + output float Constant = 0.0) +{ + float ray_length = 0.0; + float strength = Strength; + getattribute("std::ray_length", ray_length); + + if(Smooth > 0.0) { + float squared = ray_length*ray_length; + strength *= squared/(Smooth + squared); + } + + /* Quadratic */ + Quadratic = strength; + + /* Linear */ + Linear = (strength*ray_length); + + /* Constant */ + Constant = (strength*ray_length*ray_length); +} + diff --git a/intern/cycles/kernel/osl/nodes/node_light_path.osl b/intern/cycles/kernel/osl/nodes/node_light_path.osl index 0ead20bf2bb..ca92a5e6553 100644 --- a/intern/cycles/kernel/osl/nodes/node_light_path.osl +++ b/intern/cycles/kernel/osl/nodes/node_light_path.osl @@ -25,7 +25,8 @@ shader node_light_path( output float IsGlossyRay = 0.0, output float IsSingularRay = 0.0, output float IsReflectionRay = 0.0, - output float IsTransmissionRay = 0.0) + output float IsTransmissionRay = 0.0, + output float RayLength = 0.0) { IsCameraRay = raytype("camera"); IsShadowRay = raytype("shadow"); @@ -34,5 +35,7 @@ shader node_light_path( IsSingularRay = raytype("singular"); IsReflectionRay = raytype("reflection"); IsTransmissionRay = raytype("refraction"); + + getattribute("std::ray_length", RayLength); } diff --git a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl b/intern/cycles/kernel/osl/nodes/node_magic_texture.osl index c013ebfe658..e464b83bc9e 100644 --- a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_magic_texture.osl @@ -25,51 +25,51 @@ color magic(point p, int n, float distortion) { float dist = distortion; - float x = sin((p[0] + p[1] + p[2])*5.0); - float y = cos((-p[0] + p[1] - p[2])*5.0); - float z = -cos((-p[0] - p[1] + p[2])*5.0); + float x = sin(( p[0] + p[1] + p[2]) * 5.0); + float y = cos((-p[0] + p[1] - p[2]) * 5.0); + float z = -cos((-p[0] - p[1] + p[2]) * 5.0); - if(n > 0) { + if (n > 0) { x *= dist; y *= dist; z *= dist; - y = -cos(x-y+z); + y = -cos(x - y + z); y *= dist; - if(n > 1) { - x = cos(x-y-z); + if (n > 1) { + x = cos(x - y - z); x *= dist; - if(n > 2) { - z = sin(-x-y-z); + if (n > 2) { + z = sin(-x - y - z); z *= dist; - if(n > 3) { - x = -cos(-x+y-z); + if (n > 3) { + x = -cos(-x + y - z); x *= dist; - if(n > 4) { - y = -sin(-x+y+z); + if (n > 4) { + y = -sin(-x + y + z); y *= dist; - if(n > 5) { - y = -cos(-x+y+z); + if (n > 5) { + y = -cos(-x + y + z); y *= dist; - if(n > 6) { - x = cos(x+y+z); + if (n > 6) { + x = cos(x + y + z); x *= dist; - if(n > 7) { - z = sin(x+y-z); + if (n > 7) { + z = sin(x + y - z); z *= dist; - if(n > 8) { - x = -cos(-x-y+z); + if (n > 8) { + x = -cos(-x - y + z); x *= dist; - if(n > 9) { - y = -sin(x-y+z); + if (n > 9) { + y = -sin(x - y + z); y *= dist; } } @@ -82,7 +82,7 @@ color magic(point p, int n, float distortion) } } - if(dist != 0.0) { + if (dist != 0.0) { dist *= 2.0; x /= dist; y /= dist; @@ -99,6 +99,6 @@ shader node_magic_texture( point Vector = P, output color Color = color(0.0, 0.0, 0.0)) { - Color = magic(Vector*Scale, Depth, Distortion); + Color = magic(Vector * Scale, Depth, Distortion); } diff --git a/intern/cycles/kernel/osl/nodes/node_math.osl b/intern/cycles/kernel/osl/nodes/node_math.osl index 3327795286a..24dce898fd2 100644 --- a/intern/cycles/kernel/osl/nodes/node_math.osl +++ b/intern/cycles/kernel/osl/nodes/node_math.osl @@ -22,20 +22,20 @@ float safe_divide(float a, float b) { float result; - if(b == 0.0) + if (b == 0.0) result = 0.0; else - result = a/b; + result = a / b; return result; } float safe_log(float a, float b) { - if(a < 0.0 || b < 0.0) + if (a < 0.0 || b < 0.0) return 0.0; - return log(a)/log(b); + return log(a) / log(b); } shader node_math( @@ -47,42 +47,42 @@ shader node_math( { /* OSL asin, acos, pow check for values that could give rise to nan */ - if(type == "Add") + if (type == "Add") Value = Value1 + Value2; - if(type == "Subtract") + if (type == "Subtract") Value = Value1 - Value2; - if(type == "Multiply") - Value = Value1*Value2; - if(type == "Divide") + if (type == "Multiply") + Value = Value1 * Value2; + if (type == "Divide") Value = safe_divide(Value1, Value2); - if(type == "Sine") + if (type == "Sine") Value = sin(Value1); - if(type == "Cosine") + if (type == "Cosine") Value = cos(Value1); - if(type == "Tangent") + if (type == "Tangent") Value = tan(Value1); - if(type == "Arcsine") + if (type == "Arcsine") Value = asin(Value1); - if(type == "Arccosine") + if (type == "Arccosine") Value = acos(Value1); - if(type == "Arctangent") + if (type == "Arctangent") Value = atan(Value1); - if(type == "Power") + if (type == "Power") Value = pow(Value1, Value2); - if(type == "Logarithm") + if (type == "Logarithm") Value = safe_log(Value1, Value2); - if(type == "Minimum") + if (type == "Minimum") Value = min(Value1, Value2); - if(type == "Maximum") + if (type == "Maximum") Value = max(Value1, Value2); - if(type == "Round") + if (type == "Round") Value = floor(Value1 + 0.5); - if(type == "Less Than") + if (type == "Less Than") Value = Value1 < Value2; - if(type == "Greater Than") + if (type == "Greater Than") Value = Value1 > Value2; - if(Clamp) + if (Clamp) Value = clamp(Value1, 0.0, 1.0); } diff --git a/intern/cycles/kernel/osl/nodes/node_mix.osl b/intern/cycles/kernel/osl/nodes/node_mix.osl index 2ce342c49cd..69e68e5ed15 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix.osl +++ b/intern/cycles/kernel/osl/nodes/node_mix.osl @@ -38,7 +38,7 @@ color node_mix_screen(float t, color col1, color col2) { float tm = 1.0 - t; - return color(1.0) - (color(tm) + t*(color(1.0) - col2))*(color(1.0) - col1); + return color(1.0) - (color(tm) + t * (color(1.0) - col2)) * (color(1.0) - col1); } color node_mix_overlay(float t, color col1, color col2) @@ -47,20 +47,20 @@ color node_mix_overlay(float t, color col1, color col2) color outcol = col1; - if(outcol[0] < 0.5) - outcol[0] *= tm + 2.0*t*col2[0]; + if (outcol[0] < 0.5) + outcol[0] *= tm + 2.0 * t * col2[0]; else - outcol[0] = 1.0 - (tm + 2.0*t*(1.0 - col2[0]))*(1.0 - outcol[0]); + outcol[0] = 1.0 - (tm + 2.0 * t * (1.0 - col2[0])) * (1.0 - outcol[0]); - if(outcol[1] < 0.5) - outcol[1] *= tm + 2.0*t*col2[1]; + if (outcol[1] < 0.5) + outcol[1] *= tm + 2.0 * t * col2[1]; else - outcol[1] = 1.0 - (tm + 2.0*t*(1.0 - col2[1]))*(1.0 - outcol[1]); + outcol[1] = 1.0 - (tm + 2.0 * t * (1.0 - col2[1])) * (1.0 - outcol[1]); - if(outcol[2] < 0.5) - outcol[2] *= tm + 2.0*t*col2[2]; + if (outcol[2] < 0.5) + outcol[2] *= tm + 2.0 * t * col2[2]; else - outcol[2] = 1.0 - (tm + 2.0*t*(1.0 - col2[2]))*(1.0 - outcol[2]); + outcol[2] = 1.0 - (tm + 2.0 * t * (1.0 - col2[2])) * (1.0 - outcol[2]); return outcol; } @@ -76,9 +76,9 @@ color node_mix_div(float t, color col1, color col2) color outcol = col1; - if(col2[0] != 0.0) outcol[0] = tm*outcol[0] + t*outcol[0]/col2[0]; - if(col2[1] != 0.0) outcol[1] = tm*outcol[1] + t*outcol[1]/col2[1]; - if(col2[2] != 0.0) outcol[2] = tm*outcol[2] + t*outcol[2]/col2[2]; + if (col2[0] != 0.0) outcol[0] = tm * outcol[0] + t * outcol[0] / col2[0]; + if (col2[1] != 0.0) outcol[1] = tm * outcol[1] + t * outcol[1] / col2[1]; + if (col2[2] != 0.0) outcol[2] = tm * outcol[2] + t * outcol[2] / col2[2]; return outcol; } @@ -90,41 +90,41 @@ color node_mix_diff(float t, color col1, color col2) color node_mix_dark(float t, color col1, color col2) { - return min(col1, col2*t); + return min(col1, col2 * t); } color node_mix_light(float t, color col1, color col2) { - return max(col1, col2*t); + return max(col1, col2 * t); } color node_mix_dodge(float t, color col1, color col2) { color outcol = col1; - if(outcol[0] != 0.0) { - float tmp = 1.0 - t*col2[0]; - if(tmp <= 0.0) + if (outcol[0] != 0.0) { + float tmp = 1.0 - t * col2[0]; + if (tmp <= 0.0) outcol[0] = 1.0; - else if((tmp = outcol[0]/tmp) > 1.0) + else if ((tmp = outcol[0] / tmp) > 1.0) outcol[0] = 1.0; else outcol[0] = tmp; } - if(outcol[1] != 0.0) { - float tmp = 1.0 - t*col2[1]; - if(tmp <= 0.0) + if (outcol[1] != 0.0) { + float tmp = 1.0 - t * col2[1]; + if (tmp <= 0.0) outcol[1] = 1.0; - else if((tmp = outcol[1]/tmp) > 1.0) + else if ((tmp = outcol[1] / tmp) > 1.0) outcol[1] = 1.0; else outcol[1] = tmp; } - if(outcol[2] != 0.0) { - float tmp = 1.0 - t*col2[2]; - if(tmp <= 0.0) + if (outcol[2] != 0.0) { + float tmp = 1.0 - t * col2[2]; + if (tmp <= 0.0) outcol[2] = 1.0; - else if((tmp = outcol[2]/tmp) > 1.0) + else if ((tmp = outcol[2] / tmp) > 1.0) outcol[2] = 1.0; else outcol[2] = tmp; @@ -139,32 +139,32 @@ color node_mix_burn(float t, color col1, color col2) color outcol = col1; - tmp = tm + t*col2[0]; - if(tmp <= 0.0) + tmp = tm + t * col2[0]; + if (tmp <= 0.0) outcol[0] = 0.0; - else if((tmp = (1.0 - (1.0 - outcol[0])/tmp)) < 0.0) + else if ((tmp = (1.0 - (1.0 - outcol[0]) / tmp)) < 0.0) outcol[0] = 0.0; - else if(tmp > 1.0) + else if (tmp > 1.0) outcol[0] = 1.0; else outcol[0] = tmp; - tmp = tm + t*col2[1]; - if(tmp <= 0.0) + tmp = tm + t * col2[1]; + if (tmp <= 0.0) outcol[1] = 0.0; - else if((tmp = (1.0 - (1.0 - outcol[1])/tmp)) < 0.0) + else if ((tmp = (1.0 - (1.0 - outcol[1]) / tmp)) < 0.0) outcol[1] = 0.0; - else if(tmp > 1.0) + else if (tmp > 1.0) outcol[1] = 1.0; else outcol[1] = tmp; - tmp = tm + t*col2[2]; - if(tmp <= 0.0) + tmp = tm + t * col2[2]; + if (tmp <= 0.0) outcol[2] = 0.0; - else if((tmp = (1.0 - (1.0 - outcol[2])/tmp)) < 0.0) + else if ((tmp = (1.0 - (1.0 - outcol[2]) / tmp)) < 0.0) outcol[2] = 0.0; - else if(tmp > 1.0) + else if (tmp > 1.0) outcol[2] = 1.0; else outcol[2] = tmp; @@ -177,7 +177,7 @@ color node_mix_hue(float t, color col1, color col2) color outcol = col1; color hsv2 = rgb_to_hsv(col2); - if(hsv2[1] != 0.0) { + if (hsv2[1] != 0.0) { color hsv = rgb_to_hsv(outcol); hsv[0] = hsv2[0]; color tmp = hsv_to_rgb(hsv); @@ -196,10 +196,10 @@ color node_mix_sat(float t, color col1, color col2) color hsv = rgb_to_hsv(outcol); - if(hsv[1] != 0.0) { + if (hsv[1] != 0.0) { color hsv2 = rgb_to_hsv(col2); - hsv[1] = tm*hsv[1] + t*hsv2[1]; + hsv[1] = tm * hsv[1] + t * hsv2[1]; outcol = hsv_to_rgb(hsv); } @@ -213,7 +213,7 @@ color node_mix_val(float t, color col1, color col2) color hsv = rgb_to_hsv(col1); color hsv2 = rgb_to_hsv(col2); - hsv[2] = tm*hsv[2] + t*hsv2[2]; + hsv[2] = tm * hsv[2] + t * hsv2[2]; return hsv_to_rgb(hsv); } @@ -223,7 +223,7 @@ color node_mix_color(float t, color col1, color col2) color outcol = col1; color hsv2 = rgb_to_hsv(col2); - if(hsv2[1] != 0.0) { + if (hsv2[1] != 0.0) { color hsv = rgb_to_hsv(outcol); hsv[0] = hsv2[0]; hsv[1] = hsv2[1]; @@ -240,29 +240,29 @@ color node_mix_soft(float t, color col1, color col2) float tm = 1.0 - t; color one = color(1.0); - color scr = one - (one - col2)*(one - col1); + color scr = one - (one - col2) * (one - col1); - return tm*col1 + t*((one - col1)*col2*col1 + col1*scr); + return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr); } color node_mix_linear(float t, color col1, color col2) { color outcol = col1; - if(col2[0] > 0.5) - outcol[0]= col1[0] + t*(2.0*(col2[0] - 0.5)); + if (col2[0] > 0.5) + outcol[0] = col1[0] + t * (2.0 * (col2[0] - 0.5)); else - outcol[0]= col1[0] + t*(2.0*(col2[0]) - 1.0); + outcol[0] = col1[0] + t * (2.0 * (col2[0]) - 1.0); - if(col2[1] > 0.5) - outcol[1]= col1[1] + t*(2.0*(col2[1] - 0.5)); + if (col2[1] > 0.5) + outcol[1] = col1[1] + t * (2.0 * (col2[1] - 0.5)); else - outcol[1]= col1[1] + t*(2.0*(col2[1]) - 1.0); + outcol[1] = col1[1] + t * (2.0 * (col2[1]) - 1.0); - if(col2[2] > 0.5) - outcol[2]= col1[2] + t*(2.0*(col2[2] - 0.5)); + if (col2[2] > 0.5) + outcol[2] = col1[2] + t * (2.0 * (col2[2] - 0.5)); else - outcol[2]= col1[2] + t*(2.0*(col2[2]) - 1.0); + outcol[2] = col1[2] + t * (2.0 * (col2[2]) - 1.0); return outcol; } @@ -288,44 +288,44 @@ shader node_mix( { float t = clamp(Fac, 0.0, 1.0); - if(type == "Mix") + if (type == "Mix") Color = node_mix_blend(t, Color1, Color2); - if(type == "Add") + if (type == "Add") Color = node_mix_add(t, Color1, Color2); - if(type == "Multiply") + if (type == "Multiply") Color = node_mix_mul(t, Color1, Color2); - if(type == "Screen") + if (type == "Screen") Color = node_mix_screen(t, Color1, Color2); - if(type == "Overlay") + if (type == "Overlay") Color = node_mix_overlay(t, Color1, Color2); - if(type == "Subtract") + if (type == "Subtract") Color = node_mix_sub(t, Color1, Color2); - if(type == "Divide") + if (type == "Divide") Color = node_mix_div(t, Color1, Color2); - if(type == "Difference") + if (type == "Difference") Color = node_mix_diff(t, Color1, Color2); - if(type == "Darken") + if (type == "Darken") Color = node_mix_dark(t, Color1, Color2); - if(type == "Lighten") + if (type == "Lighten") Color = node_mix_light(t, Color1, Color2); - if(type == "Dodge") + if (type == "Dodge") Color = node_mix_dodge(t, Color1, Color2); - if(type == "Burn") + if (type == "Burn") Color = node_mix_burn(t, Color1, Color2); - if(type == "Hue") + if (type == "Hue") Color = node_mix_hue(t, Color1, Color2); - if(type == "Saturation") + if (type == "Saturation") Color = node_mix_sat(t, Color1, Color2); - if(type == "Value") + if (type == "Value") Color = node_mix_val (t, Color1, Color2); - if(type == "Color") + if (type == "Color") Color = node_mix_color(t, Color1, Color2); - if(type == "Soft Light") + if (type == "Soft Light") Color = node_mix_soft(t, Color1, Color2); - if(type == "Linear Light") + if (type == "Linear Light") Color = node_mix_linear(t, Color1, Color2); - if(Clamp) + if (Clamp) Color = node_mix_clamp(Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl b/intern/cycles/kernel/osl/nodes/node_mix_closure.osl index 1a377abd381..e28dd1fc436 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl +++ b/intern/cycles/kernel/osl/nodes/node_mix_closure.osl @@ -25,6 +25,6 @@ shader node_mix_closure( output closure color Closure = background()) { float t = clamp(Fac, 0.0, 1.0); - Closure = (1.0 - t)*Closure1 + t*Closure2; + Closure = (1.0 - t) * Closure1 + t * Closure2; } diff --git a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl b/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl index 7d125d50fd6..71461b8fd79 100644 --- a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl @@ -36,14 +36,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float float pwHL = pow(lacunarity, -H); int i; - for(i = 0; i < (int)octaves; i++) { + for (i = 0; i < (int)octaves; i++) { value += noise("perlin", p) * pwr; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); - if(rmd != 0.0) + if (rmd != 0.0) value += rmd * noise("perlin", p) * pwr; return value; @@ -64,14 +64,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar float pwHL = pow(lacunarity, -H); int i; - for(i = 0; i < (int)octaves; i++) { + for (i = 0; i < (int)octaves; i++) { value *= (pwr * noise("perlin", p) + 1.0); pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); - if(rmd != 0.0) + if (rmd != 0.0) value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */ return value; @@ -96,7 +96,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna value = offset + noise("perlin", p); p *= lacunarity; - for(i = 1; i < (int)octaves; i++) { + for (i = 1; i < (int)octaves; i++) { increment = (noise("perlin", p) + offset) * pwr * value; value += increment; pwr *= pwHL; @@ -104,7 +104,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna } rmd = octaves - floor(octaves); - if(rmd != 0.0) { + if (rmd != 0.0) { increment = (noise("perlin", p) + offset) * pwr * value; value += rmd * increment; } @@ -120,7 +120,8 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna * offset: raises the terrain from `sea level' */ -float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float lacunarity, float octaves, float offset, float gain) +float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, + float lacunarity, float octaves, float offset, float gain) { float result, signal, weight, rmd; float pwHL = pow(lacunarity, -H); @@ -131,8 +132,8 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float weight = gain * result; p *= lacunarity; - for(i = 1; (weight > 0.001) && (i < (int)octaves); i++) { - if(weight > 1.0) + for (i = 1; (weight > 0.001) && (i < (int)octaves); i++) { + if (weight > 1.0) weight = 1.0; signal = (noise("perlin", p) + offset) * pwr; @@ -143,7 +144,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float } rmd = octaves - floor(octaves); - if(rmd != 0.0) + if (rmd != 0.0) result += rmd * ((noise("perlin", p) + offset) * pwr); return result; @@ -157,7 +158,8 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float * offset: raises the terrain from `sea level' */ -float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float lacunarity, float octaves, float offset, float gain) +float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, + float lacunarity, float octaves, float offset, float gain) { float result, signal, weight; float pwHL = pow(lacunarity, -H); @@ -169,7 +171,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float result = signal; weight = 1.0; - for(i = 1; i < (int)octaves; i++) { + for (i = 1; i < (int)octaves; i++) { p *= lacunarity; weight = clamp(signal * gain, 0.0, 1.0); signal = offset - fabs(noise("perlin", p)); @@ -202,18 +204,18 @@ shader node_musgrave_texture( string Basis = "Perlin"; float intensity = 1.0; - point p = Vector*Scale; - - if(Type == "Multifractal") - Fac = intensity*noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves); - else if(Type == "fBM") - Fac = intensity*noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves); - else if(Type == "Hybrid Multifractal") - Fac = intensity*noise_musgrave_hybrid_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); - else if(Type == "Ridged Multifractal") - Fac = intensity*noise_musgrave_ridged_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); - else if(Type == "Hetero Terrain") - Fac = intensity*noise_musgrave_hetero_terrain(p, Basis, dimension, lacunarity, octaves, Offset); + point p = Vector * Scale; + + if (Type == "Multifractal") + Fac = intensity * noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves); + else if (Type == "fBM") + Fac = intensity * noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves); + else if (Type == "Hybrid Multifractal") + Fac = intensity * noise_musgrave_hybrid_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); + else if (Type == "Ridged Multifractal") + Fac = intensity * noise_musgrave_ridged_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); + else if (Type == "Hetero Terrain") + Fac = intensity * noise_musgrave_hetero_terrain(p, Basis, dimension, lacunarity, octaves, Offset); Color = color(Fac, Fac, Fac); } diff --git a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl b/intern/cycles/kernel/osl/nodes/node_noise_texture.osl index 1ddb4d8a08b..227b2bf8cea 100644 --- a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_noise_texture.osl @@ -25,8 +25,8 @@ float noise(point p, string basis, float distortion, float detail, float fac, co { point r; int hard = 0; - - if(distortion != 0.0) { + + if (distortion != 0.0) { r[0] = noise_basis(p + point(13.5), basis) * distortion; r[1] = noise_basis(p, basis) * distortion; r[2] = noise_basis(p - point(13.5), basis) * distortion; @@ -51,6 +51,6 @@ shader node_noise_texture( output color Color = color(0.2, 0.2, 0.2)) { string Basis = "Perlin"; - Fac = noise(Vector*Scale, Basis, Distortion, Detail, Fac, Color); + Fac = noise(Vector * Scale, Basis, Distortion, Detail, Fac, Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_object_info.osl b/intern/cycles/kernel/osl/nodes/node_object_info.osl index 21e50d8a43e..0d503258179 100644 --- a/intern/cycles/kernel/osl/nodes/node_object_info.osl +++ b/intern/cycles/kernel/osl/nodes/node_object_info.osl @@ -19,15 +19,14 @@ #include "stdosl.h" shader node_object_info( - output point Location = point(0.0, 0.0, 0.0), - output float ObjectIndex = 0.0, - output float MaterialIndex = 0.0, - output float Random = 0.0 - ) + output point Location = point(0.0, 0.0, 0.0), + output float ObjectIndex = 0.0, + output float MaterialIndex = 0.0, + output float Random = 0.0) { - getattribute("std::object_location", Location); - getattribute("std::object_index", ObjectIndex); - getattribute("std::material_index", MaterialIndex); - getattribute("std::object_random", Random); + getattribute("std::object_location", Location); + getattribute("std::object_index", ObjectIndex); + getattribute("std::material_index", MaterialIndex); + getattribute("std::object_random", Random); } diff --git a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl b/intern/cycles/kernel/osl/nodes/node_output_displacement.osl index a6b452c532a..5649b879c5b 100644 --- a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl +++ b/intern/cycles/kernel/osl/nodes/node_output_displacement.osl @@ -20,6 +20,6 @@ displacement node_output_displacement(float Displacement = 0.0) { - P += N*Displacement*0.1; /* todo: get rid of this factor */ + P += N * Displacement * 0.1; /* todo: get rid of this factor */ } diff --git a/intern/cycles/kernel/osl/nodes/node_particle_info.osl b/intern/cycles/kernel/osl/nodes/node_particle_info.osl index aadc2812865..ba51ccbd953 100644 --- a/intern/cycles/kernel/osl/nodes/node_particle_info.osl +++ b/intern/cycles/kernel/osl/nodes/node_particle_info.osl @@ -25,15 +25,14 @@ shader node_particle_info( output point Location = point(0.0, 0.0, 0.0), output float Size = 0.0, output vector Velocity = point(0.0, 0.0, 0.0), - output vector AngularVelocity = point(0.0, 0.0, 0.0) - ) + output vector AngularVelocity = point(0.0, 0.0, 0.0)) { - getattribute("std::particle_index", Index); - getattribute("std::particle_age", Age); - getattribute("std::particle_lifetime", Lifetime); - getattribute("std::particle_location", Location); - getattribute("std::particle_size", Size); - getattribute("std::particle_velocity", Velocity); - getattribute("std::particle_angular_velocity", AngularVelocity); + getattribute("std::particle_index", Index); + getattribute("std::particle_age", Age); + getattribute("std::particle_lifetime", Lifetime); + getattribute("std::particle_location", Location); + getattribute("std::particle_size", Size); + getattribute("std::particle_velocity", Velocity); + getattribute("std::particle_angular_velocity", AngularVelocity); } diff --git a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl index 2bc10f31cb3..a128ebbd1cf 100644 --- a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl +++ b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl @@ -20,25 +20,24 @@ #include "oslutil.h" shader node_rgb_ramp( - color ramp_color[RAMP_TABLE_SIZE] = {0.0}, - float ramp_alpha[RAMP_TABLE_SIZE] = {0.0}, + color ramp_color[RAMP_TABLE_SIZE] = {0.0}, + float ramp_alpha[RAMP_TABLE_SIZE] = {0.0}, - float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0), - output float Alpha = 1.0 - ) + float Fac = 0.0, + output color Color = color(0.0, 0.0, 0.0), + output float Alpha = 1.0) { - float f = clamp(Fac, 0.0, 1.0)*(RAMP_TABLE_SIZE-1); + float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); - int i = (int)f; - float t = f - (float)i; + int i = (int)f; + float t = f - (float)i; - Color = ramp_color[i]; - Alpha = ramp_alpha[i]; + Color = ramp_color[i]; + Alpha = ramp_alpha[i]; - if (t > 0.0) { - Color = (1.0 - t)*Color + t*ramp_color[i+1]; - Alpha = (1.0 - t)*Alpha + t*ramp_alpha[i+1]; - } + if (t > 0.0) { + Color = (1.0 - t) * Color + t * ramp_color[i + 1]; + Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1]; + } } diff --git a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl b/intern/cycles/kernel/osl/nodes/node_sky_texture.osl index fdb9b1d9708..932fb1e2f17 100644 --- a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_sky_texture.osl @@ -32,10 +32,10 @@ color xyY_to_xyz(float x, float y, float Y) { float X, Z; - if(y != 0.0) X = (x / y) * Y; + if (y != 0.0) X = (x / y) * Y; else X = 0.0; - if(y != 0.0 && Y != 0.0) Z = ((1.0 - x - y) / y) * Y; + if (y != 0.0 && Y != 0.0) Z = ((1.0 - x - y) / y) * Y; else Z = 0.0; return color(X, Y, Z); @@ -50,11 +50,11 @@ color xyz_to_rgb(float x, float y, float z) float sky_angle_between(float thetav, float phiv, float theta, float phi) { - float cospsi = sin(thetav)*sin(theta)*cos(phi - phiv) + cos(thetav)*cos(theta); + float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta); - if(cospsi > 1.0) + if (cospsi > 1.0) return 0.0; - if(cospsi < -1.0) + if (cospsi < -1.0) return M_PI; return acos(cospsi); @@ -70,7 +70,7 @@ float sky_perez_function(float lam[5], float theta, float gamma) float ctheta = cos(theta); float cgamma = cos(gamma); - return (1.0 + lam[0]*exp(lam[1] / ctheta)) * (1.0 + lam[2]*exp(lam[3]*gamma) + lam[4]*cgamma*cgamma); + return (1.0 + lam[0] * exp(lam[1] / ctheta)) * (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma); } color sky_xyz_radiance(KernelSunSky sunsky, vector dir) @@ -106,42 +106,42 @@ void precompute_sunsky(vector dir, float turbidity, output KernelSunSky sunsky) sunsky.phi = phi; sunsky.dir = dir; - float theta2 = theta*theta; - float theta3 = theta*theta*theta; + float theta2 = theta * theta; + float theta3 = theta * theta * theta; float T = turbidity; - float T2 = T*T; + float T2 = T * T; - float chi = (4.0/ 9.0- T / 120.0) * (M_PI - 2.0* theta); - sunsky.zenith_Y = (4.0453*T - 4.9710) * tan(chi) - 0.2155*T + 2.4192; + float chi = (4.0 / 9.0 - T / 120.0) * (M_PI - 2.0 * theta); + sunsky.zenith_Y = (4.0453 * T - 4.9710) * tan(chi) - 0.2155 * T + 2.4192; sunsky.zenith_Y *= 0.06; sunsky.zenith_x = - (0.00166* theta3 - 0.00375* theta2 + 0.00209* theta)*T2 + - (-0.02903* theta3 + 0.06377* theta2 - 0.03202* theta + 0.00394)*T + - (0.11693* theta3 - 0.21196* theta2 + 0.06052* theta + 0.25886); + ( 0.00166 * theta3 - 0.00375 * theta2 + 0.00209 * theta) * T2 + + (-0.02903 * theta3 + 0.06377 * theta2 - 0.03202 * theta + 0.00394) * T + + ( 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * theta + 0.25886); sunsky.zenith_y = - (0.00275* theta3 - 0.00610* theta2 + 0.00317* theta)*T2 + - (-0.04214* theta3 + 0.08970* theta2 - 0.04153* theta + 0.00516)*T + - (0.15346* theta3 - 0.26756* theta2 + 0.06670* theta + 0.26688); - - sunsky.perez_Y[0] = (0.1787*T - 1.4630); - sunsky.perez_Y[1] = (-0.3554*T + 0.4275); - sunsky.perez_Y[2] = (-0.0227*T + 5.3251); - sunsky.perez_Y[3] = (0.1206*T - 2.5771); - sunsky.perez_Y[4] = (-0.0670*T + 0.3703); - - sunsky.perez_x[0] = (-0.0193*T - 0.2592); - sunsky.perez_x[1] = (-0.0665*T + 0.0008); - sunsky.perez_x[2] = (-0.0004*T + 0.2125); - sunsky.perez_x[3] = (-0.0641*T - 0.8989); - sunsky.perez_x[4] = (-0.0033*T + 0.0452); - - sunsky.perez_y[0] = (-0.0167*T - 0.2608); - sunsky.perez_y[1] = (-0.0950*T + 0.0092); - sunsky.perez_y[2] = (-0.0079*T + 0.2102); - sunsky.perez_y[3] = (-0.0441*T - 1.6537); - sunsky.perez_y[4] = (-0.0109*T + 0.0529); + ( 0.00275 * theta3 - 0.00610 * theta2 + 0.00317 * theta) * T2 + + (-0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * theta + 0.00516) * T + + ( 0.15346 * theta3 - 0.26756 * theta2 + 0.06670 * theta + 0.26688); + + sunsky.perez_Y[0] = ( 0.1787 * T - 1.4630); + sunsky.perez_Y[1] = (-0.3554 * T + 0.4275); + sunsky.perez_Y[2] = (-0.0227 * T + 5.3251); + sunsky.perez_Y[3] = ( 0.1206 * T - 2.5771); + sunsky.perez_Y[4] = (-0.0670 * T + 0.3703); + + sunsky.perez_x[0] = (-0.0193 * T - 0.2592); + sunsky.perez_x[1] = (-0.0665 * T + 0.0008); + sunsky.perez_x[2] = (-0.0004 * T + 0.2125); + sunsky.perez_x[3] = (-0.0641 * T - 0.8989); + sunsky.perez_x[4] = (-0.0033 * T + 0.0452); + + sunsky.perez_y[0] = (-0.0167 * T - 0.2608); + sunsky.perez_y[1] = (-0.0950 * T + 0.0092); + sunsky.perez_y[2] = (-0.0079 * T + 0.2102); + sunsky.perez_y[3] = (-0.0441 * T - 1.6537); + sunsky.perez_y[4] = (-0.0109 * T + 0.0529); sunsky.zenith_Y /= sky_perez_function(sunsky.perez_Y, 0, theta); sunsky.zenith_x /= sky_perez_function(sunsky.perez_x, 0, theta); diff --git a/intern/cycles/kernel/osl/nodes/node_texture.h b/intern/cycles/kernel/osl/nodes/node_texture.h index 7cd0742ffe8..1b3ba8207ab 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture.h +++ b/intern/cycles/kernel/osl/nodes/node_texture.h @@ -235,21 +235,21 @@ float noise_turbulence(point p, string basis, float details, int hard) float rmd = octaves - floor(octaves); - if(rmd != 0.0) { - float t = noise_basis(fscale*p, basis); + if (rmd != 0.0) { + float t = noise_basis(fscale * p, basis); - if(hard) - t = fabs(2.0*t - 1.0); + if (hard) + t = fabs(2.0 * t - 1.0); float sum2 = sum + t*amp; - sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); - sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1)); + sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1)); + sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1)); return (1.0 - rmd)*sum + rmd*sum2; } else { - sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); + sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1)); return sum; } } diff --git a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl b/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl index 2acf72aef54..883135d2a43 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl +++ b/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl @@ -30,7 +30,7 @@ shader node_texture_coordinate( output point Window = point(0.0, 0.0, 0.0), output point Reflection = point(0.0, 0.0, 0.0)) { - if(is_background) { + if (is_background) { Generated = P; UV = point(0.0, 0.0, 0.0); Object = P; @@ -48,14 +48,14 @@ shader node_texture_coordinate( Reflection = reflect(I, Normal); } - if(bump_offset == "dx") { + if (bump_offset == "dx") { Generated += Dx(Generated); UV += Dx(UV); Object += Dx(Object); Camera += Dx(Camera); Window += Dx(Window); } - else if(bump_offset == "dy") { + else if (bump_offset == "dy") { Generated += Dy(Generated); UV += Dy(UV); Object += Dy(Object); diff --git a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl index 9acd46756d2..e7efe73700c 100644 --- a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl @@ -23,6 +23,6 @@ shader node_translucent_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - BSDF = Color*translucent(Normal); + BSDF = Color * translucent(Normal); } diff --git a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl index b347bfb116b..875bce3f16c 100644 --- a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl @@ -23,6 +23,6 @@ shader node_transparent_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - BSDF = Color*transparent(); + BSDF = Color * transparent(); } diff --git a/intern/cycles/kernel/osl/nodes/node_vector_math.osl b/intern/cycles/kernel/osl/nodes/node_vector_math.osl index 9e0f0b60522..f22a6e8441a 100644 --- a/intern/cycles/kernel/osl/nodes/node_vector_math.osl +++ b/intern/cycles/kernel/osl/nodes/node_vector_math.osl @@ -25,27 +25,27 @@ shader node_vector_math( output float Value = 0.0, output vector Vector = vector(0.0, 0.0, 0.0)) { - if(type == "Add") { + if (type == "Add") { Vector = Vector1 + Vector2; - Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2]))/3.0; + Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0; } - if(type == "Subtract") { + if (type == "Subtract") { Vector = Vector1 - Vector2; - Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2]))/3.0; + Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0; } - if(type == "Average") { + if (type == "Average") { Value = length(Vector1 + Vector2); Vector = normalize(Vector1 + Vector2); } - if(type == "Dot Product") { + if (type == "Dot Product") { Value = dot(Vector1, Vector2); } - if(type == "Cross Product") { + if (type == "Cross Product") { vector c = cross(Vector1, Vector2); Value = length(c); Vector = normalize(c); } - if(type == "Normalize") { + if (type == "Normalize") { Value = length(Vector1); Vector = normalize(Vector1); } diff --git a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl index 5e0cae8cbd1..4bb4e39a1ba 100644 --- a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl @@ -27,6 +27,6 @@ shader node_velvet_bsdf( { float sigma = clamp(Sigma, 0.0, 1.0); - BSDF = Color*ashikhmin_velvet(Normal, sigma, 1.0); + BSDF = Color * ashikhmin_velvet(Normal, sigma, 1.0); } diff --git a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl b/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl index db08b64de1c..a44df00a267 100644 --- a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl @@ -32,16 +32,16 @@ shader node_voronoi_texture( float da[4]; point pa[4]; - voronoi(Vector*Scale, "Distance Squared", 1.0, da, pa); + voronoi(Vector * Scale, "Distance Squared", 1.0, da, pa); /* Colored output */ - if(Coloring == "Intensity") { + if (Coloring == "Intensity") { Fac = fabs(da[0]); Color = color(Fac); } else { Color = cellnoise_color(pa[0]); - Fac = (Color[0]+Color[1]+Color[2])*(1.0/3.0); + Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0); } } diff --git a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl index 68db07109ed..e204be123b8 100644 --- a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl @@ -25,6 +25,6 @@ shader node_ward_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - BSDF = Color*ward(Normal, normalize(dPdu), RoughnessU, RoughnessV); + BSDF = Color * ward(Normal, normalize(dPdu), RoughnessU, RoughnessV); } diff --git a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl b/intern/cycles/kernel/osl/nodes/node_wave_texture.osl index db53faaf94b..79b8a8885d1 100644 --- a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_wave_texture.osl @@ -30,15 +30,15 @@ float wave(point p, float scale, string type, float detail, float distortion, fl float result = 0.0; float n = 0.0; - if(type == "Bands") { - n = (x + y + z)*10.0; + if (type == "Bands") { + n = (x + y + z) * 10.0; } - else if(type == "Rings") { - n = (sqrt(x*x + y*y + z*z)*20.0); + else if (type == "Rings") { + n = (sqrt(x * x + y * y + z * z) * 20.0); } - - if(distortion != 0.0) { - n = n +(distortion * noise_turbulence(p*dscale, "Perlin", detail, 0)); + + if (distortion != 0.0) { + n = n + (distortion * noise_turbulence(p * dscale, "Perlin", detail, 0)); } result = noise_wave("Sine", n); diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 9e99d4d2480..73e96643df7 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -37,10 +37,100 @@ #include "osl_shader.h" #include "util_debug.h" +#include "util_math.h" #include "util_param.h" +#include "kernel_types.h" +#include "kernel_montecarlo.h" + +#include "closure/bsdf.h" +#include "closure/bsdf_ashikhmin_velvet.h" +#include "closure/bsdf_diffuse.h" +#include "closure/bsdf_microfacet.h" +#include "closure/bsdf_oren_nayar.h" +#include "closure/bsdf_reflection.h" +#include "closure/bsdf_refraction.h" +#include "closure/bsdf_transparent.h" +#include "closure/bsdf_ward.h" +#include "closure/bsdf_westin.h" + CCL_NAMESPACE_BEGIN +using namespace OSL; + +/* BSDF class definitions */ + +BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(DiffuseClosure, N), +BSDF_CLOSURE_CLASS_END(Diffuse, diffuse) + +BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(TranslucentClosure, N), +BSDF_CLOSURE_CLASS_END(Translucent, translucent) + +BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(OrenNayarClosure, N), + CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar) + +BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR) + CLOSURE_VECTOR_PARAM(ReflectionClosure, N), +BSDF_CLOSURE_CLASS_END(Reflection, reflection) + +BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR) + CLOSURE_VECTOR_PARAM(RefractionClosure, N), + CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(Refraction, refraction) + +BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N), + CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter) + +BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(WestinSheenClosure, N), + CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen) + +BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR) +BSDF_CLOSURE_CLASS_END(Transparent, transparent) + +BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N), + CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) + +BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(WardClosure, N), + CLOSURE_VECTOR_PARAM(WardClosure, T), + CLOSURE_FLOAT_PARAM(WardClosure, sc.data0), + CLOSURE_FLOAT_PARAM(WardClosure, sc.data1), +BSDF_CLOSURE_CLASS_END(Ward, ward) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0), + CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1), +BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1), +BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) + +/* Registration */ + static void generic_closure_setup(OSL::RendererServices *, int id, void *data) { assert(data); @@ -64,28 +154,42 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O void OSLShader::register_closures(OSL::ShadingSystem *ss) { - register_closure(ss, "diffuse", OSL_CLOSURE_BSDF_DIFFUSE_ID, bsdf_diffuse_params(), bsdf_diffuse_prepare); - register_closure(ss, "oren_nayar", OSL_CLOSURE_BSDF_OREN_NAYAR_ID, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare); - register_closure(ss, "translucent", OSL_CLOSURE_BSDF_TRANSLUCENT_ID, bsdf_translucent_params(), bsdf_translucent_prepare); - register_closure(ss, "reflection", OSL_CLOSURE_BSDF_REFLECTION_ID, bsdf_reflection_params(), bsdf_reflection_prepare); - register_closure(ss, "refraction", OSL_CLOSURE_BSDF_REFRACTION_ID, bsdf_refraction_params(), bsdf_refraction_prepare); - register_closure(ss, "transparent", OSL_CLOSURE_BSDF_TRANSPARENT_ID, bsdf_transparent_params(), bsdf_transparent_prepare); - register_closure(ss, "microfacet_ggx", OSL_CLOSURE_BSDF_MICROFACET_GGX_ID, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare); - register_closure(ss, "microfacet_ggx_refraction", OSL_CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare); - register_closure(ss, "microfacet_beckmann", OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_ID, bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare); - register_closure(ss, "microfacet_beckmann_refraction", OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare); - register_closure(ss, "ward", OSL_CLOSURE_BSDF_WARD_ID, bsdf_ward_params(), bsdf_ward_prepare); - register_closure(ss, "phong", OSL_CLOSURE_BSDF_PHONG_ID, bsdf_phong_params(), bsdf_phong_prepare); - register_closure(ss, "phong_ramp", OSL_CLOSURE_BSDF_PHONG_RAMP_ID, bsdf_phong_ramp_params(), bsdf_phong_ramp_prepare); - register_closure(ss, "ashikhmin_velvet", OSL_CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare); - register_closure(ss, "westin_backscatter", OSL_CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare); - register_closure(ss, "westin_sheen", OSL_CLOSURE_BSDF_WESTIN_SHEEN_ID, bsdf_westin_sheen_params(), bsdf_westin_sheen_prepare); - register_closure(ss, "bssrdf_cubic", OSL_CLOSURE_BSSRDF_CUBIC_ID, closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare); - register_closure(ss, "emission", OSL_CLOSURE_EMISSION_ID, closure_emission_params(), closure_emission_prepare); - register_closure(ss, "debug", OSL_CLOSURE_DEBUG_ID, closure_debug_params(), closure_debug_prepare); - register_closure(ss, "background", OSL_CLOSURE_BACKGROUND_ID, closure_background_params(), closure_background_prepare); - register_closure(ss, "holdout", OSL_CLOSURE_HOLDOUT_ID, closure_holdout_params(), closure_holdout_prepare); - register_closure(ss, "subsurface", OSL_CLOSURE_SUBSURFACE_ID, closure_subsurface_params(), closure_subsurface_prepare); + int id = 0; + + register_closure(ss, "diffuse", id++, + bsdf_diffuse_params(), bsdf_diffuse_prepare); + register_closure(ss, "oren_nayar", id++, + bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare); + register_closure(ss, "translucent", id++, + bsdf_translucent_params(), bsdf_translucent_prepare); + register_closure(ss, "reflection", id++, + bsdf_reflection_params(), bsdf_reflection_prepare); + register_closure(ss, "refraction", id++, + bsdf_refraction_params(), bsdf_refraction_prepare); + register_closure(ss, "transparent", id++, + bsdf_transparent_params(), bsdf_transparent_prepare); + register_closure(ss, "microfacet_ggx", id++, + bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare); + register_closure(ss, "microfacet_ggx_refraction", id++, + bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare); + register_closure(ss, "microfacet_beckmann", id++, + bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare); + register_closure(ss, "microfacet_beckmann_refraction", id++, + bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare); + register_closure(ss, "ward", id++, + bsdf_ward_params(), bsdf_ward_prepare); + register_closure(ss, "ashikhmin_velvet", id++, + bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare); + register_closure(ss, "westin_backscatter", id++, + bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare); + register_closure(ss, "westin_sheen", id++, + bsdf_westin_sheen_params(), bsdf_westin_sheen_prepare); + register_closure(ss, "emission", id++, + closure_emission_params(), closure_emission_prepare); + register_closure(ss, "background", id++, + closure_background_params(), closure_background_prepare); + register_closure(ss, "holdout", id++, + closure_holdout_params(), closure_holdout_prepare); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index a69af45672d..873e03673c3 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -37,78 +37,19 @@ #include <OSL/oslexec.h> #include <OSL/genclosure.h> -CCL_NAMESPACE_BEGIN +#include "kernel_types.h" -enum { - OSL_CLOSURE_BSDF_DIFFUSE_ID, - OSL_CLOSURE_BSDF_OREN_NAYAR_ID, - OSL_CLOSURE_BSDF_TRANSLUCENT_ID, - OSL_CLOSURE_BSDF_REFLECTION_ID, - OSL_CLOSURE_BSDF_REFRACTION_ID, - OSL_CLOSURE_BSDF_TRANSPARENT_ID, - OSL_CLOSURE_BSDF_MICROFACET_GGX_ID, - OSL_CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, - OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_ID, - OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, - OSL_CLOSURE_BSDF_WARD_ID, - OSL_CLOSURE_BSDF_PHONG_ID, - OSL_CLOSURE_BSDF_PHONG_RAMP_ID, - OSL_CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, - OSL_CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, - OSL_CLOSURE_BSDF_WESTIN_SHEEN_ID, - OSL_CLOSURE_BSSRDF_CUBIC_ID, - OSL_CLOSURE_EMISSION_ID, - OSL_CLOSURE_DEBUG_ID, - OSL_CLOSURE_BACKGROUND_ID, - OSL_CLOSURE_HOLDOUT_ID, - OSL_CLOSURE_SUBSURFACE_ID -}; +#include "util_types.h" + +CCL_NAMESPACE_BEGIN -OSL::ClosureParam *bsdf_diffuse_params(); -OSL::ClosureParam *bsdf_oren_nayar_params(); -OSL::ClosureParam *bsdf_translucent_params(); -OSL::ClosureParam *bsdf_reflection_params(); -OSL::ClosureParam *bsdf_refraction_params(); -OSL::ClosureParam *bsdf_transparent_params(); -OSL::ClosureParam *bsdf_microfacet_ggx_params(); -OSL::ClosureParam *bsdf_microfacet_ggx_refraction_params(); -OSL::ClosureParam *bsdf_microfacet_beckmann_params(); -OSL::ClosureParam *bsdf_microfacet_beckmann_refraction_params(); -OSL::ClosureParam *bsdf_ward_params(); -OSL::ClosureParam *bsdf_phong_params(); -OSL::ClosureParam *bsdf_phong_ramp_params(); -OSL::ClosureParam *bsdf_ashikhmin_velvet_params(); -OSL::ClosureParam *bsdf_westin_backscatter_params(); -OSL::ClosureParam *bsdf_westin_sheen_params(); -OSL::ClosureParam *closure_bssrdf_cubic_params(); OSL::ClosureParam *closure_emission_params(); -OSL::ClosureParam *closure_debug_params(); OSL::ClosureParam *closure_background_params(); OSL::ClosureParam *closure_holdout_params(); -OSL::ClosureParam *closure_subsurface_params(); - -void bsdf_diffuse_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_oren_nayar_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_translucent_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_reflection_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_refraction_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_ggx_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_ggx_refraction_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_beckmann_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_beckmann_refraction_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_ward_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_phong_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_ashikhmin_velvet_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_westin_backscatter_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_westin_sheen_prepare(OSL::RendererServices *, int id, void *data); -void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data); + void closure_emission_prepare(OSL::RendererServices *, int id, void *data); -void closure_debug_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); void closure_holdout_prepare(OSL::RendererServices *, int id, void *data); -void closure_subsurface_prepare(OSL::RendererServices *, int id, void *data); #define CLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ @@ -117,6 +58,106 @@ void name(RendererServices *, int id, void *data) \ new (data) classname(); \ } +#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) +#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) +#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) + +/* BSDF */ + +class CBSDFClosure : public OSL::ClosurePrimitive { +public: + ShaderClosure sc; + OSL::Vec3 N, T; + + CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF), + m_scattering_label(scattering), m_shaderdata_flag(0) { } + ~CBSDFClosure() { } + + int scattering() const { return m_scattering_label; } + int shaderdata_flag() const { return m_shaderdata_flag; } + ClosureType shaderclosure_type() const { return sc.type; } + + virtual void blur(float roughness); + virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0; + virtual float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0; + + virtual int sample(const float3 &Ng, + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, + float randu, float randv, + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, + float &pdf, float3 &eval) const = 0; + +protected: + int m_scattering_label; + int m_shaderdata_flag; +}; + +#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, svmlower, TYPE) \ +\ +class Upper##Closure : public CBSDFClosure { \ +public: \ + Upper##Closure() : CBSDFClosure(TYPE) {} \ + size_t memsize() const { return sizeof(*this); } \ + const char *name() const { return #lower; } \ +\ + void setup() \ + { \ + sc.N = TO_FLOAT3(N); \ + sc.T = TO_FLOAT3(T); \ + m_shaderdata_flag = bsdf_##lower##_setup(&sc); \ + } \ +\ + bool mergeable(const ClosurePrimitive *other) const \ + { \ + return false; \ + } \ + \ + void blur(float roughness) \ + { \ + bsdf_##svmlower##_blur(&sc, roughness); \ + } \ +\ + void print_on(std::ostream &out) const \ + { \ + out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))"; \ + } \ +\ + float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const \ + { \ + return bsdf_##svmlower##_eval_reflect(&sc, omega_out, omega_in, &pdf); \ + } \ +\ + float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const \ + { \ + return bsdf_##svmlower##_eval_transmit(&sc, omega_out, omega_in, &pdf); \ + } \ +\ + int sample(const float3 &Ng, \ + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, \ + float randu, float randv, \ + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, \ + float &pdf, float3 &eval) const \ + { \ + return bsdf_##svmlower##_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy, \ + randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); \ + } \ +}; \ +\ +ClosureParam *bsdf_##lower##_params() \ +{ \ + static ClosureParam params[] = { + +/* parameters */ + +#define BSDF_CLOSURE_CLASS_END(Upper, lower) \ + CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_FINISH_PARAM(Upper##Closure) \ + }; \ + return params; \ +} \ +\ +CLOSURE_PREPARE(bsdf_##lower##_prepare, Upper##Closure) + CCL_NAMESPACE_END #endif /* __OSL_CLOSURES_H__ */ diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index f1deaa9db9d..83574c91d31 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -72,7 +72,11 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr int object = sd->object; if (object != ~0) { - Transform tfm = object_fetch_transform(kg, object, time, OBJECT_TRANSFORM); +#ifdef __OBJECT_MOTION__ + Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL); +#else + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); +#endif tfm = transform_transpose(tfm); result = TO_MATRIX44(tfm); @@ -93,9 +97,14 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform int object = sd->object; if (object != ~0) { - Transform tfm = object_fetch_transform(kg, object, time, OBJECT_INVERSE_TRANSFORM); - tfm = transform_transpose(tfm); - result = TO_MATRIX44(tfm); +#ifdef __OBJECT_MOTION__ + Transform itfm; + object_fetch_transform_motion_test(kg, object, time, &itfm); +#else + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); +#endif + itfm = transform_transpose(itfm); + result = TO_MATRIX44(itfm); return true; } @@ -109,7 +118,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti KernelGlobals *kg = kernel_globals; if (from == u_ndc) { - Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); + Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); result = TO_MATRIX44(tfm); return true; } @@ -162,14 +171,108 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) { - // XXX implementation - return true; + /* this is only used for shader and object space, we don't really have + * a concept of shader space, so we just use object space for both. */ + if (xform) { + const ShaderData *sd = (const ShaderData *)xform; + int object = sd->object; + + if (object != ~0) { +#ifdef __OBJECT_MOTION__ + Transform tfm = sd->ob_tfm; +#else + KernelGlobals *kg = kernel_globals; + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); +#endif + tfm = transform_transpose(tfm); + result = TO_MATRIX44(tfm); + + return true; + } + } + + return false; +} + +bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) +{ + /* this is only used for shader and object space, we don't really have + * a concept of shader space, so we just use object space for both. */ + if (xform) { + const ShaderData *sd = (const ShaderData *)xform; + int object = sd->object; + + if (object != ~0) { +#ifdef __OBJECT_MOTION__ + Transform tfm = sd->ob_itfm; +#else + KernelGlobals *kg = kernel_globals; + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); +#endif + tfm = transform_transpose(tfm); + result = TO_MATRIX44(tfm); + + return true; + } + } + + return false; } bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from) { - // XXX implementation - return true; + KernelGlobals *kg = kernel_globals; + + if (from == u_ndc) { + Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); + result = TO_MATRIX44(tfm); + return true; + } + else if (from == u_raster) { + Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); + result = TO_MATRIX44(tfm); + return true; + } + else if (from == u_screen) { + Transform tfm = transform_transpose(kernel_data.cam.screentoworld); + result = TO_MATRIX44(tfm); + return true; + } + else if (from == u_camera) { + Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); + result = TO_MATRIX44(tfm); + return true; + } + + return false; +} + +bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to) +{ + KernelGlobals *kg = kernel_globals; + + if (to == u_ndc) { + Transform tfm = transform_transpose(kernel_data.cam.worldtondc); + result = TO_MATRIX44(tfm); + return true; + } + else if (to == u_raster) { + Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); + result = TO_MATRIX44(tfm); + return true; + } + else if (to == u_screen) { + Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); + result = TO_MATRIX44(tfm); + return true; + } + else if (to == u_camera) { + Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); + result = TO_MATRIX44(tfm); + return true; + } + + return false; } bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives, @@ -361,6 +464,22 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust return false; } +static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, + TypeDesc type, bool derivatives, void *val) +{ + /* Ray Length */ + if (name == "std::ray_length") { + float fval[3]; + fval[0] = sd->ray_length; + fval[1] = fval[2] = 0.0; /* derivates set to 0 */ + set_attribute_float(fval, type, derivatives, val); + return true; + } + + else + return false; +} + bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val) { @@ -380,8 +499,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri tri = ~0; } else if (object == ~0) { - /* no background attributes supported */ - return false; + return get_background_attribute(kg, sd, name, type, derivatives, val); } /* find attribute on object */ @@ -404,7 +522,12 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri } else { /* not found in attribute, check standard object info */ - return get_object_standard_attribute(kg, sd, name, type, derivatives, val); + bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val); + if (is_std_object_attribute) + return true; + else { + return get_background_attribute(kg, sd, name, type, derivatives, val); + } } return false; diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 790b02a8abc..fa32d47a89f 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -54,7 +54,10 @@ public: bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time); bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform); + bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform); + bool get_matrix(OSL::Matrix44 &result, ustring from); + bool get_inverse_matrix(OSL::Matrix44 &result, ustring from); bool get_array_attribute(void *renderstate, bool derivatives, ustring object, TypeDesc type, ustring name, diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index ea508dcb660..8b71ac30ab6 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -21,6 +21,7 @@ #include "kernel_globals.h" #include "kernel_object.h" +#include "osl_closures.h" #include "osl_services.h" #include "osl_shader.h" @@ -61,10 +62,6 @@ void OSLShader::thread_free(KernelGlobals *kg) /* Globals */ -#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) -#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) -#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) - static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, int path_flag, OSL::ShaderGlobals *globals) { @@ -127,39 +124,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, if (sd->num_closure == MAX_CLOSURE) return; - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim; - ustring scattering = bsdf->scattering(); + CBSDFClosure *bsdf = (CBSDFClosure *)prim; + int scattering = bsdf->scattering(); /* no caustics option */ - if (no_glossy && scattering == OSL::Labels::GLOSSY) + if (no_glossy && scattering == LABEL_GLOSSY) return; /* sample weight */ - float albedo = bsdf->albedo(TO_VEC3(sd->I)); - float sample_weight = fabsf(average(weight)) * albedo; + float sample_weight = fabsf(average(weight)); - sc.sample_weight = sample_weight; + sd->flag |= bsdf->shaderdata_flag(); - /* scattering flags */ - if (scattering == OSL::Labels::DIFFUSE) { - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; - sc.type = CLOSURE_BSDF_DIFFUSE_ID; - } - else if (scattering == OSL::Labels::GLOSSY) { - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; - sc.type = CLOSURE_BSDF_GLOSSY_ID; - } - else if (scattering == OSL::Labels::STRAIGHT) { - sd->flag |= SD_BSDF; - sc.type = CLOSURE_BSDF_TRANSPARENT_ID; - } - else { - /* todo: we don't actually have a way to determine if - * this closure will reflect/transmit. could add our own - * own scattering flag that do give this info */ - sd->flag |= SD_BSDF; - sc.type = CLOSURE_BSDF_GLOSSY_ID; - } + sc.sample_weight = sample_weight; + sc.type = bsdf->shaderclosure_type(); /* add */ sd->closure[sd->num_closure++] = sc; @@ -406,54 +384,34 @@ void OSLShader::release(KernelGlobals *kg, ShaderData *sd) int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf) { - OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim; - int label = LABEL_NONE; + CBSDFClosure *sample_bsdf = (CBSDFClosure *)sc->prim; pdf = 0.0f; - /* sample BSDF closure */ - ustring ulabel; - - ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng), - TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), - randu, randv, - TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), - pdf, TO_COLOR3(eval)); - - /* convert OSL label */ - if (ulabel == OSL::Labels::REFLECT) - label = LABEL_REFLECT; - else if (ulabel == OSL::Labels::TRANSMIT) - label = LABEL_TRANSMIT; - else - return LABEL_NONE; /* sampling failed */ - - /* convert scattering to our bitflag label */ - ustring uscattering = sample_bsdf->scattering(); - - if (uscattering == OSL::Labels::DIFFUSE) - label |= LABEL_DIFFUSE; - else if (uscattering == OSL::Labels::GLOSSY) - label |= LABEL_GLOSSY; - else if (uscattering == OSL::Labels::SINGULAR) - label |= LABEL_SINGULAR; - else - label |= LABEL_TRANSPARENT; - - return label; + return sample_bsdf->sample(sd->Ng, + sd->I, sd->dI.dx, sd->dI.dy, + randu, randv, + omega_in, domega_in.dx, domega_in.dy, + pdf, eval); } float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf) { - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim; - OSL::Color3 bsdf_eval; + CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim; + float3 bsdf_eval; if (dot(sd->Ng, omega_in) >= 0.0f) - bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); + bsdf_eval = bsdf->eval_reflect(sd->I, omega_in, pdf); else - bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); + bsdf_eval = bsdf->eval_transmit(sd->I, omega_in, pdf); - return TO_FLOAT3(bsdf_eval); + return bsdf_eval; +} + +void OSLShader::bsdf_blur(ShaderClosure *sc, float roughness) +{ + CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim; + bsdf->blur(roughness); } /* Emissive Closure */ @@ -468,7 +426,7 @@ float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) /* Volume Closure */ -float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim; OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out)); diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h index e2f4d1e94b8..9ff31e9160b 100644 --- a/intern/cycles/kernel/osl/osl_shader.h +++ b/intern/cycles/kernel/osl/osl_shader.h @@ -72,10 +72,11 @@ public: float3& eval, float3& omega_in, differential3& domega_in, float& pdf); static float3 bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf); + static void bsdf_blur(ShaderClosure *sc, float roughness); static float3 emissive_eval(const ShaderData *sd, const ShaderClosure *sc); - static float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, + static float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out); /* release */ diff --git a/intern/cycles/kernel/osl/vol_subsurface.cpp b/intern/cycles/kernel/osl/vol_subsurface.cpp deleted file mode 100644 index 5845428ed43..00000000000 --- a/intern/cycles/kernel/osl/vol_subsurface.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * 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 Sony Pictures Imageworks 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. - */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -// Computes scattering properties based on Jensen's reparameterization -// described in: -// http://graphics.ucsd.edu/~henrik/papers/fast_bssrdf/ - -class SubsurfaceClosure : public VolumeClosure { -public: - float m_g; - float m_eta; - Color3 m_mfp, m_albedo; - static float root_find_Rd(const float Rd0, const float A) { - // quick exit for trivial cases - if (Rd0 <= 0) return 0; - const float A43 = A * 4.0f / 3.0f; - // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection - // method can be used because this function is monotonicaly increasing. - float lo = 0, hi = 1; - for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient - // eval function at midpoint - float alpha = 0.5f * (lo + hi); - float a1 = sqrtf(3 * (1 - alpha)); - float e1 = expf(-a1); - float e2 = expf(-A43 * a1); - float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0; - if (fabsf(Rd) < 1e-6f) - return alpha; // close enough - else if (Rd > 0) - hi = alpha; // root is on left side - else - lo = alpha; // root is on right side - } - // didn't quite converge, pick result in the middle of remaining interval - return 0.5f * (lo + hi); - } - SubsurfaceClosure() { - } - - void setup() - { - ior(m_eta); - - if (m_g >= 0.99f) m_g = 0.99f; - if (m_g <= -0.99f) m_g = -0.99f; - - // eq.10 - float inv_eta = 1 / m_eta; - float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta; - float A = (1 + Fdr) / (1 - Fdr); - // compute sigma_s, sigma_a (eq.16) - Color3 alpha_prime = Color3(root_find_Rd(m_albedo[0], A), - root_find_Rd(m_albedo[1], A), - root_find_Rd(m_albedo[2], A)); - Color3 sigma_t_prime = Color3(m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f, - m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f, - m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f); - Color3 sigma_s_prime = alpha_prime * sigma_t_prime; - - sigma_s((1.0f / (1 - m_g)) * sigma_s_prime); - sigma_a(sigma_t_prime - sigma_s_prime); - } - - bool mergeable(const ClosurePrimitive *other) const { - const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; - return m_g == comp->m_g && VolumeClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "subsurface"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } - - virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { - float costheta = omega_in.dot(omega_out); - float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f)); - return Color3(ph, ph, ph); - } -}; - - - -ClosureParam *closure_subsurface_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_eta), - CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_g), - CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_mfp), - CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_albedo), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(SubsurfaceClosure) - }; - return params; -} - -CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 5b0f192ea47..698ef5016f0 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -82,6 +82,25 @@ __device_inline void stack_store_float(float *stack, uint a, float f) stack[a] = f; } +__device_inline int stack_load_int(float *stack, uint a) +{ + kernel_assert(a < SVM_STACK_SIZE); + + return __float_as_int(stack[a]); +} + +__device_inline float stack_load_int_default(float *stack, uint a, uint value) +{ + return (a == (uint)SVM_STACK_INVALID)? (int)value: stack_load_int(stack, a); +} + +__device_inline void stack_store_int(float *stack, uint a, int i) +{ + kernel_assert(a < SVM_STACK_SIZE); + + stack[a] = __int_as_float(i); +} + __device_inline bool stack_valid(uint a) { return a != (uint)SVM_STACK_INVALID; @@ -185,7 +204,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT break; } case NODE_CLOSURE_BSDF: - svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag); + svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag, &offset); break; case NODE_CLOSURE_EMISSION: svm_node_closure_emission(sd, stack, node); @@ -261,14 +280,14 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT svm_node_camera(kg, sd, stack, node.y, node.z, node.w); break; case NODE_GEOMETRY: - svm_node_geometry(sd, stack, node.y, node.z); + svm_node_geometry(kg, sd, stack, node.y, node.z); break; #ifdef __EXTRA_NODES__ case NODE_GEOMETRY_BUMP_DX: - svm_node_geometry_bump_dx(sd, stack, node.y, node.z); + svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z); break; case NODE_GEOMETRY_BUMP_DY: - svm_node_geometry_bump_dy(sd, stack, node.y, node.z); + svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z); break; case NODE_LIGHT_PATH: svm_node_light_path(sd, stack, node.y, node.z, path_flag); @@ -334,7 +353,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT svm_node_set_displacement(sd, stack, node.y); break; case NODE_SET_BUMP: - svm_node_set_bump(sd, stack, node.y, node.z, node.w); + svm_node_set_bump(kg, sd, stack, node); break; case NODE_MATH: svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset); @@ -362,6 +381,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_TEX_COORD_BUMP_DY: svm_node_tex_coord_bump_dy(kg, sd, stack, node.y, node.z); break; + case NODE_CLOSURE_SET_NORMAL: + svm_node_set_normal(kg, sd, stack, node.y, node.z ); + break; #endif case NODE_EMISSION_SET_WEIGHT_TOTAL: svm_node_emission_set_weight_total(kg, sd, node.y, node.z, node.w); @@ -376,7 +398,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_LIGHT_FALLOFF: svm_node_light_falloff(sd, stack, node); break; -#endif +#endif case NODE_END: default: #ifndef __MULTI_CLOSURE__ diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h index 411916f8aa0..07c20231d54 100644 --- a/intern/cycles/kernel/svm/svm_bsdf.h +++ b/intern/cycles/kernel/svm/svm_bsdf.h @@ -16,17 +16,17 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "bsdf_ashikhmin_velvet.h" -#include "bsdf_diffuse.h" -#include "bsdf_oren_nayar.h" -#include "bsdf_microfacet.h" -#include "bsdf_reflection.h" -#include "bsdf_refraction.h" -#include "bsdf_transparent.h" +#include "../closure/bsdf_ashikhmin_velvet.h" +#include "../closure/bsdf_diffuse.h" +#include "../closure/bsdf_oren_nayar.h" +#include "../closure/bsdf_microfacet.h" +#include "../closure/bsdf_reflection.h" +#include "../closure/bsdf_refraction.h" +#include "../closure/bsdf_transparent.h" #ifdef __DPDU__ -#include "bsdf_ward.h" +#include "../closure/bsdf_ward.h" #endif -#include "bsdf_westin.h" +#include "../closure/bsdf_westin.h" CCL_NAMESPACE_BEGIN @@ -36,45 +36,57 @@ __device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, floa switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: - label = bsdf_translucent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - label = bsdf_transparent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - label = bsdf_microfacet_ggx_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - label = bsdf_microfacet_beckmann_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #ifdef __DPDU__ case CLOSURE_BSDF_WARD_ID: - label = bsdf_ward_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - label = bsdf_ashikhmin_velvet_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - label = bsdf_westin_backscatter_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_WESTIN_SHEEN_ID: - label = bsdf_westin_sheen_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #endif default: @@ -92,45 +104,45 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con if(dot(sd->Ng, omega_in) >= 0.0f) { switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf); break; #ifdef __DPDU__ case CLOSURE_BSDF_WARD_ID: - eval = bsdf_ward_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf); break; #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - eval = bsdf_westin_backscatter_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_SHEEN_ID: - eval = bsdf_westin_sheen_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf); break; #endif default: @@ -141,45 +153,45 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con else { switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf); break; #ifdef __DPDU__ case CLOSURE_BSDF_WARD_ID: - eval = bsdf_ward_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf); break; #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - eval = bsdf_westin_backscatter_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_SHEEN_ID: - eval = bsdf_westin_sheen_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf); break; #endif default: diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 935504026ef..b72fad26a1f 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -23,16 +23,31 @@ CCL_NAMESPACE_BEGIN __device void svm_node_glossy_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract) { if(type == CLOSURE_BSDF_REFRACTION_ID) { - if(refract) - bsdf_refraction_setup(sd, sc, eta); + if(refract) { + sc->data0 = eta; + sd->flag |= bsdf_refraction_setup(sc); + } else - bsdf_reflection_setup(sd, sc); + sd->flag |= bsdf_reflection_setup(sc); } else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) { - bsdf_microfacet_beckmann_setup(sd, sc, roughness, eta, refract); + sc->data0 = roughness; + sc->data1 = eta; + + if(refract) + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc); + else + sd->flag |= bsdf_microfacet_beckmann_setup(sc); + } + else { + sc->data0 = roughness; + sc->data1 = eta; + + if(refract) + sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc); + else + sd->flag |= bsdf_microfacet_ggx_setup(sc); } - else - bsdf_microfacet_ggx_setup(sd, sc, roughness, eta, refract); } __device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd) @@ -57,7 +72,7 @@ __device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mi #endif } -__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag) +__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag, int *offset) { uint type, param1_offset, param2_offset; @@ -66,11 +81,19 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); + /* note we read this extra node before weight check, so offset is added */ + uint4 data_node = read_node(kg, offset); + if(mix_weight == 0.0f) return; + + float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; #else decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, NULL); float mix_weight = 1.0f; + + uint4 data_node = read_node(kg, offset); + float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; #endif float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __int_as_float(node.z); @@ -79,25 +102,32 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st switch(type) { case CLOSURE_BSDF_DIFFUSE_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); float roughness = param1; - if(roughness == 0.0f) - bsdf_diffuse_setup(sd, sc); - else - bsdf_oren_nayar_setup(sd, sc, roughness); + + if(roughness == 0.0f) { + sd->flag |= bsdf_diffuse_setup(sc); + } + else { + sc->data0 = roughness; + sd->flag |= bsdf_oren_nayar_setup(sc); + } break; } case CLOSURE_BSDF_TRANSLUCENT_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); - bsdf_translucent_setup(sd, sc); + sd->flag |= bsdf_translucent_setup(sc); break; } case CLOSURE_BSDF_TRANSPARENT_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); - bsdf_transparent_setup(sd, sc); + sd->flag |= bsdf_transparent_setup(sc); break; } case CLOSURE_BSDF_REFLECTION_ID: @@ -108,17 +138,17 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; #endif ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; + sc->data0 = param1; svm_node_closure_set_mix_weight(sc, mix_weight); - float roughness = param1; - /* setup bsdf */ if(type == CLOSURE_BSDF_REFLECTION_ID) - bsdf_reflection_setup(sd, sc); + sd->flag |= bsdf_reflection_setup(sc); else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) - bsdf_microfacet_beckmann_setup(sd, sc, roughness, 1.0f, false); + sd->flag |= bsdf_microfacet_beckmann_setup(sc); else - bsdf_microfacet_ggx_setup(sd, sc, roughness, 1.0f, false); + sd->flag |= bsdf_microfacet_ggx_setup(sc); break; } @@ -134,13 +164,14 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; /* fresnel */ - float cosNO = dot(sd->N, sd->I); + float cosNO = dot(N, sd->I); float fresnel = fresnel_dielectric_cos(cosNO, eta); float roughness = param1; #ifdef __MULTI_CLOSURE__ /* reflection */ ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; float3 weight = sc->weight; float sample_weight = sc->sample_weight; @@ -150,6 +181,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st /* refraction */ sc = svm_node_closure_get(sd); + sc->N = N; sc->weight = weight; sc->sample_weight = sample_weight; @@ -158,6 +190,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st svm_node_glossy_setup(sd, sc, type, eta, roughness, true); #else ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; bool refract = (randb > fresnel); @@ -174,22 +207,25 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; #endif ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; + sc->T = stack_load_float3(stack, data_node.z); svm_node_closure_set_mix_weight(sc, mix_weight); - float roughness_u = param1; - float roughness_v = param2; + sc->data0 = param1; + sc->data1 = param2; - bsdf_ward_setup(sd, sc, normalize(sd->dPdu), roughness_u, roughness_v); + sd->flag |= bsdf_ward_setup(sc); break; } #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); /* sigma */ - float sigma = clamp(param1, 0.0f, 1.0f); - bsdf_ashikhmin_velvet_setup(sd, sc, sigma); + sc->data0 = clamp(param1, 0.0f, 1.0f); + sd->flag |= bsdf_ashikhmin_velvet_setup(sc); break; } default: @@ -222,7 +258,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * svm_node_closure_set_mix_weight(sc, mix_weight); float density = param1; - volume_transparent_setup(sd, sc, density); + sd->flag |= volume_transparent_setup(sc, density); break; } case CLOSURE_VOLUME_ISOTROPIC_ID: { @@ -230,7 +266,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * svm_node_closure_set_mix_weight(sc, mix_weight); float density = param1; - volume_isotropic_setup(sd, sc, density); + sd->flag |= volume_isotropic_setup(sc, density); break; } default: @@ -425,5 +461,14 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused, #endif } +/* (Bump) normal */ + +__device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) +{ + float3 normal = stack_load_float3(stack, in_direction); + sd->N = normal; + stack_store_float3(stack, out_normal, normal); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h index 188b0489d9e..f74915a4bc9 100644 --- a/intern/cycles/kernel/svm/svm_convert.h +++ b/intern/cycles/kernel/svm/svm_convert.h @@ -23,6 +23,11 @@ CCL_NAMESPACE_BEGIN __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to) { switch(type) { + case NODE_CONVERT_FI: { + float f = stack_load_float(stack, from); + stack_store_int(stack, to, (int)f); + break; + } case NODE_CONVERT_FV: { float f = stack_load_float(stack, from); stack_store_float3(stack, to, make_float3(f, f, f)); @@ -34,13 +39,34 @@ __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint fro stack_store_float(stack, to, g); break; } + case NODE_CONVERT_CI: { + float3 f = stack_load_float3(stack, from); + int i = (int)linear_rgb_to_gray(f); + stack_store_int(stack, to, i); + break; + } case NODE_CONVERT_VF: { float3 f = stack_load_float3(stack, from); float g = (f.x + f.y + f.z)*(1.0f/3.0f); stack_store_float(stack, to, g); break; } - + case NODE_CONVERT_VI: { + float3 f = stack_load_float3(stack, from); + int i = (f.x + f.y + f.z)*(1.0f/3.0f); + stack_store_int(stack, to, i); + break; + } + case NODE_CONVERT_IF: { + float f = (float)stack_load_int(stack, from); + stack_store_float(stack, to, f); + break; + } + case NODE_CONVERT_IV: { + float f = (float)stack_load_int(stack, from); + stack_store_float3(stack, to, make_float3(f, f, f)); + break; + } } } diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index b1677f67eca..92f23990ad1 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -20,23 +20,35 @@ CCL_NAMESPACE_BEGIN /* Bump Node */ -__device void svm_node_set_bump(ShaderData *sd, float *stack, uint c_offset, uint x_offset, uint y_offset) +__device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { #ifdef __RAY_DIFFERENTIALS__ + /* get normal input */ + float3 normal_in = stack_valid(node.y)? stack_load_float3(stack, node.y): sd->N; + + /* get surface tangents from normal */ + float3 Rx = cross(sd->dP.dy, normal_in); + float3 Ry = cross(normal_in, sd->dP.dx); + + /* get bump values */ + uint c_offset, x_offset, y_offset, intensity_offset; + decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &intensity_offset); + float h_c = stack_load_float(stack, c_offset); float h_x = stack_load_float(stack, x_offset); float h_y = stack_load_float(stack, y_offset); - float3 Rx = cross(sd->dP.dy, sd->N); - float3 Ry = cross(sd->N, sd->dP.dx); - + /* compute surface gradient and determinant */ float det = dot(sd->dP.dx, Rx); float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry; + float intensity = stack_load_float(stack, intensity_offset); - surfgrad *= 0.1f; /* todo: remove this factor */ - + surfgrad *= intensity; float absdet = fabsf(det); - sd->N = normalize(absdet*sd->N - signf(det)*surfgrad); + + /* compute and output perturbed normal */ + float3 outN = normalize(absdet*normal_in - signf(det)*surfgrad); + stack_store_float3(stack, node.w, outN); #endif } diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h index 7684eabeecb..d5b415a87ce 100644 --- a/intern/cycles/kernel/svm/svm_fresnel.h +++ b/intern/cycles/kernel/svm/svm_fresnel.h @@ -54,7 +54,7 @@ __device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node) f = fabsf(dot(sd->I, sd->N)); if(blend != 0.5f) { - blend = clamp(blend, 0.0f, 1.0f); + blend = clamp(blend, 0.0f, 1.0f-1e-5f); blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend); f = powf(f, blend); diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 22741bdb067..e0f9e337652 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -20,7 +20,23 @@ CCL_NAMESPACE_BEGIN /* Geometry Node */ -__device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint out_offset) +__device_inline float3 svm_tangent_from_generated(float3 P) +{ + float length = len(P); + + if(length == 0.0f) + return make_float3(0.0f, 0.0f, 0.0f); + + float u = 0.0f; + if(!(P.x == 0.0f && P.y == 0.0f)) + u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F); + + float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F; + + return make_float3(u, v, 0.0f); +} + +__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; @@ -28,7 +44,31 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou case NODE_GEOM_P: data = sd->P; break; case NODE_GEOM_N: data = sd->N; break; #ifdef __DPDU__ - case NODE_GEOM_T: data = normalize(sd->dPdu); break; + case NODE_GEOM_T: { + if(sd->object != ~0) { + int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT); + + if(attr_offset != ATTR_STD_NOT_FOUND) { + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + object_normal_transform(kg, sd, &data); + } + else { + attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED); + + if(attr_offset != ATTR_STD_NOT_FOUND) { + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + svm_tangent_from_generated(data); + object_normal_transform(kg, sd, &data); + } + else + data = normalize(sd->dPdu); + } + } + else + data = normalize(sd->dPdu); + + break; + } #endif case NODE_GEOM_I: data = sd->I; break; case NODE_GEOM_Ng: data = sd->Ng; break; @@ -40,7 +80,7 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou stack_store_float3(stack, out_offset, data); } -__device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -48,16 +88,16 @@ __device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, switch(type) { case NODE_GEOM_P: data = sd->P + sd->dP.dx; break; case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); break; - default: svm_node_geometry(sd, stack, type, out_offset); return; + default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } -__device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -65,12 +105,12 @@ __device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, switch(type) { case NODE_GEOM_P: data = sd->P + sd->dP.dy; break; case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); break; - default: svm_node_geometry(sd, stack, type, out_offset); return; + default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index ee423573cdf..77df373a159 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -92,7 +92,8 @@ typedef enum NodeType { NODE_LIGHT_FALLOFF, NODE_OBJECT_INFO, NODE_PARTICLE_INFO, - NODE_TEX_BRICK + NODE_TEX_BRICK, + NODE_CLOSURE_SET_NORMAL, } NodeType; typedef enum NodeAttributeType { @@ -209,8 +210,13 @@ typedef enum NodeVectorMath { typedef enum NodeConvert { NODE_CONVERT_FV, + NODE_CONVERT_FI, NODE_CONVERT_CF, - NODE_CONVERT_VF + NODE_CONVERT_CI, + NODE_CONVERT_VF, + NODE_CONVERT_VI, + NODE_CONVERT_IF, + NODE_CONVERT_IV } NodeConvert; typedef enum NodeDistanceMetric { diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index e75a3b37f3b..7907061c19c 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -8,6 +8,7 @@ set(INC ../bvh ../util ) + set(INC_SYS ${GLEW_INCLUDE_PATH} ) diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 5122c1af410..4bcaef0fb17 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -162,6 +162,8 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) attr = add(name, TypeDesc::TypeNormal, Attribute::FACE); else if(std == ATTR_STD_UV) attr = add(name, TypeDesc::TypePoint, Attribute::CORNER); + else if(std == ATTR_STD_TANGENT) + attr = add(name, TypeDesc::TypeVector, Attribute::VERTEX); else if(std == ATTR_STD_GENERATED) attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX); else if(std == ATTR_STD_POSITION_UNDEFORMED) diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 3fd7a1b28e3..649936bec04 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -19,6 +19,8 @@ #include "camera.h" #include "scene.h" +#include "device.h" + #include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -141,7 +143,7 @@ void Camera::update() void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - Scene::MotionType need_motion = scene->need_motion(); + Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); update(); @@ -160,7 +162,6 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) /* store matrices */ kcam->screentoworld = screentoworld; kcam->rastertoworld = rastertoworld; - kcam->ndctoworld = ndctoworld; kcam->rastertocamera = rastertocamera; kcam->cameratoworld = cameratoworld; kcam->worldtoscreen = transform_inverse(screentoworld); @@ -193,13 +194,14 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) } } } +#ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { - /* todo: exact camera position will not be hit this way */ if(use_motion) { - transform_motion_decompose(&kcam->motion, &motion); + transform_motion_decompose(&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } } +#endif /* depth of field */ kcam->aperturesize = aperturesize; @@ -208,7 +210,11 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) kcam->bladesrotation = bladesrotation; /* motion blur */ +#ifdef __CAMERA_MOTION__ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: 0.0f; +#else + kcam->shuttertime = 0.0f; +#endif /* type */ kcam->type = type; @@ -268,13 +274,17 @@ bool Camera::modified(const Camera& cam) (border_bottom == cam.border_bottom) && (border_top == cam.border_top) && (matrix == cam.matrix) && - (motion == cam.motion) && - (use_motion == cam.use_motion) && (panorama_type == cam.panorama_type) && (fisheye_fov == cam.fisheye_fov) && (fisheye_lens == cam.fisheye_lens)); } +bool Camera::motion_modified(const Camera& cam) +{ + return !((motion == cam.motion) && + (use_motion == cam.use_motion)); +} + void Camera::tag_update() { need_update = true; diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 82852bde5e0..1407c86e7c2 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -103,6 +103,7 @@ public: void device_free(Device *device, DeviceScene *dscene); bool modified(const Camera& cam); + bool motion_modified(const Camera& cam); void tag_update(); }; diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 62758128a73..c1c976dc193 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -229,6 +229,8 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl) if(!finalized) { clean(); default_inputs(do_osl); + refine_bump_nodes(); + if(do_bump) bump_from_displacement(); @@ -468,6 +470,12 @@ void ShaderGraph::default_inputs(bool do_osl) connect(geom->output("Position"), input); } + else if(input->default_value == ShaderInput::TANGENT) { + if(!geom) + geom = new GeometryNode(); + + connect(geom->output("Tangent"), input); + } } } } @@ -478,6 +486,61 @@ void ShaderGraph::default_inputs(bool do_osl) add(texco); } +void ShaderGraph::refine_bump_nodes() +{ + /* we transverse the node graph looking for bump nodes, when we find them, + * like in bump_from_displacement(), we copy the sub-graph defined from "bump" + * input to the inputs "center","dx" and "dy" What is in "bump" input is moved + * to "center" input. */ + + foreach(ShaderNode *node, nodes) { + if(node->name == ustring("bump") && node->input("Height")->link) { + ShaderInput *bump_input = node->input("Height"); + set<ShaderNode*> nodes_bump; + + /* make 2 extra copies of the subgraph defined in Bump input */ + map<ShaderNode*, ShaderNode*> nodes_dx; + map<ShaderNode*, ShaderNode*> nodes_dy; + + /* find dependencies for the given input */ + find_dependencies(nodes_bump, bump_input ); + + copy_nodes(nodes_bump, nodes_dx); + copy_nodes(nodes_bump, nodes_dy); + + /* mark nodes to indicate they are use for bump computation, so + that any texture coordinates are shifted by dx/dy when sampling */ + foreach(ShaderNode *node, nodes_bump) + node->bump = SHADER_BUMP_CENTER; + foreach(NodePair& pair, nodes_dx) + pair.second->bump = SHADER_BUMP_DX; + foreach(NodePair& pair, nodes_dy) + pair.second->bump = SHADER_BUMP_DY; + + ShaderOutput *out = bump_input->link; + ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name); + ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name); + + connect(out_dx, node->input("SampleX")); + connect(out_dy, node->input("SampleY")); + + /* add generated nodes */ + foreach(NodePair& pair, nodes_dx) + add(pair.second); + foreach(NodePair& pair, nodes_dy) + add(pair.second); + + /* connect what is conected is bump to samplecenter input*/ + connect(out , node->input("SampleCenter")); + + /* bump input is just for connectivity purpose for the graph input, + * we reconected this input to samplecenter, so lets disconnect it + * from bump input */ + disconnect(bump_input); + } + } +} + void ShaderGraph::bump_from_displacement() { /* generate bump mapping automatically from displacement. bump mapping is @@ -491,7 +554,7 @@ void ShaderGraph::bump_from_displacement() * different shifted coordinates. * * these 3 displacement values are then fed into the bump node, which will - * modify the normal. */ + * output the the perturbed normal. */ ShaderInput *displacement_in = output()->input("Displacement"); @@ -520,6 +583,12 @@ void ShaderGraph::bump_from_displacement() foreach(NodePair& pair, nodes_dy) pair.second->bump = SHADER_BUMP_DY; + /* add set normal node and connect the bump normal ouput to the set normal + * output, so it can finally set the shader normal, note we are only doing + * this for bump from displacement, this will be the only bump allowed to + * overwrite the shader normal */ + ShaderNode *set_normal = add(new SetNormalNode()); + /* add bump node and connect copied graphs to it */ ShaderNode *bump = add(new BumpNode()); @@ -531,6 +600,9 @@ void ShaderGraph::bump_from_displacement() connect(out_center, bump->input("SampleCenter")); connect(out_dx, bump->input("SampleX")); connect(out_dy, bump->input("SampleY")); + + /* connect the bump out to the set normal in: */ + connect(bump->output("Normal"), set_normal->input("Direction")); /* connect bump output to normal input nodes that aren't set yet. actually * this will only set the normal input to the geometry node that we created @@ -538,8 +610,14 @@ void ShaderGraph::bump_from_displacement() foreach(ShaderNode *node, nodes) foreach(ShaderInput *input, node->inputs) if(!input->link && input->default_value == ShaderInput::NORMAL) - connect(bump->output("Normal"), input); - + connect(set_normal->output("Normal"), input); + + /* for displacement bump, clear the normal input in case the above loop + * connected the setnormal out to the bump normalin */ + ShaderInput *bump_normal_in = bump->input("NormalIn"); + if(bump_normal_in) + bump_normal_in->link = NULL; + /* finally, add the copied nodes to the graph. we can't do this earlier * because we would create dependency cycles in the above loop */ foreach(NodePair& pair, nodes_center) diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index c3b674d0f23..b339c3c3847 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -44,6 +44,7 @@ class OSLCompiler; enum ShaderSocketType { SHADER_SOCKET_FLOAT, + SHADER_SOCKET_INT, SHADER_SOCKET_COLOR, SHADER_SOCKET_VECTOR, SHADER_SOCKET_POINT, @@ -112,6 +113,7 @@ public: INCOMING, NORMAL, POSITION, + TANGENT, NONE }; @@ -234,6 +236,7 @@ protected: void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack); void clean(); void bump_from_displacement(); + void refine_bump_nodes(); void default_inputs(bool do_osl); }; diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 5c1737bd60a..d77516a1b18 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -68,20 +68,15 @@ static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, main_task.shader_w = width*height; /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */ -#if 0 list<DeviceTask> split_tasks; main_task.split_max_size(split_tasks, 128*128); foreach(DeviceTask& task, split_tasks) { device->task_add(task); device->task_wait(); + device->mem_copy_from(d_output, task.shader_x, 1, task.shader_w, sizeof(float4)); } -#else - device->task_add(main_task); - device->task_wait(); -#endif - device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); device->mem_free(d_input); device->mem_free(d_output); diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 7037e36f313..3c41b4f1ad3 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -19,6 +19,7 @@ #include "bvh.h" #include "bvh_build.h" +#include "camera.h" #include "device.h" #include "shader.h" #include "light.h" @@ -722,10 +723,16 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen foreach(Shader *shader, scene->shaders) shader->need_update_attributes = false; - bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR; + float shuttertime = scene->camera->shuttertime; +#ifdef __OBJECT_MOTION__ + Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); + bool motion_blur = need_motion == Scene::MOTION_BLUR; +#else + bool motion_blur = false; +#endif foreach(Object *object, scene->objects) - object->compute_bounds(motion_blur); + object->compute_bounds(motion_blur, shuttertime); if(progress.get_cancel()) return; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 4e16eea2774..76267e9d014 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1065,6 +1065,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) if(from == SHADER_SOCKET_FLOAT) add_input("Val", SHADER_SOCKET_FLOAT); + else if(from == SHADER_SOCKET_INT) + add_input("ValInt", SHADER_SOCKET_INT); else if(from == SHADER_SOCKET_COLOR) add_input("Color", SHADER_SOCKET_COLOR); else if(from == SHADER_SOCKET_VECTOR) @@ -1078,6 +1080,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) if(to == SHADER_SOCKET_FLOAT) add_output("Val", SHADER_SOCKET_FLOAT); + else if(to == SHADER_SOCKET_INT) + add_output("ValInt", SHADER_SOCKET_INT); else if(to == SHADER_SOCKET_COLOR) add_output("Color", SHADER_SOCKET_COLOR); else if(to == SHADER_SOCKET_VECTOR) @@ -1095,10 +1099,29 @@ void ConvertNode::compile(SVMCompiler& compiler) ShaderInput *in = inputs[0]; ShaderOutput *out = outputs[0]; - if(to == SHADER_SOCKET_FLOAT) { + if(from == SHADER_SOCKET_FLOAT) { compiler.stack_assign(in); compiler.stack_assign(out); + if(to == SHADER_SOCKET_INT) + /* float to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, in->stack_offset, out->stack_offset); + else + /* float to float3 */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); + } + else if(from == SHADER_SOCKET_INT) { + compiler.stack_assign(in); + compiler.stack_assign(out); + + if(to == SHADER_SOCKET_FLOAT) + /* int to float */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, in->stack_offset, out->stack_offset); + else + /* int to vector/point/normal */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, in->stack_offset, out->stack_offset); + } + else if(to == SHADER_SOCKET_FLOAT) { if(from == SHADER_SOCKET_COLOR) /* color to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, in->stack_offset, out->stack_offset); @@ -1106,12 +1129,13 @@ void ConvertNode::compile(SVMCompiler& compiler) /* vector/point/normal to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset); } - else if(from == SHADER_SOCKET_FLOAT) { - compiler.stack_assign(in); - compiler.stack_assign(out); - - /* float to float3 */ - compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); + else if(to == SHADER_SOCKET_INT) { + if(from == SHADER_SOCKET_COLOR) + /* color to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, in->stack_offset, out->stack_offset); + else + /* vector/point/normal to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, in->stack_offset, out->stack_offset); } else { /* float3 to float3 */ @@ -1134,6 +1158,8 @@ void ConvertNode::compile(OSLCompiler& compiler) { if(from == SHADER_SOCKET_FLOAT) compiler.add(this, "node_convert_from_float"); + else if(from == SHADER_SOCKET_INT) + compiler.add(this, "node_convert_from_int"); else if(from == SHADER_SOCKET_COLOR) compiler.add(this, "node_convert_from_color"); else if(from == SHADER_SOCKET_VECTOR) @@ -1175,7 +1201,7 @@ BsdfNode::BsdfNode() closure = ccl::CLOSURE_BSDF_DIFFUSE_ID; add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); add_output("BSDF", SHADER_SOCKET_CLOSURE); } @@ -1183,6 +1209,8 @@ BsdfNode::BsdfNode() void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2) { ShaderInput *color_in = input("Color"); + ShaderInput *normal_in = input("Normal"); + ShaderInput *tangent_in = input("Tangent"); if(color_in->link) { compiler.stack_assign(color_in); @@ -1203,6 +1231,19 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * compiler.closure_mix_weight_offset()), __float_as_int((param1)? param1->value.x: 0.0f), __float_as_int((param2)? param2->value.x: 0.0f)); + + if(normal_in->link) + compiler.stack_assign(normal_in); + + if(tangent_in) { + if(tangent_in->link) + compiler.stack_assign(tangent_in); + + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset); + } + else { + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset); + } } void BsdfNode::compile(SVMCompiler& compiler) @@ -1221,10 +1262,24 @@ WardBsdfNode::WardBsdfNode() { closure = CLOSURE_BSDF_WARD_ID; + add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); + add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f); add_input("Roughness V", SHADER_SOCKET_FLOAT, 0.2f); } +void WardBsdfNode::attributes(AttributeRequestSet *attributes) +{ + ShaderInput *tangent_in = input("Tangent"); + + if(!tangent_in->link) { + attributes->add(ATTR_STD_TANGENT); + attributes->add(ATTR_STD_GENERATED); + } + + ShaderNode::attributes(attributes); +} + void WardBsdfNode::compile(SVMCompiler& compiler) { BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V")); @@ -1566,6 +1621,16 @@ GeometryNode::GeometryNode() add_output("Backfacing", SHADER_SOCKET_FLOAT); } +void GeometryNode::attributes(AttributeRequestSet *attributes) +{ + if(!output("Tangent")->links.empty()) { + attributes->add(ATTR_STD_TANGENT); + attributes->add(ATTR_STD_GENERATED); + } + + ShaderNode::attributes(attributes); +} + void GeometryNode::compile(SVMCompiler& compiler) { ShaderOutput *out; @@ -2184,7 +2249,7 @@ static ShaderEnum mix_type_init() enm.insert("Burn", NODE_MIX_BURN); enm.insert("Hue", NODE_MIX_HUE); enm.insert("Saturation", NODE_MIX_SAT); - enm.insert("Value", NODE_MIX_VAL ); + enm.insert("Value", NODE_MIX_VAL); enm.insert("Color", NODE_MIX_COLOR); enm.insert("Soft Light", NODE_MIX_SOFT); enm.insert("Linear Light", NODE_MIX_LINEAR); @@ -2544,7 +2609,7 @@ void LayerWeightNode::compile(SVMCompiler& compiler) void LayerWeightNode::compile(OSLCompiler& compiler) { - compiler.add(this, "node_blend_weight"); + compiler.add(this, "node_layer_weight"); } /* Output */ @@ -2555,6 +2620,7 @@ OutputNode::OutputNode() add_input("Surface", SHADER_SOCKET_CLOSURE); add_input("Volume", SHADER_SOCKET_CLOSURE); add_input("Displacement", SHADER_SOCKET_FLOAT); + add_input("Normal", SHADER_SOCKET_NORMAL); } void OutputNode::compile(SVMCompiler& compiler) @@ -2702,9 +2768,15 @@ void VectorMathNode::compile(OSLCompiler& compiler) BumpNode::BumpNode() : ShaderNode("bump") { + /* this input is used by the user, but after graph transform it is no longer + * used and moved to sampler center/x/y instead */ + add_input("Height", SHADER_SOCKET_NORMAL); + add_input("SampleCenter", SHADER_SOCKET_FLOAT); add_input("SampleX", SHADER_SOCKET_FLOAT); add_input("SampleY", SHADER_SOCKET_FLOAT); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); + add_input("Strength", SHADER_SOCKET_FLOAT, 0.1f); add_output("Normal", SHADER_SOCKET_NORMAL); } @@ -2714,12 +2786,25 @@ void BumpNode::compile(SVMCompiler& compiler) ShaderInput *center_in = input("SampleCenter"); ShaderInput *dx_in = input("SampleX"); ShaderInput *dy_in = input("SampleY"); + ShaderInput *normal_in = input("NormalIn"); + ShaderInput *intensity_in = input("Strength"); + ShaderOutput *normal_out = output("Normal"); compiler.stack_assign(center_in); compiler.stack_assign(dx_in); compiler.stack_assign(dy_in); + compiler.stack_assign(intensity_in); + compiler.stack_assign(normal_out); - compiler.add_node(NODE_SET_BUMP, center_in->stack_offset, dx_in->stack_offset, dy_in->stack_offset); + if(normal_in->link) + compiler.stack_assign(normal_in); + + /* pack all parameters in the node */ + compiler.add_node(NODE_SET_BUMP, + normal_in->stack_offset, + compiler.encode_uchar4(center_in->stack_offset, dx_in->stack_offset, + dy_in->stack_offset, intensity_in->stack_offset), + normal_out->stack_offset); } void BumpNode::compile(OSLCompiler& compiler) @@ -2788,17 +2873,44 @@ void RGBRampNode::compile(OSLCompiler& compiler) /* NB: cycles float3 type is actually 4 floats! need to use an explicit array */ float ramp_color[RAMP_TABLE_SIZE][3]; float ramp_alpha[RAMP_TABLE_SIZE]; + for (int i = 0; i < RAMP_TABLE_SIZE; ++i) { ramp_color[i][0] = ramp[i].x; ramp_color[i][1] = ramp[i].y; ramp_color[i][2] = ramp[i].z; ramp_alpha[i] = ramp[i].w; } + compiler.parameter_color_array("ramp_color", ramp_color, RAMP_TABLE_SIZE); compiler.parameter_array("ramp_alpha", ramp_alpha, RAMP_TABLE_SIZE); compiler.add(this, "node_rgb_ramp"); } +/* Set Normal Node */ + +SetNormalNode::SetNormalNode() +: ShaderNode("set_normal") +{ + add_input("Direction", SHADER_SOCKET_VECTOR); + add_output("Normal", SHADER_SOCKET_NORMAL); +} + +void SetNormalNode::compile(SVMCompiler& compiler) +{ + ShaderInput *direction_in = input("Direction"); + ShaderOutput *normal_out = output("Normal"); + + compiler.stack_assign(direction_in); + compiler.stack_assign(normal_out); + + compiler.add_node(NODE_CLOSURE_SET_NORMAL, direction_in->stack_offset, normal_out->stack_offset); +} + +void SetNormalNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "set_normal"); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index e8e584dd8ef..fbc61e12fd4 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -201,6 +201,7 @@ public: class WardBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(WardBsdfNode) + void attributes(AttributeRequestSet *attributes); }; class DiffuseBsdfNode : public BsdfNode { @@ -278,6 +279,7 @@ public: class GeometryNode : public ShaderNode { public: SHADER_NODE_CLASS(GeometryNode) + void attributes(AttributeRequestSet *attributes); }; class TextureCoordinateNode : public ShaderNode { @@ -438,6 +440,11 @@ public: float4 ramp[RAMP_TABLE_SIZE]; }; +class SetNormalNode : public ShaderNode { +public: + SHADER_NODE_CLASS(SetNormalNode) +}; + CCL_NAMESPACE_END #endif /* __NODES_H__ */ diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index d78a82d589a..25b4d1f08cc 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -51,20 +51,23 @@ Object::~Object() { } -void Object::compute_bounds(bool motion_blur) +void Object::compute_bounds(bool motion_blur, float shuttertime) { BoundBox mbounds = mesh->bounds; if(motion_blur && use_motion) { MotionTransform decomp; - transform_motion_decompose(&decomp, &motion); + transform_motion_decompose(&decomp, &motion, &tfm); bounds = BoundBox::empty; /* todo: this is really terrible. according to pbrt there is a better * way to find this iteratively, but did not find implementation yet * or try to implement myself */ - for(float t = 0.0f; t < 1.0f; t += 1.0f/128.0f) { + float start_t = 0.5f - shuttertime*0.25f; + float end_t = 0.5f + shuttertime*0.25f; + + for(float t = start_t; t < end_t; t += (1.0f/128.0f)*shuttertime) { Transform ttfm; transform_motion_interpolate(&ttfm, &decomp, t); @@ -109,7 +112,7 @@ void Object::apply_transform() if(bounds.valid()) { mesh->compute_bounds(); - compute_bounds(false); + compute_bounds(false, 0.0f); } /* tfm is not reset to identity, all code that uses it needs to check the @@ -151,7 +154,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene uint *object_flag = dscene->object_flag.resize(scene->objects.size()); int i = 0; map<Mesh*, float> surface_area_map; - Scene::MotionType need_motion = scene->need_motion(); + Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); + bool have_motion = false; foreach(Object *ob, scene->objects) { Mesh *mesh = ob->mesh; @@ -218,26 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene mtfm_post = mtfm_post * itfm; memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4); - memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4); + memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4); } +#ifdef __OBJECT_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(ob->use_motion) { /* decompose transformations for interpolation */ MotionTransform decomp; - transform_motion_decompose(&decomp, &ob->motion); - memcpy(&objects[offset+8], &decomp, sizeof(float4)*8); + transform_motion_decompose(&decomp, &ob->motion, &ob->tfm); + memcpy(&objects[offset+8], &decomp, sizeof(float4)*12); flag |= SD_OBJECT_MOTION; + have_motion = true; } else { float4 no_motion = make_float4(FLT_MAX); - memcpy(&objects[offset+8], &no_motion, sizeof(float4)); + memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12); } } +#endif /* dupli object coords */ - objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); - objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); + objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); + objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); /* object flag */ if(ob->use_holdout) @@ -251,6 +258,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene device->tex_alloc("__objects", dscene->objects); device->tex_alloc("__object_flag", dscene->object_flag); + + dscene->data.bvh.have_motion = have_motion; } void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) @@ -297,7 +306,12 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress) /* counter mesh users */ map<Mesh*, int> mesh_users; - bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR; +#ifdef __OBJECT_MOTION__ + Scene::MotionType need_motion = scene->need_motion(); + bool motion_blur = need_motion == Scene::MOTION_BLUR; +#else + bool motion_blur = false; +#endif foreach(Object *object, scene->objects) { map<Mesh*, int>::iterator it = mesh_users.find(object->mesh); diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index e2c3ad4e071..922c886d961 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -59,7 +59,7 @@ public: void tag_update(Scene *scene); - void compute_bounds(bool motion_blur); + void compute_bounds(bool motion_blur, float shuttertime); void apply_transform(); }; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 6d23097d7a8..21e6c7749b8 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -206,6 +206,8 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) return true; if(strcmp(input->name, "Displacement") == 0 && current_type != SHADER_TYPE_DISPLACEMENT) return true; + if(strcmp(input->name, "Normal") == 0) + return true; } else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->name == ustring("bump")) return true; @@ -244,6 +246,9 @@ void OSLCompiler::add(ShaderNode *node, const char *name) case SHADER_SOCKET_FLOAT: parameter(param_name.c_str(), input->value.x); break; + case SHADER_SOCKET_INT: + parameter(param_name.c_str(), (int)input->value.x); + break; case SHADER_SOCKET_CLOSURE: break; } diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 071338d49c2..15031b9500c 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -183,10 +183,10 @@ void Scene::device_update(Device *device_, Progress& progress) device->const_copy_to("__data", &dscene.data, sizeof(dscene.data)); } -Scene::MotionType Scene::need_motion() +Scene::MotionType Scene::need_motion(bool advanced_shading) { if(integrator->motion_blur) - return MOTION_BLUR; + return (advanced_shading)? MOTION_BLUR: MOTION_NONE; else if(Pass::contains(film->passes, PASS_MOTION)) return MOTION_PASS; else diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 09087fb2970..bd45c1c04e6 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -194,7 +194,7 @@ public: void need_global_attributes(AttributeRequestSet& attributes); enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR }; - MotionType need_motion(); + MotionType need_motion(bool advanced_shading = true); bool need_update(); bool need_reset(); diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index cd410e4e011..65b20f1dd2c 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -96,6 +96,9 @@ Session::~Session() display->write(device, params.output_path); } + foreach(RenderBuffers *buffers, tile_buffers) + delete buffers; + delete buffers; delete display; delete scene; @@ -173,6 +176,8 @@ bool Session::draw_gpu(BufferParams& buffer_params) void Session::run_gpu() { + bool tiles_written = false; + start_time = time_dt(); reset_time = time_dt(); paused_time = 0.0; @@ -267,10 +272,15 @@ void Session::run_gpu() if(device->error_message() != "") progress.set_cancel(device->error_message()); + tiles_written = update_progressive_refine(progress.get_cancel()); + if(progress.get_cancel()) break; } } + + if(!tiles_written) + update_progressive_refine(true); } /* CPU Session */ @@ -313,8 +323,12 @@ bool Session::draw_cpu(BufferParams& buffer_params) bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) { - if(progress.get_cancel()) - return false; + if(progress.get_cancel()) { + if(params.progressive_refine == false) { + /* for progressive refine current sample should be finished for all tiles */ + return false; + } + } thread_scoped_lock tile_lock(tile_mutex); @@ -338,7 +352,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) /* in case of a permant buffer, return it, otherwise we will allocate * a new temporary buffer */ - if(!write_render_tile_cb) { + if(!params.background) { tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride); rtile.buffer = buffers->buffer.device_pointer; @@ -360,9 +374,35 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) buffer_params.get_offset_stride(rtile.offset, rtile.stride); - /* allocate buffers */ RenderBuffers *tilebuffers = new RenderBuffers(tile_device); - tilebuffers->reset(tile_device, buffer_params); + + /* allocate buffers */ + if(params.progressive_refine) { + int tile_x = rtile.x / params.tile_size.x; + int tile_y = rtile.y / params.tile_size.y; + + int tile_index = tile_y * tile_manager.state.tile_w + tile_x; + + tile_lock.lock(); + + if(tile_buffers.size() == 0) + tile_buffers.resize(tile_manager.state.num_tiles, NULL); + + tilebuffers = tile_buffers[tile_index]; + if(tilebuffers == NULL) { + tilebuffers = new RenderBuffers(tile_device); + tile_buffers[tile_index] = tilebuffers; + + tilebuffers->reset(tile_device, buffer_params); + } + + tile_lock.unlock(); + } + else { + tilebuffers = new RenderBuffers(tile_device); + + tilebuffers->reset(tile_device, buffer_params); + } rtile.buffer = tilebuffers->buffer.device_pointer; rtile.rng_state = tilebuffers->rng_state.device_pointer; @@ -377,9 +417,11 @@ void Session::update_tile_sample(RenderTile& rtile) thread_scoped_lock tile_lock(tile_mutex); if(update_render_tile_cb) { - /* todo: optimize this by making it thread safe and removing lock */ + if(params.progressive_refine == false) { + /* todo: optimize this by making it thread safe and removing lock */ - update_render_tile_cb(rtile); + update_render_tile_cb(rtile); + } } update_status_time(); @@ -390,10 +432,12 @@ void Session::release_tile(RenderTile& rtile) thread_scoped_lock tile_lock(tile_mutex); if(write_render_tile_cb) { - /* todo: optimize this by making it thread safe and removing lock */ - write_render_tile_cb(rtile); + if(params.progressive_refine == false) { + /* todo: optimize this by making it thread safe and removing lock */ + write_render_tile_cb(rtile); - delete rtile.buffers; + delete rtile.buffers; + } } update_status_time(); @@ -401,6 +445,8 @@ void Session::release_tile(RenderTile& rtile) void Session::run_cpu() { + bool tiles_written = false; + { /* reset once to start */ thread_scoped_lock reset_lock(delayed_reset.mutex); @@ -502,10 +548,15 @@ void Session::run_cpu() if(device->error_message() != "") progress.set_cancel(device->error_message()); + + tiles_written = update_progressive_refine(progress.get_cancel()); } progress.set_update(); } + + if(!tiles_written) + update_progressive_refine(true); } void Session::run() @@ -722,6 +773,7 @@ void Session::path_trace() task.get_cancel = function_bind(&Progress::get_cancel, &this->progress); task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1); task.update_progress_sample = function_bind(&Session::update_progress_sample, this); + task.need_finish_queue = params.progressive_refine; device->task_add(task); } @@ -752,5 +804,24 @@ void Session::tonemap() display_outdated = false; } -CCL_NAMESPACE_END +bool Session::update_progressive_refine(bool cancel) +{ + int sample = tile_manager.state.sample + 1; + + if(params.progressive_refine) { + foreach(RenderBuffers *buffers, tile_buffers) { + RenderTile rtile; + rtile.buffers = buffers; + rtile.sample = sample; + + if(rtile.sample == params.samples || cancel) + write_render_tile_cb(rtile); + else + update_render_tile_cb(rtile); + } + } + + return sample == params.samples; +} +CCL_NAMESPACE_END diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index eda8b3da60e..dc3e7504766 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -25,6 +25,7 @@ #include "util_progress.h" #include "util_thread.h" +#include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -42,6 +43,7 @@ class SessionParams { public: DeviceInfo device; bool background; + bool progressive_refine; string output_path; bool progressive; @@ -58,6 +60,7 @@ public: SessionParams() { background = false; + progressive_refine = false; output_path = ""; progressive = false; @@ -76,6 +79,7 @@ public: { return !(device.type == params.device.type && device.id == params.device.id && background == params.background + && progressive_refine == params.progressive_refine && output_path == params.output_path /* && samples == params.samples */ && progressive == params.progressive @@ -173,6 +177,11 @@ protected: double reset_time; double preview_time; double paused_time; + + /* progressive refine */ + bool update_progressive_refine(bool cancel); + + vector<RenderBuffers *> tile_buffers; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index da287a10199..c41d503b217 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -119,6 +119,8 @@ int SVMCompiler::stack_size(ShaderSocketType type) { if(type == SHADER_SOCKET_FLOAT) return 1; + else if(type == SHADER_SOCKET_INT) + return 1; else if(type == SHADER_SOCKET_COLOR) return 3; else if(type == SHADER_SOCKET_VECTOR) @@ -212,10 +214,13 @@ void SVMCompiler::stack_assign(ShaderInput *input) if(input->type == SHADER_SOCKET_FLOAT) { add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset); } + else if(input->type == SHADER_SOCKET_INT) { + add_node(NODE_VALUE_F, (int)input->value.x, input->stack_offset); + } else if(input->type == SHADER_SOCKET_VECTOR || - input->type == SHADER_SOCKET_NORMAL || - input->type == SHADER_SOCKET_POINT || - input->type == SHADER_SOCKET_COLOR) { + input->type == SHADER_SOCKET_NORMAL || + input->type == SHADER_SOCKET_POINT || + input->type == SHADER_SOCKET_COLOR) { add_node(NODE_VALUE_V, input->stack_offset); add_node(NODE_VALUE_V, input->value); @@ -274,17 +279,6 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done) foreach(ShaderInput *in, output->links) in->stack_offset = SVM_STACK_INVALID; - - /* unmark any nodes that have no more valid outputs, see [#31806] */ - if(done.find(output->parent) != done.end()) { - all_done = true; - foreach(ShaderOutput *pout, output->parent->outputs) - if(pout->stack_offset != SVM_STACK_INVALID) - all_done = false; - - if(all_done) - done.erase(output->parent); - } } } } diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 874f1a6b3aa..02c0ee640a3 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -102,6 +102,8 @@ void TileManager::set_tiles() } state.num_tiles = state.tiles.size(); + state.tile_w = (tile_size.x >= image_w) ? 1 : (image_w + tile_size.x - 1) / tile_size.x; + state.tile_h = (tile_size.y >= image_h) ? 1 : (image_h + tile_size.y - 1) / tile_size.y; state.buffer.width = image_w; state.buffer.height = image_h; diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index d820f74e3bd..587dfbe4f1a 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -54,6 +54,8 @@ public: int resolution_divider; int num_tiles; int num_rendered_tiles; + int tile_w; + int tile_h; list<Tile> tiles; } state; diff --git a/intern/cycles/subd/CMakeLists.txt b/intern/cycles/subd/CMakeLists.txt index c0986e9c173..838776d60bf 100644 --- a/intern/cycles/subd/CMakeLists.txt +++ b/intern/cycles/subd/CMakeLists.txt @@ -6,7 +6,9 @@ set(INC ../kernel/svm ../render ) + set(INC_SYS + ) set(SRC diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index c677f2b13f4..bf5f791a245 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -2,6 +2,7 @@ set(INC . ) + set(INC_SYS ${GLEW_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR} diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp index 2960022fd8d..2716f00e173 100644 --- a/intern/cycles/util/util_cuda.cpp +++ b/intern/cycles/util/util_cuda.cpp @@ -17,6 +17,7 @@ */ #include <stdlib.h> +#include <stdio.h> #include "util_cuda.h" #include "util_debug.h" @@ -413,8 +414,18 @@ string cuCompilerPath() return nvcc; #ifndef _WIN32 - if(system("which nvcc") == 0) - return "nvcc"; + { + FILE *handle = popen("which nvcc", "r"); + if(handle) { + char buffer[4096] = {0}; + int len = fread(buffer, 1, sizeof(buffer) - 1, handle); + buffer[len] = '\0'; + pclose(handle); + + if(buffer[0]) + return "nvcc"; + } + } #endif return ""; diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 9bea4e7808a..843764ca9d6 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -60,6 +60,7 @@ public: bool join() { + joined = true; return pthread_join(pthread_id, NULL) == 0; } diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index b3c6506dfa0..70ee13d96d7 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -246,9 +246,10 @@ static void transform_decompose(Transform *decomp, const Transform *tfm) decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion) +void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid) { transform_decompose(&decomp->pre, &motion->pre); + transform_decompose(&decomp->mid, mid); transform_decompose(&decomp->post, &motion->post); } diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index d93bbff5415..df525542207 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -41,6 +41,7 @@ typedef struct Transform { typedef struct MotionTransform { Transform pre; + Transform mid; Transform post; } MotionTransform; @@ -304,10 +305,18 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t) { float costheta = dot(q1, q2); + /* rotate around shortest angle */ + if(costheta < 0.0f) { + costheta = -costheta; + q1 = -q1; + } + if(costheta > 0.9995f) { + /* linear interpolation in degenerate case */ return normalize((1.0f - t)*q1 + t*q2); } else { + /* slerp */ float theta = acosf(clamp(costheta, -1.0f, 1.0f)); float thetap = theta * t; float4 qperp = normalize(q2 - q1 * costheta); @@ -375,11 +384,37 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform { Transform decomp; - decomp.x = quat_interpolate(motion->pre.x, motion->post.x, t); - decomp.y = (1.0f - t)*motion->pre.y + t*motion->post.y; - decomp.z = (1.0f - t)*motion->pre.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->pre.w + t*motion->post.w; + /* 3 point bezier curve interpolation for position */ + float3 Ppre = float4_to_float3(motion->pre.y); + float3 Pmid = float4_to_float3(motion->mid.y); + float3 Ppost = float4_to_float3(motion->post.y); + + float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost); + float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t); + + decomp.y.x = P.x; + decomp.y.y = P.y; + decomp.y.z = P.z; + + /* linear interpolation for rotation and scale */ + if(t < 0.5f) { + t *= 2.0f; + + decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); + decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w; + decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z; + decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w; + } + else { + t = (t - 0.5f)*2.0f; + + decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t); + decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w; + decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; + decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; + } + /* compose rotation, translation, scale into matrix */ transform_compose(tfm, &decomp); } @@ -390,7 +425,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform& return (A.pre == B.pre && A.post == B.post); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion); +void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid); #endif diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index 5c6b9d5bb78..f2c02cadcbf 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -449,6 +449,7 @@ typedef enum AttributeStandard { ATTR_STD_VERTEX_NORMAL, ATTR_STD_FACE_NORMAL, ATTR_STD_UV, + ATTR_STD_TANGENT, ATTR_STD_GENERATED, ATTR_STD_POSITION_UNDEFORMED, ATTR_STD_POSITION_UNDISPLACED, diff --git a/intern/decimation/intern/LOD_Quadric.h b/intern/decimation/intern/LOD_Quadric.h index 9dde0502aa3..fc69530ac43 100644 --- a/intern/decimation/intern/LOD_Quadric.h +++ b/intern/decimation/intern/LOD_Quadric.h @@ -45,7 +45,7 @@ private: MT_Scalar c2, cd; MT_Scalar d2; - void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d); + //void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d); public: diff --git a/intern/decimation/intern/LOD_QuadricEditor.cpp b/intern/decimation/intern/LOD_QuadricEditor.cpp index fbaf0c1180f..9c895ee25f1 100644 --- a/intern/decimation/intern/LOD_QuadricEditor.cpp +++ b/intern/decimation/intern/LOD_QuadricEditor.cpp @@ -179,7 +179,7 @@ BuildQuadrics( MT_Vector3 target = TargetVertex(*edge_it); LOD_Edge &e = *edge_it; - LOD_Quadric q0 = quadrics[e.m_verts[0]]; + const LOD_Quadric &q0 = quadrics[e.m_verts[0]]; const LOD_Quadric &q1 = quadrics[e.m_verts[1]]; e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target)); diff --git a/intern/dualcon/CMakeLists.txt b/intern/dualcon/CMakeLists.txt index caa1ea09b04..da5e10fe6a7 100644 --- a/intern/dualcon/CMakeLists.txt +++ b/intern/dualcon/CMakeLists.txt @@ -19,6 +19,9 @@ set(INC . intern +) + +set(INC_SYS ../../extern/Eigen3 ) @@ -42,5 +45,5 @@ set(SRC dualcon.h ) -blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "") +blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp index c912e70b281..2b9b8d5b8a5 100644 --- a/intern/elbeem/intern/utilities.cpp +++ b/intern/elbeem/intern/utilities.cpp @@ -51,7 +51,7 @@ int getElbeemState(void) { return gElbeemState; } int isSimworldOk(void) { - return (getElbeemState>=0); + return (getElbeemState() >=0); } // last error as string, acces with get/setElbeemErrorString diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index c6d364c361c..9b563ef7e55 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -50,7 +50,7 @@ typedef unsigned short GHOST_TUns16; typedef int GHOST_TInt32; typedef unsigned int GHOST_TUns32; -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER typedef __int64 GHOST_TInt64; typedef unsigned __int64 GHOST_TUns64; #else diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h index c364f1d26a4..f0db1b3de8d 100644 --- a/intern/ghost/intern/GHOST_Debug.h +++ b/intern/ghost/intern/GHOST_Debug.h @@ -33,12 +33,12 @@ #ifndef __GHOST_DEBUG_H__ #define __GHOST_DEBUG_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER # ifdef DEBUG # pragma warning (disable:4786) // suppress stl-MSVC debug info warning // #define GHOST_DEBUG # endif // DEBUG -#endif // WIN32 +#endif // _MSC_VER #ifdef WITH_GHOST_DEBUG # define GHOST_DEBUG // spit ghost events to stdout diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 0bd90854a31..3d702c02b0f 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -89,7 +89,7 @@ getNumDisplaySettings( #else /* We only have one X11 setting at the moment. */ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - numSettings = GHOST_TInt32(1); + numSettings = 1; #endif return GHOST_kSuccess; @@ -160,7 +160,7 @@ getCurrentDisplaySetting( /* According to the xf86vidmodegetallmodelines man page, * "The first element of the array corresponds to the current video mode." */ - return getDisplaySetting(display, GHOST_TInt32(0), setting); + return getDisplaySetting(display, 0, setting); } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 232bea6749b..3ba84e157ed 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -1456,7 +1456,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, /* check size and format of the property */ XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, (unsigned char **) &buffer); + &pty_items, &pty_size, &buffer); if (pty_format != 8) { /* property does not contain text, delete it @@ -1484,7 +1484,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, * text, we know the size. */ XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, False, AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, (unsigned char **) &buffer); + &pty_items, &pty_size, &buffer); /* allocate memory to accommodate data in *txt */ if (*len == 0) { @@ -1538,12 +1538,12 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const if (sseln == m_clipboard) { sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1); strcpy((char *)sel_buf, txt_cut_buffer); - return((GHOST_TUns8 *)sel_buf); + return sel_buf; } else { sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1); strcpy((char *)sel_buf, txt_select_buffer); - return((GHOST_TUns8 *)sel_buf); + return sel_buf; } } else if (owner == None) @@ -1594,7 +1594,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const else free(sel_buf); - return (GHOST_TUns8 *)tmp_data; + return tmp_data; } return(NULL); } diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index dc05fe42a70..2077afd4086 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -637,7 +637,7 @@ void* GHOST_WindowCocoa::getOSWindow() const void GHOST_WindowCocoa::setTitle(const STR_String& title) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; @@ -684,7 +684,7 @@ void GHOST_WindowCocoa::setTitle(const STR_String& title) void GHOST_WindowCocoa::getTitle(STR_String& title) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -701,7 +701,7 @@ void GHOST_WindowCocoa::getTitle(STR_String& title) const void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const { NSRect rect; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -721,7 +721,7 @@ void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const { NSRect rect; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -753,7 +753,7 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); @@ -770,7 +770,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); @@ -787,7 +787,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); @@ -806,7 +806,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 GHOST_TWindowState GHOST_WindowCocoa::getState() const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_TWindowState state; if (m_fullScreen) { @@ -828,7 +828,7 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid"); screenToClientIntern(inX, inY, outX, outY); @@ -841,7 +841,7 @@ void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid"); /* switch y to match ghost convention */ GHOST_Rect cBnds; @@ -895,7 +895,7 @@ NSScreen* GHOST_WindowCocoa::getScreen() */ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid"); switch (state) { case GHOST_kWindowStateMinimized: [m_window miniaturize:nil]; @@ -1049,7 +1049,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid"); if (order == GHOST_kWindowOrderTop) { [m_window makeKeyAndOrderFront:nil]; } @@ -1199,7 +1199,7 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext() GHOST_TSuccess GHOST_WindowCocoa::invalidate() { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [m_openGLView setNeedsDisplay:YES]; [pool drain]; diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c index 5d207dafaaf..2d0afcf671c 100644 --- a/intern/ghost/test/multitest/MultiTest.c +++ b/intern/ghost/test/multitest/MultiTest.c @@ -26,9 +26,8 @@ */ #define FALSE 0 -#ifdef WIN32 - -#pragma warning(disable: 4244 4305) +#ifdef _MSC_VER +# pragma warning(disable: 4244 4305) #endif #include <stdlib.h> diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt index f4bc0326ea1..55879e85cdf 100644 --- a/intern/itasc/CMakeLists.txt +++ b/intern/itasc/CMakeLists.txt @@ -24,11 +24,11 @@ # ***** END GPL LICENSE BLOCK ***** set(INC - ../../extern/Eigen3 + ) set(INC_SYS - + ../../extern/Eigen3 ) set(SRC @@ -121,201 +121,245 @@ set(SRC kdl/framevel.inl # until we have another user... - ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/BlockMethods.h - ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h - ../../extern/Eigen3/Eigen/src/misc/Kernel.h - ../../extern/Eigen3/Eigen/src/misc/Image.h - ../../extern/Eigen3/Eigen/src/misc/Solve.h - ../../extern/Eigen3/Eigen/src/QR/HouseholderQR.h - ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h - ../../extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h - ../../extern/Eigen3/Eigen/src/StlSupport/details.h - ../../extern/Eigen3/Eigen/src/StlSupport/StdList.h - ../../extern/Eigen3/Eigen/src/StlSupport/StdDeque.h - ../../extern/Eigen3/Eigen/src/StlSupport/StdVector.h - ../../extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h - ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h - ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h - ../../extern/Eigen3/Eigen/src/Householder/Householder.h - ../../extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h - ../../extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h - ../../extern/Eigen3/Eigen/src/Geometry/RotationBase.h - ../../extern/Eigen3/Eigen/src/Geometry/Rotation2D.h - ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h - ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h - ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h - ../../extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h - ../../extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h - ../../extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h - ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h - ../../extern/Eigen3/Eigen/src/Geometry/Umeyama.h - ../../extern/Eigen3/Eigen/src/Geometry/Scaling.h - ../../extern/Eigen3/Eigen/src/Geometry/Translation.h - ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h - ../../extern/Eigen3/Eigen/src/Geometry/Transform.h - ../../extern/Eigen3/Eigen/src/Geometry/Quaternion.h - ../../extern/Eigen3/Eigen/src/LU/PartialPivLU.h - ../../extern/Eigen3/Eigen/src/LU/Determinant.h - ../../extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h - ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h - ../../extern/Eigen3/Eigen/src/LU/Inverse.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseVector.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h - ../../extern/Eigen3/Eigen/src/Sparse/AmbiVector.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseDenseProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseBlock.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h - ../../extern/Eigen3/Eigen/src/Sparse/CoreIterators.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseAssign.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseDot.h - ../../extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseRedux.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseView.h - ../../extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseUtil.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/QR.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Memory.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/SVD.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Meta.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Macros.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Minor.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h - ../../extern/Eigen3/Eigen/src/Core/SelfAdjointView.h - ../../extern/Eigen3/Eigen/src/Core/MatrixBase.h - ../../extern/Eigen3/Eigen/src/Core/Swap.h - ../../extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h - ../../extern/Eigen3/Eigen/src/Core/DenseBase.h - ../../extern/Eigen3/Eigen/src/Core/GlobalFunctions.h - ../../extern/Eigen3/Eigen/src/Core/ProductBase.h - ../../extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h - ../../extern/Eigen3/Eigen/src/Core/Stride.h - ../../extern/Eigen3/Eigen/src/Core/Matrix.h - ../../extern/Eigen3/Eigen/src/Core/Visitor.h + ../../extern/Eigen3/Eigen/src/Cholesky/LDLT.h + ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h + ../../extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h + ../../extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h + ../../extern/Eigen3/Eigen/src/Core/arch ../../extern/Eigen3/Eigen/src/Core/Array.h - ../../extern/Eigen3/Eigen/src/Core/ReturnByValue.h - ../../extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h - ../../extern/Eigen3/Eigen/src/Core/EigenBase.h - ../../extern/Eigen3/Eigen/src/Core/Random.h - ../../extern/Eigen3/Eigen/src/Core/Redux.h - ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h - ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h - ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h - ../../extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h - ../../extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h - ../../extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h - ../../extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h - ../../extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h - ../../extern/Eigen3/Eigen/src/Core/BooleanRedux.h - ../../extern/Eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h - ../../extern/Eigen3/Eigen/src/Core/util/BlasUtil.h - ../../extern/Eigen3/Eigen/src/Core/util/Memory.h - ../../extern/Eigen3/Eigen/src/Core/util/Meta.h - ../../extern/Eigen3/Eigen/src/Core/util/Constants.h - ../../extern/Eigen3/Eigen/src/Core/util/Macros.h - ../../extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h - ../../extern/Eigen3/Eigen/src/Core/util/StaticAssert.h - ../../extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h - ../../extern/Eigen3/Eigen/src/Core/util/XprHelper.h - ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h - ../../extern/Eigen3/Eigen/src/Core/Transpositions.h - ../../extern/Eigen3/Eigen/src/Core/Select.h + ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h + ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h + ../../extern/Eigen3/Eigen/src/Core/Assign.h + ../../extern/Eigen3/Eigen/src/Core/Assign_MKL.h ../../extern/Eigen3/Eigen/src/Core/BandMatrix.h + ../../extern/Eigen3/Eigen/src/Core/Block.h + ../../extern/Eigen3/Eigen/src/Core/BooleanRedux.h + ../../extern/Eigen3/Eigen/src/Core/CommaInitializer.h + ../../extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h + ../../extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h + ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h + ../../extern/Eigen3/Eigen/src/Core/DenseBase.h + ../../extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h + ../../extern/Eigen3/Eigen/src/Core/DenseStorage.h + ../../extern/Eigen3/Eigen/src/Core/Diagonal.h + ../../extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h + ../../extern/Eigen3/Eigen/src/Core/DiagonalProduct.h ../../extern/Eigen3/Eigen/src/Core/Dot.h + ../../extern/Eigen3/Eigen/src/Core/EigenBase.h + ../../extern/Eigen3/Eigen/src/Core/Flagged.h + ../../extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h + ../../extern/Eigen3/Eigen/src/Core/Functors.h + ../../extern/Eigen3/Eigen/src/Core/Fuzzy.h + ../../extern/Eigen3/Eigen/src/Core/GeneralProduct.h ../../extern/Eigen3/Eigen/src/Core/GenericPacketMath.h - ../../extern/Eigen3/Eigen/src/Core/Product.h - ../../extern/Eigen3/Eigen/src/Core/Transpose.h - ../../extern/Eigen3/Eigen/src/Core/Block.h - ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h + ../../extern/Eigen3/Eigen/src/Core/GlobalFunctions.h + ../../extern/Eigen3/Eigen/src/Core/IO.h + ../../extern/Eigen3/Eigen/src/Core/Map.h ../../extern/Eigen3/Eigen/src/Core/MapBase.h + ../../extern/Eigen3/Eigen/src/Core/MathFunctions.h + ../../extern/Eigen3/Eigen/src/Core/Matrix.h + ../../extern/Eigen3/Eigen/src/Core/MatrixBase.h + ../../extern/Eigen3/Eigen/src/Core/NestByValue.h ../../extern/Eigen3/Eigen/src/Core/NoAlias.h - ../../extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h - ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h - ../../extern/Eigen3/Eigen/src/Core/IO.h - ../../extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h - ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h - ../../extern/Eigen3/Eigen/src/Core/Reverse.h - ../../extern/Eigen3/Eigen/src/Core/Fuzzy.h - ../../extern/Eigen3/Eigen/src/Core/DenseStorage.h - ../../extern/Eigen3/Eigen/src/Core/StableNorm.h ../../extern/Eigen3/Eigen/src/Core/NumTraits.h - ../../extern/Eigen3/Eigen/src/Core/Map.h - ../../extern/Eigen3/Eigen/src/Core/Functors.h ../../extern/Eigen3/Eigen/src/Core/PermutationMatrix.h - ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h - ../../extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h - ../../extern/Eigen3/Eigen/src/Core/SolveTriangular.h - ../../extern/Eigen3/Eigen/src/Core/NestByValue.h - ../../extern/Eigen3/Eigen/src/Core/DiagonalProduct.h - ../../extern/Eigen3/Eigen/src/Core/CommaInitializer.h - ../../extern/Eigen3/Eigen/src/Core/MathFunctions.h - ../../extern/Eigen3/Eigen/src/Core/Diagonal.h + ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h + ../../extern/Eigen3/Eigen/src/Core/Product.h + ../../extern/Eigen3/Eigen/src/Core/ProductBase.h + ../../extern/Eigen3/Eigen/src/Core/products + ../../extern/Eigen3/Eigen/src/Core/Random.h + ../../extern/Eigen3/Eigen/src/Core/Redux.h ../../extern/Eigen3/Eigen/src/Core/Replicate.h - ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/ReturnByValue.h + ../../extern/Eigen3/Eigen/src/Core/Reverse.h + ../../extern/Eigen3/Eigen/src/Core/Select.h + ../../extern/Eigen3/Eigen/src/Core/SelfAdjointView.h + ../../extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h + ../../extern/Eigen3/Eigen/src/Core/SolveTriangular.h + ../../extern/Eigen3/Eigen/src/Core/StableNorm.h + ../../extern/Eigen3/Eigen/src/Core/Stride.h + ../../extern/Eigen3/Eigen/src/Core/Swap.h + ../../extern/Eigen3/Eigen/src/Core/Transpose.h + ../../extern/Eigen3/Eigen/src/Core/Transpositions.h + ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h + ../../extern/Eigen3/Eigen/src/Core/util + ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h + ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h + ../../extern/Eigen3/Eigen/src/Core/Visitor.h + ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec + ../../extern/Eigen3/Eigen/src/Core/arch/Default + ../../extern/Eigen3/Eigen/src/Core/arch/NEON + ../../extern/Eigen3/Eigen/src/Core/arch/SSE + ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h + ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h + ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h + ../../extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h + ../../extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h + ../../extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h + ../../extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h + ../../extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h ../../extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h ../../extern/Eigen3/Eigen/src/Core/products/Parallelizer.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h - ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h - ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h - ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h - ../../extern/Eigen3/Eigen/src/Core/Assign.h - ../../extern/Eigen3/Eigen/src/Core/Flagged.h - ../../extern/Eigen3/Eigen/src/Cholesky/LDLT.h - ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h + ../../extern/Eigen3/Eigen/src/Core/util/BlasUtil.h + ../../extern/Eigen3/Eigen/src/Core/util/Constants.h + ../../extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h + ../../extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h + ../../extern/Eigen3/Eigen/src/Core/util/Macros.h + ../../extern/Eigen3/Eigen/src/Core/util/Memory.h + ../../extern/Eigen3/Eigen/src/Core/util/Meta.h + ../../extern/Eigen3/Eigen/src/Core/util/MKL_support.h + ../../extern/Eigen3/Eigen/src/Core/util/NonMPL2.h + ../../extern/Eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h + ../../extern/Eigen3/Eigen/src/Core/util/StaticAssert.h + ../../extern/Eigen3/Eigen/src/Core/util/XprHelper.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry + ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Macros.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Memory.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Meta.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Minor.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/QR.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/SVD.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h + ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h + ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h + ../../extern/Eigen3/Eigen/src/Geometry/arch + ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h + ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h + ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h + ../../extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h + ../../extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h + ../../extern/Eigen3/Eigen/src/Geometry/Quaternion.h + ../../extern/Eigen3/Eigen/src/Geometry/Rotation2D.h + ../../extern/Eigen3/Eigen/src/Geometry/RotationBase.h + ../../extern/Eigen3/Eigen/src/Geometry/Scaling.h + ../../extern/Eigen3/Eigen/src/Geometry/Transform.h + ../../extern/Eigen3/Eigen/src/Geometry/Translation.h + ../../extern/Eigen3/Eigen/src/Geometry/Umeyama.h + ../../extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h + ../../extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h + ../../extern/Eigen3/Eigen/src/Householder/Householder.h + ../../extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h + ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h + ../../extern/Eigen3/Eigen/src/LU/arch + ../../extern/Eigen3/Eigen/src/LU/Determinant.h + ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h + ../../extern/Eigen3/Eigen/src/LU/Inverse.h + ../../extern/Eigen3/Eigen/src/LU/PartialPivLU.h + ../../extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h + ../../extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h + ../../extern/Eigen3/Eigen/src/misc/blas.h + ../../extern/Eigen3/Eigen/src/misc/Image.h + ../../extern/Eigen3/Eigen/src/misc/Kernel.h + ../../extern/Eigen3/Eigen/src/misc/Solve.h + ../../extern/Eigen3/Eigen/src/misc/SparseSolve.h + ../../extern/Eigen3/Eigen/src/OrderingMethods/Amd.h + ../../extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h + ../../extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h + ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/BlockMethods.h + ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h + ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h + ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h + ../../extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h + ../../extern/Eigen3/Eigen/src/QR/HouseholderQR.h + ../../extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h + ../../extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h + ../../extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h + ../../extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h + ../../extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h + ../../extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseDot.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseVector.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseView.h + ../../extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h + ../../extern/Eigen3/Eigen/src/StlSupport/details.h + ../../extern/Eigen3/Eigen/src/StlSupport/StdDeque.h + ../../extern/Eigen3/Eigen/src/StlSupport/StdList.h + ../../extern/Eigen3/Eigen/src/StlSupport/StdVector.h + ../../extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h + ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD.h + ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h + ../../extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h + ../../extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h ) diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index d46b09cf76a..c281a6e7bbb 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC ) set(INC_SYS + ) set(SRC diff --git a/intern/opennl/CMakeLists.txt b/intern/opennl/CMakeLists.txt index 322428386b1..b7a24839e38 100644 --- a/intern/opennl/CMakeLists.txt +++ b/intern/opennl/CMakeLists.txt @@ -40,11 +40,10 @@ add_definitions( set(INC extern superlu - ../../extern/colamd/Include ) set(INC_SYS - + ../../extern/colamd/Include ) set(SRC diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt index 9524f7b2935..3b8a4c06e69 100644 --- a/intern/smoke/CMakeLists.txt +++ b/intern/smoke/CMakeLists.txt @@ -26,10 +26,10 @@ set(INC intern ../memutil - ../../extern/bullet2/src ) set(INC_SYS + ../../extern/bullet2/src ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ) @@ -40,6 +40,7 @@ set(SRC intern/FLUID_3D_SOLVERS.cpp intern/FLUID_3D_STATIC.cpp intern/LU_HELPER.cpp + intern/spectrum.cpp intern/SPHERE.cpp intern/WTURBULENCE.cpp intern/smoke_API.cpp @@ -53,6 +54,7 @@ set(SRC intern/LU_HELPER.h intern/MERSENNETWISTER.h intern/OBSTACLE.h + intern/spectrum.h intern/SPHERE.h intern/VEC3.h intern/WAVELET_NOISE.h diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h index a0eb1bf38e0..98c63f08fbd 100644 --- a/intern/smoke/extern/smoke_API.h +++ b/intern/smoke/extern/smoke_API.h @@ -37,17 +37,23 @@ extern "C" { struct FLUID_3D; -// export -void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles); - // low res -struct FLUID_3D *smoke_init(int *res, float *p0, float dtdef); +struct FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors); void smoke_free(struct FLUID_3D *fluid); -void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli); -void smoke_step(struct FLUID_3D *fluid, float dtSubdiv); +void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp); +void smoke_step(struct FLUID_3D *fluid, float gravity[3], float dtSubdiv); float *smoke_get_density(struct FLUID_3D *fluid); +float *smoke_get_flame(struct FLUID_3D *fluid); +float *smoke_get_fuel(struct FLUID_3D *fluid); +float *smoke_get_react(struct FLUID_3D *fluid); +float *smoke_get_color_r(struct FLUID_3D *fluid); +float *smoke_get_color_g(struct FLUID_3D *fluid); +float *smoke_get_color_b(struct FLUID_3D *fluid); +void smoke_get_rgba(struct FLUID_3D *fluid, float *data, int sequential); +void smoke_get_rgba_from_density(struct FLUID_3D *fluid, float color[3], float *data, int sequential); float *smoke_get_heat(struct FLUID_3D *fluid); float *smoke_get_velocity_x(struct FLUID_3D *fluid); float *smoke_get_velocity_y(struct FLUID_3D *fluid); @@ -68,19 +74,44 @@ size_t smoke_get_index2d(int x, int max_x, int y); void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log); // wavelet turbulence functions -struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype); +struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors); void smoke_turbulence_free(struct WTURBULENCE *wt); void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid); float *smoke_turbulence_get_density(struct WTURBULENCE *wt); +float *smoke_turbulence_get_color_r(struct WTURBULENCE *wt); +float *smoke_turbulence_get_color_g(struct WTURBULENCE *wt); +float *smoke_turbulence_get_color_b(struct WTURBULENCE *wt); +void smoke_turbulence_get_rgba(struct WTURBULENCE *wt, float *data, int sequential); +void smoke_turbulence_get_rgba_from_density(struct WTURBULENCE *wt, float color[3], float *data, int sequential); +float *smoke_turbulence_get_flame(struct WTURBULENCE *wt); +float *smoke_turbulence_get_fuel(struct WTURBULENCE *wt); +float *smoke_turbulence_get_react(struct WTURBULENCE *wt); void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res); +int smoke_turbulence_get_cells(struct WTURBULENCE *wt); void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type); void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength); - void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log); -// export -void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw); +/* export */ +void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, float **heatold, + float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles); +void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, + float **r, float **g, float **b, float **tcu, float **tcv, float **tcw); + +/* flame spectrum */ +void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2); + +/* data fields */ +int smoke_has_heat(struct FLUID_3D *fluid); +int smoke_has_fuel(struct FLUID_3D *fluid); +int smoke_has_colors(struct FLUID_3D *fluid); +int smoke_turbulence_has_fuel(struct WTURBULENCE *wt); +int smoke_turbulence_has_colors(struct WTURBULENCE *wt); + +void smoke_ensure_heat(struct FLUID_3D *fluid); +void smoke_ensure_fire(struct FLUID_3D *fluid, struct WTURBULENCE *wt); +void smoke_ensure_colors(struct FLUID_3D *fluid, struct WTURBULENCE *wt, float init_r, float init_g, float init_b); #ifdef __cplusplus } diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index e006132ea8f..4eb11a46f5b 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -44,16 +44,11 @@ // Construction/Destruction ////////////////////////////////////////////////////////////////////// -FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : +FLUID_3D::FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors) : _xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f) { // set simulation consts _dt = dtdef; // just in case. set in step from a RNA factor - - // start point of array - _p0[0] = p0[0]; - _p0[1] = p0[1]; - _p0[2] = p0[2]; _iterations = 100; _tempAmb = 0; @@ -72,7 +67,10 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : */ // scale the constants according to the refinement of the grid - _dx = 1.0f / (float)_maxRes; + if (!dx) + _dx = 1.0f / (float)_maxRes; + else + _dx = dx; _constantScaling = 64.0f / _maxRes; _constantScaling = (_constantScaling < 1.0f) ? 1.0f : _constantScaling; _vorticityEps = 2.0f / _constantScaling; // Just in case set a default value @@ -94,8 +92,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _zForce = new float[_totalCells]; _density = new float[_totalCells]; _densityOld = new float[_totalCells]; - _heat = new float[_totalCells]; - _heatOld = new float[_totalCells]; _obstacles = new unsigned char[_totalCells]; // set 0 at end of step // For threaded version: @@ -103,7 +99,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _yVelocityTemp = new float[_totalCells]; _zVelocityTemp = new float[_totalCells]; _densityTemp = new float[_totalCells]; - _heatTemp = new float[_totalCells]; // DG TODO: check if alloc went fine @@ -111,8 +106,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : { _density[x] = 0.0f; _densityOld[x] = 0.0f; - _heat[x] = 0.0f; - _heatOld[x] = 0.0f; _xVelocity[x] = 0.0f; _yVelocity[x] = 0.0f; _zVelocity[x] = 0.0f; @@ -128,6 +121,25 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _obstacles[x] = false; } + /* heat */ + _heat = _heatOld = _heatTemp = NULL; + if (init_heat) { + initHeat(); + } + // Fire simulation + _flame = _fuel = _fuelTemp = _fuelOld = NULL; + _react = _reactTemp = _reactOld = NULL; + if (init_fire) { + initFire(); + } + // Smoke color + _color_r = _color_rOld = _color_rTemp = NULL; + _color_g = _color_gOld = _color_gTemp = NULL; + _color_b = _color_bOld = _color_bTemp = NULL; + if (init_colors) { + initColors(0.0f, 0.0f, 0.0f); + } + // boundary conditions of the fluid domain // set default values -> vertically non-colliding _domainBcFront = true; @@ -138,9 +150,70 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _domainBcRight = _domainBcLeft; _colloPrev = 1; // default value +} - setBorderObstacles(); // walls +void FLUID_3D::initHeat() +{ + if (!_heat) { + _heat = new float[_totalCells]; + _heatOld = new float[_totalCells]; + _heatTemp = new float[_totalCells]; + for (int x = 0; x < _totalCells; x++) + { + _heat[x] = 0.0f; + _heatOld[x] = 0.0f; + } + } +} + +void FLUID_3D::initFire() +{ + if (!_flame) { + _flame = new float[_totalCells]; + _fuel = new float[_totalCells]; + _fuelTemp = new float[_totalCells]; + _fuelOld = new float[_totalCells]; + _react = new float[_totalCells]; + _reactTemp = new float[_totalCells]; + _reactOld = new float[_totalCells]; + + for (int x = 0; x < _totalCells; x++) + { + _flame[x] = 0.0f; + _fuel[x] = 0.0f; + _fuelTemp[x] = 0.0f; + _fuelOld[x] = 0.0f; + _react[x] = 0.0f; + _reactTemp[x] = 0.0f; + _reactOld[x] = 0.0f; + } + } +} + +void FLUID_3D::initColors(float init_r, float init_g, float init_b) +{ + if (!_color_r) { + _color_r = new float[_totalCells]; + _color_rOld = new float[_totalCells]; + _color_rTemp = new float[_totalCells]; + _color_g = new float[_totalCells]; + _color_gOld = new float[_totalCells]; + _color_gTemp = new float[_totalCells]; + _color_b = new float[_totalCells]; + _color_bOld = new float[_totalCells]; + _color_bTemp = new float[_totalCells]; + + for (int x = 0; x < _totalCells; x++) + { + _color_r[x] = _density[x] * init_r; + _color_rOld[x] = 0.0f; + _color_g[x] = _density[x] * init_g; + _color_gOld[x] = 0.0f; + _color_b[x] = _density[x] * init_b; + _color_bOld[x] = 0.0f; + } + } } void FLUID_3D::setBorderObstacles() @@ -204,7 +277,6 @@ FLUID_3D::~FLUID_3D() if (_heat) delete[] _heat; if (_heatOld) delete[] _heatOld; if (_obstacles) delete[] _obstacles; - // if (_wTurbulence) delete _wTurbulence; if (_xVelocityTemp) delete[] _xVelocityTemp; if (_yVelocityTemp) delete[] _yVelocityTemp; @@ -212,23 +284,48 @@ FLUID_3D::~FLUID_3D() if (_densityTemp) delete[] _densityTemp; if (_heatTemp) delete[] _heatTemp; + if (_flame) delete[] _flame; + if (_fuel) delete[] _fuel; + if (_fuelTemp) delete[] _fuelTemp; + if (_fuelOld) delete[] _fuelOld; + if (_react) delete[] _react; + if (_reactTemp) delete[] _reactTemp; + if (_reactOld) delete[] _reactOld; + + if (_color_r) delete[] _color_r; + if (_color_rOld) delete[] _color_rOld; + if (_color_rTemp) delete[] _color_rTemp; + if (_color_g) delete[] _color_g; + if (_color_gOld) delete[] _color_gOld; + if (_color_gTemp) delete[] _color_gTemp; + if (_color_b) delete[] _color_b; + if (_color_bOld) delete[] _color_bOld; + if (_color_bTemp) delete[] _color_bTemp; + // printf("deleted fluid\n"); } // init direct access functions from blender -void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision) +void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp) { _alpha = alpha; _beta = beta; _dtFactor = dt_factor; _vorticityRNA = vorticity; _borderColli = borderCollision; + _burning_rate = burning_rate; + _flame_smoke = flame_smoke; + _flame_smoke_color = flame_smoke_color; + _flame_vorticity = flame_vorticity; + _ignition_temp = flame_ignition_temp; + _max_temp = flame_max_temp; } ////////////////////////////////////////////////////////////////////// // step simulation once ////////////////////////////////////////////////////////////////////// -void FLUID_3D::step(float dt) +void FLUID_3D::step(float dt, float gravity[3]) { #if 0 // If border rules have been changed @@ -281,7 +378,7 @@ void FLUID_3D::step(float dt) wipeBoundariesSL(zBegin, zEnd); addVorticity(zBegin, zEnd); - addBuoyancy(_heat, _density, zBegin, zEnd); + addBuoyancy(_heat, _density, gravity, zBegin, zEnd); addForce(zBegin, zEnd); #if PARALLEL==1 @@ -312,13 +409,15 @@ void FLUID_3D::step(float dt) if (i==0) { #endif - project(); + project(); #if PARALLEL==1 } - else + else if (i==1) { #endif - diffuseHeat(); + if (_heat) { + diffuseHeat(); + } #if PARALLEL==1 } } @@ -338,6 +437,13 @@ void FLUID_3D::step(float dt) SWAP_POINTERS(_density, _densityOld); SWAP_POINTERS(_heat, _heatOld); + SWAP_POINTERS(_fuel, _fuelOld); + SWAP_POINTERS(_react, _reactOld); + + SWAP_POINTERS(_color_r, _color_rOld); + SWAP_POINTERS(_color_g, _color_gOld); + SWAP_POINTERS(_color_b, _color_bOld); + advectMacCormackBegin(0, _zRes); #if PARALLEL==1 @@ -398,11 +504,8 @@ void FLUID_3D::step(float dt) SWAP_POINTERS(_yVelocity, _yForce); SWAP_POINTERS(_zVelocity, _zForce); - - - _totalTime += _dt; - _totalSteps++; + _totalSteps++; for (int i = 0; i < _totalCells; i++) { @@ -643,6 +746,15 @@ void FLUID_3D::wipeBoundaries(int zBegin, int zEnd) setZeroBorder(_yVelocity, _res, zBegin, zEnd); setZeroBorder(_zVelocity, _res, zBegin, zEnd); setZeroBorder(_density, _res, zBegin, zEnd); + if (_fuel) { + setZeroBorder(_fuel, _res, zBegin, zEnd); + setZeroBorder(_react, _res, zBegin, zEnd); + } + if (_color_r) { + setZeroBorder(_color_r, _res, zBegin, zEnd); + setZeroBorder(_color_g, _res, zBegin, zEnd); + setZeroBorder(_color_b, _res, zBegin, zEnd); + } } void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) @@ -668,6 +780,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } // right slab index += _xRes - 1; @@ -675,6 +796,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } ///////////////////////////////////// @@ -690,6 +820,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } // top slab index += slabSize - _xRes; @@ -697,6 +836,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } @@ -717,6 +865,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } if (zEnd == _zRes) @@ -735,6 +892,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[indexx] = 0.0f; _zVelocity[indexx] = 0.0f; _density[indexx] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } } @@ -781,35 +947,6 @@ void FLUID_3D::project() if(!_domainBcTop) setNeumannZ(_zVelocity, _res, 0, _zRes); else setZeroZ(_zVelocity, _res, 0, _zRes); - /* - { - float maxx = 0, maxy = 0, maxz = 0; - for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++) - { - if(_xVelocity[i] > maxx) - maxx = _xVelocity[i]; - if(_yVelocity[i] > maxy) - maxy = _yVelocity[i]; - if(_zVelocity[i] > maxz) - maxz = _zVelocity[i]; - } - printf("Max velx: %f, vely: %f, velz: %f\n", maxx, maxy, maxz); - } - */ - - /* - { - float maxvalue = 0; - for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++) - { - if(_heat[i] > maxvalue) - maxvalue = _heat[i]; - - } - printf("Max heat: %f\n", maxvalue); - } - */ - // calculate divergence index = _slabSize + _xRes + 1; for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) @@ -910,21 +1047,52 @@ void FLUID_3D::project() setObstaclePressure(_pressure, 0, _zRes); // project out solution + // New idea for code from NVIDIA graphic gems 3 - DG float invDx = 1.0f / _dx; index = _slabSize + _xRes + 1; for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) for (y = 1; y < _yRes - 1; y++, index += 2) for (x = 1; x < _xRes - 1; x++, index++) { + float vMask[3] = {1.0f, 1.0f, 1.0f}, vObst[3] = {0, 0, 0}; + float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f; + + float pC = _pressure[index]; // center + float pR = _pressure[index + 1]; // right + float pL = _pressure[index - 1]; // left + float pU = _pressure[index + _xRes]; // Up + float pD = _pressure[index - _xRes]; // Down + float pT = _pressure[index + _slabSize]; // top + float pB = _pressure[index - _slabSize]; // bottom + if(!_obstacles[index]) { - _xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx; - _yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx; - _zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx; + // DG TODO: What if obstacle is left + right and one of them is moving? + if(_obstacles[index+1]) { pR = pC; vObst[0] = _xVelocityOb[index + 1]; vMask[0] = 0; } + if(_obstacles[index-1]) { pL = pC; vObst[0] = _xVelocityOb[index - 1]; vMask[0] = 0; } + if(_obstacles[index+_xRes]) { pU = pC; vObst[1] = _yVelocityOb[index + _xRes]; vMask[1] = 0; } + if(_obstacles[index-_xRes]) { pD = pC; vObst[1] = _yVelocityOb[index - _xRes]; vMask[1] = 0; } + if(_obstacles[index+_slabSize]) { pT = pC; vObst[2] = _zVelocityOb[index + _slabSize]; vMask[2] = 0; } + if(_obstacles[index-_slabSize]) { pB = pC; vObst[2] = _zVelocityOb[index - _slabSize]; vMask[2] = 0; } + + _xVelocity[index] -= 0.5f * (pR - pL) * invDx; + _yVelocity[index] -= 0.5f * (pU - pD) * invDx; + _zVelocity[index] -= 0.5f * (pT - pB) * invDx; + + _xVelocity[index] = (vMask[0] * _xVelocity[index]) + vObst[0]; + _yVelocity[index] = (vMask[1] * _yVelocity[index]) + vObst[1]; + _zVelocity[index] = (vMask[2] * _zVelocity[index]) + vObst[2]; + } + else + { + _xVelocity[index] = _xVelocityOb[index]; + _yVelocity[index] = _yVelocityOb[index]; + _zVelocity[index] = _zVelocityOb[index]; } } - setObstacleVelocity(0, _zRes); + // DG: was enabled in original code but now we do this later + // setObstacleVelocity(0, _zRes); if (_pressure) delete[] _pressure; if (_divergence) delete[] _divergence; @@ -1007,7 +1175,6 @@ void FLUID_3D::diffuseHeat() for (int x = 0; x < _totalCells; x++) if (_obstacles[x]) _heat[x] = 0.0f; - } ////////////////////////////////////////////////////////////////////// @@ -1175,7 +1342,7 @@ void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd) ////////////////////////////////////////////////////////////////////// // add buoyancy forces ////////////////////////////////////////////////////////////////////// -void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd) +void FLUID_3D::addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd) { int index = zBegin*_slabSize; @@ -1183,17 +1350,26 @@ void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd) for (int y = 0; y < _yRes; y++) for (int x = 0; x < _xRes; x++, index++) { - _zForce[index] += *_alpha * density[index] + (*_beta * (heat[index] - _tempAmb)); // DG: was _yForce, changed for Blender + float buoyancy = *_alpha * density[index] + (*_beta * (((heat) ? heat[index] : 0.0f) - _tempAmb)); + _xForce[index] -= gravity[0] * buoyancy; + _yForce[index] -= gravity[1] * buoyancy; + _zForce[index] -= gravity[2] * buoyancy; } } + ////////////////////////////////////////////////////////////////////// // add vorticity to the force field ////////////////////////////////////////////////////////////////////// +#define VORT_VEL(i, j) \ + ((_obstacles[obpos[(i)]] & 8) ? ((abs(objvelocity[(j)][obpos[(i)]]) > FLT_EPSILON) ? objvelocity[(j)][obpos[(i)]] : velocity[(j)][index]) : velocity[(j)][obpos[(i)]]) + void FLUID_3D::addVorticity(int zBegin, int zEnd) { + // set flame vorticity from RNA value + float flame_vorticity = (*_flame_vorticity)/_constantScaling; //int x,y,z,index; - if(_vorticityEps<=0.) return; + if(_vorticityEps+flame_vorticity<=0.) return; int _blockSize=zEnd-zBegin; int _blockTotalCells = _slabSize * (_blockSize+2); @@ -1225,9 +1401,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) float gridSize = 0.5f / _dx; //index = _slabSize + _xRes + 1; + float *velocity[3]; + float *objvelocity[3]; - size_t vIndex=_xRes + 1; + velocity[0] = _xVelocity; + velocity[1] = _yVelocity; + velocity[2] = _zVelocity; + + objvelocity[0] = _xVelocityOb; + objvelocity[1] = _yVelocityOb; + objvelocity[2] = _zVelocityOb; + size_t vIndex=_xRes + 1; for (int z = zBegin + bb1; z < (zEnd - bt1); z++) { size_t index = index_ +(z-1)*_slabSize; @@ -1237,25 +1422,47 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) { for (int x = 1; x < _xRes - 1; x++, index++) { + if (!_obstacles[index]) + { + int obpos[6]; + + obpos[0] = (_obstacles[index + _xRes] == 1) ? index : index + _xRes; // up + obpos[1] = (_obstacles[index - _xRes] == 1) ? index : index - _xRes; // down + float dy = (obpos[0] == index || obpos[1] == index) ? 1.0f / _dx : gridSize; + + obpos[2] = (_obstacles[index + _slabSize] == 1) ? index : index + _slabSize; // out + obpos[3] = (_obstacles[index - _slabSize] == 1) ? index : index - _slabSize; // in + float dz = (obpos[2] == index || obpos[3] == index) ? 1.0f / _dx : gridSize; + + obpos[4] = (_obstacles[index + 1] == 1) ? index : index + 1; // right + obpos[5] = (_obstacles[index - 1] == 1) ? index : index - 1; // left + float dx = (obpos[4] == index || obpos[5] == index) ? 1.0f / _dx : gridSize; + + float xV[2], yV[2], zV[2]; + + zV[1] = VORT_VEL(0, 2); + zV[0] = VORT_VEL(1, 2); + yV[1] = VORT_VEL(2, 1); + yV[0] = VORT_VEL(3, 1); + _xVorticity[vIndex] = (zV[1] - zV[0]) * dy + (-yV[1] + yV[0]) * dz; + + xV[1] = VORT_VEL(2, 0); + xV[0] = VORT_VEL(3, 0); + zV[1] = VORT_VEL(4, 2); + zV[0] = VORT_VEL(5, 2); + _yVorticity[vIndex] = (xV[1] - xV[0]) * dz + (-zV[1] + zV[0]) * dx; + + yV[1] = VORT_VEL(4, 1); + yV[0] = VORT_VEL(5, 1); + xV[1] = VORT_VEL(0, 0); + xV[0] = VORT_VEL(1, 0); + _zVorticity[vIndex] = (yV[1] - yV[0]) * dx + (-xV[1] + xV[0])* dy; - int up = _obstacles[index + _xRes] ? index : index + _xRes; - int down = _obstacles[index - _xRes] ? index : index - _xRes; - float dy = (up == index || down == index) ? 1.0f / _dx : gridSize; - int out = _obstacles[index + _slabSize] ? index : index + _slabSize; - int in = _obstacles[index - _slabSize] ? index : index - _slabSize; - float dz = (out == index || in == index) ? 1.0f / _dx : gridSize; - int right = _obstacles[index + 1] ? index : index + 1; - int left = _obstacles[index - 1] ? index : index - 1; - float dx = (right == index || left == index) ? 1.0f / _dx : gridSize; - - _xVorticity[vIndex] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz; - _yVorticity[vIndex] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx; - _zVorticity[vIndex] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy; - - _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] + + _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] + _yVorticity[vIndex] * _yVorticity[vIndex] + _zVorticity[vIndex] * _zVorticity[vIndex]); + } vIndex++; } vIndex+=2; @@ -1284,15 +1491,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) { float N[3]; - int up = _obstacles[index + _xRes] ? vIndex : vIndex + _xRes; - int down = _obstacles[index - _xRes] ? vIndex : vIndex - _xRes; + int up = (_obstacles[index + _xRes] == 1) ? vIndex : vIndex + _xRes; + int down = (_obstacles[index - _xRes] == 1) ? vIndex : vIndex - _xRes; float dy = (up == vIndex || down == vIndex) ? 1.0f / _dx : gridSize; - int out = _obstacles[index + _slabSize] ? vIndex : vIndex + _slabSize; - int in = _obstacles[index - _slabSize] ? vIndex : vIndex - _slabSize; + + int out = (_obstacles[index + _slabSize] == 1) ? vIndex : vIndex + _slabSize; + int in = (_obstacles[index - _slabSize] == 1) ? vIndex : vIndex - _slabSize; float dz = (out == vIndex || in == vIndex) ? 1.0f / _dx : gridSize; - int right = _obstacles[index + 1] ? vIndex : vIndex + 1; - int left = _obstacles[index - 1] ? vIndex : vIndex - 1; + + int right = (_obstacles[index + 1] == 1) ? vIndex : vIndex + 1; + int left = (_obstacles[index - 1] == 1) ? vIndex : vIndex - 1; float dx = (right == vIndex || left == vIndex) ? 1.0f / _dx : gridSize; + N[0] = (_vorticity[right] - _vorticity[left]) * dx; N[1] = (_vorticity[up] - _vorticity[down]) * dy; N[2] = (_vorticity[out] - _vorticity[in]) * dz; @@ -1300,14 +1510,15 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) float magnitude = sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); if (magnitude > FLT_EPSILON) { + float flame_vort = (_fuel) ? _fuel[index]*flame_vorticity : 0.0f; magnitude = 1.0f / magnitude; N[0] *= magnitude; N[1] *= magnitude; N[2] *= magnitude; - _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * eps; - _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * eps; - _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * eps; + _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * (eps + flame_vort); + _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * (eps + flame_vort); + _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * (eps + flame_vort); } } // if vIndex++; @@ -1328,14 +1539,9 @@ void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd) { Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - if(!_domainBcLeft) copyBorderX(_xVelocityOld, res, zBegin, zEnd); - else setZeroX(_xVelocityOld, res, zBegin, zEnd); - - if(!_domainBcFront) copyBorderY(_yVelocityOld, res, zBegin, zEnd); - else setZeroY(_yVelocityOld, res, zBegin, zEnd); - - if(!_domainBcTop) copyBorderZ(_zVelocityOld, res, zBegin, zEnd); - else setZeroZ(_zVelocityOld, res, zBegin, zEnd); + setZeroX(_xVelocityOld, res, zBegin, zEnd); + setZeroY(_yVelocityOld, res, zBegin, zEnd); + setZeroZ(_zVelocityOld, res, zBegin, zEnd); } ////////////////////////////////////////////////////////////////////// @@ -1355,7 +1561,18 @@ void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd) // advectFieldMacCormack1(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res) advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _densityTemp, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd); + if (_heat) { + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd); + } + if (_fuel) { + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuelTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _reactTemp, res, zBegin, zEnd); + } + if (_color_r) { + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_rTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_gTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_bTemp, res, zBegin, zEnd); + } advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, res, zBegin, zEnd); advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, res, zBegin, zEnd); advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, res, zBegin, zEnd); @@ -1371,17 +1588,30 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) const float dt0 = _dt / _dx; Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - // use force array as temp arrays + // use force array as temp array float* t1 = _xForce; // advectFieldMacCormack2(dt, xVelocity, yVelocity, zVelocity, oldField, newField, tempfield, temp, res, obstacles) + /* finish advection */ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, _densityTemp, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd); + if (_heat) { + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd); + } + if (_fuel) { + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuel, _fuelTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _react, _reactTemp, t1, res, _obstacles, zBegin, zEnd); + } + if (_color_r) { + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_r, _color_rTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_g, _color_gTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_b, _color_bTemp, t1, res, _obstacles, zBegin, zEnd); + } advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocityTemp, _xVelocity, t1, res, _obstacles, zBegin, zEnd); advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd); advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd); + /* set boundary conditions for velocity */ if(!_domainBcLeft) copyBorderX(_xVelocityTemp, res, zBegin, zEnd); else setZeroX(_xVelocityTemp, res, zBegin, zEnd); @@ -1391,40 +1621,71 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) if(!_domainBcTop) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd); else setZeroZ(_zVelocityTemp, res, zBegin, zEnd); + /* clear data boundaries */ setZeroBorder(_density, res, zBegin, zEnd); - setZeroBorder(_heat, res, zBegin, zEnd); -#if 0 - { - const size_t index_ = _slabSize + _xRes + 1; - int bb=0; - int bt=0; + if (_fuel) { + setZeroBorder(_fuel, res, zBegin, zEnd); + setZeroBorder(_react, res, zBegin, zEnd); + } + if (_color_r) { + setZeroBorder(_color_r, res, zBegin, zEnd); + setZeroBorder(_color_g, res, zBegin, zEnd); + setZeroBorder(_color_b, res, zBegin, zEnd); + } +} - if (zBegin == 0) {bb = 1;} - if (zEnd == _zRes) {bt = 1;} - - for (int z = zBegin + bb; z < zEnd - bt; z++) + +void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat, + float *r, float *g, float *b, int total_cells, float dt) +{ + float burning_rate = *_burning_rate; + float flame_smoke = *_flame_smoke; + float ignition_point = *_ignition_temp; + float temp_max = *_max_temp; + + for (int index = 0; index < total_cells; index++) { - size_t index = index_ +(z-1)*_slabSize; + float orig_fuel = fuel[index]; + float orig_smoke = smoke[index]; + float smoke_emit = 0.0f; + float react_coord = 0.0f; + + /* process fuel */ + fuel[index] -= burning_rate * dt; + if (fuel[index] < 0.0f) fuel[index] = 0.0f; + /* process reaction coordinate */ + if (orig_fuel) { + react[index] *= fuel[index]/orig_fuel; + react_coord = react[index]; + } + else { + react[index] = 0.0f; + } - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - // clean custom velocities from moving obstacles again - if (_obstacles[index]) - { - _xVelocity[index] = - _yVelocity[index] = - _zVelocity[index] = 0.0f; - } - } + /* emit smoke based on fuel burn rate and "flame_smoke" factor */ + smoke_emit = (orig_fuel < 1.0f) ? (1.0f - orig_fuel)*0.5f : 0.0f; + smoke_emit = (smoke_emit + 0.5f) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke; + smoke[index] += smoke_emit; + CLAMP(smoke[index], 0.0f, 1.0f); + + /* model flame temperature curve from the reaction coordinate (fuel) */ + if (react_coord>0.0f) { + /* do a smooth falloff for rest of the values */ + flame[index] = pow(react_coord, 0.5f); + } + else + flame[index] = 0.0f; + + /* set fluid temperature from the flame temperature profile */ + if (heat && flame[index]) + heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max; + + /* mix new color */ + if (r && smoke_emit) { + float smoke_factor = smoke[index]/(orig_smoke+smoke_emit); + r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor; + g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor; + b[index] = (b[index] + _flame_smoke_color[2] * smoke_emit) * smoke_factor; } } - } -#endif - - /*int begin=zBegin * _slabSize; - int end=begin + (zEnd - zBegin) * _slabSize; - for (int x = begin; x < end; x++) - _xForce[x] = _yForce[x] = 0.0f;*/ } diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h index ac77148ce84..8cadf3bc989 100644 --- a/intern/smoke/intern/FLUID_3D.h +++ b/intern/smoke/intern/FLUID_3D.h @@ -46,11 +46,16 @@ class WTURBULENCE; class FLUID_3D { public: - FLUID_3D(int *res, /* int amplify, */ float *p0, float dtdef); + FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors); FLUID_3D() {}; virtual ~FLUID_3D(); - void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli); + void initHeat(); + void initFire(); + void initColors(float init_r, float init_g, float init_b); + + void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *ignition_temp, float *max_temp); // create & allocate vector noise advection void initVectorNoise(int amplify); @@ -58,7 +63,7 @@ class FLUID_3D void addSmokeColumn(); static void addSmokeTestCase(float* field, Vec3Int res); - void step(float dt); + void step(float dt, float gravity[3]); void addObstacle(OBSTACLE* obstacle); const float* xVelocity() { return _xVelocity; }; @@ -115,6 +120,27 @@ class FLUID_3D float* _heatTemp; float* _densityTemp; + // fire simulation + float *_flame; + float *_fuel; + float *_fuelTemp; + float *_fuelOld; + float *_react; + float *_reactTemp; + float *_reactOld; + + // smoke color + float *_color_r; + float *_color_rOld; + float *_color_rTemp; + float *_color_g; + float *_color_gOld; + float *_color_gTemp; + float *_color_b; + float *_color_bOld; + float *_color_bTemp; + + // CG fields int _iterations; @@ -153,14 +179,16 @@ class FLUID_3D void wipeBoundariesSL(int zBegin, int zEnd); void addForce(int zBegin, int zEnd); void addVorticity(int zBegin, int zEnd); - void addBuoyancy(float *heat, float *density, int zBegin, int zEnd); + void addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd); // solver stuff void project(); void diffuseHeat(); + void diffuseColor(); void solvePressure(float* field, float* b, unsigned char* skip); void solvePressurePre(float* field, float* b, unsigned char* skip); void solveHeat(float* field, float* b, unsigned char* skip); + void solveDiffusion(float* field, float* b, float* factor); // handle obstacle boundaries @@ -174,6 +202,16 @@ class FLUID_3D void advectMacCormackEnd1(int zBegin, int zEnd); void advectMacCormackEnd2(int zBegin, int zEnd); + /* burning */ + float *_burning_rate; // RNA pointer + float *_flame_smoke; // RNA pointer + float *_flame_smoke_color; // RNA pointer + float *_flame_vorticity; // RNA pointer + float *_ignition_temp; // RNA pointer + float *_max_temp; // RNA pointer + void processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat, + float *r, float *g, float *b, int total_cells, float dt); + // boundary setting functions static void copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd); static void copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd); diff --git a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp index 3cf94eb00a9..42a8b2d6923 100644 --- a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp +++ b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp @@ -165,7 +165,6 @@ void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip) if (_Acenter) delete[] _Acenter; } - void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip) { int x, y, z; diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index c7a0ddcd04c..ac485ad983a 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -92,18 +92,10 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd) // left slab index = y * res[0] + z * slabSize; field[index] = field[index + 2]; - /* only allow outwards flux */ - if(field[index]>0.) field[index] = 0.; - index += 1; - if(field[index]>0.) field[index] = 0.; // right slab index = y * res[0] + z * slabSize + res[0] - 1; field[index] = field[index - 2]; - /* only allow outwards flux */ - if(field[index]<0.) field[index] = 0.; - index -= 1; - if(field[index]<0.) field[index] = 0.; } } @@ -120,18 +112,10 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd) // front slab index = x + z * slabSize; field[index] = field[index + 2 * res[0]]; - /* only allow outwards flux */ - if(field[index]>0.) field[index] = 0.; - index += res[0]; - if(field[index]>0.) field[index] = 0.; // back slab index = x + z * slabSize + slabSize - res[0]; field[index] = field[index - 2 * res[0]]; - /* only allow outwards flux */ - if(field[index]<0.) field[index] = 0.; - index -= res[0]; - if(field[index]<0.) field[index] = 0.; } } @@ -152,14 +136,6 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd) // front slab index = x + y * res[0]; field[index] = field[index + 2 * slabSize]; - /* only allow outwards flux */ - - // DG: Disable this for z-axis. - // The problem is that smoke somehow gets sucked in again - // from the TOP slab when this is enabled - // if(field[index]>0.) field[index] = 0.; - // index += slabSize; - // if(field[index]>0.) field[index] = 0.; } } @@ -170,10 +146,6 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd) // back slab index = x + y * res[0] + cellsslab; field[index] = field[index - 2 * slabSize]; - /* only allow outwards flux */ - if(field[index]<0.) field[index] = 0.; - index -= slabSize; - if(field[index]<0.) field[index] = 0.; } } diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp index 671198065e8..1c89f5d681b 100644 --- a/intern/smoke/intern/WTURBULENCE.cpp +++ b/intern/smoke/intern/WTURBULENCE.cpp @@ -51,7 +51,7 @@ static const float persistence = 0.56123f; ////////////////////////////////////////////////////////////////////// // constructor ////////////////////////////////////////////////////////////////////// -WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype) +WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors) { // if noise magnitude is below this threshold, its contribution // is negilgible, so stop evaluating new octaves @@ -87,12 +87,26 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no // allocate high resolution density field _totalStepsBig = 0; _densityBig = new float[_totalCellsBig]; - _densityBigOld = new float[_totalCellsBig]; + _densityBigOld = new float[_totalCellsBig]; for(int i = 0; i < _totalCellsBig; i++) { _densityBig[i] = _densityBigOld[i] = 0.; } + + /* fire */ + _flameBig = _fuelBig = _fuelBigOld = NULL; + _reactBig = _reactBigOld = NULL; + if (init_fire) { + initFire(); + } + /* colors */ + _color_rBig = _color_rBigOld = NULL; + _color_gBig = _color_gBigOld = NULL; + _color_bBig = _color_bBigOld = NULL; + if (init_colors) { + initColors(0.0f, 0.0f, 0.0f); + } // allocate & init texture coordinates _tcU = new float[_totalCellsSm]; @@ -128,12 +142,64 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no */ } +void WTURBULENCE::initFire() +{ + if (!_fuelBig) { + _flameBig = new float[_totalCellsBig]; + _fuelBig = new float[_totalCellsBig]; + _fuelBigOld = new float[_totalCellsBig]; + _reactBig = new float[_totalCellsBig]; + _reactBigOld = new float[_totalCellsBig]; + + for(int i = 0; i < _totalCellsBig; i++) { + _flameBig[i] = + _fuelBig[i] = + _fuelBigOld[i] = 0.; + _reactBig[i] = + _reactBigOld[i] = 0.; + } + } +} + +void WTURBULENCE::initColors(float init_r, float init_g, float init_b) +{ + if (!_color_rBig) { + _color_rBig = new float[_totalCellsBig]; + _color_rBigOld = new float[_totalCellsBig]; + _color_gBig = new float[_totalCellsBig]; + _color_gBigOld = new float[_totalCellsBig]; + _color_bBig = new float[_totalCellsBig]; + _color_bBigOld = new float[_totalCellsBig]; + + for(int i = 0; i < _totalCellsBig; i++) { + _color_rBig[i] = _densityBig[i] * init_r; + _color_rBigOld[i] = 0.0f; + _color_gBig[i] = _densityBig[i] * init_g; + _color_gBigOld[i] = 0.0f; + _color_bBig[i] = _densityBig[i] * init_b; + _color_bBigOld[i] = 0.0f; + } + } +} + ////////////////////////////////////////////////////////////////////// // destructor ////////////////////////////////////////////////////////////////////// WTURBULENCE::~WTURBULENCE() { delete[] _densityBig; delete[] _densityBigOld; + if (_flameBig) delete[] _flameBig; + if (_fuelBig) delete[] _fuelBig; + if (_fuelBigOld) delete[] _fuelBigOld; + if (_reactBig) delete[] _reactBig; + if (_reactBigOld) delete[] _reactBigOld; + + if (_color_rBig) delete[] _color_rBig; + if (_color_rBigOld) delete[] _color_rBigOld; + if (_color_gBig) delete[] _color_gBig; + if (_color_gBigOld) delete[] _color_gBigOld; + if (_color_bBig) delete[] _color_bBig; + if (_color_bBigOld) delete[] _color_bBigOld; delete[] _tcU; delete[] _tcV; @@ -757,8 +823,10 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // enlarge timestep to match grid const float dt = dtOrg * _amplify; const float invAmp = 1.0f / _amplify; - float *tempBig1 = (float *)calloc(_totalCellsBig, sizeof(float)); - float *tempBig2 = (float *)calloc(_totalCellsBig, sizeof(float)); + float *tempFuelBig = NULL, *tempReactBig = NULL; + float *tempColor_rBig = NULL, *tempColor_gBig = NULL, *tempColor_bBig = NULL; + float *tempDensityBig = (float *)calloc(_totalCellsBig, sizeof(float)); + float *tempBig = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUy = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUz = (float *)calloc(_totalCellsBig, sizeof(float)); @@ -767,11 +835,21 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa float *eigMin = (float *)calloc(_totalCellsSm, sizeof(float)); float *eigMax = (float *)calloc(_totalCellsSm, sizeof(float)); + if (_fuelBig) { + tempFuelBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempReactBig = (float *)calloc(_totalCellsBig, sizeof(float)); + } + if (_color_rBig) { + tempColor_rBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempColor_gBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempColor_bBig = (float *)calloc(_totalCellsBig, sizeof(float)); + } + memset(_tcTemp, 0, sizeof(float)*_totalCellsSm); // prepare textures - advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2); + advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempDensityBig, tempBig); // do wavelet decomposition of energy computeEnergy(_energy, xvel, yvel, zvel, obstacles); @@ -972,6 +1050,11 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // prepare density for an advection SWAP_POINTERS(_densityBig, _densityBigOld); + SWAP_POINTERS(_fuelBig, _fuelBigOld); + SWAP_POINTERS(_reactBig, _reactBigOld); + SWAP_POINTERS(_color_rBig, _color_rBigOld); + SWAP_POINTERS(_color_gBig, _color_gBigOld); + SWAP_POINTERS(_color_bBig, _color_bBigOld); // based on the maximum velocity present, see if we need to substep, // but cap the maximum number of substeps to 5 @@ -1017,7 +1100,21 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa int zEnd = (int)((float)(i+1)*partSize + 0.5f); #endif FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, tempBig1, _resBig, zBegin, zEnd); + _densityBigOld, tempDensityBig, _resBig, zBegin, zEnd); + if (_fuelBig) { + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _fuelBigOld, tempFuelBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _reactBigOld, tempReactBig, _resBig, zBegin, zEnd); + } + if (_color_rBig) { + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _color_rBigOld, tempColor_rBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _color_gBigOld, tempColor_gBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _color_bBigOld, tempColor_bBig, _resBig, zBegin, zEnd); + } #if PARALLEL==1 } @@ -1030,18 +1127,43 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa int zEnd = (int)((float)(i+1)*partSize + 0.5f); #endif FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL, zBegin, zEnd); + _densityBigOld, _densityBig, tempDensityBig, tempBig, _resBig, NULL, zBegin, zEnd); + if (_fuelBig) { + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _fuelBigOld, _fuelBig, tempFuelBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _reactBigOld, _reactBig, tempReactBig, tempBig, _resBig, NULL, zBegin, zEnd); + } + if (_color_rBig) { + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _color_rBigOld, _color_rBig, tempColor_rBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _color_gBigOld, _color_gBig, tempColor_gBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _color_bBigOld, _color_bBig, tempColor_bBig, tempBig, _resBig, NULL, zBegin, zEnd); + } #if PARALLEL==1 } } #endif - if (substep < totalSubsteps - 1) + if (substep < totalSubsteps - 1) { SWAP_POINTERS(_densityBig, _densityBigOld); + SWAP_POINTERS(_fuelBig, _fuelBigOld); + SWAP_POINTERS(_reactBig, _reactBigOld); + SWAP_POINTERS(_color_rBig, _color_rBigOld); + SWAP_POINTERS(_color_gBig, _color_gBigOld); + SWAP_POINTERS(_color_bBig, _color_bBigOld); + } } // substep - free(tempBig1); - free(tempBig2); + free(tempDensityBig); + if (tempFuelBig) free(tempFuelBig); + if (tempReactBig) free(tempReactBig); + if (tempColor_rBig) free(tempColor_rBig); + if (tempColor_gBig) free(tempColor_gBig); + if (tempColor_bBig) free(tempColor_bBig); + free(tempBig); free(bigUx); free(bigUy); free(bigUz); @@ -1050,6 +1172,15 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // wipe the density borders FLUID_3D::setZeroBorder(_densityBig, _resBig, 0 , _resBig[2]); + if (_fuelBig) { + FLUID_3D::setZeroBorder(_fuelBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_reactBig, _resBig, 0 , _resBig[2]); + } + if (_color_rBig) { + FLUID_3D::setZeroBorder(_color_rBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_color_gBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_color_bBig, _resBig, 0 , _resBig[2]); + } // reset texture coordinates now in preparation for next timestep // Shouldn't do this before generating the noise because then the diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h index f31ca100fdf..1655bd95d32 100644 --- a/intern/smoke/intern/WTURBULENCE.h +++ b/intern/smoke/intern/WTURBULENCE.h @@ -36,10 +36,13 @@ class WTURBULENCE { public: // both config files can be NULL, altCfg might override values from noiseCfg - WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype); + WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors); /// destructor virtual ~WTURBULENCE(); + + void initFire(); + void initColors(float init_r, float init_g, float init_b); void setNoise(int type); void initBlenderRNA(float *strength); @@ -63,6 +66,8 @@ class WTURBULENCE // access functions inline float* getDensityBig() { return _densityBig; } + inline float* getFlameBig() { return _flameBig; } + inline float* getFuelBig() { return _fuelBig; } inline float* getArrayTcU() { return _tcU; } inline float* getArrayTcV() { return _tcV; } inline float* getArrayTcW() { return _tcW; } @@ -111,6 +116,18 @@ class WTURBULENCE float* _densityBig; float* _densityBigOld; + float* _flameBig; + float* _fuelBig; + float* _fuelBigOld; + float* _reactBig; + float* _reactBigOld; + + float* _color_rBig; + float* _color_rBigOld; + float* _color_gBig; + float* _color_gBigOld; + float* _color_bBig; + float* _color_bBigOld; // texture coordinates for noise float* _tcU; diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index 4bbf8e0a82b..e51c3176699 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -30,6 +30,7 @@ #include "FLUID_3D.h" #include "WTURBULENCE.h" +#include "spectrum.h" #include <stdio.h> #include <stdlib.h> @@ -37,22 +38,16 @@ #include "../extern/smoke_API.h" /* to ensure valid prototypes */ -// y in smoke is z in blender -extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dtdef) +extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors) { - // smoke lib uses y as top-bottom/vertical axis where blender uses z - FLUID_3D *fluid = new FLUID_3D(res, p0, dtdef); - - // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]); - + FLUID_3D *fluid = new FLUID_3D(res, dx, dtdef, use_heat, use_fire, use_colors); return fluid; } -extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype) +extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors) { - // initialize wavelet turbulence if(amplify) - return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype); + return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, use_fire, use_colors); else return NULL; } @@ -71,7 +66,6 @@ extern "C" void smoke_turbulence_free(WTURBULENCE *wt) extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */) { - // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1]; return x + y * max_x + z * max_x*max_y; } @@ -80,137 +74,134 @@ extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z return x + y * max_x; } -extern "C" void smoke_step(FLUID_3D *fluid, float dtSubdiv) +extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv) { - fluid->step(dtSubdiv); + if (fluid->_fuel) { + fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_flame, fluid->_heat, + fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv); + } + fluid->step(dtSubdiv, gravity); } extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid) { + if (wt->_fuelBig) { + fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, wt->_flameBig, 0, + wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt); + } wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); } -extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli) +extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp) { - fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli); + fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli, burning_rate, flame_smoke, flame_smoke_color, flame_vorticity, flame_ignition_temp, flame_max_temp); } -extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) +extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) { - float *density = fluid->_density; - //float *densityOld = fluid->_densityOld; - float *heat = fluid->_heat; + wt->initBlenderRNA(strength); +} +static void data_dissolve(float *density, float *heat, float *r, float *g, float *b, int total_cells, int speed, int log) +{ if(log) { /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes; + float fac = 1.0f - (1.0f / (float)speed); - for(size_t i = 0; i < size; i++) + for(size_t i = 0; i < total_cells; i++) { - density[i] *= (1.0 - dydx); - - if(density[i] < 0.0f) - density[i] = 0.0f; - - heat[i] *= (1.0 - dydx); - - /*if(heat[i] < 0.0f) - heat[i] = 0.0f;*/ + /* density */ + density[i] *= fac; + + /* heat */ + if (heat) { + heat[i] *= fac; + } + + /* color */ + if (r) { + r[i] *= fac; + g[i] *= fac; + b[i] *= fac; + } } } else // linear falloff { /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes; + float dydx = 1.0f / (float)speed; - for(size_t i = 0; i < size; i++) + for(size_t i = 0; i < total_cells; i++) { + float d = density[i]; + /* density */ density[i] -= dydx; - if(density[i] < 0.0f) density[i] = 0.0f; - if(abs(heat[i]) < dydx) heat[i] = 0.0f; - else if (heat[i]>0.0f) heat[i] -= dydx; - else if (heat[i]<0.0f) heat[i] += dydx; + /* heat */ + if (heat) { + if(abs(heat[i]) < dydx) heat[i] = 0.0f; + else if (heat[i]>0.0f) heat[i] -= dydx; + else if (heat[i]<0.0f) heat[i] += dydx; + } + + /* color */ + if (r && d) { + r[i] *= (density[i]/d); + g[i] *= (density[i]/d); + b[i] *= (density[i]/d); + } } } } -extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) -{ - float *density = wt->getDensityBig(); - Vec3Int r = wt->getResBig(); - - if(log) - { - /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= r[0] * r[1] * r[2]; - - for(size_t i = 0; i < size; i++) - { - density[i] *= (1.0 - dydx); - - if(density[i] < 0.0f) - density[i] = 0.0f; - } - } - else // linear falloff - { - /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= r[0] * r[1] * r[2]; - - for(size_t i = 0; i < size; i++) - { - density[i] -= dydx; - - if(density[i] < 0.0f) - density[i] = 0.0f; - } - } -} - -extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) +extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) { - wt->initBlenderRNA(strength); + data_dissolve(fluid->_density, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, speed, log); } -template < class T > inline T ABS( T a ) +extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) { - return (0 < a) ? a : -a ; + data_dissolve(wt->_densityBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, speed, log); } -extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles) +extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, + float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles) { *dens = fluid->_density; - *densold = fluid->_densityOld; + *fuel = fluid->_fuel; + *react = fluid->_react; + *flame = fluid->_flame; *heat = fluid->_heat; *heatold = fluid->_heatOld; *vx = fluid->_xVelocity; *vy = fluid->_yVelocity; *vz = fluid->_zVelocity; - *vxold = fluid->_xVelocityOld; - *vyold = fluid->_yVelocityOld; - *vzold = fluid->_zVelocityOld; + *r = fluid->_color_r; + *g = fluid->_color_g; + *b = fluid->_color_b; *obstacles = fluid->_obstacles; *dt = fluid->_dt; *dx = fluid->_dx; - } -extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw) +extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, + float **r, float **g, float **b , float **tcu, float **tcv, float **tcw) { if(!wt) return; *dens = wt->_densityBig; - *densold = wt->_densityBigOld; + *fuel = wt->_fuelBig; + *react = wt->_reactBig; + *flame = wt->_flameBig; + *r = wt->_color_rBig; + *g = wt->_color_gBig; + *b = wt->_color_bBig; *tcu = wt->_tcU; *tcv = wt->_tcV; *tcw = wt->_tcW; @@ -221,6 +212,16 @@ extern "C" float *smoke_get_density(FLUID_3D *fluid) return fluid->_density; } +extern "C" float *smoke_get_fuel(FLUID_3D *fluid) +{ + return fluid->_fuel; +} + +extern "C" float *smoke_get_react(FLUID_3D *fluid) +{ + return fluid->_react; +} + extern "C" float *smoke_get_heat(FLUID_3D *fluid) { return fluid->_heat; @@ -256,15 +257,137 @@ extern "C" float *smoke_get_force_z(FLUID_3D *fluid) return fluid->_zForce; } +extern "C" float *smoke_get_flame(FLUID_3D *fluid) +{ + return fluid->_flame; +} + +extern "C" float *smoke_get_color_r(FLUID_3D *fluid) +{ + return fluid->_color_r; +} + +extern "C" float *smoke_get_color_g(FLUID_3D *fluid) +{ + return fluid->_color_g; +} + +extern "C" float *smoke_get_color_b(FLUID_3D *fluid) +{ + return fluid->_color_b; +} + +static void get_rgba(float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential) +{ + int i; + int m = 4, i_g = 1, i_b = 2, i_a = 3; + /* sequential data */ + if (sequential) { + m = 1; + i_g *= total_cells; + i_b *= total_cells; + i_a *= total_cells; + } + + for (i=0; i<total_cells; i++) { + float alpha = a[i]; + if (alpha) { + data[i*m ] = r[i]; + data[i*m+i_g] = g[i]; + data[i*m+i_b] = b[i]; + } + else { + data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f; + } + data[i*m+i_a] = alpha; + } +} + +extern "C" void smoke_get_rgba(FLUID_3D *fluid, float *data, int sequential) +{ + get_rgba(fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_density, fluid->_totalCells, data, sequential); +} + +extern "C" void smoke_turbulence_get_rgba(WTURBULENCE *wt, float *data, int sequential) +{ + get_rgba(wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_densityBig, wt->_totalCellsBig, data, sequential); +} + +/* get a single color premultiplied voxel grid */ +static void get_rgba_from_density(float color[3], float *a, int total_cells, float *data, int sequential) +{ + int i; + int m = 4, i_g = 1, i_b = 2, i_a = 3; + /* sequential data */ + if (sequential) { + m = 1; + i_g *= total_cells; + i_b *= total_cells; + i_a *= total_cells; + } + + for (i=0; i<total_cells; i++) { + float alpha = a[i]; + if (alpha) { + data[i*m ] = color[0] * alpha; + data[i*m+i_g] = color[1] * alpha; + data[i*m+i_b] = color[2] * alpha; + } + else { + data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f; + } + data[i*m+i_a] = alpha; + } +} + +extern "C" void smoke_get_rgba_from_density(FLUID_3D *fluid, float color[3], float *data, int sequential) +{ + get_rgba_from_density(color, fluid->_density, fluid->_totalCells, data, sequential); +} + +extern "C" void smoke_turbulence_get_rgba_from_density(WTURBULENCE *wt, float color[3], float *data, int sequential) +{ + get_rgba_from_density(color, wt->_densityBig, wt->_totalCellsBig, data, sequential); +} + extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt) { return wt ? wt->getDensityBig() : NULL; } +extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt) +{ + return wt ? wt->getFuelBig() : NULL; +} + +extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt) +{ + return wt ? wt->_reactBig : NULL; +} + +extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt) +{ + return wt ? wt->_color_rBig : NULL; +} + +extern "C" float *smoke_turbulence_get_color_g(WTURBULENCE *wt) +{ + return wt ? wt->_color_gBig : NULL; +} + +extern "C" float *smoke_turbulence_get_color_b(WTURBULENCE *wt) +{ + return wt ? wt->_color_bBig : NULL; +} + +extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt) +{ + return wt ? wt->getFlameBig() : NULL; +} + extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) { - if(wt) - { + if(wt) { Vec3Int r = wt->getResBig(); res[0] = r[0]; res[1] = r[1]; @@ -272,6 +395,15 @@ extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) } } +extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt) +{ + if(wt) { + Vec3Int r = wt->getResBig(); + return r[0]*r[1]*r[2]; + } + return 0; +} + extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid) { return fluid->_obstacles; @@ -295,3 +427,61 @@ extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type) { wt->setNoise(type); } + +extern "C" void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2) +{ + spectrum(t1, t2, width, spec); +} + +extern "C" int smoke_has_heat(FLUID_3D *fluid) +{ + return (fluid->_heat) ? 1 : 0; +} + +extern "C" int smoke_has_fuel(FLUID_3D *fluid) +{ + return (fluid->_fuel) ? 1 : 0; +} + +extern "C" int smoke_has_colors(FLUID_3D *fluid) +{ + return (fluid->_color_r && fluid->_color_g && fluid->_color_b) ? 1 : 0; +} + +extern "C" int smoke_turbulence_has_fuel(WTURBULENCE *wt) +{ + return (wt->_fuelBig) ? 1 : 0; +} + +extern "C" int smoke_turbulence_has_colors(WTURBULENCE *wt) +{ + return (wt->_color_rBig && wt->_color_gBig && wt->_color_bBig) ? 1 : 0; +} + +/* additional field initialization */ +extern "C" void smoke_ensure_heat(FLUID_3D *fluid) +{ + if (fluid) { + fluid->initHeat(); + } +} + +extern "C" void smoke_ensure_fire(FLUID_3D *fluid, WTURBULENCE *wt) +{ + if (fluid) { + fluid->initFire(); + } + if (wt) { + wt->initFire(); + } +} + +extern "C" void smoke_ensure_colors(FLUID_3D *fluid, WTURBULENCE *wt, float init_r, float init_g, float init_b) +{ + if (fluid) { + fluid->initColors(init_r, init_g, init_b); + } + if (wt) { + wt->initColors(init_r, init_g, init_b); + } +}
\ No newline at end of file diff --git a/intern/smoke/intern/spectrum.cpp b/intern/smoke/intern/spectrum.cpp new file mode 100644 index 00000000000..359f3ab73a9 --- /dev/null +++ b/intern/smoke/intern/spectrum.cpp @@ -0,0 +1,426 @@ +/* + Colour Rendering of Spectra + + by John Walker + http://www.fourmilab.ch/ + + Last updated: March 9, 2003 + + This program is in the public domain. + + For complete information about the techniques employed in + this program, see the World-Wide Web document: + + http://www.fourmilab.ch/documents/specrend/ + + The xyz_to_rgb() function, which was wrong in the original + version of this program, was corrected by: + + Andrew J. S. Hamilton 21 May 1999 + Andrew.Hamilton@Colorado.EDU + http://casa.colorado.edu/~ajsh/ + + who also added the gamma correction facilities and + modified constrain_rgb() to work by desaturating the + colour by adding white. + + A program which uses these functions to plot CIE + "tongue" diagrams called "ppmcie" is included in + the Netpbm graphics toolkit: + http://netpbm.sourceforge.net/ + (The program was called cietoppm in earlier + versions of Netpbm.) + +*/ + +#include <stdio.h> +#include <math.h> +#include "spectrum.h" + +/* A colour system is defined by the CIE x and y coordinates of + its three primary illuminants and the x and y coordinates of + the white point. */ + +struct colourSystem { + const char *name; /* Colour system name */ + double xRed, yRed, /* Red x, y */ + xGreen, yGreen, /* Green x, y */ + xBlue, yBlue, /* Blue x, y */ + xWhite, yWhite, /* White point x, y */ + gamma; /* Gamma correction for system */ +}; + +/* White point chromaticities. */ + +#define IlluminantC 0.3101, 0.3162 /* For NTSC television */ +#define IlluminantD65 0.3127, 0.3291 /* For EBU and SMPTE */ +#define IlluminantE 0.33333333, 0.33333333 /* CIE equal-energy illuminant */ + +/* Gamma of nonlinear correction. + + See Charles Poynton's ColorFAQ Item 45 and GammaFAQ Item 6 at: + + http://www.poynton.com/ColorFAQ.html + http://www.poynton.com/GammaFAQ.html + +*/ + +#define GAMMA_REC709 0 /* Rec. 709 */ + +static struct colourSystem + /* Name xRed yRed xGreen yGreen xBlue yBlue White point Gamma */ +#if 0 /* UNUSED */ + NTSCsystem = { "NTSC", 0.67, 0.33, 0.21, 0.71, 0.14, 0.08, IlluminantC, GAMMA_REC709 }, + EBUsystem = { "EBU (PAL/SECAM)", 0.64, 0.33, 0.29, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 }, + SMPTEsystem = { "SMPTE", 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, IlluminantD65, GAMMA_REC709 }, + HDTVsystem = { "HDTV", 0.670, 0.330, 0.210, 0.710, 0.150, 0.060, IlluminantD65, GAMMA_REC709 }, +#endif + + CIEsystem = { "CIE", 0.7355, 0.2645, 0.2658, 0.7243, 0.1669, 0.0085, IlluminantE, GAMMA_REC709 }; + +#if 0 /* UNUSED */ + Rec709system = { "CIE REC 709", 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 }; +#endif + +/* UPVP_TO_XY + + Given 1976 coordinates u', v', determine 1931 chromaticities x, y + +*/ + +#if 0 /* UNUSED */ +static void upvp_to_xy(double up, double vp, double *xc, double *yc) +{ + *xc = (9 * up) / ((6 * up) - (16 * vp) + 12); + *yc = (4 * vp) / ((6 * up) - (16 * vp) + 12); +} +#endif + +/* XY_TO_UPVP + + Given 1931 chromaticities x, y, determine 1976 coordinates u', v' + +*/ + +#if 0 /* UNUSED */ +static void xy_to_upvp(double xc, double yc, double *up, double *vp) +{ + *up = (4 * xc) / ((-2 * xc) + (12 * yc) + 3); + *vp = (9 * yc) / ((-2 * xc) + (12 * yc) + 3); +} +#endif + +/* XYZ_TO_RGB + + Given an additive tricolour system CS, defined by the CIE x + and y chromaticities of its three primaries (z is derived + trivially as 1-(x+y)), and a desired chromaticity (XC, YC, + ZC) in CIE space, determine the contribution of each + primary in a linear combination which sums to the desired + chromaticity. If the requested chromaticity falls outside + the Maxwell triangle (colour gamut) formed by the three + primaries, one of the r, g, or b weights will be negative. + + Caller can use constrain_rgb() to desaturate an + outside-gamut colour to the closest representation within + the available gamut and/or norm_rgb to normalise the RGB + components so the largest nonzero component has value 1. + +*/ + +static void xyz_to_rgb(struct colourSystem *cs, + double xc, double yc, double zc, + double *r, double *g, double *b) +{ + double xr, yr, zr, xg, yg, zg, xb, yb, zb; + double xw, yw, zw; + double rx, ry, rz, gx, gy, gz, bx, by, bz; + double rw, gw, bw; + + xr = cs->xRed; yr = cs->yRed; zr = 1 - (xr + yr); + xg = cs->xGreen; yg = cs->yGreen; zg = 1 - (xg + yg); + xb = cs->xBlue; yb = cs->yBlue; zb = 1 - (xb + yb); + + xw = cs->xWhite; yw = cs->yWhite; zw = 1 - (xw + yw); + + /* xyz -> rgb matrix, before scaling to white. */ + + rx = (yg * zb) - (yb * zg); ry = (xb * zg) - (xg * zb); rz = (xg * yb) - (xb * yg); + gx = (yb * zr) - (yr * zb); gy = (xr * zb) - (xb * zr); gz = (xb * yr) - (xr * yb); + bx = (yr * zg) - (yg * zr); by = (xg * zr) - (xr * zg); bz = (xr * yg) - (xg * yr); + + /* White scaling factors. + Dividing by yw scales the white luminance to unity, as conventional. */ + + rw = ((rx * xw) + (ry * yw) + (rz * zw)) / yw; + gw = ((gx * xw) + (gy * yw) + (gz * zw)) / yw; + bw = ((bx * xw) + (by * yw) + (bz * zw)) / yw; + + /* xyz -> rgb matrix, correctly scaled to white. */ + + rx = rx / rw; ry = ry / rw; rz = rz / rw; + gx = gx / gw; gy = gy / gw; gz = gz / gw; + bx = bx / bw; by = by / bw; bz = bz / bw; + + /* rgb of the desired point */ + + *r = (rx * xc) + (ry * yc) + (rz * zc); + *g = (gx * xc) + (gy * yc) + (gz * zc); + *b = (bx * xc) + (by * yc) + (bz * zc); +} + +/* INSIDE_GAMUT + + Test whether a requested colour is within the gamut + achievable with the primaries of the current colour + system. This amounts simply to testing whether all the + primary weights are non-negative. */ + +#if 0 /* UNUSED */ +static int inside_gamut(double r, double g, double b) +{ + return (r >= 0) && (g >= 0) && (b >= 0); +} +#endif + +/* CONSTRAIN_RGB + + If the requested RGB shade contains a negative weight for + one of the primaries, it lies outside the colour gamut + accessible from the given triple of primaries. Desaturate + it by adding white, equal quantities of R, G, and B, enough + to make RGB all positive. The function returns 1 if the + components were modified, zero otherwise. + +*/ + +static int constrain_rgb(double *r, double *g, double *b) +{ + double w; + + /* Amount of white needed is w = - min(0, *r, *g, *b) */ + + w = (0 < *r) ? 0 : *r; + w = (w < *g) ? w : *g; + w = (w < *b) ? w : *b; + w = -w; + + /* Add just enough white to make r, g, b all positive. */ + + if (w > 0) { + *r += w; *g += w; *b += w; + return 1; /* Colour modified to fit RGB gamut */ + } + + return 0; /* Colour within RGB gamut */ +} + +/* GAMMA_CORRECT_RGB + + Transform linear RGB values to nonlinear RGB values. Rec. + 709 is ITU-R Recommendation BT. 709 (1990) ``Basic + Parameter Values for the HDTV Standard for the Studio and + for International Programme Exchange'', formerly CCIR Rec. + 709. For details see + + http://www.poynton.com/ColorFAQ.html + http://www.poynton.com/GammaFAQ.html +*/ + +#if 0 /* UNUSED */ +static void gamma_correct(const struct colourSystem *cs, double *c) +{ + double gamma; + + gamma = cs->gamma; + + if (gamma == GAMMA_REC709) { + /* Rec. 709 gamma correction. */ + double cc = 0.018; + + if (*c < cc) { + *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc; + } else { + *c = (1.099 * pow(*c, 0.45)) - 0.099; + } + } else { + /* Nonlinear colour = (Linear colour)^(1/gamma) */ + *c = pow(*c, 1.0 / gamma); + } +} + +static void gamma_correct_rgb(const struct colourSystem *cs, double *r, double *g, double *b) +{ + gamma_correct(cs, r); + gamma_correct(cs, g); + gamma_correct(cs, b); +} +#endif + +/* NORM_RGB + + Normalise RGB components so the most intense (unless all + are zero) has a value of 1. + +*/ + +static void norm_rgb(double *r, double *g, double *b) +{ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) + double greatest = Max(*r, Max(*g, *b)); + + if (greatest > 0) { + *r /= greatest; + *g /= greatest; + *b /= greatest; + } +#undef Max +} + +/* SPECTRUM_TO_XYZ + + Calculate the CIE X, Y, and Z coordinates corresponding to + a light source with spectral distribution given by the + function SPEC_INTENS, which is called with a series of + wavelengths between 380 and 780 nm (the argument is + expressed in meters), which returns emittance at that + wavelength in arbitrary units. The chromaticity + coordinates of the spectrum are returned in the x, y, and z + arguments which respect the identity: + + x + y + z = 1. +*/ + +static void spectrum_to_xyz(double (*spec_intens)(double wavelength), + double *x, double *y, double *z) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, XYZ; + + /* CIE colour matching functions xBar, yBar, and zBar for + wavelengths from 380 through 780 nanometers, every 5 + nanometers. For a wavelength lambda in this range: + + cie_colour_match[(lambda - 380) / 5][0] = xBar + cie_colour_match[(lambda - 380) / 5][1] = yBar + cie_colour_match[(lambda - 380) / 5][2] = zBar + + To save memory, this table can be declared as floats + rather than doubles; (IEEE) float has enough + significant bits to represent the values. It's declared + as a double here to avoid warnings about "conversion + between floating-point types" from certain persnickety + compilers. */ + + static double cie_colour_match[81][3] = { + {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201}, + {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102}, + {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456}, + {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230}, + {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721}, + {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281}, + {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130}, + {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533}, + {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582}, + {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573}, + {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203}, + {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057}, + {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021}, + {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014}, + {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008}, + {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002}, + {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000}, + {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000}, + {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000}, + {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000}, + {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000}, + {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000}, + {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000}, + {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000}, + {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000}, + {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000}, + {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000} + }; + + for (i = 0, lambda = 380; lambda < 780.1; i++, lambda += 5) { + double Me; + + Me = (*spec_intens)(lambda); + X += Me * cie_colour_match[i][0]; + Y += Me * cie_colour_match[i][1]; + Z += Me * cie_colour_match[i][2]; + } + XYZ = (X + Y + Z); + *x = X / XYZ; + *y = Y / XYZ; + *z = Z / XYZ; +} + +/* BB_SPECTRUM + + Calculate, by Planck's radiation law, the emittance of a black body + of temperature bbTemp at the given wavelength (in metres). */ + +double bbTemp = 5000; /* Hidden temperature argument + to BB_SPECTRUM. */ +static double bb_spectrum(double wavelength) +{ + double wlm = wavelength * 1e-9; /* Wavelength in meters */ + + return (3.74183e-16 * pow(wlm, -5.0)) / + (exp(1.4388e-2 / (wlm * bbTemp)) - 1.0); +} + +static void xyz_to_lms(double x, double y, double z, double* l, double* m, double* s) +{ + *l = 0.3897*x + 0.6890*y - 0.0787*z; + *m = -0.2298*x + 1.1834*y + 0.0464*z; + *s = z; +} + +static void lms_to_xyz(double l, double m, double s, double* x, double *y, double* z) +{ + *x = 1.9102*l - 1.1121*m + 0.2019*s; + *y = 0.3709*l + 0.6290*m + 0.0000*s; + *z = s; +} + +void spectrum(double t1, double t2, int N, unsigned char* d) +{ + int i,j,dj; + double X,Y,Z,R,G,B,L,M,S, Lw, Mw, Sw; + struct colourSystem *cs = &CIEsystem; + + j = 0; dj = 1; + if (t1<t2) { + double t = t1; + t1 = t2; + t2 = t; + j = N-1; dj=-1; + } + + for (i=0; i<N; i++) { + bbTemp = t1 + (t2-t1)/N*i; + + // integrate blackbody radiation spectrum to XYZ + spectrum_to_xyz(bb_spectrum, &X, &Y, &Z); + + // normalize highest temperature to white (in LMS system) + xyz_to_lms(X,Y,Z,&L,&M,&S); + if (i==0) { + Lw=1/L; Mw=1/M; Sw=1/S; + } + L *= Lw; M *= Mw; S *= Sw; + lms_to_xyz(L,M,S,&X,&Y,&Z); + + // convert to RGB + xyz_to_rgb(cs, X, Y, Z, &R, &G, &B); + constrain_rgb(&R, &G, &B); + norm_rgb(&R, &G, &B); + d[(j<<2)] = (unsigned char) ((double)R*255); + d[(j<<2)+1] = (unsigned char) ((double)G*255); + d[(j<<2)+2] = (unsigned char) ((double)B*255); + d[(j<<2)+3] = (B>0.1)? B*255 : 0; + j += dj; + } +} diff --git a/intern/smoke/intern/spectrum.h b/intern/smoke/intern/spectrum.h new file mode 100644 index 00000000000..9edd9ad887c --- /dev/null +++ b/intern/smoke/intern/spectrum.h @@ -0,0 +1,6 @@ +#ifndef __SPECTRUM_H +#define __SPECTRUM_H + +void spectrum(double t1, double t2, int n, unsigned char* d); + +#endif diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png Binary files differindex a0d460b0153..09a63f4c47d 100644 --- a/release/datafiles/blender_icons.png +++ b/release/datafiles/blender_icons.png diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend Binary files differindex 3db58b8fb69..8b0e052fad8 100644 --- a/release/datafiles/startup.blend +++ b/release/datafiles/startup.blend diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index ab68c9424cd..7e604c5de4c 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -311,7 +311,7 @@ def disable(module_name, default_set=True): # possible this addon is from a previous session and didn't load a # module this time. So even if the module is not found, still disable # the addon in the user prefs. - if mod: + if mod and getattr(mod, "__addon_enabled__", False) is not False: mod.__addon_enabled__ = False mod.__addon_persistent = False @@ -323,7 +323,8 @@ def disable(module_name, default_set=True): import traceback traceback.print_exc() else: - print("addon_utils.disable", module_name, "not loaded") + print("addon_utils.disable: %s not %s." % + (module_name, "disabled" if mod is None else "loaded")) # could be in more then once, unlikely but better do this just in case. addons = _bpy.context.user_preferences.addons diff --git a/release/scripts/modules/bl_i18n_utils/bl_process_msg.py b/release/scripts/modules/bl_i18n_utils/bl_process_msg.py index 33d3be63b0b..cf545840b6f 100644 --- a/release/scripts/modules/bl_i18n_utils/bl_process_msg.py +++ b/release/scripts/modules/bl_i18n_utils/bl_process_msg.py @@ -298,7 +298,7 @@ def dump_messages_pytext(messages, check_ctxt): # check it has a 'text' argument for (arg_pos, (arg_kw, arg)) in enumerate(func.parameters.items()): if ((arg_kw in translate_kw) and - (arg.is_output == False) and + (arg.is_output is False) and (arg.type == 'STRING')): func_translate_args.setdefault(func_id, []).append((arg_kw, diff --git a/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py b/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py index a15bea9ef0d..533dded3c57 100755 --- a/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py +++ b/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py @@ -39,6 +39,8 @@ except: TRUNK_PO_DIR = settings.TRUNK_PO_DIR BRANCHES_DIR = settings.BRANCHES_DIR +IMPORT_LANGUAGES_SKIP = settings.IMPORT_LANGUAGES_SKIP + RTL_PREPROCESS_FILE = settings.RTL_PREPROCESS_FILE PY3 = settings.PYTHON3_EXEC @@ -63,7 +65,7 @@ def main(): threshold = float(args.threshold) / 100.0 for lang in os.listdir(BRANCHES_DIR): - if args.langs and lang not in args.langs: + if (args.langs and lang not in args.langs) or lang in IMPORT_LANGUAGES_SKIP: continue po = os.path.join(BRANCHES_DIR, lang, ".".join((lang, "po"))) if os.path.exists(po): diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index d323dd37979..26a4cbaeb01 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -35,6 +35,9 @@ import os.path # into /trunk, as a percentage. -1 means "import everything". IMPORT_MIN_LEVEL = -1 +# Languages in /branches we do not want to import in /trunk currently... +IMPORT_LANGUAGES_SKIP = {'bg', 'ca', 'fi', 'el', 'ko', 'ne', 'pl', 'ro'} + # The comment prefix used in generated messages.txt file. COMMENT_PREFIX = "#~ " @@ -98,7 +101,9 @@ PYGETTEXT_KEYWORDS = (() + tuple((r"{}\(\s*" + _msg_re + r"\s*\)").format(it) for it in ("IFACE_", "TIP_", "N_")) + tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*" + _msg_re + r"\s*\)").format(it) - for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_")) + for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_")) + + tuple(("{}\\([^\"',]+,(?:[^\"',]+,)?\\s*" + _msg_re + r"\s*(?:\)|,)").format(it) + for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf")) ) ESCAPE_RE = ( @@ -167,6 +172,8 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "uk_UA", "tr_TR", "hu_HU", + "et_EE", + "eo", "available with", # Is part of multi-line msg. "virtual parents", # Is part of multi-line msg. "description", # Addons' field. :/ diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index 46b369146b7..d8cb77cd364 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -37,10 +37,12 @@ dict_uimsgs = { "aren", # aren't "betweens", # yuck! in-betweens! "boolean", "booleans", + "couldn", #couldn't "decrement", "derivate", "doesn", # doesn't "fader", + "hasn", # hasn't "hoc", # ad-hoc "indices", "iridas", @@ -90,6 +92,7 @@ dict_uimsgs = { "gridline", "hemi", "inscatter", "inscattering", + "libdata", "lightless", "lookup", "lookups", "mathutils", @@ -101,6 +104,7 @@ dict_uimsgs = { "multires", "multiresolution", "multisampling", "multitexture", + "multiuser", "namespace", "keyconfig", "playhead", @@ -157,7 +161,7 @@ dict_uimsgs = { "unreacted", "unregister", "unselected", - "unsubdivided", + "unsubdivided", "unsubdivide", "unshadowed", "unspill", "unstitchable", @@ -185,6 +189,7 @@ dict_uimsgs = { "selectability", "slurph", "stitchable", + "symmetrize", "trackability", "transmissivity", "rasterized", "rasterization", @@ -290,6 +295,7 @@ dict_uimsgs = { "crossfade", "deinterlace", "dropoff", + "dv", "eigenvectors", "equirectangular", "fisheye", @@ -303,6 +309,7 @@ dict_uimsgs = { "midtones", "mipmap", "mipmaps", "mip", "ngon", "ngons", + "ntsc", "nurb", "nurbs", "perlin", "phong", @@ -323,6 +330,7 @@ dict_uimsgs = { "ztransp", # Blender terms + "audaspace", "bbone", "breakdowner", "bspline", @@ -347,6 +355,8 @@ dict_uimsgs = { "metaelement", "metaelements", "metastrip", "metastrips", "movieclip", + "mpoly", + "mtex", "nabla", "navmesh", "outliner", @@ -362,6 +372,7 @@ dict_uimsgs = { "stucci", "sunsky", "subsurf", + "tessface", "tessfaces", "texface", "timeline", "timelines", "tosphere", @@ -376,6 +387,7 @@ dict_uimsgs = { "catmull", "catrom", "chebychev", + "courant", "kutta", "lennard", "minkowski", @@ -406,6 +418,7 @@ dict_uimsgs = { "dpi", "dvar", "dx", + "eo", "fh", "fov", "fft", @@ -448,6 +461,7 @@ dict_uimsgs = { "dop", # BLI K-Dop BVH "ik", "nla", + "py", "qbvh", "rna", "rvo", diff --git a/release/scripts/modules/bl_i18n_utils/update_pot.py b/release/scripts/modules/bl_i18n_utils/update_pot.py index f98fc5d7705..6a7efddda6c 100755 --- a/release/scripts/modules/bl_i18n_utils/update_pot.py +++ b/release/scripts/modules/bl_i18n_utils/update_pot.py @@ -117,28 +117,30 @@ def check_file(path, rel_path, messages): def py_xgettext(messages): + forbidden = set() + forced = set() with open(SRC_POTFILES) as src: - forbidden = set() - forced = set() for l in src: if l[0] == '-': forbidden.add(l[1:].rstrip('\n')) elif l[0] != '#': forced.add(l.rstrip('\n')) - for root, dirs, files in os.walk(POTFILES_DIR): - if "/.svn" in root: + for root, dirs, files in os.walk(POTFILES_DIR): + if "/.svn" in root: + continue + for fname in files: + if os.path.splitext(fname)[1] not in PYGETTEXT_ALLOWED_EXTS: + continue + path = os.path.join(root, fname) + rel_path = os.path.relpath(path, SOURCE_DIR) + if rel_path in forbidden: continue - for fname in files: - if os.path.splitext(fname)[1] not in PYGETTEXT_ALLOWED_EXTS: - continue - path = os.path.join(root, fname) - rel_path = os.path.relpath(path, SOURCE_DIR) - if rel_path in forbidden | forced: - continue - check_file(path, rel_path, messages) - for path in forced: - if os.path.exists(path): - check_file(os.path.join(SOURCE_DIR, path), path, messages) + elif rel_path in forced: + forced.remove(rel_path) + check_file(path, rel_path, messages) + for path in forced: + if os.path.exists(path): + check_file(os.path.join(SOURCE_DIR, path), path, messages) # Spell checking! @@ -250,7 +252,7 @@ def main(): print("Running fake py gettext…") # Not using any more xgettext, simpler to do it ourself! - messages = {} + messages = utils.new_messages() py_xgettext(messages) print("Finished, found {} messages.".format(len(messages))) @@ -268,7 +270,7 @@ def main(): # add messages collected automatically from RNA print("\tMerging RNA messages from {}…".format(FILE_NAME_MESSAGES)) - messages = {} + messages = utils.new_messages() with open(FILE_NAME_MESSAGES, encoding="utf-8") as f: srcs = [] context = "" diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 25b9daa99e5..9481f750092 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -41,6 +41,10 @@ def is_tooltip(msgid): return len(msgid) > 30 +def new_messages(): + return getattr(collections, 'OrderedDict', dict)() + + def parse_messages(fname): """ Returns a tupple (messages, states, stats). @@ -78,7 +82,7 @@ def parse_messages(fname): msgctxt_lines = [] comment_lines = [] - messages = getattr(collections, 'OrderedDict', dict)() + messages = new_messages() translated_messages = set() fuzzy_messages = set() commented_messages = set() @@ -282,7 +286,7 @@ def gen_empty_messages(blender_rev, time_str, year_str): """Generate an empty messages & state data (only header if present!).""" header_key = ("", "") - messages = getattr(collections, 'OrderedDict', dict)() + messages = new_messages() messages[header_key] = { "msgid_lines": [""], "msgctxt_lines": [], diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index 41fe052c434..d32b69b501c 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -264,8 +264,8 @@ def module_names(path, recursive=False): if recursive: for mod_name, mod_path in module_names(directory, True): modules.append(("%s.%s" % (filename, mod_name), - mod_path, - )) + mod_path, + )) return modules diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py index ad0fe06b68b..ad3cf8c08ec 100644 --- a/release/scripts/modules/bpy_extras/mesh_utils.py +++ b/release/scripts/modules/bpy_extras/mesh_utils.py @@ -232,7 +232,7 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()): ed_adj = edges[context_loop[-1]] if len(ed_adj) != 2: # the original edge had 2 other edges - if other_dir and flipped == False: + if other_dir and flipped is False: flipped = True # only flip the list once context_loop.reverse() ed_adj[:] = [] diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index b1de1fd47a4..46731b807f7 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -187,3 +187,16 @@ class AddObjectHelper: name="Rotation", subtype='EULER', ) + + +def object_add_grid_scale(context): + """ + Return scale which should be applied on object data to align it to grid scale + """ + + space_data = context.space_data + + if space_data and space_data.type == 'VIEW_3D': + return space_data.grid_scale_unit + + return 1.0 diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 9ad9a7affc3..4cd823d9184 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -689,10 +689,10 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): files = [] for directory in searchpaths: files.extend([(f, os.path.join(directory, f)) - for f in os.listdir(directory) - if (not f.startswith(".")) - if ((filter_ext is None) or - (filter_ext(os.path.splitext(f)[1]))) + for f in os.listdir(directory) + if (not f.startswith(".")) + if ((filter_ext is None) or + (filter_ext(os.path.splitext(f)[1]))) ]) files.sort() diff --git a/release/scripts/modules/bpyml.py b/release/scripts/modules/bpyml.py index 42d2bf94fba..e942006010b 100644 --- a/release/scripts/modules/bpyml.py +++ b/release/scripts/modules/bpyml.py @@ -160,7 +160,7 @@ if __name__ == "__main__": from bpyml_test import * draw = [ - ui()[ + ui()[ split()[ column()[ prop(data='context.scene.render', property='use_stamp_time', text='Time'), diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py index 582a1c6ae14..60dfa2b6344 100644 --- a/release/scripts/modules/console_python.py +++ b/release/scripts/modules/console_python.py @@ -30,7 +30,7 @@ _BPY_MAIN_OWN = True def add_scrollback(text, text_type): for l in text.split("\n"): bpy.ops.console.scrollback_append(text=l.replace("\t", " "), - type=text_type) + type=text_type) def replace_help(namespace): @@ -195,7 +195,7 @@ def execute(context): # insert a new blank line bpy.ops.console.history_append(text="", current_character=0, - remove_duplicates=True) + remove_duplicates=True) # Insert the output into the editor # not quite correct because the order might have changed, @@ -294,8 +294,8 @@ def copy_as_script(context): sc = context.space_data lines = [ "import bpy", - "import bpy.context as C", - "import bpy.data as D", + "from bpy import data as D", + "from bpy import context as C", "from mathutils import *", "from math import *", "", diff --git a/release/scripts/modules/console_shell.py b/release/scripts/modules/console_shell.py index 8beff24eedb..42348f453cd 100644 --- a/release/scripts/modules/console_shell.py +++ b/release/scripts/modules/console_shell.py @@ -26,7 +26,7 @@ language_id = "shell" def add_scrollback(text, text_type): for l in text.split("\n"): bpy.ops.console.scrollback_append(text=l.replace("\t", " "), - type=text_type) + type=text_type) def shell_run(text): @@ -57,7 +57,7 @@ def execute(context): # insert a new blank line bpy.ops.console.history_append(text="", current_character=0, - remove_duplicates=True) + remove_duplicates=True) sc.prompt = os.getcwd() + PROMPT return {'FINISHED'} diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py index 0ef2ac5164d..6f4b63fc99a 100644 --- a/release/scripts/modules/rna_info.py +++ b/release/scripts/modules/rna_info.py @@ -249,7 +249,7 @@ class InfoPropertyRNA: def get_arg_default(self, force=True): default = self.default_str - if default and (force or self.is_required == False): + if default and (force or self.is_required is False): return "%s=%s" % (self.identifier, default) return self.identifier @@ -493,7 +493,7 @@ def BuildRNAInfo(): # Arrange so classes are always defined in the correct order deps_ok = False - while deps_ok == False: + while deps_ok is False: deps_ok = True rna_done = set() diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index 2ea978419b9..fc8e3125228 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -250,7 +250,7 @@ def xml2rna(root_xml, if value_xml.startswith("#"): # read hexidecimal value as float array value_xml_split = value_xml[1:] - value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)] + value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)] del value_xml_split else: value_xml_split = value_xml.split() diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index d54766ec88f..05075f06239 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -1,69 +1,69 @@ <bpy> <Theme> <view_3d> - <ThemeView3D object_active="#f58032" + <ThemeView3D object_active="#f47421" editmesh_active="#ffffff80" act_spline="#ee4000" - handle_align="#862074" - handle_sel_align="#f090a0" - handle_auto="#909000" - handle_sel_auto="#f0ff40" + handle_align="#93237f" + handle_sel_align="#f47421" + handle_auto="#00c59a" + handle_sel_auto="#f47421" bone_pose="#50c8ff" bone_pose_active="#8cffff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" - camera="#000000" - camera_path="#000000" + camera="#159dce" + camera_path="#7dbd00" frame_current="#60c040" edge_crease="#ce33b8" extra_edge_len="#200000" edge_seam="#db4100" - edge_select="#f68d46" + edge_select="#f47421" edge_sharp="#ff4c00" edge_facesel="#4b4b4b" - empty="#000000" + empty="#93237f" face="#75757512" extra_face_angle="#002000" extra_face_area="#0059ee" - face_dot="#ff8500" + face_dot="#f47421" facedot_size="3" normal="#19b6ee" - face_select="#ff85003c" - handle_free="#000000" - handle_sel_free="#000000" + face_select="#f474213c" + handle_free="#a5ca00" + handle_sel_free="#f47421" grid="#3c3b37" - lamp="#00000028" + lamp="#ffffff34" lastsel_point="#ffffff" nurb_uline="#909000" nurb_vline="#862074" nurb_sel_uline="#f0ff40" nurb_sel_vline="#d15d85" - object_grouped="#083008" - object_grouped_active="#55bb55" + object_grouped="#117211" + object_grouped_active="#65d665" object_selected="#f15800" - outline_width="1" + outline_width="2" panel="#a5a5a57f" skin_root="#000000" - speaker="#000000" + speaker="#93237f" transform="#ffffff" handle_vect="#409030" handle_sel_vect="#82c036" vertex="#c96cb8" vertex_normal="#19b6ee" - vertex_select="#f15800" + vertex_select="#f47421" vertex_size="2" - wire="#862074"> + wire="#93237f"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" button_text="#9c9c9c" button_text_hi="#ffffff" button_title="#9c9c9c" - text="#000000" + text="#9c9c9c" text_hi="#ffffff" - title="#000000" + title="#9c9c9c" back="#131311"> </ThemeSpaceGeneric> </space> @@ -71,7 +71,7 @@ </view_3d> <clip_editor> <ThemeClipEditor active_marker="#ffffff" - frame_current="#c07100" + frame_current="#f47421" disabled_marker="#7f0000" grid="#302e2c" handle_vertex="#000000" @@ -86,16 +86,16 @@ strips="#0c0a0a" strips_selected="#ff8c00"> <space> - <ThemeSpaceGeneric header="#3c3b37" - header_text="#000000" + <ThemeSpaceGeneric header="#464541" + header_text="#9c9c9c" header_text_hi="#ffffff" button="#3c3b37" - button_text="#000000" + button_text="#ffffff" button_text_hi="#ffffff" - button_title="#000000" - text="#000000" + button_title="#9c9c9c" + text="#9c9c9c" text_hi="#ffffff" - title="#000000" + title="#9c9c9c" back="#131311"> </ThemeSpaceGeneric> </space> @@ -109,14 +109,14 @@ </ThemeClipEditor> </clip_editor> <console> - <ThemeConsole cursor="#dc5a00" - line_error="#dc0000" - line_info="#85aa00" - line_input="#828282" - line_output="#f58032"> + <ThemeConsole cursor="#f47421" + line_error="#ff0000" + line_info="#f47421" + line_input="#19b6ee" + line_output="#97f500"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" button_text="#000000" @@ -133,7 +133,7 @@ <dopesheet_editor> <ThemeDopeSheet active_channels_group="#a2b15c" channel_group="#4f6549" - channels="#74736e" + channels="#9c9c9c" channels_selected="#6592f5" frame_current="#f58032" dopesheet_channel="#64486e" @@ -143,26 +143,26 @@ long_key_selected="#f47421" summary="#00000000" value_sliders="#000000" - view_sliders="#969696"> + view_sliders="#9c9c9c"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#cacaca" header_text_hi="#ffffff" button="#3c3b37" - button_text="#000000" + button_text="#9c9c9c" button_text_hi="#ffffff" - button_title="#000000" - text="#000000" + button_title="#9c9c9c" + text="#e7e7e7" text_hi="#ffffff" - title="#000000" + title="#9c9c9c" back="#131311"> </ThemeSpaceGeneric> </space> <space_list> <ThemeSpaceListGeneric list="#3c3b37" - list_text="#000000" - list_text_hi="#ffffff" - list_title="#dddddd"> + list_text="#e2e2e2" + list_text_hi="#f47421" + list_title="#ffffff"> </ThemeSpaceListGeneric> </space_list> </ThemeDopeSheet> @@ -175,8 +175,8 @@ selected_file="#6b395a" tiles="#3c3b37"> <space> - <ThemeSpaceGeneric header="#3c3b37" - header_text="#000000" + <ThemeSpaceGeneric header="#464541" + header_text="#acacac" header_text_hi="#ffffff" button="#727272" button_text="#000000" @@ -199,50 +199,50 @@ </file_browser> <graph_editor> <ThemeGraphEditor active_channels_group="#87b17d" - handle_align="#803060" - handle_sel_align="#f090a0" - handle_auto="#909000" - handle_sel_auto="#f0ff40" - handle_auto_clamped="#994030" - handle_sel_auto_clamped="#f0af90" + handle_align="#93237f" + handle_sel_align="#f49600" + handle_auto="#00c59a" + handle_sel_auto="#f49600" + handle_auto_clamped="#03aa60" + handle_sel_auto_clamped="#f49600" channel_group="#4f6549" channels_region="#707070" frame_current="#f58032" dopesheet_channel="#695c6e" dopesheet_subchannel="#7c8996" - handle_free="#000000" - handle_sel_free="#000000" + handle_free="#a5ca00" + handle_sel_free="#f49600" grid="#3c3b37" - handle_vertex="#000000" - handle_vertex_select="#f47421" - handle_vertex_size="3" - lastsel_point="#000000" + handle_vertex="#bbbbbb" + handle_vertex_select="#f49600" + handle_vertex_size="4" + lastsel_point="#fafafa" panel="#ffffff" handle_vect="#409030" handle_sel_vect="#40c030" - vertex="#000000" - vertex_select="#ff8500" - vertex_size="3" + vertex="#ffffff" + vertex_select="#f49600" + vertex_size="4" window_sliders="#95948f"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" - button_text="#c3c2bc" + button_text="#9c9c9c" button_text_hi="#ffffff" - button_title="#9e9d98" - text="#000000" + button_title="#9c9c9c" + text="#e9e9e9" text_hi="#ffffff" - title="#000000" + title="#9c9c9c" back="#131311"> </ThemeSpaceGeneric> </space> <space_list> <ThemeSpaceListGeneric list="#3c3b37" - list_text="#000000" - list_text_hi="#ffffff" - list_title="#000000"> + list_text="#e2e2e2" + list_text_hi="#f47421" + list_title="#ffffff"> </ThemeSpaceListGeneric> </space_list> </ThemeGraphEditor> @@ -265,7 +265,7 @@ vertex_size="3"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" button_text="#b9b9b9" @@ -301,16 +301,16 @@ <ThemeLogicEditor panel="#acacac"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" - button="#131311" + button="#353430" button_text="#acacac" button_text_hi="#ffffff" button_title="#7d7d7d" text="#acacac" text_hi="#ffffff" title="#000000" - back="#131311"> + back="#29001b"> </ThemeSpaceGeneric> </space> </ThemeLogicEditor> @@ -333,7 +333,7 @@ view_sliders="#969696"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" button_text="#000000" @@ -369,7 +369,7 @@ wire="#f45b00"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#353430" button_text="#acacac" @@ -395,7 +395,7 @@ selected_highlight="#6a3859"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" button_text="#000000" @@ -413,7 +413,7 @@ <ThemeProperties panel="#3c3b37"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" button_text="#000000" @@ -444,32 +444,32 @@ window_sliders="#a0a0a0"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" - button_text="#000000" + button_text="#acacac" button_text_hi="#ffffff" - button_title="#000000" - text="#000000" + button_title="#acacac" + text="#acacac" text_hi="#ffffff" - title="#000000" + title="#acacac" back="#191919"> </ThemeSpaceGeneric> </space> </ThemeSequenceEditor> </sequence_editor> <text_editor> - <ThemeTextEditor cursor="#df5106" - syntax_special="#8c8c28" + <ThemeTextEditor cursor="#f47421" + syntax_special="#33a500" line_numbers_background="#3c3b37" - selected_text="#ffffff" - syntax_builtin="#df3ac2" + selected_text="#641f44" + syntax_builtin="#d6ff01" syntax_comment="#249d60" - syntax_numbers="#3c68ff" - syntax_string="#aa2694"> + syntax_numbers="#972144" + syntax_string="#6e00ff"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#191919" button_text="#95948f" @@ -488,13 +488,13 @@ grid="#272727"> <space> <ThemeSpaceGeneric header="#464541" - header_text="#000000" + header_text="#acacac" header_text_hi="#ffffff" button="#3c3b37" - button_text="#000000" + button_text="#9c9c9c" button_text_hi="#ffffff" - button_title="#000000" - text="#949494" + button_title="#9c9c9c" + text="#9c9c9c" text_hi="#ffffff" title="#000000" back="#131311"> @@ -532,13 +532,13 @@ <wcol_menu_back> <ThemeWidgetColors inner="#131312db" inner_sel="#2d2d2de6" - item="#cbc3bbff" + item="#6a3859ff" outline="#0d0d0d" shadedown="-20" shadetop="25" show_shaded="FALSE" - text="#7a7a7a" - text_sel="#ffffff"> + text="#dddddd" + text_sel="#dddddd"> </ThemeWidgetColors> </wcol_menu_back> <wcol_menu_item> @@ -574,7 +574,7 @@ shadetop="20" show_shaded="TRUE" text="#dfdbcf" - text_sel="#fffbed"> + text_sel="#f47421"> </ThemeWidgetColors> </wcol_num> <wcol_option> @@ -615,7 +615,7 @@ shadetop="25" show_shaded="FALSE" text="#dddddd" - text_sel="#fff7fb"> + text_sel="#ffffff"> </ThemeWidgetColors> </wcol_pulldown> <wcol_radio> @@ -627,7 +627,7 @@ shadetop="5" show_shaded="TRUE" text="#dfdbcf" - text_sel="#ffffff"> + text_sel="#dfdbcf"> </ThemeWidgetColors> </wcol_radio> <wcol_regular> @@ -639,16 +639,16 @@ shadetop="21" show_shaded="TRUE" text="#dfdfdf" - text_sel="#ffffff"> + text_sel="#dfdfdf"> </ThemeWidgetColors> </wcol_regular> <wcol_scroll> - <ThemeWidgetColors inner="#020202b4" + <ThemeWidgetColors inner="#000000b4" inner_sel="#646464c6" - item="#2c2b28ff" - outline="#0d0d0d" - shadedown="-5" - shadetop="5" + item="#2e2d2aff" + outline="#000000" + shadedown="-10" + shadetop="10" show_shaded="TRUE" text="#cbc3bb" text_sel="#ffffff"> @@ -685,7 +685,7 @@ shadetop="-10" show_shaded="TRUE" text="#dfdbcf" - text_sel="#fffaec"> + text_sel="#ffffff"> </ThemeWidgetColors> </wcol_text> <wcol_toggle> @@ -721,7 +721,7 @@ shadetop="25" show_shaded="FALSE" text="#ffffff" - text_sel="#ffffff"> + text_sel="#ff5d0d"> </ThemeWidgetColors> </wcol_tooltip> </ThemeUserInterface> diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py index fe011a51e22..b5df519cf59 100644 --- a/release/scripts/presets/keyconfig/maya.py +++ b/release/scripts/presets/keyconfig/maya.py @@ -133,42 +133,42 @@ kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True) kmi.properties.data_path = 'space_data.viewport_shade' kmi.properties.value_1 = 'TEXTURED' kmi.properties.value_2 = 'SOLID' -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS') +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE') kmi.properties.extend = False kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True) kmi.properties.extend = True kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True) kmi.properties.extend = False kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True) kmi.properties.extend = False kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True) kmi.properties.extend = True kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True) kmi.properties.extend = False kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True) kmi.properties.extend = True kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True) kmi.properties.extend = True kmi.properties.center = True kmi.properties.object = False diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 6c48ae72e4b..552247f0940 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -49,9 +49,9 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg): angle = 2 * pi * minor_index / minor_seg vec = quat * Vector((major_rad + (cos(angle) * minor_rad), - 0.0, - (sin(angle) * minor_rad), - )) + 0.0, + (sin(angle) * minor_rad), + )) verts.extend(vec[:]) @@ -133,13 +133,15 @@ class AddTorus(Operator, object_utils.AddObjectHelper): ) def execute(self, context): - if self.use_abso == True: + grid_scale = object_utils.object_add_grid_scale(context) + + if self.use_abso is True: extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5 self.major_radius = self.abso_minor_rad + extra_helper self.minor_radius = extra_helper - verts_loc, faces = add_torus(self.major_radius, - self.minor_radius, + verts_loc, faces = add_torus(self.major_radius * grid_scale, + self.minor_radius * grid_scale, self.major_segments, self.minor_segments) diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index c5fc3c50f3f..902c7007fb9 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -214,7 +214,7 @@ class BakeAction(Operator): 'OBJECT' in self.bake_types, self.clear_constraints, True, - ) + ) if action is None: self.report({'INFO'}, "Nothing to bake") @@ -252,8 +252,8 @@ class ClearUselessActions(Operator): for action in bpy.data.actions: # if only user is "fake" user... - if ((self.only_unused is False) or - (action.use_fake_user and action.users == 1)): + if ((self.only_unused is False) or + (action.use_fake_user and action.users == 1)): # if it has F-Curves, then it's a "action library" # (i.e. walk, wave, jump, etc.) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index c45d2f2e702..70967a01d1c 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -57,7 +57,7 @@ def CLIP_set_viewport_background(context, all_screens, clip, clip_user): space_v3d.show_background_images = True CLIP_spaces_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D', - set_background, clip, clip_user) + set_background, clip, clip_user) def CLIP_camera_for_clip(context, clip): @@ -329,7 +329,7 @@ object's movement caused by this constraint""" if not con: self.report({'ERROR'}, - "Motion Tracking constraint to be converted not found") + "Motion Tracking constraint to be converted not found") return {'CANCELLED'} @@ -341,7 +341,7 @@ object's movement caused by this constraint""" if not clip: self.report({'ERROR'}, - "Movie clip to use tracking data from isn't set") + "Movie clip to use tracking data from isn't set") return {'CANCELLED'} @@ -461,9 +461,9 @@ class CLIP_OT_setup_tracking_scene(Operator): scene.camera = camob camob.matrix_local = (Matrix.Translation((7.481, -6.508, 5.344)) * - Matrix.Rotation(0.815, 4, 'Z') * - Matrix.Rotation(0.011, 4, 'Y') * - Matrix.Rotation(1.109, 4, 'X')) + Matrix.Rotation(0.815, 4, 'Z') * + Matrix.Rotation(0.011, 4, 'Y') * + Matrix.Rotation(1.109, 4, 'X')) return camob @@ -629,7 +629,7 @@ class CLIP_OT_setup_tracking_scene(Operator): if need_stabilization: tree.links.new(distortion.outputs["Image"], - stabilize.inputs["Image"]) + stabilize.inputs["Image"]) tree.links.new(stabilize.outputs["Image"], scale.inputs["Image"]) else: tree.links.new(distortion.outputs["Image"], scale.inputs["Image"]) diff --git a/release/scripts/startup/bl_operators/console.py b/release/scripts/startup/bl_operators/console.py index fd95da02b28..307165a4d18 100644 --- a/release/scripts/startup/bl_operators/console.py +++ b/release/scripts/startup/bl_operators/console.py @@ -129,6 +129,6 @@ class ConsoleLanguage(Operator): # insert a new blank line bpy.ops.console.history_append(text="", current_character=0, - remove_duplicates=True) + remove_duplicates=True) return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index 3dc25d84aca..df21349da47 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -92,7 +92,7 @@ class MeshMirrorUV(Operator): puvs[i] = tuple(uv.uv for uv in uv_loops[lstart:lend]) puvs_cpy[i] = tuple(uv.copy() for uv in puvs[i]) puvsel[i] = (False not in - (uv.select for uv in uv_loops[lstart:lend])) + (uv.select for uv in uv_loops[lstart:lend])) # Vert idx of the poly. vidxs[i] = tuple(l.vertex_index for l in loops[lstart:lend]) # As we have no poly.center yet... diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 5000d718182..4e90f2e8585 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -408,13 +408,13 @@ class ShapeTransfer(Operator): n2loc_to = v2_to + target_normals[i2] * edlen_to pt = barycentric_transform(orig_shape_coords[i1], - v2, v1, n1loc, - v2_to, v1_to, n1loc_to) + v2, v1, n1loc, + v2_to, v1_to, n1loc_to) median_coords[i1].append(pt) pt = barycentric_transform(orig_shape_coords[i2], - v1, v2, n2loc, - v1_to, v2_to, n2loc_to) + v1, v2, n2loc, + v1_to, v2_to, n2loc_to) median_coords[i2].append(pt) # apply the offsets to the new shape @@ -507,7 +507,7 @@ class JoinUVs(Operator): if obj_other != obj and obj_other.type == 'MESH': mesh_other = obj_other.data if mesh_other != mesh: - if mesh_other.tag == False: + if mesh_other.tag is False: mesh_other.tag = True if len(mesh_other.loops) != nbr_loops: @@ -520,7 +520,7 @@ class JoinUVs(Operator): len(mesh_other.polygons), nbr_loops, ), - ) + ) else: uv_other = mesh_other.uv_layers.active if not uv_other: diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 35b496b6dd0..cd0b63a6b78 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -299,7 +299,6 @@ class QuickSmoke(Operator): style = EnumProperty( name="Smoke Style", items=(('STREAM', "Stream", ""), - ('PUFF', "Puff", ""), ('FIRE', "Fire", ""), ), default='STREAM', @@ -328,20 +327,9 @@ class QuickSmoke(Operator): bpy.ops.object.modifier_add(fake_context, type='SMOKE') obj.modifiers[-1].smoke_type = 'FLOW' - psys = obj.particle_systems[-1] - if self.style == 'PUFF': - psys.settings.frame_end = psys.settings.frame_start - psys.settings.emit_from = 'VOLUME' - psys.settings.distribution = 'RAND' - elif self.style == 'FIRE': - psys.settings.effector_weights.gravity = -1 - psys.settings.lifetime = 5 - psys.settings.count = 100000 - - obj.modifiers[-2].flow_settings.initial_velocity = True - obj.modifiers[-2].flow_settings.temperature = 2 - - psys.settings.use_render_emitter = self.show_flows + if self.style == 'FIRE': + obj.modifiers[-1].flow_settings.smoke_flow_type = 'FIRE' + if not self.show_flows: obj.draw_type = 'WIRE' @@ -361,8 +349,6 @@ class QuickSmoke(Operator): bpy.ops.object.modifier_add(type='SMOKE') obj.modifiers[-1].smoke_type = 'DOMAIN' if self.style == 'FIRE': - obj.modifiers[-1].domain_settings.use_dissolve_smoke = True - obj.modifiers[-1].domain_settings.dissolve_speed = 20 obj.modifiers[-1].domain_settings.use_high_resolution = True # create a volume material with a voxel data texture for the domain @@ -373,6 +359,7 @@ class QuickSmoke(Operator): mat.type = 'VOLUME' mat.volume.density = 0 mat.volume.density_scale = 5 + mat.volume.step_size = 0.1 tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA') tex.voxel_data.domain_object = obj @@ -381,29 +368,35 @@ class QuickSmoke(Operator): tex_slot.texture = tex tex_slot.use_map_color_emission = False tex_slot.use_map_density = True + tex_slot.use_map_color_reflection = True - # for fire add a second texture for emission and emission color - if self.style == 'FIRE': - mat.volume.emission = 5 - tex = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA') - tex.voxel_data.domain_object = obj - tex.use_color_ramp = True - - tex_slot = mat.texture_slots.add() - tex_slot.texture = tex - - ramp = tex.color_ramp - - elem = ramp.elements.new(0.333) - elem.color[0] = elem.color[3] = 1 - elem.color[1] = elem.color[2] = 0 + # for fire add a second texture for flame emission + mat.volume.emission_color = Vector((0.0, 0.0, 0.0)) + tex = bpy.data.textures.new("Flame", 'VOXEL_DATA') + tex.voxel_data.domain_object = obj + tex.voxel_data.smoke_data_type = 'SMOKEFLAME' + tex.use_color_ramp = True - elem = ramp.elements.new(0.666) - elem.color[0] = elem.color[1] = elem.color[3] = 1 - elem.color[2] = 0 + tex_slot = mat.texture_slots.add() + tex_slot.texture = tex - mat.texture_slots[1].use_map_emission = True - mat.texture_slots[1].blend_type = 'MULTIPLY' + # add color ramp for flame color + ramp = tex.color_ramp + # dark orange + elem = ramp.elements.new(0.333) + elem.color[0] = 0.2 + elem.color[1] = 0.03 + elem.color[2] = 0 + elem.color[3] = 1 + # yellow glow + elem = ramp.elements.new(0.666) + elem.color[0] = elem.color[3] = 1 + elem.color[1] = 0.65 + elem.color[2] = 0.25 + + mat.texture_slots[1].use_map_density = True + mat.texture_slots[1].use_map_emission = True + mat.texture_slots[1].emission_factor = 5 return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index db492450e28..5482912345d 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -436,19 +436,19 @@ class AddPresetTrackingSettings(AddPresetBase, Operator): ] preset_values = [ - "default_correlation_min", - "default_pattern_size", - "default_search_size", - "default_frames_limit", - "default_pattern_match", - "default_margin", - "default_motion_model", - "use_default_brute", - "use_default_normalization", - "use_default_mask", - "use_default_red_channel", - "use_default_green_channel", - "use_default_blue_channel" + "settings.default_correlation_min", + "settings.default_pattern_size", + "settings.default_search_size", + "settings.default_frames_limit", + "settings.default_pattern_match", + "settings.default_margin", + "settings.default_motion_model", + "settings.use_default_brute", + "settings.use_default_normalization", + "settings.use_default_mask", + "settings.use_default_red_channel", + "settings.use_default_green_channel", + "settings.use_default_blue_channel" ] preset_subdir = "tracking_settings" diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index 32658d353d9..694412e51d7 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -89,7 +89,7 @@ class PlayRenderedAnim(Operator): if player_path == "": player_path = guess_player_path(preset) - if is_movie == False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}: + if is_movie is False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}: # replace the number with '#' file_a = rd.frame_path(frame=0) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 21843d80742..ac72b39a04d 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -608,9 +608,9 @@ class WM_OT_context_collection_boolean_set(Operator): except: continue - if value_orig == True: + if value_orig is True: is_set = True - elif value_orig == False: + elif value_orig is False: pass else: self.report({'WARNING'}, "Non boolean value found: %s[ ].%s" % @@ -1583,7 +1583,7 @@ class WM_OT_addon_enable(Operator): "version %d.%d.%d and might not " "function (correctly), " "though it is enabled") % - info_ver) + info_ver) return {'FINISHED'} else: return {'CANCELLED'} @@ -1668,7 +1668,7 @@ class WM_OT_theme_install(Operator): class WM_OT_addon_install(Operator): "Install an addon" bl_idname = "wm.addon_install" - bl_label = "Install Addon..." + bl_label = "Install from File..." overwrite = BoolProperty( name="Overwrite", @@ -1773,12 +1773,6 @@ class WM_OT_addon_install(Operator): try: # extract the file to "addons" file_to_extract.extractall(path_addons) - - # zip files can create this dir with metadata, don't need it - macosx_dir = os.path.join(path_addons, '__MACOSX') - if os.path.isdir(macosx_dir): - shutil.rmtree(macosx_dir) - except: traceback.print_exc() return {'CANCELLED'} @@ -1822,8 +1816,11 @@ class WM_OT_addon_install(Operator): # in case a new module path was created to install this addon. bpy.utils.refresh_script_paths() - # TODO, should not be a warning. - #~ self.report({'WARNING'}, "File installed to '%s'\n" % path_dest) + # print message + msg = "Modules Installed from %r into %r (%s)" % (pyfile, path_addons, ", ".join(sorted(addons_new))) + print(msg) + self.report({'INFO'}, msg) + return {'FINISHED'} def invoke(self, context, event): diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 847807029fa..e4be84d5396 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -92,10 +92,11 @@ def register(): def addon_filter_items(self, context): import addon_utils - items = [('All', "All", ""), - ('Enabled', "Enabled", ""), - ('Disabled', "Disabled", ""), - ] + items = [('All', "All", "All Addons"), + ('User', "User", "All Addons Installed by User"), + ('Enabled', "Enabled", "All Enabled Addons"), + ('Disabled', "Disabled", "All Disabled Addons"), + ] items_unique = set() @@ -119,8 +120,8 @@ def register(): WindowManager.addon_support = EnumProperty( items=[('OFFICIAL', "Official", "Officially supported"), ('COMMUNITY', "Community", "Maintained by community developers"), - ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"), - ], + ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)") + ], name="Support", description="Display support level", default={'OFFICIAL', 'COMMUNITY'}, diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index e194d7a1370..50c34be1414 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -285,10 +285,9 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): row.prop(itasc, "damping_max", text="Damp", slider=True) row.prop(itasc, "damping_epsilon", text="Eps", slider=True) -from bl_ui.properties_animviz import ( - MotionPathButtonsPanel, - OnionSkinButtonsPanel, - ) +from bl_ui.properties_animviz import (MotionPathButtonsPanel, + OnionSkinButtonsPanel, + ) class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index e6d9affee93..1e70483864c 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -251,52 +251,52 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel): split.active = pchan.is_in_ik_chain row = split.row() row.prop(pchan, "ik_stiffness_x", text="Stiffness", slider=True) - row.active = pchan.lock_ik_x == False and pchan.is_in_ik_chain + row.active = pchan.lock_ik_x is False and pchan.is_in_ik_chain split = layout.split(percentage=0.25) sub = split.row() sub.prop(pchan, "use_ik_limit_x", text="Limit") - sub.active = pchan.lock_ik_x == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_x is False and pchan.is_in_ik_chain sub = split.row(align=True) sub.prop(pchan, "ik_min_x", text="") sub.prop(pchan, "ik_max_x", text="") - sub.active = pchan.lock_ik_x == False and pchan.use_ik_limit_x and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_x is False and pchan.use_ik_limit_x and pchan.is_in_ik_chain split = layout.split(percentage=0.25) split.prop(pchan, "lock_ik_y", icon='LOCKED' if pchan.lock_ik_y else 'UNLOCKED', text="Y") split.active = pchan.is_in_ik_chain row = split.row() row.prop(pchan, "ik_stiffness_y", text="Stiffness", slider=True) - row.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain + row.active = pchan.lock_ik_y is False and pchan.is_in_ik_chain split = layout.split(percentage=0.25) sub = split.row() sub.prop(pchan, "use_ik_limit_y", text="Limit") - sub.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_y is False and pchan.is_in_ik_chain sub = split.row(align=True) sub.prop(pchan, "ik_min_y", text="") sub.prop(pchan, "ik_max_y", text="") - sub.active = pchan.lock_ik_y == False and pchan.use_ik_limit_y and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_y is False and pchan.use_ik_limit_y and pchan.is_in_ik_chain split = layout.split(percentage=0.25) split.prop(pchan, "lock_ik_z", icon='LOCKED' if pchan.lock_ik_z else 'UNLOCKED', text="Z") split.active = pchan.is_in_ik_chain sub = split.row() sub.prop(pchan, "ik_stiffness_z", text="Stiffness", slider=True) - sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_z is False and pchan.is_in_ik_chain split = layout.split(percentage=0.25) sub = split.row() sub.prop(pchan, "use_ik_limit_z", text="Limit") - sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_z is False and pchan.is_in_ik_chain sub = split.row(align=True) sub.prop(pchan, "ik_min_z", text="") sub.prop(pchan, "ik_max_z", text="") - sub.active = pchan.lock_ik_z == False and pchan.use_ik_limit_z and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_z is False and pchan.use_ik_limit_z and pchan.is_in_ik_chain split = layout.split(percentage=0.25) split.label(text="Stretch:") diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index ed390be49f5..0398cb36b18 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -397,7 +397,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = layout.column() - if md.use_mirror_merge == True: + if md.use_mirror_merge is True: col.prop(md, "merge_threshold") col.label(text="Mirror Object:") col.prop(md, "mirror_object", text="") @@ -559,7 +559,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() row = col.row() - row.active = (md.object is None or md.use_object_screw_offset == False) + row.active = (md.object is None or md.use_object_screw_offset is False) row.prop(md, "screw_offset") row = col.row() row.active = (md.object is not None) diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 8eecbf4b604..951644db752 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -753,6 +753,7 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel): row = sub.row() row.active = bool(mat.light_group) row.prop(mat, "use_light_group_exclusive", text="Exclusive") + row.prop(mat, "use_light_group_local", text="Local") col = split.column() col.prop(mat, "use_face_texture") diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index f2c631b7ab1..8a668b5d95b 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -290,10 +290,8 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): row.prop(ob, "slow_parent_offset", text="Offset") -from bl_ui.properties_animviz import ( - MotionPathButtonsPanel, - OnionSkinButtonsPanel, - ) +from bl_ui.properties_animviz import (MotionPathButtonsPanel, + OnionSkinButtonsPanel) class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index fba7bd8712a..1eac232de88 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -485,6 +485,8 @@ class ConstraintButtonsPanel(): row.prop(con, "use_transform_limit") row.label() + self.space_template(layout, con) + def STRETCH_TO(self, context, layout, con): self.target_template(layout, con) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index aa0ea1d2d9e..6fcd56fb99e 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -21,12 +21,11 @@ import bpy from bpy.types import Panel from rna_prop_ui import PropertyPanel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - basic_force_field_settings_ui, - basic_force_field_falloff_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui, + basic_force_field_settings_ui, + basic_force_field_falloff_ui, + ) def particle_panel_enabled(context, psys): @@ -52,7 +51,7 @@ def particle_panel_poll(cls, context): if not settings: return False - return settings.is_fluid == False and (engine in cls.COMPAT_ENGINES) + return settings.is_fluid is False and (engine in cls.COMPAT_ENGINES) def particle_get_settings(context): @@ -133,13 +132,13 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): split = layout.split(percentage=0.32) col = split.column() col.label(text="Name:") - if part.is_fluid == False: + if part.is_fluid is False: col.label(text="Settings:") col.label(text="Type:") col = split.column() col.prop(psys, "name", text="") - if part.is_fluid == False: + if part.is_fluid is False: row = col.row() row.enabled = particle_panel_enabled(context, psys) row.template_ID(psys, "settings", new="particle.new") @@ -279,7 +278,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): cloth = psys.cloth.settings - layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked == False + layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False split = layout.split() @@ -813,7 +812,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): sub.active = (part.use_strand_primitive is False) sub.prop(part, "use_render_adaptive") sub = col.column() - sub.active = part.use_render_adaptive or part.use_strand_primitive == True + sub.active = part.use_render_adaptive or part.use_strand_primitive is True sub.prop(part, "adaptive_angle") sub = col.column() sub.active = (part.use_render_adaptive is True and part.use_strand_primitive is False) @@ -831,9 +830,9 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): row = layout.row() col = row.column() - if part.type == 'HAIR' and part.use_strand_primitive == True and part.child_type == 'INTERPOLATED': + if part.type == 'HAIR' and part.use_strand_primitive is True and part.child_type == 'INTERPOLATED': layout.prop(part, "use_simplify") - if part.use_simplify == True: + if part.use_simplify is True: row = layout.row() row.prop(part, "simplify_refsize") row.prop(part, "simplify_rate") @@ -841,7 +840,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): row = layout.row() row.prop(part, "use_simplify_viewport") sub = row.row() - sub.active = part.use_simplify_viewport == True + sub.active = part.use_simplify_viewport is True sub.prop(part, "simplify_viewport") elif part.render_type == 'OBJECT': @@ -988,11 +987,11 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): if part.draw_percentage != 100 and psys is not None: if part.type == 'HAIR': - if psys.use_hair_dynamics and psys.point_cache.is_baked == False: + if psys.use_hair_dynamics and psys.point_cache.is_baked is False: layout.row().label(text="Display percentage makes dynamics inaccurate without baking!") else: phystype = part.physics_type - if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked == False: + if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked is False: layout.row().label(text="Display percentage makes dynamics inaccurate without baking!") row = layout.row() @@ -1125,7 +1124,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): def draw(self, context): part = particle_get_settings(context) - effector_weights_ui(self, context, part.effector_weights) + effector_weights_ui(self, context, part.effector_weights, 'PSYS') if part.type == 'HAIR': row = self.layout.row() diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 33b977b5f04..5a44294f0e0 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -20,10 +20,8 @@ import bpy from bpy.types import Menu, Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui) def cloth_panel_enabled(md): @@ -178,7 +176,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): ob = context.object cloth = context.cloth.settings - layout.active = cloth.use_stiffness_scale and cloth_panel_enabled(md) + layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md)) split = layout.split() @@ -199,7 +197,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): def draw(self, context): cloth = context.cloth.settings - effector_weights_ui(self, context, cloth.effector_weights) + effector_weights_ui(self, context, cloth.effector_weights, 'CLOTH') if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 7f824d94431..b94df3148a9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -160,7 +160,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col = split.column() - if cache.is_baked == True: + if cache.is_baked is True: col.operator("ptcache.free_bake", text="Free Bake") else: col.operator("ptcache.bake", text="Bake").bake = True @@ -179,7 +179,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.operator("ptcache.bake_all", text="Update All To Frame").bake = False -def effector_weights_ui(self, context, weights): +def effector_weights_ui(self, context, weights, weight_type): layout = self.layout layout.prop(weights, "group") @@ -200,6 +200,8 @@ def effector_weights_ui(self, context, weights): col.prop(weights, "wind", slider=True) col.prop(weights, "curve_guide", slider=True) col.prop(weights, "texture", slider=True) + if weight_type != 'SMOKE': + col.prop(weights, "smokeflow", slider=True) col = split.column() col.prop(weights, "harmonic", slider=True) diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index db0794d8a8a..1df2936b2d4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -20,10 +20,9 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui, + ) class PhysicButtonsPanel(): @@ -350,7 +349,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): col = layout.column() col.active = surface.use_drip - effector_weights_ui(self, context, surface.effector_weights) + effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') layout.label(text="Surface Movement:") row = layout.row() diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 569037cb0da..933a9aa12a3 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -20,10 +20,9 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - basic_force_field_settings_ui, - basic_force_field_falloff_ui, - ) +from bl_ui.properties_physics_common import (basic_force_field_settings_ui, + basic_force_field_falloff_ui, + ) class PhysicButtonsPanel(): @@ -113,6 +112,14 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): col = split.column() col.prop(field, "use_object_coords") col.prop(field, "use_2d_force") + elif field.type == 'SMOKE_FLOW': + col = split.column() + col.prop(field, "strength") + col.prop(field, "flow") + col = split.column() + col.label(text="Domain Object:") + col.prop(field, "source_object", "") + col.prop(field, "use_smoke_density") else: basic_force_field_settings_ui(self, context, field) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 1b333f1e505..ce5053f0ecf 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -20,10 +20,8 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui) class PhysicButtonsPanel(): @@ -78,28 +76,40 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): elif md.smoke_type == 'FLOW': flow = md.flow_settings - - split = layout.split() - - col = split.column() - col.prop(flow, "use_outflow") - col.label(text="Particle System:") - col.prop_search(flow, "particle_system", ob, "particle_systems", text="") - - sub = col.column() - sub.active = not md.flow_settings.use_outflow - - sub.prop(flow, "initial_velocity", text="Initial Velocity") - sub = sub.column() - sub.active = flow.initial_velocity - sub.prop(flow, "velocity_factor", text="Multiplier") - - sub = split.column() - sub.active = not md.flow_settings.use_outflow - sub.label(text="Initial Values:") - sub.prop(flow, "use_absolute") - sub.prop(flow, "density") - sub.prop(flow, "temperature") + + layout.prop(flow, "smoke_flow_type", expand=False) + + if flow.smoke_flow_type != "OUTFLOW": + split = layout.split() + col = split.column() + col.label(text="Flow Source:") + col.prop(flow, "smoke_flow_source", expand=False, text="") + if flow.smoke_flow_source == "PARTICLES": + col.label(text="Particle System:") + col.prop_search(flow, "particle_system", ob, "particle_systems", text="") + else: + col.prop(flow, "surface_distance") + col.prop(flow, "volume_density") + + sub = col.column(align=True) + + sub.prop(flow, "initial_velocity") + sub = sub.column() + sub.active = flow.initial_velocity + sub.prop(flow, "velocity_factor") + if flow.smoke_flow_source == "MESH": + sub.prop(flow, "velocity_normal") + #sub.prop(flow, "velocity_random") + + sub = split.column() + sub.label(text="Initial Values:") + sub.prop(flow, "use_absolute") + if flow.smoke_flow_type in {'SMOKE', 'BOTH'}: + sub.prop(flow, "density") + sub.prop(flow, "temperature") + sub.prop(flow, "smoke_color") + if flow.smoke_flow_type in {'FIRE', 'BOTH'}: + sub.prop(flow, "fuel_amount") elif md.smoke_type == 'COLLISION': coll = md.coll_settings @@ -108,36 +118,99 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): col = split.column() col.prop(coll, "collision_type") + +class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): + bl_label = "Smoke Flow Advanced" + bl_options = {'DEFAULT_CLOSED'} + @classmethod + def poll(cls, context): + md = context.smoke + return md and (md.smoke_type == 'FLOW') and (md.flow_settings.smoke_flow_source == "MESH") -class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): - bl_label = "Smoke Groups" + def draw(self, context): + layout = self.layout + ob = context.object + flow = context.smoke.flow_settings + + split = layout.split() + col = split.column() + + col.prop(flow, "use_texture") + sub = col.column() + sub.active = flow.use_texture + sub.prop(flow, "noise_texture", text="") + sub.label(text="Mapping:") + sub.prop(flow, "texture_map_type", expand=False, text="") + if flow.texture_map_type == "UV": + sub.prop_search(flow, "uv_layer", ob.data, "uv_textures", text="") + if flow.texture_map_type == "AUTO": + sub.prop(flow, "texture_size") + sub.prop(flow, "texture_offset") + + col = split.column() + col.label(text="Vertex Group:") + col.prop_search(flow, "density_vertex_group", ob, "vertex_groups", text="") + +class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel): + bl_label = "Smoke Flames" bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): md = context.smoke - rd = context.scene.render - return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine) + return md and (md.smoke_type == 'DOMAIN') def draw(self, context): layout = self.layout - - group = context.smoke.domain_settings + domain = context.smoke.domain_settings split = layout.split() + split.enabled = not domain.point_cache.is_baked + + col = split.column(align=True) + col.label(text="Reaction:") + col.prop(domain, "burning_rate") + col.prop(domain, "flame_smoke") + col.prop(domain, "flame_vorticity") + + col = split.column(align=True) + col.label(text="Temperatures:") + col.prop(domain, "flame_ignition") + col.prop(domain, "flame_max_temp") + col.prop(domain, "flame_smoke_color") + +class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel): + bl_label = "Smoke Adaptive Domain" + bl_options = {'DEFAULT_CLOSED'} - col = split.column() - col.label(text="Flow Group:") - col.prop(group, "fluid_group", text="") + @classmethod + def poll(cls, context): + md = context.smoke + return md and (md.smoke_type == 'DOMAIN') - #col.label(text="Effector Group:") - #col.prop(group, "effector_group", text="") + def draw_header(self, context): + md = context.smoke.domain_settings - col = split.column() - col.label(text="Collision Group:") - col.prop(group, "collision_group", text="") + self.layout.prop(md, "use_adaptive_domain", text="") + def draw(self, context): + layout = self.layout + + domain = context.smoke.domain_settings + layout.active = domain.use_adaptive_domain + + split = layout.split() + split.enabled = not domain.point_cache.is_baked + + col = split.column(align=True) + col.label(text="Resolution:") + col.prop(domain, "additional_res") + col.prop(domain, "adapt_margin") + + col = split.column(align=True) + col.label(text="Advanced:") + col.prop(domain, "adapt_threshold") class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): bl_label = "Smoke High Resolution" @@ -176,6 +249,32 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): layout.prop(md, "show_high_resolution") +class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): + bl_label = "Smoke Groups" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + md = context.smoke + rd = context.scene.render + return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine) + + def draw(self, context): + layout = self.layout + domain = context.smoke.domain_settings + + split = layout.split() + + col = split.column() + col.label(text="Flow Group:") + col.prop(domain, "fluid_group", text="") + + #col.label(text="Effector Group:") + #col.prop(domain, "effector_group", text="") + + col = split.column() + col.label(text="Collision Group:") + col.prop(domain, "collision_group", text="") class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): bl_label = "Smoke Cache" @@ -211,7 +310,7 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel): def draw(self, context): domain = context.smoke.domain_settings - effector_weights_ui(self, context, domain.effector_weights) + effector_weights_ui(self, context, domain.effector_weights, 'SMOKE') if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index b043c1f9b68..79d676533a5 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -20,10 +20,8 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui) def softbody_panel_enabled(md): @@ -233,7 +231,7 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): md = context.soft_body softbody = md.settings - effector_weights_ui(self, context, softbody.effector_weights) + effector_weights_ui(self, context, softbody.effector_weights, 'SOFTBODY') if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 31a613d07bf..bae0a390ff7 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -775,7 +775,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): # TODO: Change the following to iterate over existing presets custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60}) - if custom_framerate == True: + if custom_framerate is True: fps_label_text = "Custom (" + str(fps_rate) + " fps)" else: fps_label_text = str(fps_rate) + " fps" diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 46a17675c91..d4752e4e7b5 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -111,8 +111,14 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): engine = context.scene.render.engine if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): return False - return ((context.material or context.world or context.lamp or context.brush or context.texture or context.particle_system or isinstance(context.space_data.pin_id, ParticleSettings)) - and (engine in cls.COMPAT_ENGINES)) + return ((context.material or + context.world or + context.lamp or + context.brush or + context.texture or + context.particle_system or + isinstance(context.space_data.pin_id, ParticleSettings)) and + (engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout @@ -881,8 +887,12 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): col = split.column() if tex.texture_coords in {'ORCO', 'UV'}: col.prop(tex, "use_from_dupli") + if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'): + col.prop(tex, "use_map_to_bounds") elif tex.texture_coords == 'OBJECT': col.prop(tex, "use_from_original") + if (idblock.type == 'VOLUME'): + col.prop(tex, "use_map_to_bounds") else: col.label() diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index b0e8a847084..f7b9f59b066 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -311,8 +311,8 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): col = layout.column(align=True) col.active = not settings.use_tripod_solver - col.prop(settings, "keyframe_a") - col.prop(settings, "keyframe_b") + col.prop(tracking_object, "keyframe_a") + col.prop(tracking_object, "keyframe_b") col = layout.column(align=True) col.active = (tracking_object.is_camera and @@ -891,6 +891,12 @@ class CLIP_MT_view(Menu): layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b else: + if sc.view == 'GRAPH': + layout.operator_context = 'INVOKE_REGION_PREVIEW' + layout.operator("clip.graph_center_current_frame") + layout.operator("clip.graph_view_all") + layout.operator_context = 'INVOKE_DEFAULT' + layout.prop(sc, "show_seconds") layout.separator() @@ -942,7 +948,7 @@ class CLIP_MT_track(Menu): props.action = 'UPTO' props = layout.operator("clip.clear_track_path", - text="Clear Track Path") + text="Clear Track Path") props.action = 'ALL' layout.separator() @@ -957,7 +963,7 @@ class CLIP_MT_track(Menu): layout.separator() props = layout.operator("clip.track_markers", - text="Track Frame Backwards") + text="Track Frame Backwards") props.backwards = True props = layout.operator("clip.track_markers", text="Track Backwards") diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py index 7ded4954f80..5ff179902a3 100644 --- a/release/scripts/startup/bl_ui/space_console.py +++ b/release/scripts/startup/bl_ui/space_console.py @@ -86,7 +86,7 @@ class CONSOLE_MT_language(Menu): def add_scrollback(text, text_type): for l in text.split("\n"): bpy.ops.console.scrollback_append(text=l.replace('\t', ' '), - type=text_type) + type=text_type) if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 8e955338480..a81553a8257 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -29,6 +29,7 @@ from bpy.types import Header, Menu def dopesheet_filter(layout, context, genericFiltersOnly=False): dopesheet = context.space_data.dopesheet is_nla = context.area.type == 'NLA_EDITOR' + is_drivers = (context.area.type == 'GRAPH_EDITOR' and context.space_data.mode == 'DRIVERS') row = layout.row(align=True) row.prop(dopesheet, "show_only_selected", text="") @@ -37,6 +38,9 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False): if is_nla: row.prop(dopesheet, "show_missing_nla", text="") + if is_drivers: + row.prop(dopesheet, "show_only_errors", text="") + if not genericFiltersOnly: if bpy.data.groups: row = layout.row(align=True) @@ -161,7 +165,6 @@ class DOPESHEET_MT_view(Menu): layout.operator("action.previewrange_set") layout.separator() - layout.operator("action.frame_jump") layout.operator("action.view_all") layout.operator("action.view_selected") @@ -272,6 +275,9 @@ class DOPESHEET_MT_key(Menu): layout.operator("action.keyframe_insert") layout.separator() + layout.operator("action.frame_jump") + + layout.separator() layout.operator("action.duplicate_move") layout.operator("action.delete") diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 972b4ebe721..e89bd78a84f 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -96,7 +96,6 @@ class GRAPH_MT_view(Menu): layout.operator("graph.previewrange_set") layout.separator() - layout.operator("graph.frame_jump") layout.operator("graph.view_all") layout.operator("graph.view_selected") @@ -199,6 +198,9 @@ class GRAPH_MT_key(Menu): layout.operator("graph.sound_bake") layout.separator() + layout.operator("graph.frame_jump") + + layout.separator() layout.operator("graph.duplicate_move") layout.operator("graph.delete") diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 64bf1e29348..85ea4985715 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -92,7 +92,7 @@ class USERPREF_HT_header(Header): layout.operator("wm.keyconfig_import") layout.operator("wm.keyconfig_export") elif userpref.active_section == 'ADDONS': - layout.operator("wm.addon_install") + layout.operator("wm.addon_install", icon="FILESEL") layout.menu("USERPREF_MT_addons_dev_guides") elif userpref.active_section == 'THEMES': layout.operator("ui.reset_default_theme") @@ -248,7 +248,7 @@ class USERPREF_PT_interface(Panel): col.prop(view, "show_splash") if os.name == "nt": - col.prop(view, "quit_dialog") + col.prop(view, "use_quit_dialog") class USERPREF_PT_edit(Panel): @@ -324,6 +324,7 @@ class USERPREF_PT_edit(Panel): col.separator() col.prop(edit, "use_auto_keying", text="Auto Keyframing:") + col.prop(edit, "use_auto_keying_warning") sub = col.column() @@ -1039,6 +1040,9 @@ class USERPREF_PT_addons(Panel): userpref = context.user_preferences used_ext = {ext.module for ext in userpref.addons} + userpref_addons_folder = os.path.join(userpref.filepaths.script_directory, "addons") + scripts_addons_folder = bpy.utils.user_resource('SCRIPTS', "addons") + # collect the categories that can be filtered on addons = [(mod, addon_utils.module_bl_info(mod)) for mod in addon_utils.modules(addon_utils.addons_fake_modules)] @@ -1084,10 +1088,12 @@ class USERPREF_PT_addons(Panel): continue # check if addon should be visible with current filters - if ((filter == "All") or - (filter == info["category"]) or - (filter == "Enabled" and is_enabled) or - (filter == "Disabled" and not is_enabled)): + if ((filter == "All") or + (filter == info["category"]) or + (filter == "Enabled" and is_enabled) or + (filter == "Disabled" and not is_enabled) or + (filter == "User" and (mod.__file__.startswith(scripts_addons_folder, userpref_addons_folder))) + ): if search and search not in info["name"].lower(): if info["author"]: diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 6646da4a91a..da498268b9b 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -218,8 +218,8 @@ class InputKeyMapPanel: layout.context_pointer_set("keymap", km) filtered_items = [kmi for kmi in km.keymap_items - if filter_text in kmi.idname.lower() or - filter_text in kmi.name.lower()] + if (filter_text in kmi.idname.lower() or + filter_text in kmi.name.lower())] if filtered_items: col = layout.column() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index d113853eaed..37f1afe3336 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -223,8 +223,8 @@ class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base): layout.separator() obj = context.object - if (obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'} and - obj.data.draw_type in {'BBONE', 'ENVELOPE'}): + if (obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'} and + obj.data.draw_type in {'BBONE', 'ENVELOPE'}): layout.operator("transform.transform", text="Scale Envelope/BBone").mode = 'BONE_SIZE' if context.edit_object and context.edit_object.type == 'ARMATURE': @@ -580,7 +580,7 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() layout.operator("mesh.select_by_number_vertices", text="By Number of Verts") - if context.scene.tool_settings.mesh_select_mode[2] == False: + if context.scene.tool_settings.mesh_select_mode[2] is False: layout.operator("mesh.select_non_manifold", text="Non Manifold") layout.operator("mesh.select_loose_verts", text="Loose Verts/Edges") layout.operator_menu_enum("mesh.select_similar", "type", text="Similar") @@ -1247,6 +1247,8 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_blend", text="Blend") + layout.operator("object.vertex_group_transfer_weight", text="Transfer Weights") + layout.operator("object.vertex_group_limit_total", text="Limit Total") layout.operator("object.vertex_group_fix", text="Fix Deforms") layout.separator() @@ -1528,13 +1530,20 @@ class VIEW3D_MT_pose_group(Menu): def draw(self, context): layout = self.layout - layout.operator("pose.group_add") - layout.operator("pose.group_remove") + + pose = context.active_object.pose - layout.separator() + layout.operator_context = 'EXEC_AREA' + layout.operator("pose.group_assign", text="Assign to New Group").type = 0 + if pose.bone_groups: + active_group = pose.bone_groups.active_index + 1 + layout.operator("pose.group_assign", text="Assign to Group").type = active_group + + layout.separator() - layout.operator("pose.group_assign") - layout.operator("pose.group_unassign") + #layout.operator_context = 'INVOKE_AREA' + layout.operator("pose.group_unassign") + layout.operator("pose.group_remove") class VIEW3D_MT_pose_ik(Menu): @@ -1659,7 +1668,7 @@ class VIEW3D_MT_edit_mesh(Menu): layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...") layout.separator() - + layout.operator("mesh.symmetrize") layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region") layout.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual") layout.operator("mesh.duplicate_move") @@ -1710,6 +1719,7 @@ class VIEW3D_MT_edit_mesh_specials(Menu): layout.operator("mesh.shape_propagate_to_all") layout.operator("mesh.select_vertex_path") layout.operator("mesh.sort_elements") + layout.operator("mesh.symmetrize") class VIEW3D_MT_edit_mesh_select_mode(Menu): @@ -1776,6 +1786,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.operator("mesh.merge") layout.operator("mesh.rip_move") + layout.operator("mesh.rip_move_fill") layout.operator("mesh.split") layout.operator_menu_enum("mesh.separate", "type") layout.operator("mesh.vert_connect") @@ -1810,6 +1821,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.operator("mesh.edge_face_add") layout.operator("mesh.subdivide") + layout.operator("mesh.unsubdivide") layout.separator() @@ -2155,6 +2167,7 @@ class VIEW3D_MT_edit_lattice(Menu): layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_snap") + layout.operator_menu_enum("lattice.flip", "axis") layout.separator() @@ -2292,7 +2305,7 @@ class VIEW3D_PT_view3d_properties(Panel): if lock_object.type == 'ARMATURE': col.prop_search(view, "lock_bone", lock_object.data, "edit_bones" if lock_object.mode == 'EDIT' - else "bones", + else "bones", text="") else: col.prop(view, "lock_cursor", text="Lock to Cursor") @@ -2310,6 +2323,9 @@ class VIEW3D_PT_view3d_properties(Panel): subcol.label(text="Local Camera:") subcol.prop(view, "camera", text="") + col = layout.column(align=True) + col.prop(view, "use_render_border") + class VIEW3D_PT_view3d_cursor(Panel): bl_space_type = 'VIEW_3D' diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 1b67b30d17a..d162a97d32c 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -520,8 +520,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): row = col.row(align=True) ups = toolsettings.unified_paint_settings - if ((ups.use_unified_size and ups.use_locked_size) or - ((not ups.use_unified_size) and brush.use_locked_size)): + if ((ups.use_unified_size and ups.use_locked_size) or + ((not ups.use_unified_size) and brush.use_locked_size)): self.prop_unified_size(row, context, brush, "use_locked_size", icon='LOCKED') self.prop_unified_size(row, context, brush, "unprojected_radius", slider=True, text="Radius") else: @@ -707,8 +707,8 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): @classmethod def poll(cls, context): settings = cls.paint_settings(context) - return (settings and settings.brush and (context.sculpt_object or - context.image_paint_object)) + return (settings and settings.brush and + (context.sculpt_object or context.image_paint_object)) def draw(self, context): layout = self.layout @@ -747,10 +747,12 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): @classmethod def poll(cls, context): settings = cls.paint_settings(context) - return (settings and settings.brush and (context.sculpt_object or - context.vertex_paint_object or - context.weight_paint_object or - context.image_paint_object)) + return (settings and + settings.brush and + (context.sculpt_object or + context.vertex_paint_object or + context.weight_paint_object or + context.image_paint_object)) def draw(self, context): layout = self.layout @@ -965,6 +967,8 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_levels", text="Levels") col.operator("object.vertex_group_blend", text="Blend") + col.operator("object.vertex_group_transfer_weight", text="Transfer Weights") + col.operator("object.vertex_group_limit_total", text="Limit Total") col.operator("object.vertex_group_fix", text="Fix Deforms") diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index b7693880f9c..6ad87375738 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -360,10 +360,10 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): # add rotation properties if they will if bone.lock_rotations_4d: # can check individually - if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w == False): + if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w is False): ksi.addProp(ks, bone, prop) else: - if bone.lock_rotation_w == False: + if bone.lock_rotation_w is False: ksi.addProp(ks, bone, prop, 0) # w = 0 for i in range(3): diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py new file mode 100644 index 00000000000..3b3212892d5 --- /dev/null +++ b/release/scripts/templates/script_stub.py @@ -0,0 +1,11 @@ +# This stub runs a python script relative to the currently open +# blend file, useful when editing scripts externally. + +import bpy +import os + +# Use your own script name here: +filename = "my_script.py" + +filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename) +exec(compile(open(filepath).read(), filepath, 'exec')) diff --git a/release/scripts/templates/ui_panel.py b/release/scripts/templates/ui_panel.py index 9ffa0cbeeea..cacdb83e815 100644 --- a/release/scripts/templates/ui_panel.py +++ b/release/scripts/templates/ui_panel.py @@ -22,7 +22,7 @@ class LayoutDemoPanel(bpy.types.Panel): row.prop(scene, "frame_end") # Create an row where the buttons are aligned to each other. - layout.label(text=" Aligned Row") + layout.label(text=" Aligned Row:") row = layout.row(align=True) row.prop(scene, "frame_start") @@ -39,9 +39,26 @@ class LayoutDemoPanel(bpy.types.Panel): # Second column, aligned col = split.column(align=True) - col.label(text="Column Two") + col.label(text="Column Two:") col.prop(scene, "frame_start") col.prop(scene, "frame_end") + + # Big render button + layout.label(text="Big Button:") + row = layout.row() + row.scale_y = 3.0 + row.operator("render.render") + + # Different sizes in a row + layout.label(text="Different button sizes:") + row = layout.row(align=True) + row.operator("render.render") + + sub = row.row() + sub.scale_x = 2.0 + sub.operator("render.render") + + row.operator("render.render") def register(): diff --git a/release/windows/contrib/vfapi/vfapi-plugin.c b/release/windows/contrib/vfapi/vfapi-plugin.c index 8d63baa0ce4..0af96d14d6f 100644 --- a/release/windows/contrib/vfapi/vfapi-plugin.c +++ b/release/windows/contrib/vfapi/vfapi-plugin.c @@ -15,7 +15,6 @@ * */ - #include <windows.h> #include <winbase.h> #include <stdio.h> @@ -83,16 +82,16 @@ typedef struct { } VF_ReadData_Audio,*LPVF_ReadData_Audio; typedef struct { - DWORD dwSize; - HRESULT (__stdcall *OpenFile)( - char *lpFileName, LPVF_FileHandle lpFileHandle ); + DWORD dwSize; + HRESULT (__stdcall *OpenFile)( + char *lpFileName, LPVF_FileHandle lpFileHandle ); HRESULT (__stdcall *CloseFile)( VF_FileHandle hFileHandle ); HRESULT (__stdcall *GetFileInfo)( VF_FileHandle hFileHandle, - LPVF_FileInfo lpFileInfo ); + LPVF_FileInfo lpFileInfo ); HRESULT (__stdcall *GetStreamInfo)( VF_FileHandle hFileHandle, - DWORD dwStream,void *lpStreamInfo ); + DWORD dwStream,void *lpStreamInfo ); HRESULT (__stdcall *ReadData)( VF_FileHandle hFileHandle, - DWORD dwStream,void *lpData ); + DWORD dwStream,void *lpData ); } VF_PluginFunc,*LPVF_PluginFunc; __declspec(dllexport) HRESULT vfGetPluginInfo( @@ -117,8 +116,9 @@ static unsigned long getipaddress(const char * ipaddr) struct hostent *host; unsigned long ip; - if (((ip = inet_addr(ipaddr)) == INADDR_NONE) - && strcmp(ipaddr, "255.255.255.255") != 0) { + if (((ip = inet_addr(ipaddr)) == INADDR_NONE) && + strcmp(ipaddr, "255.255.255.255") != 0) + { if ((host = gethostbyname(ipaddr)) != NULL) { memcpy(&ip, host->h_addr, sizeof(ip)); } @@ -419,6 +419,3 @@ __declspec(dllexport) HRESULT vfGetPluginFunc( return VF_OK; } - - - diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 611a920b7f1..e8558806a72 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -102,7 +102,6 @@ add_subdirectory(blenloader) add_subdirectory(ikplugin) add_subdirectory(gpu) add_subdirectory(imbuf) -add_subdirectory(avi) add_subdirectory(nodes) add_subdirectory(modifiers) add_subdirectory(makesdna) @@ -126,6 +125,10 @@ if(WITH_IMAGE_CINEON) add_subdirectory(imbuf/intern/cineon) endif() +if(WITH_CODEC_AVI) + add_subdirectory(avi) +endif() + if(WITH_CODEC_QUICKTIME) add_subdirectory(quicktime) endif() diff --git a/source/blender/avi/AVI_avi.h b/source/blender/avi/AVI_avi.h index bdfdbc117ed..4dc52970119 100644 --- a/source/blender/avi/AVI_avi.h +++ b/source/blender/avi/AVI_avi.h @@ -178,7 +178,7 @@ typedef struct _AviStreamRec { } AviStreamRec; typedef struct _AviMovie { - FILE *fp; + FILE *fp; int type; #define AVI_MOVIE_READ 0 diff --git a/source/blender/avi/CMakeLists.txt b/source/blender/avi/CMakeLists.txt index 79422dff917..292206d8cb9 100644 --- a/source/blender/avi/CMakeLists.txt +++ b/source/blender/avi/CMakeLists.txt @@ -35,19 +35,19 @@ set(INC_SYS set(SRC intern/avi.c - intern/avirgb.c - intern/codecs.c - intern/endian.c - intern/mjpeg.c - intern/options.c - intern/rgb32.c + intern/avi_rgb.c + intern/avi_codecs.c + intern/avi_endian.c + intern/avi_mjpeg.c + intern/avi_options.c + intern/avi_rgb32.c AVI_avi.h intern/avi_intern.h - intern/avirgb.h - intern/endian.h - intern/mjpeg.h - intern/rgb32.h + intern/avi_rgb.h + intern/avi_endian.h + intern/avi_mjpeg.h + intern/avi_rgb32.h ) blender_add_lib(bf_avi "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 2845b2f95c9..15d8702a5ec 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -32,7 +32,6 @@ * This is external code. */ - #include <stdlib.h> #include <string.h> #include <stdarg.h> @@ -49,7 +48,7 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "endian.h" +#include "avi_endian.h" static int AVI_DEBUG = 0; static char DEBUG_FCC[4]; diff --git a/source/blender/avi/intern/codecs.c b/source/blender/avi/intern/avi_codecs.c index 01e228d570e..e43826064a6 100644 --- a/source/blender/avi/intern/codecs.c +++ b/source/blender/avi/intern/avi_codecs.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/codecs.c +/** \file blender/avi/intern/avi_codecs.c * \ingroup avi * * This is external code. Identify and convert different avi-files. @@ -35,9 +35,9 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "avirgb.h" -#include "mjpeg.h" -#include "rgb32.h" +#include "avi_rgb.h" +#include "avi_mjpeg.h" +#include "avi_rgb32.h" void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size) { diff --git a/source/blender/avi/intern/endian.c b/source/blender/avi/intern/avi_endian.c index c9b95d25810..70add8bd90f 100644 --- a/source/blender/avi/intern/endian.c +++ b/source/blender/avi/intern/avi_endian.c @@ -26,7 +26,7 @@ * */ -/** \file blender/avi/intern/endian.c +/** \file blender/avi/intern/avi_endian.c * \ingroup avi * * This is external code. Streams bytes to output depending on the @@ -36,9 +36,10 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> +#include <stdio.h> + #include "AVI_avi.h" -#include "endian.h" +#include "avi_endian.h" #include "avi_intern.h" #ifdef __BIG_ENDIAN__ @@ -46,31 +47,22 @@ #endif #ifdef __BIG_ENDIAN__ + +/* copied from BLI_endian_switch_inline.h */ static void invert(int *num) { - int new = 0, i, j; - - for (j = 0; j < 4; j++) { - for (i = 0; i < 8; i++) { - new |= ((*num >> (j * 8 + i)) & 1) << ((3 - j) * 8 + i); - } - } - - *num = new; + int tval = *val; + *val = ((tval >> 24)) | + ((tval << 8) & 0x00ff0000) | + ((tval >> 8) & 0x0000ff00) | + ((tval << 24)); } -static void sinvert(short int *num) +static void sinvert(short int *val) { - short int new = 0; - int i, j; - - for (j = 0; j < 2; j++) { - for (i = 0; i < 8; i++) { - new |= ((*num >> (j * 8 + i)) & 1) << ((1 - j) * 8 + i); - } - } - - *num = new; + short tval = *val; + *val = (tval >> 8) | + (tval << 8); } static void Ichunk(AviChunk *chunk) diff --git a/source/blender/avi/intern/endian.h b/source/blender/avi/intern/avi_endian.h index 7ef49cb1699..8cea283a553 100644 --- a/source/blender/avi/intern/endian.h +++ b/source/blender/avi/intern/avi_endian.h @@ -25,17 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/endian.h +/** \file blender/avi/intern/avi_endian.h * \ingroup avi * * This is external code. */ -#ifndef __ENDIAN_H__ -#define __ENDIAN_H__ - -#include <stdio.h> -#include "AVI_avi.h" +#ifndef __AVI_ENDIAN_H__ +#define __AVI_ENDIAN_H__ #define AVI_RAW 0 #define AVI_CHUNK 1 @@ -48,5 +45,4 @@ void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type); -#endif - +#endif /* __AVI_ENDIAN_H__ */ diff --git a/source/blender/avi/intern/mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c index a700284bf68..b98e03d6a19 100644 --- a/source/blender/avi/intern/mjpeg.c +++ b/source/blender/avi/intern/avi_mjpeg.c @@ -26,21 +26,23 @@ * */ -/** \file blender/avi/intern/mjpeg.c +/** \file blender/avi/intern/avi_mjpeg.c * \ingroup avi * * This is external code. Converts between avi and mpeg/jpeg. */ - -#include "AVI_avi.h" #include <stdlib.h> #include <string.h> + +#include "AVI_avi.h" + +#include "MEM_guardedalloc.h" + #include "jpeglib.h" #include "jerror.h" -#include "MEM_guardedalloc.h" -#include "mjpeg.h" +#include "avi_mjpeg.h" #define PADUP(num, amt) ((num + (amt - 1)) & ~(amt - 1)) diff --git a/source/blender/avi/intern/mjpeg.h b/source/blender/avi/intern/avi_mjpeg.h index 75649891f2b..6ae0e56ffa4 100644 --- a/source/blender/avi/intern/mjpeg.h +++ b/source/blender/avi/intern/avi_mjpeg.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/mjpeg.h +/** \file blender/avi/intern/avi_mjpeg.h * \ingroup avi */ +#ifndef __AVI_MJPEG_H__ +#define __AVI_MJPEG_H__ void *avi_converter_from_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size); void *avi_converter_to_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_MJPEG_H__ */ diff --git a/source/blender/avi/intern/options.c b/source/blender/avi/intern/avi_options.c index 7de91318ecf..f7759a1099f 100644 --- a/source/blender/avi/intern/options.c +++ b/source/blender/avi/intern/avi_options.c @@ -26,7 +26,7 @@ * */ -/** \file blender/avi/intern/options.c +/** \file blender/avi/intern/avi_options.c * \ingroup avi * * This is external code. Sets some compression related options @@ -35,7 +35,7 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "endian.h" +#include "avi_endian.h" #ifdef WIN32 # include "BLI_winstuff.h" diff --git a/source/blender/avi/intern/avirgb.c b/source/blender/avi/intern/avi_rgb.c index 7a95972845a..61587e15e61 100644 --- a/source/blender/avi/intern/avirgb.c +++ b/source/blender/avi/intern/avi_rgb.c @@ -26,19 +26,19 @@ * */ -/** \file blender/avi/intern/avirgb.c +/** \file blender/avi/intern/avi_rgb.c * \ingroup avi * * This is external code. Converts rgb-type avi-s. */ - -#include "AVI_avi.h" #include <stdlib.h> #include <string.h> #include "MEM_guardedalloc.h" -#include "avirgb.h" + +#include "AVI_avi.h" +#include "avi_rgb.h" /* implementation */ diff --git a/source/blender/avi/intern/avirgb.h b/source/blender/avi/intern/avi_rgb.h index 20211d6ab2d..773166e9fab 100644 --- a/source/blender/avi/intern/avirgb.h +++ b/source/blender/avi/intern/avi_rgb.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/avirgb.h +/** \file blender/avi/intern/avi_rgb.h * \ingroup avi */ +#ifndef __AVI_RGB_H__ +#define __AVI_RGB_H__ -void *avi_converter_from_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size); -void *avi_converter_to_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_RGB_H__ */ diff --git a/source/blender/avi/intern/rgb32.c b/source/blender/avi/intern/avi_rgb32.c index 84630f09fe5..5c7a4889d97 100644 --- a/source/blender/avi/intern/rgb32.c +++ b/source/blender/avi/intern/avi_rgb32.c @@ -26,18 +26,19 @@ * */ -/** \file blender/avi/intern/rgb32.c +/** \file blender/avi/intern/avi_rgb32.c * \ingroup avi * * This is external code. Converts between rgb32 and avi. */ - -#include "AVI_avi.h" #include <stdlib.h> #include <string.h> + #include "MEM_guardedalloc.h" -#include "rgb32.h" + +#include "AVI_avi.h" +#include "avi_rgb32.h" void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size) { diff --git a/source/blender/avi/intern/rgb32.h b/source/blender/avi/intern/avi_rgb32.h index 55f9771a4df..523f9e795fd 100644 --- a/source/blender/avi/intern/rgb32.h +++ b/source/blender/avi/intern/avi_rgb32.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/rgb32.h +/** \file blender/avi/intern/avi_rgb32.h * \ingroup avi */ +#ifndef __AVI_RGB32_H__ +#define __AVI_RGB32_H__ -void *avi_converter_from_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size); -void *avi_converter_to_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_RGB32_H__ */ diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index ce10951d6ff..6f348ccc267 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -109,6 +109,7 @@ float BLF_fixed_width(int fontid); * of the string, using the default font and both value * are multiplied by the aspect of the font. */ +void BLF_width_and_height_default(const char *str, float *width, float *height); float BLF_width_default(const char *str); float BLF_height_default(const char *str); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 92fcb576e7d..f3cc92e7a27 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -69,7 +69,7 @@ static int global_font_dpi = 72; int blf_mono_font = -1; int blf_mono_font_render = -1; -static FontBLF *BLF_get(int fontid) +static FontBLF *blf_get(int fontid) { if (fontid >= 0 && fontid < BLF_MAX_FONT) return global_font[fontid]; @@ -141,6 +141,21 @@ static int blf_search_available(void) return -1; } +static int blf_global_font_init(void) +{ + if (global_font_default == -1) { + global_font_default = blf_search("default"); + } + + if (global_font_default == -1) { + printf("Warning: Can't find default font!\n"); + return 0; + } + else { + return 1; + } +} + int BLF_load(const char *name) { FontBLF *font; @@ -219,7 +234,7 @@ int BLF_load_unique(const char *name) void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_attach_from_mem(font, mem, mem_size); @@ -311,7 +326,7 @@ void BLF_unload(const char *name) void BLF_enable(int fontid, int option) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->flags |= option; @@ -320,7 +335,7 @@ void BLF_enable(int fontid, int option) void BLF_disable(int fontid, int option) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->flags &= ~option; @@ -329,7 +344,7 @@ void BLF_disable(int fontid, int option) void BLF_enable_default(int option) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->flags |= option; @@ -338,7 +353,7 @@ void BLF_enable_default(int option) void BLF_disable_default(int option) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->flags &= ~option; @@ -347,7 +362,7 @@ void BLF_disable_default(int option) void BLF_aspect(int fontid, float x, float y, float z) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->aspect[0] = x; @@ -358,7 +373,7 @@ void BLF_aspect(int fontid, float x, float y, float z) void BLF_matrix(int fontid, const double m[16]) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { memcpy(font->m, m, sizeof(font->m)); @@ -367,7 +382,7 @@ void BLF_matrix(int fontid, const double m[16]) void BLF_position(int fontid, float x, float y, float z) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { float xa, ya, za; @@ -416,7 +431,7 @@ void BLF_position(int fontid, float x, float y, float z) void BLF_size(int fontid, int size, int dpi) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_size(font, size, dpi); @@ -425,7 +440,7 @@ void BLF_size(int fontid, int size, int dpi) void BLF_blur(int fontid, int size) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->blur = size; @@ -437,13 +452,8 @@ void BLF_draw_default(float x, float y, float z, const char *str, size_t len) if (!str) return; - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + if (!blf_global_font_init()) return; - } BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_position(global_font_default, x, y, z); @@ -456,13 +466,8 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l if (!str) return; - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + if (!blf_global_font_init()) return; - } BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_position(global_font_default, x, y, z); @@ -471,7 +476,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l void BLF_rotation_default(float angle) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->angle = angle; @@ -543,7 +548,7 @@ static void blf_draw__end(GLint mode, GLint param) void BLF_draw(int fontid, const char *str, size_t len) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); GLint mode, param; if (font && font->glyph_cache) { @@ -555,7 +560,7 @@ void BLF_draw(int fontid, const char *str, size_t len) void BLF_draw_ascii(int fontid, const char *str, size_t len) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); GLint mode, param; if (font && font->glyph_cache) { @@ -567,7 +572,7 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len) void BLF_boundbox(int fontid, const char *str, rctf *box) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_boundbox(font, str, box); @@ -576,16 +581,29 @@ void BLF_boundbox(int fontid, const char *str, rctf *box) void BLF_width_and_height(int fontid, const char *str, float *width, float *height) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { blf_font_width_and_height(font, str, width, height); } + else { + *width = *height = 0.0f; + } +} + +void BLF_width_and_height_default(const char *str, float *width, float *height) +{ + if (!blf_global_font_init()) { + *width = *height = 0.0f; + return; + } + + BLF_width_and_height(global_font_default, str, width, height); } float BLF_width(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_width(font, str); @@ -596,7 +614,7 @@ float BLF_width(int fontid, const char *str) float BLF_fixed_width(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_fixed_width(font); @@ -607,13 +625,8 @@ float BLF_fixed_width(int fontid) float BLF_width_default(const char *str) { - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Error: Can't found default font!!\n"); + if (!blf_global_font_init()) return 0.0f; - } BLF_size(global_font_default, global_font_points, global_font_dpi); return BLF_width(global_font_default, str); @@ -621,7 +634,7 @@ float BLF_width_default(const char *str) float BLF_height(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_height(font, str); @@ -632,7 +645,7 @@ float BLF_height(int fontid, const char *str) float BLF_height_max(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->max_glyph_height; @@ -643,7 +656,7 @@ float BLF_height_max(int fontid) float BLF_width_max(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->max_glyph_width; @@ -654,7 +667,7 @@ float BLF_width_max(int fontid) float BLF_descender(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->descender; @@ -665,7 +678,7 @@ float BLF_descender(int fontid) float BLF_ascender(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->ascender; @@ -676,13 +689,8 @@ float BLF_ascender(int fontid) float BLF_height_default(const char *str) { - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Error: Can't found default font!!\n"); + if (!blf_global_font_init()) return 0.0f; - } BLF_size(global_font_default, global_font_points, global_font_dpi); @@ -691,7 +699,7 @@ float BLF_height_default(const char *str) void BLF_rotation(int fontid, float angle) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->angle = angle; @@ -700,7 +708,7 @@ void BLF_rotation(int fontid, float angle) void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->clip_rec.xmin = xmin; @@ -712,7 +720,7 @@ void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax) void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->clip_rec.xmin = xmin; @@ -724,7 +732,7 @@ void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax) void BLF_shadow(int fontid, int level, float r, float g, float b, float a) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->shadow = level; @@ -737,7 +745,7 @@ void BLF_shadow(int fontid, int level, float r, float g, float b, float a) void BLF_shadow_offset(int fontid, int x, int y) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->shadow_x = x; @@ -747,7 +755,7 @@ void BLF_shadow_offset(int fontid, int x, int y) void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->buf_info.fbuf = fbuf; @@ -761,7 +769,7 @@ void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int void BLF_buffer_col(int fontid, float r, float g, float b, float a) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->buf_info.col[0] = r; @@ -773,7 +781,7 @@ void BLF_buffer_col(int fontid, float r, float g, float b, float a) void BLF_draw_buffer(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache && (font->buf_info.fbuf || font->buf_info.cbuf)) { blf_font_buffer(font, str); diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index b694f1fafa7..af2f9df3c00 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -109,6 +109,8 @@ static const char *locales[] = { "hungarian", "hu_HU", "portuguese-brazilian", "pt_BR", "hebrew", "he_IL", + "estonian", "et_EE", + "esperanto", "eo", /* No country code for esperanto! ;) */ }; void BLF_lang_init(void) @@ -169,7 +171,6 @@ void BLF_lang_set(const char *str) char *locreturn; const char *short_locale; int ok = 1; - const char *long_locale = locales[2 * U.language]; if ((U.transopts & USER_DOTRANSLATE) == 0) return; @@ -180,25 +181,29 @@ void BLF_lang_set(const char *str) short_locale = locales[2 * U.language + 1]; #if defined(_WIN32) && !defined(FREE_WINDOWS) - if (short_locale) { - char *envStr; + { + const char *long_locale = locales[2 * U.language]; - if (U.language == 0) /* Use system setting. */ - envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); - else - envStr = BLI_sprintfN("LANG=%s", short_locale); + if (short_locale) { + char *envStr; - gettext_putenv(envStr); - MEM_freeN(envStr); - } + if (U.language == 0) /* Use system setting. */ + envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); + else + envStr = BLI_sprintfN("LANG=%s", short_locale); - locreturn = setlocale(LC_ALL, long_locale); + gettext_putenv(envStr); + MEM_freeN(envStr); + } - if (locreturn == NULL) { - if (G.debug & G_DEBUG) - printf("Could not change locale to %s\n", long_locale); + locreturn = setlocale(LC_ALL, long_locale); - ok = 0; + if (locreturn == NULL) { + if (G.debug & G_DEBUG) + printf("Could not change locale to %s\n", long_locale); + + ok = 0; + } } #else { @@ -212,11 +217,33 @@ void BLF_lang_set(const char *str) get_language_variable("LANGUAGE", default_language, sizeof(default_language)); if (short_locale[0]) { + char *short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); + if (G.debug & G_DEBUG) - printf("Setting LANG= and LANGUAGE to %s\n", short_locale); + printf("Setting LANG and LANGUAGE to %s\n", short_locale_utf8); + + locreturn = setlocale(LC_ALL, short_locale_utf8); + + if (locreturn != NULL) { + BLI_setenv("LANG", short_locale_utf8); + BLI_setenv("LANGUAGE", short_locale_utf8); + } + else { + if (G.debug & G_DEBUG) + printf("Setting LANG and LANGUAGE to %s\n", short_locale); - BLI_setenv("LANG", short_locale); - BLI_setenv("LANGUAGE", short_locale); + locreturn = setlocale(LC_ALL, short_locale); + + if (locreturn != NULL) { + BLI_setenv("LANG", short_locale); + BLI_setenv("LANGUAGE", short_locale); + } + } + + if (G.debug & G_DEBUG && locreturn == NULL) + printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); + + MEM_freeN(short_locale_utf8); } else { if (G.debug & G_DEBUG) @@ -224,43 +251,27 @@ void BLF_lang_set(const char *str) BLI_setenv("LANG", default_lang); BLI_setenv("LANGUAGE", default_language); - } + locreturn = setlocale(LC_ALL, ""); - locreturn = setlocale(LC_ALL, short_locale); + if (G.debug & G_DEBUG && locreturn == NULL) + printf("Could not reset locale\n"); + } if (locreturn == NULL) { - char *short_locale_utf8 = NULL; - - if (short_locale[0]) { - short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); - locreturn = setlocale(LC_ALL, short_locale_utf8); - } - - if (locreturn == NULL) { - char language[65]; + char language[65]; - get_language(long_locale, default_lang, language, sizeof(language)); + get_language(short_locale, default_lang, language, sizeof(language)); - if (G.debug & G_DEBUG) { - if (short_locale[0]) - printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); - else - printf("Could not reset locale\n"); - - printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - } - - /* Fallback to default settings. */ - BLI_setenv("LANG", default_lang); - BLI_setenv("LANGUAGE", language); + if (G.debug & G_DEBUG) + printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - locreturn = setlocale(LC_ALL, ""); + /* Fallback to default settings. */ + BLI_setenv("LANG", default_lang); + BLI_setenv("LANGUAGE", language); - ok = 0; - } + locreturn = setlocale(LC_ALL, ""); - if (short_locale_utf8) - MEM_freeN(short_locale_utf8); + ok = 0; } } #endif diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index a3f3beefbaf..b0f372e0bac 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -99,7 +99,7 @@ void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); /* get_objectspace_bone_matrix has to be removed still */ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed); void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]); -void mat3_to_vec_roll(float mat[][3], float *vec, float *roll); +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll); /* Common Conversions Between Co-ordinate Spaces */ void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]); @@ -131,8 +131,14 @@ typedef struct Mat4 { Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest); /* like EBONE_VISIBLE */ -#define PBONE_VISIBLE(arm, bone) (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) -#define PBONE_SELECTABLE(arm, bone) (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) +#define PBONE_VISIBLE(arm, bone) ( \ + CHECK_TYPE_INLINE(arm, bArmature), \ + CHECK_TYPE_INLINE(bone, Bone), \ + (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) \ + ) + +#define PBONE_SELECTABLE(arm, bone) \ + (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 56dfdf404f8..cf67899dfb0 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 264 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 4 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ @@ -51,7 +51,7 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR +#define BLENDER_VERSION_CHAR a /* alpha/beta/rc/release, docs use this */ #define BLENDER_VERSION_CYCLE alpha diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 728f88b3c16..f30cc57bde4 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -88,7 +88,6 @@ int curvemapping_RGBA_does_something(const struct CurveMapping * void curvemapping_table_RGBA(const struct CurveMapping *cumap, float **array, int *size); /* non-const, these modify the curve */ -void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf); void curvemapping_premultiply(struct CurveMapping *cumap, int restore); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index e6161cebf54..536bbecb79b 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -108,7 +108,7 @@ void BKE_nurb_free(struct Nurb *nu); struct Nurb *BKE_nurb_duplicate(struct Nurb *nu); void BKE_nurb_test2D(struct Nurb *nu); -void BKE_nurb_minmax(struct Nurb *nu, float *min, float *max); +void BKE_nurb_minmax(struct Nurb *nu, float min[3], float max[3]); void BKE_nurb_makeFaces(struct Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv); void BKE_nurb_makeCurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 01baf8feb2a..d7d75b4c4c9 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -92,4 +92,4 @@ extern int slurph_opt; }; #endif -#endif // __BKE_KEY_H__ +#endif /* __BKE_KEY_H__ */ diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 31626ef4a58..34baa48dbe2 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -46,7 +46,7 @@ struct Lattice *BKE_lattice_add(const char *name); struct Lattice *BKE_lattice_copy(struct Lattice *lt); void BKE_lattice_free(struct Lattice *lt); void BKE_lattice_make_local(struct Lattice *lt); -void calc_lat_fudu(int flag, int res, float *fu, float *du); +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du); void init_latt_deform(struct Object *oblatt, struct Object *ob); void calc_latt_deform(struct Object *, float co[3], float weight); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index c14085a559a..9fffb71785b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -130,7 +130,7 @@ struct Mesh *BKE_mesh_copy(struct Mesh *me); void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess_cd); void BKE_mesh_make_local(struct Mesh *me); -void BKE_mesh_boundbox_calc(struct Mesh *me, float *loc, float *size); +void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]); void BKE_mesh_texspace_calc(struct Mesh *me); float *BKE_mesh_orco_verts_get(struct Object *ob); void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 3b675f3b620..7ee1c85d0de 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -352,6 +352,7 @@ int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); +struct Object *modifiers_isDeformedByCurve(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 82a791348dd..8fa20eb2cc2 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -116,5 +116,4 @@ void multires_topology_changed(struct Mesh *me); void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v); int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y); -#endif // __BKE_MULTIRES_H__ - +#endif /* __BKE_MULTIRES_H__ */ diff --git a/source/blender/blenkernel/BKE_navmesh_conversion.h b/source/blender/blenkernel/BKE_navmesh_conversion.h index aab359b307a..cc9c18c764d 100644 --- a/source/blender/blenkernel/BKE_navmesh_conversion.h +++ b/source/blender/blenkernel/BKE_navmesh_conversion.h @@ -60,4 +60,4 @@ int polyFindVertex(const unsigned short *p, const int vertsPerPoly, unsigned sho float distPointToSegmentSq(const float *point, const float *a, const float *b); -#endif //NAVMESH_CONVERSION_H +#endif /* NAVMESH_CONVERSION_H */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index acd6f120f93..4ee5c894b5c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -349,7 +349,7 @@ struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); -void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage); +void nodeAddToPreview(struct bNode *node, const float col[4], int x, int y, int do_manage); struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); @@ -551,6 +551,7 @@ struct ShadeResult; #define SH_NODE_OBJECT_INFO 167 #define SH_NODE_PARTICLE_INFO 168 #define SH_NODE_TEX_BRICK 169 +#define SH_NODE_BUMP 170 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 @@ -784,7 +785,9 @@ void ntreeTexCheckCyclics(struct bNodeTree *ntree); struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree, int use_tree_data); void ntreeTexEndExecTree(struct bNodeTreeExec *exec, int use_tree_data); -int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); +int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, + float coord[3], float dxt[3], float dyt[3], int osatex, const short thread, + struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); /*************************************************/ diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index b3e650b2aa5..ec03f53dbdb 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -257,7 +257,9 @@ void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time); -void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], + float utan[3], float vtan[3], float orco[3], float ornor[3]); struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys); struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name); @@ -282,8 +284,11 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, s int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); /* for anim.c */ -void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco); -void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale); +void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, + struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, + float uv[2], float orco[3]); +void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, + struct ParticleCacheKey *cache, float mat[][4], float *scale); ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); void psys_threads_free(ParticleThread *threads); @@ -327,13 +332,17 @@ void psys_free_pdd(struct ParticleSystem *psys); float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup); void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra); -void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, + float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]); float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values); -void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time); +void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time); /* BLI_bvhtree_ray_cast callback */ void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); -void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]); +void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]); /* particle_system.c */ void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index c12e913be45..9927c7a42ed 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -55,7 +55,12 @@ struct Text; #define SCE_COPY_LINK_DATA 3 #define SCE_COPY_FULL 4 -#define SETLOOPER(_sce_basis, _sce_iter, _base) _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); _base; _base = _setlooper_base_step(&_sce_iter, _base) +/* Use as the contents of a 'for' loop: for (SETLOOPER(...)) { ... */ +#define SETLOOPER(_sce_basis, _sce_iter, _base) \ + _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); \ + _base; \ + _base = _setlooper_base_step(&_sce_iter, _base) + struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base); void free_avicodecdata(struct AviCodecData *acd); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index cecff2d9516..1667c119790 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -68,25 +68,27 @@ void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_ void BKE_sequence_iterator_next(SeqIterator *iter); void BKE_sequence_iterator_end(SeqIterator *iter); -#define SEQP_BEGIN(ed, _seq) \ +#define SEQP_BEGIN(_ed, _seq) \ { \ - SeqIterator iter; \ - for (BKE_sequence_iterator_begin(ed, &iter, 1); \ - iter.valid; \ - BKE_sequence_iterator_next(&iter)) { \ - _seq = iter.seq; - + SeqIterator iter_macro; \ + for (BKE_sequence_iterator_begin(_ed, &iter_macro, 1); \ + iter_macro.valid; \ + BKE_sequence_iterator_next(&iter_macro)) \ + { \ + _seq = iter_macro.seq; + #define SEQ_BEGIN(ed, _seq) \ { \ - SeqIterator iter; \ - for (BKE_sequence_iterator_begin(ed, &iter, 0); \ - iter.valid; \ - BKE_sequence_iterator_next(&iter)) { \ - _seq = iter.seq; + SeqIterator iter_macro; \ + for (BKE_sequence_iterator_begin(ed, &iter_macro, 0); \ + iter_macro.valid; \ + BKE_sequence_iterator_next(&iter_macro)) \ + { \ + _seq = iter_macro.seq; #define SEQ_END \ } \ - BKE_sequence_iterator_end(&iter); \ + BKE_sequence_iterator_end(&iter_macro); \ } typedef struct SeqRenderData { diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h index 1f824ccbafc..3a9d2b86b41 100644 --- a/source/blender/blenkernel/BKE_smoke.h +++ b/source/blender/blenkernel/BKE_smoke.h @@ -35,8 +35,10 @@ typedef float (*bresenham_callback)(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); -void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +void smoke_reallocate_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); +void smoke_reallocate_highres_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); void smokeModifier_free(struct SmokeModifierData *smd); void smokeModifier_reset(struct SmokeModifierData *smd); void smokeModifier_reset_turbulence(struct SmokeModifierData *smd); @@ -44,5 +46,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd); void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData *tsmd); long long smoke_get_mem_req(int xres, int yres, int zres, int amplify); +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]); +int smoke_get_data_flags(struct SmokeDomainSettings *sds); #endif /* __BKE_SMOKE_H__ */ diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index c14476a3b59..167f7bd831a 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -80,7 +80,7 @@ int BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, int int BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr); void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action); -void BKE_tracking_tracks_join(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); +void BKE_tracking_tracks_join(struct MovieTracking *tracking, struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking, struct MovieTrackingObject *object, diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 63f5ec59a0b..06f8b89ec05 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -38,4 +38,4 @@ extern "C" { } #endif -#endif // __BKE_UTILDEFINES_H__ +#endif /* __BKE_UTILDEFINES_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 9a24a3ca4e0..f690c9dcda4 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -25,7 +25,6 @@ set(INC . - ../avi ../blenfont ../blenlib ../blenloader @@ -196,8 +195,8 @@ set(SRC BKE_lattice.h BKE_library.h BKE_linestyle.h - BKE_mask.h BKE_main.h + BKE_mask.h BKE_material.h BKE_mball.h BKE_mesh.h @@ -252,7 +251,7 @@ if(WITH_AUDASPACE) endif() if(WITH_BULLET) - list(APPEND INC + list(APPEND INC_SYS ../../../extern/bullet2/src ) add_definitions(-DUSE_BULLET) @@ -294,6 +293,13 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_CODEC_AVI) + list(APPEND INC + ../avi + ) + add_definitions(-DWITH_AVI) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 9aaeb4c8baf..30804518e1d 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2249,8 +2249,16 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d { DerivedMesh *final; + /* XXX hack + * psys modifier updates particle state when called during dupli-list generation, + * which can lead to wrong transforms. This disables particle system modifier execution. + */ + ob->transflag |= OB_NO_PSYS_UPDATE; + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0, 0); + ob->transflag &= ~OB_NO_PSYS_UPDATE; + return final; } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 58d20fff2bc..622658e0a49 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -40,6 +40,8 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_group_types.h" @@ -174,10 +176,10 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec /* avoid 0 size allocs */ if (avs->path_sf >= avs->path_ef) { BKE_reportf(reports, RPT_ERROR, - "Motion Path frame extents invalid for %s (%d to %d).%s\n", + "Motion Path frame extents invalid for %s (%d to %d)%s", (pchan) ? pchan->name : ob->id.name, avs->path_sf, avs->path_ef, - (avs->path_sf == avs->path_ef) ? " Cannot have single-frame paths." : ""); + (avs->path_sf == avs->path_ef) ? TIP_(", cannot have single-frame paths") : ""); return NULL; } @@ -1678,8 +1680,8 @@ ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); int flag = 0; - if(update) flag |= DUPLILIST_DO_UPDATE; - if(for_render) flag |= DUPLILIST_FOR_RENDER; + if (update) flag |= DUPLILIST_DO_UPDATE; + if (for_render) flag |= DUPLILIST_FOR_RENDER; duplilist->first = duplilist->last = NULL; object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b87342f85fa..f5c7cab6019 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -534,10 +534,12 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) mul_m4_v3(imat, h2); /* if next bone is B-bone too, use average handle direction */ - if (next->bone->segments > 1) - ; - else + if (next->bone->segments > 1) { + /* pass */ + } + else { h2[1] -= length; + } normalize_v3(h2); /* find the next roll to interpolate as well */ @@ -1423,19 +1425,20 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float * *************************************************************************** */ /* Computes vector and roll based on a rotation. * "mat" must contain only a rotation, and no scaling. */ -void mat3_to_vec_roll(float mat[][3], float vec[3], float *roll) +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) { - if (vec) - copy_v3_v3(vec, mat[1]); + if (r_vec) { + copy_v3_v3(r_vec, mat[1]); + } - if (roll) { + if (r_roll) { float vecmat[3][3], vecmatinv[3][3], rollmat[3][3]; vec_roll_to_mat3(mat[1], 0.0f, vecmat); invert_m3_m3(vecmatinv, vecmat); mul_m3_m3m3(rollmat, vecmatinv, mat); - *roll = (float)atan2(rollmat[2][0], rollmat[2][2]); + *r_roll = atan2f(rollmat[2][0], rollmat[2][2]); } } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 99b788e80ce..197e38ac778 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -621,7 +621,9 @@ void BKE_undo_step(bContext *C, int step) } else if (step == 1) { /* curundo should never be NULL, after restart or load file it should call undo_save */ - if (curundo == NULL || curundo->prev == NULL) ; // XXX error("No undo available"); + if (curundo == NULL || curundo->prev == NULL) { + // XXX error("No undo available"); + } else { if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name); curundo = curundo->prev; @@ -631,7 +633,9 @@ void BKE_undo_step(bContext *C, int step) else { /* curundo has to remain current situation! */ - if (curundo == NULL || curundo->next == NULL) ; // XXX error("No redo available"); + if (curundo == NULL || curundo->next == NULL) { + // XXX error("No redo available"); + } else { read_undosave(C, curundo->next); curundo = curundo->next; diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 79d5e092a10..aafc7fe89b4 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -101,13 +101,15 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, break; } } - else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) - ; /* skip current object */ + else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) { + /* skip current object */ + } else if (pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(cur, &cur_efd, &epoint, 0)) { float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights); - if (temp == 0.0f) - ; /* do nothing */ + if (temp == 0.0f) { + /* do nothing */ + } else if (temp > priority) { priority = temp; eff = cur; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index ce39eea5ceb..f4efc30068c 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -741,7 +741,7 @@ void BKE_brush_scale_unprojected_radius(float *unprojected_radius, } /* scale brush size to reflect a change in the brush's unprojected radius */ -void BKE_brush_scale_size(int *BKE_brush_size_get, +void BKE_brush_scale_size(int *r_brush_size, float new_unprojected_radius, float old_unprojected_radius) { @@ -749,7 +749,7 @@ void BKE_brush_scale_size(int *BKE_brush_size_get, /* avoid division by zero */ if (old_unprojected_radius != 0) scale /= new_unprojected_radius; - (*BKE_brush_size_get) = (int)((float)(*BKE_brush_size_get) * scale); + (*r_brush_size) = (int)((float)(*r_brush_size) * scale); } /* Brush Painting */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4241756a109..da162ab37d0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -773,11 +773,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) else verts->goal= 0.0f; + /* Reset vertex flags */ + verts->flags &= ~CLOTH_VERT_FLAG_PINNED; + verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { - for ( j = 0; j < dvert->totweight; j++ ) { - verts->flags &= ~CLOTH_VERT_FLAG_PINNED; if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) { verts->goal = dvert->dw [j].weight; @@ -789,7 +791,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) */ verts->goal = powf(verts->goal, 4.0f); - if ( verts->goal >=SOFTGOALSNAP ) + if ( verts->goal >= SOFTGOALSNAP ) verts->flags |= CLOTH_VERT_FLAG_PINNED; } @@ -804,7 +806,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) } } - verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { if ( dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol-1)) { if (dvert->dw [j].weight > 0.0f) { diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6631afcddaf..05c916f9362 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -458,7 +458,8 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2, distance = 2.0 * (double)( epsilon1 + epsilon2 + ALMOST_ZERO ); #endif - if (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO)) { + // distance -1 means no collision result + if (distance != -1.0f && (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO))) { normalize_v3_v3(collpair->normal, collpair->vector); collpair->distance = distance; diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 1bd5786debd..d5d6d31b1e1 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -835,64 +835,6 @@ void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char ve vecout_byte[2] = FTOCHAR(vecout[2]); } - -/* only used for image editor curves */ -void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf) -{ - ImBuf *tmpbuf; - int pixel; - float *pix_in; - float col[3]; - int stride = 4; - float *pix_out; - - if (ibuf == NULL) - return; - if (ibuf->rect_float == NULL) - IMB_float_from_rect(ibuf); - else if (ibuf->rect == NULL) - imb_addrectImBuf(ibuf); - - if (!ibuf->rect || !ibuf->rect_float) - return; - - /* work on a temp buffer, so can color manage afterwards. - * No worse off memory wise than comp nodes */ - tmpbuf = IMB_dupImBuf(ibuf); - - curvemapping_premultiply(cumap, 0); - - pix_in = ibuf->rect_float; - pix_out = tmpbuf->rect_float; - - if (ibuf->channels) - stride = ibuf->channels; - - for (pixel = ibuf->x * ibuf->y; pixel > 0; pixel--, pix_in += stride, pix_out += stride) { - if (stride < 3) { - col[0] = curvemap_evaluateF(cumap->cm, *pix_in); - - pix_out[1] = pix_out[2] = pix_out[3] = pix_out[0] = col[0]; - } - else { - curvemapping_evaluate_premulRGBF(cumap, col, pix_in); - pix_out[0] = col[0]; - pix_out[1] = col[1]; - pix_out[2] = col[2]; - if (stride > 3) - pix_out[3] = pix_in[3]; - else - pix_out[3] = 1.f; - } - } - - IMB_rect_from_float(tmpbuf); - SWAP(unsigned int *, tmpbuf->rect, ibuf->rect); - IMB_freeImBuf(tmpbuf); - - curvemapping_premultiply(cumap, 1); -} - int curvemapping_RGBA_does_something(const CurveMapping *cumap) { int a; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 0bda3b266b8..e09e2eeb493 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -2109,7 +2109,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ int nr; - float bevp0_tan[3], cross_tmp[3]; + float bevp0_tan[3]; bevel_list_calc_bisect(bl); if (bl->poly == -1) /* check its not cyclic */ @@ -2123,6 +2123,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) nr = bl->nr; while (nr--) { + float cross_tmp[3]; cross_v3_v3v3(cross_tmp, bevp1->tan, bevp1->dir); cross_v3_v3v3(bevp1->tan, cross_tmp, bevp1->dir); normalize_v3(bevp1->tan); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index de55751f2ec..423bd93c70f 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2358,7 +2358,9 @@ void CustomData_bmesh_free_block(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) return; + if (*block == NULL) + return; + for (i = 0; i < data->totlayer; ++i) { if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { typeInfo = layerType_getInfo(data->layers[i].type); @@ -2394,7 +2396,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i; - if (!*dest_block) { + if (*dest_block == NULL) { CustomData_bmesh_alloc_block(dest, dest_block); if (*dest_block) memset(*dest_block, 0, dest->totsize); @@ -2614,7 +2616,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) + if (*block == NULL) CustomData_bmesh_alloc_block(data, block); for (i = 0; i < data->totlayer; ++i) { @@ -2634,7 +2636,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i, src_offset; - if (!*dest_block) + if (*dest_block == NULL) CustomData_bmesh_alloc_block(dest, dest_block); /* copies a layer at a time */ @@ -2866,7 +2868,9 @@ void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { if (typeInfo->free) typeInfo->free(layer->data, totelem, typeInfo->size); @@ -2892,10 +2896,15 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { update = 1; + } } if (!update) @@ -2913,15 +2922,23 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { blay = cdf_layer_find(cdf, layer->type, layer->name); if (blay) { if (cdf_read_layer(cdf, blay)) { - if (typeInfo->read(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->read(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } layer->flag |= CD_FLAG_IN_MEMORY; } else @@ -2952,9 +2969,12 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { update = 1; + } } if (!update) @@ -2995,11 +3015,16 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in blay = cdf_layer_find(cdf, layer->type, layer->name); if (cdf_write_layer(cdf, blay)) { - if (typeInfo->write(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->write(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } } - else + else { break; + } } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 31a6f768f89..20b029371f1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -400,8 +400,7 @@ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Mat } } -static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node) -{ +static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield){ Base *base; DagNode *node2; @@ -411,6 +410,8 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec if ((base->lay & ob->lay) && base->object->pd) { Object *ob1 = base->object; if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) { + if (skip_forcefield && ob1->pd->forcefield == skip_forcefield) + continue; node2 = dag_get_node(dag, ob1); dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision"); } @@ -443,7 +444,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (ob->type == OB_ARMATURE) { if (ob->pose) { bPoseChannel *pchan; - bConstraint *con; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { @@ -570,12 +570,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O /* softbody collision */ if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) { if (ob->particlesystem.first || - modifiers_isModifierEnabled(ob, eModifierType_Softbody) || - modifiers_isModifierEnabled(ob, eModifierType_Cloth) || - modifiers_isModifierEnabled(ob, eModifierType_Smoke) || - modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) + modifiers_isModifierEnabled(ob, eModifierType_Softbody) || + modifiers_isModifierEnabled(ob, eModifierType_Cloth) || + modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) { - dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */ + dag_add_collision_field_relation(dag, scene, ob, node, 0); /* TODO: use effectorweight->group */ + } + else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) { + dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW); } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 64959fd3aa1..10c9f30f5ee 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -299,7 +299,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i else resolu = nu->resolu; - if (!BKE_nurb_check_valid_u(nu)) ; + if (!BKE_nurb_check_valid_u(nu)) { + /* pass */ + } else if (nu->type == CU_BEZIER) { /* count */ len = 0; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4f4bafd00b4..7c0b43c24df 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -54,6 +54,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_jitter.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -84,6 +85,7 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" +#include "BKE_smoke.h" #include "RE_render_ext.h" @@ -137,6 +139,9 @@ PartDeflect *object_add_collision_fields(int type) case PFIELD_TEXTURE: pd->f_size = 1.0f; break; + case PFIELD_SMOKEFLOW: + pd->f_flow = 1.0f; + break; } pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; @@ -922,12 +927,27 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp)); break; + case PFIELD_SMOKEFLOW: + zero_v3(force); + if (pd->f_source) { + float density; + if ((density = smoke_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) { + float influence = strength * efd->falloff; + if (pd->flag & PFIELD_SMOKE_DENSITY) + influence *= density; + mul_v3_fl(force, influence); + /* apply flow */ + madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence); + } + } + break; + } if (pd->flag & PFIELD_DO_LOCATION) { madd_v3_v3fl(total_force, force, 1.0f/point->vel_to_sec); - if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) { + if (ELEM3(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_SMOKEFLOW)==0 && pd->f_flow != 0.0f) { madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); } } @@ -993,10 +1013,12 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we if (efd.falloff > 0.0f) efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point); - if (efd.falloff <= 0.0f) - ; /* don't do anything */ - else if (eff->pd->forcefield == PFIELD_TEXTURE) + if (efd.falloff <= 0.0f) { + /* don't do anything */ + } + else if (eff->pd->forcefield == PFIELD_TEXTURE) { do_texture_effector(eff, &efd, point, force); + } else { float temp1[3]={0, 0, 0}, temp2[3]; copy_v3_v3(temp1, force); diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 68321076398..1e6eb77f666 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -42,6 +42,7 @@ #include "BLF_translation.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" /* windows needs for M_PI */ #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 8b35974ea62..06b21fbbd29 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -928,8 +928,12 @@ makebreak: * 3: curs down */ ct = chartransdata + cu->pos; - if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) ; - else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) ; + if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) { + /* pass */ + } + else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) { + /* pass */ + } else { switch (mode) { case FO_CURSUP: lnr = ct->linenr - 1; break; diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 84871375788..76b00ffdb1c 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -87,6 +87,7 @@ void free_gpencil_frames(bGPDlayer *gpl) free_gpencil_strokes(gpf); BLI_freelinkN(&gpl->frames, gpf); } + gpl->actframe = NULL; } /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c003a86a0b7..9a1ea15da97 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2617,11 +2617,21 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ /* free rect buffer if float buffer changes, so it can be recreated with * the updated result, and also in case we got byte buffer from sequencer, * so we don't keep reference to freed buffer */ - if (ibuf->rect_float != rectf || rect || !rectf) + if (ibuf->rect_float != rectf || rect) imb_freerectImBuf(ibuf); - if (rect) + if (rect) { ibuf->rect = rect; + } + else { + /* byte buffer of render result has been freed, make sure image buffers + * does not reference to this buffer anymore + * need check for whether byte buffer was allocated and owned by image itself + * or if it's reusing buffer from render result + */ + if ((ibuf->mall & IB_rect) == 0) + ibuf->rect = NULL; + } if (rectf) { ibuf->rect_float = rectf; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index ebb95a6561e..235d7858e17 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -857,23 +857,22 @@ DO_INLINE float fbderiv(float length, float L) DO_INLINE float fbstar(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) - return fbstar; + if (tempfb_fl < fbstar_fl) + return fbstar_fl; else - return tempfb; + return tempfb_fl; } // function to calculae bending spring force (taken from Choi & Co) DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) { + if (tempfb_fl < fbstar_fl) { return cb; } else { @@ -1450,7 +1449,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0); j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1); k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2); - if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10) + if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10) continue; grid[i][j][k].velocity[0] += lV[v][0]; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 5216aefab58..b7e33f1cf71 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2093,7 +2093,7 @@ void do_versions_ipos_to_animato(Main *main) bAction *new_act; /* add a new action for this, and convert all data into that action */ - new_act = add_empty_action(id->name+2); + new_act = add_empty_action(id->name + 2); ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); new_act->idroot = ipo->blocktype; } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 17e4103c7d3..5382ea453eb 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -64,19 +64,19 @@ #include "BKE_deform.h" -void calc_lat_fudu(int flag, int res, float *fu, float *du) +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du) { if (res == 1) { - *fu = 0.0; - *du = 0.0; + *r_fu = 0.0; + *r_du = 0.0; } else if (flag & LT_GRID) { - *fu = -0.5f * (res - 1); - *du = 1.0f; + *r_fu = -0.5f * (res - 1); + *r_du = 1.0f; } else { - *fu = -1.0f; - *du = 2.0f / (res - 1); + *r_fu = -1.0f; + *r_du = 2.0f / (res - 1); } } @@ -879,9 +879,10 @@ void outside_lattice(Lattice *lt) for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < lt->pntsu; u++, bp++) { - if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) ; + if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) { + /* pass */ + } else { - bp->hide = 1; bp->f1 &= ~SELECT; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b8f891eabe1..ad28e3a6d79 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -38,6 +38,7 @@ #include "DNA_anim_types.h" #include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -981,6 +982,15 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) /* parses the geom+tex nodes */ if (ma->nodetree && ma->use_nodes) ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l); + + /* local group override */ + if((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) { + Group *group; + + for(group= G.main->group.first; group; group= group->id.next) + if(!group->id.lib && strcmp(group->id.name, ma->group->id.name) == 0) + ma->group = group; + } } static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 1aaeebf5109..c244317ccb7 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -576,7 +576,7 @@ static void expand_local_mesh(Mesh *me) for (i = 0; i < me->pdata.totlayer; i++) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->fdata.layers[i].data; + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; for (a = 0; a < me->totpoly; a++, txface++) { /* special case: ima always local immediately */ @@ -2039,7 +2039,7 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); float (*disps)[3] = fd->disps; - int i, tot = mf->v4 ? 4 : 3; + int tot = mf->v4 ? 4 : 3; int side, corners; if (CustomData_external_test(fdata, CD_MDISPS)) { diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 79e3fc19d20..c4d663e17bd 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -228,7 +228,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, } for (i = 1; i < totvert; i++, mv++) { - int j; int fix_normal = TRUE; for (j = 0; j < 3; j++) { @@ -717,7 +716,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, MDeformVert *dv; for (i = 0, dv = dverts; i < totvert; i++, dv++) { MDeformWeight *dw; - unsigned int j; for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { /* note, greater then max defgroups is accounted for in our code, but not < 0 */ @@ -914,7 +912,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) { CustomData edata; EdgeHashIterator *ehi; - MPoly *mp = mesh->mpoly; + MPoly *mp; MEdge *med, *med_orig; EdgeHash *eh = BLI_edgehash_new(); int i, totedge, totpoly = mesh->totpoly; @@ -932,7 +930,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) } /* mesh loops (bmesh only) */ - for (i = 0; i < totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; int j, l_prev = (l + (mp->totloop - 1))->v; for (j = 0; j < mp->totloop; j++, l++) { @@ -970,8 +968,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) if (mesh->totpoly) { /* second pass, iterate through all loops again and assign * the newly created edges to them. */ - MPoly *mp = mesh->mpoly; - for (i = 0; i < mesh->totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; MLoop *l_prev = (l + (mp->totloop - 1)); int j; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 28de80a7157..0afd048e7f2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -494,8 +494,8 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) return md; } -/* Takes an object and returns its first selected armature, else just its - * armature + +/* Takes an object and returns its first selected armature, else just its armature * This should work for multiple armatures per object */ Object *modifiers_isDeformedByArmature(Object *ob) @@ -518,9 +518,8 @@ Object *modifiers_isDeformedByArmature(Object *ob) return NULL; } -/* Takes an object and returns its first selected lattice, else just its - * lattice - * This should work for multiple lattics per object +/* Takes an object and returns its first selected lattice, else just its lattice + * This should work for multiple lattices per object */ Object *modifiers_isDeformedByLattice(Object *ob) { @@ -542,7 +541,28 @@ Object *modifiers_isDeformedByLattice(Object *ob) return NULL; } - +/* Takes an object and returns its first selected curve, else just its curve + * This should work for multiple curves per object + */ +Object *modifiers_isDeformedByCurve(Object *ob) +{ + ModifierData *md = modifiers_getVirtualModifierList(ob); + CurveModifierData *cmd = NULL; + + /* return the first selected curve, this lets us use multiple curves */ + for (; md; md = md->next) { + if (md->type == eModifierType_Curve) { + cmd = (CurveModifierData *) md; + if (cmd->object && (cmd->object->flag & SELECT)) + return cmd->object; + } + } + + if (cmd) /* if were still here then return the last curve */ + return cmd->object; + + return NULL; +} int modifiers_usesArmature(Object *ob, bArmature *arm) { @@ -574,10 +594,12 @@ int modifiers_isCorrectableDeformed(Object *ob) ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md = md->next) { - if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) ; - else - if (modifier_isCorrectableDeformed(md)) + if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) { + /* pass */ + } + else if (modifier_isCorrectableDeformed(md)) { return 1; + } } return 0; } diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index dc3d4a89e62..98eac9b95af 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -55,6 +55,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; + int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -81,6 +82,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) v = BM_vert_create(bm, mv->co, NULL); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); + BM_elem_index_set(v, i); /* set_inline */ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); @@ -89,13 +91,16 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) vtable[i] = v; } MEM_freeN(mvert); + if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ me = medge = dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { + //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); e->head.hflag = BM_edge_flag_from_mflag(me->flag); + BM_elem_index_set(e, i); /* set_inline */ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); etable[i] = e; @@ -106,8 +111,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); } MEM_freeN(medge); + if (is_init) bm->elem_index_dirty &= ~BM_EDGE; - /*do faces*/ + /* do faces */ + /* note: i_alt is aligned with bmesh faces which may not always align with mpolys */ mp = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */ @@ -134,6 +141,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) } f->head.hflag = BM_face_flag_from_mflag(mp->flag); + BM_elem_index_set(f, bm->totface - 1); /* set_inline */ f->mat_nr = mp->mat_nr; l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); @@ -151,6 +159,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_face_normal_update(f); } } + if (is_init) bm->elem_index_dirty &= ~BM_FACE; MEM_freeN(vtable); MEM_freeN(etable); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 0aa1f9e0822..4bd6676608e 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -616,11 +616,6 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist else undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); - if (undistibuf->userflags & IB_RECT_INVALID) { - ibuf->userflags &= ~IB_RECT_INVALID; - IMB_rect_from_float(undistibuf); - } - IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); return undistibuf; @@ -1096,6 +1091,18 @@ void BKE_movieclip_reload(MovieClip *clip) movieclip_load_get_szie(clip); movieclip_calc_length(clip); + + /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded + * (node trees which are not currently visible wouldn't be refreshed) + */ + { + Scene *scene; + for (scene = G.main->scene.first; scene; scene = scene->id.next) { + if (scene->nodetree) { + nodeUpdateID(scene->nodetree, &clip->id); + } + } + } } void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 591524e5156..58348483c61 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1161,7 +1161,6 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) int totlvl = ccgdm->multires.totlvl; if (lvl < totlvl) { - Mesh *me = ob->data; DerivedMesh *lowdm, *cddm, *highdm; CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; CCGKey highGridKey, lowGridKey; diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index a21878d1d7d..5fe4f8e90ba 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -44,36 +44,36 @@ #include "recast-capi.h" -BLI_INLINE float area2(const float* a, const float* b, const float* c) +BLI_INLINE float area2(const float *a, const float *b, const float *c) { return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); } -BLI_INLINE int left(const float* a, const float* b, const float* c) +BLI_INLINE int left(const float *a, const float *b, const float *c) { return area2(a, b, c) < 0; } -int polyNumVerts(const unsigned short* p, const int vertsPerPoly) +int polyNumVerts(const unsigned short *p, const int vertsPerPoly) { int i, nv = 0; - for (i=0; i<vertsPerPoly; i++) { - if (p[i]==0xffff) + for (i = 0; i < vertsPerPoly; i++) { + if (p[i] == 0xffff) break; nv++; } return nv; } -int polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts) +int polyIsConvex(const unsigned short *p, const int vertsPerPoly, const float *verts) { int j, nv = polyNumVerts(p, vertsPerPoly); - if (nv<3) + if (nv < 3) return 0; - for (j=0; j<nv; j++) { - const float* v = &verts[3*p[j]]; - const float* v_next = &verts[3*p[(j+1)%nv]]; - const float* v_prev = &verts[3*p[(nv+j-1)%nv]]; + for (j = 0; j < nv; j++) { + const float *v = &verts[3 * p[j]]; + const float *v_next = &verts[3 * p[(j + 1) % nv]]; + const float *v_prev = &verts[3 * p[(nv + j - 1) % nv]]; if (!left(v_prev, v, v_next)) return 0; @@ -81,7 +81,8 @@ int polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* v return 1; } -float distPointToSegmentSq(const float* point, const float* a, const float* b) +/* XXX, could replace with #dist_to_line_segment_v3(), or add a squared version */ +float distPointToSegmentSq(const float point[3], const float a[3], const float b[3]) { float abx[3], dx[3]; float d, t; @@ -89,24 +90,24 @@ float distPointToSegmentSq(const float* point, const float* a, const float* b) sub_v3_v3v3(abx, b, a); sub_v3_v3v3(dx, point, a); - d = abx[0]*abx[0]+abx[2]*abx[2]; - t = abx[0]*dx[0]+abx[2]*dx[2]; + d = abx[0] * abx[0] + abx[2] * abx[2]; + t = abx[0] * dx[0] + abx[2] * dx[2]; - if (d > 0) + if (d > 0.0f) t /= d; - if (t < 0) - t = 0; - else if (t > 1) - t = 1; - dx[0] = a[0] + t*abx[0] - point[0]; - dx[2] = a[2] + t*abx[2] - point[2]; - - return dx[0]*dx[0] + dx[2]*dx[2]; + if (t < 0.0f) + t = 0.0f; + else if (t > 1.0f) + t = 1.0f; + dx[0] = a[0] + t * abx[0] - point[0]; + dx[2] = a[2] + t * abx[2] - point[2]; + + return dx[0] * dx[0] + dx[2] * dx[2]; } -int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, - int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, - int **recastData) +int buildRawVertIndicesData(DerivedMesh *dm, int *nverts_r, float **verts_r, + int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, + int **recastData) { int vi, fi, triIdx; int nverts, ntris; @@ -117,49 +118,49 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, MFace *faces; nverts = dm->getNumVerts(dm); - if (nverts>=0xffff) { + if (nverts >= 0xffff) { printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff); return 0; } - verts = MEM_callocN(sizeof(float)*3*nverts, "buildRawVertIndicesData verts"); + verts = MEM_callocN(sizeof(float) * 3 * nverts, "buildRawVertIndicesData verts"); dm->getVertCos(dm, (float(*)[3])verts); - //flip coordinates - for (vi=0; vi<nverts; vi++) { - SWAP(float, verts[3*vi+1], verts[3*vi+2]); + /* flip coordinates */ + for (vi = 0; vi < nverts; vi++) { + SWAP(float, verts[3 * vi + 1], verts[3 * vi + 2]); } - //calculate number of tris + /* calculate number of tris */ nfaces = dm->getNumTessFaces(dm); faces = dm->getTessFaceArray(dm); ntris = nfaces; - for (fi=0; fi<nfaces; fi++) { - MFace* face = &faces[fi]; + for (fi = 0; fi < nfaces; fi++) { + MFace *face = &faces[fi]; if (face->v4) ntris++; } - //copy and transform to triangles (reorder on the run) - trisToFacesMap = MEM_callocN(sizeof(int)*ntris, "buildRawVertIndicesData trisToFacesMap"); - tris = MEM_callocN(sizeof(unsigned short)*3*ntris, "buildRawVertIndicesData tris"); + /* copy and transform to triangles (reorder on the run) */ + trisToFacesMap = MEM_callocN(sizeof(int) * ntris, "buildRawVertIndicesData trisToFacesMap"); + tris = MEM_callocN(sizeof(unsigned short) * 3 * ntris, "buildRawVertIndicesData tris"); tri = tris; triIdx = 0; - for (fi=0; fi<nfaces; fi++) { - MFace* face = &faces[fi]; - tri[3*triIdx+0] = (unsigned short) face->v1; - tri[3*triIdx+1] = (unsigned short) face->v3; - tri[3*triIdx+2] = (unsigned short) face->v2; - trisToFacesMap[triIdx++]=fi; + for (fi = 0; fi < nfaces; fi++) { + MFace *face = &faces[fi]; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v3; + tri[3 * triIdx + 2] = (unsigned short) face->v2; + trisToFacesMap[triIdx++] = fi; if (face->v4) { - tri[3*triIdx+0] = (unsigned short) face->v1; - tri[3*triIdx+1] = (unsigned short) face->v4; - tri[3*triIdx+2] = (unsigned short) face->v3; - trisToFacesMap[triIdx++]=fi; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v4; + tri[3 * triIdx + 2] = (unsigned short) face->v3; + trisToFacesMap[triIdx++] = fi; } } - //carefully, recast data is just reference to data in derived mesh - *recastData = (int*)CustomData_get_layer(&dm->polyData, CD_RECAST); + /* carefully, recast data is just reference to data in derived mesh */ + *recastData = (int *)CustomData_get_layer(&dm->polyData, CD_RECAST); *nverts_r = nverts; *verts_r = verts; @@ -170,122 +171,122 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, return 1; } -int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, - unsigned short* polys, const unsigned short* dmeshes, - const float* verts, const unsigned short* dtris, - const int* dtrisToPolysMap) +int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short *polys, const unsigned short *dmeshes, + const float *verts, const unsigned short *dtris, + const int *dtrisToPolysMap) { int polyidx; int capacity = vertsPerPoly; - unsigned short* newPoly = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPoly"); - memset(newPoly, 0xff, sizeof(unsigned short)*capacity); + unsigned short *newPoly = MEM_callocN(sizeof(unsigned short) * capacity, "buildPolygonsByDetailedMeshes newPoly"); + memset(newPoly, 0xff, sizeof(unsigned short) * capacity); - for (polyidx=0; polyidx<npolys; polyidx++) { + for (polyidx = 0; polyidx < npolys; polyidx++) { size_t i; int j, k; int nv = 0; - //search border + /* search border */ int tri, btri = -1; int edge, bedge = -1; - int dtrisNum = dmeshes[polyidx*4+3]; - int dtrisBase = dmeshes[polyidx*4+2]; - unsigned char *traversedTris = MEM_callocN(sizeof(unsigned char)*dtrisNum, "buildPolygonsByDetailedMeshes traversedTris"); - unsigned short* adjustedPoly; + int dtrisNum = dmeshes[polyidx * 4 + 3]; + int dtrisBase = dmeshes[polyidx * 4 + 2]; + unsigned char *traversedTris = MEM_callocN(sizeof(unsigned char) * dtrisNum, "buildPolygonsByDetailedMeshes traversedTris"); + unsigned short *adjustedPoly; int adjustedNv; int allBorderTraversed; - for (j=0; j<dtrisNum && btri==-1;j++) { - int curpolytri = dtrisBase+j; - for (k=0; k<3; k++) { - unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; - if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { + for (j = 0; j < dtrisNum && btri == -1; j++) { + int curpolytri = dtrisBase + j; + for (k = 0; k < 3; k++) { + unsigned short neighbortri = dtris[curpolytri * 3 * 2 + 3 + k]; + if (neighbortri == 0xffff || dtrisToPolysMap[neighbortri] != polyidx + 1) { btri = curpolytri; bedge = k; break; } - } + } } - if (btri==-1 || bedge==-1) { - //can't find triangle with border edge + if (btri == -1 || bedge == -1) { + /* can't find triangle with border edge */ MEM_freeN(traversedTris); MEM_freeN(newPoly); return 0; } - newPoly[nv++] = dtris[btri*3*2+bedge]; + newPoly[nv++] = dtris[btri * 3 * 2 + bedge]; tri = btri; - edge = (bedge+1)%3; - traversedTris[tri-dtrisBase] = 1; + edge = (bedge + 1) % 3; + traversedTris[tri - dtrisBase] = 1; while (tri != btri || edge != bedge) { - int neighbortri = dtris[tri*3*2+3+edge]; - if (neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { - if (nv==capacity) { - unsigned short* newPolyBig; + int neighbortri = dtris[tri * 3 * 2 + 3 + edge]; + if (neighbortri == 0xffff || dtrisToPolysMap[neighbortri] != polyidx + 1) { + if (nv == capacity) { + unsigned short *newPolyBig; capacity += vertsPerPoly; - newPolyBig = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPolyBig"); - memset(newPolyBig, 0xff, sizeof(unsigned short)*capacity); - memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv); + newPolyBig = MEM_callocN(sizeof(unsigned short) * capacity, "buildPolygonsByDetailedMeshes newPolyBig"); + memset(newPolyBig, 0xff, sizeof(unsigned short) * capacity); + memcpy(newPolyBig, newPoly, sizeof(unsigned short) * nv); MEM_freeN(newPoly); - newPoly = newPolyBig; + newPoly = newPolyBig; } - newPoly[nv++] = dtris[tri*3*2+edge]; - //move to next edge - edge = (edge+1)%3; + newPoly[nv++] = dtris[tri * 3 * 2 + edge]; + /* move to next edge */ + edge = (edge + 1) % 3; } else { - //move to next tri + /* move to next tri */ int twinedge = -1; - for (k=0; k<3; k++) { - if (dtris[neighbortri*3*2+3+k] == tri) { + for (k = 0; k < 3; k++) { + if (dtris[neighbortri * 3 * 2 + 3 + k] == tri) { twinedge = k; break; } } - if (twinedge==-1) { + if (twinedge == -1) { printf("Converting navmesh: Error! Can't find neighbor edge - invalid adjacency info\n"); MEM_freeN(traversedTris); goto returnLabel; } tri = neighbortri; - edge = (twinedge+1)%3; - traversedTris[tri-dtrisBase] = 1; + edge = (twinedge + 1) % 3; + traversedTris[tri - dtrisBase] = 1; } } - adjustedPoly = MEM_callocN(sizeof(unsigned short)*nv, "buildPolygonsByDetailedMeshes adjustedPoly"); + adjustedPoly = MEM_callocN(sizeof(unsigned short) * nv, "buildPolygonsByDetailedMeshes adjustedPoly"); adjustedNv = 0; - for (i=0; i<nv; i++) { - unsigned short prev = newPoly[(nv+i-1)%nv]; + for (i = 0; i < nv; i++) { + unsigned short prev = newPoly[(nv + i - 1) % nv]; unsigned short cur = newPoly[i]; - unsigned short next = newPoly[(i+1)%nv]; - float distSq = distPointToSegmentSq(&verts[3*cur], &verts[3*prev], &verts[3*next]); + unsigned short next = newPoly[(i + 1) % nv]; + float distSq = distPointToSegmentSq(&verts[3 * cur], &verts[3 * prev], &verts[3 * next]); static const float tolerance = 0.001f; - if (distSq>tolerance) + if (distSq > tolerance) adjustedPoly[adjustedNv++] = cur; } - memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); + memcpy(newPoly, adjustedPoly, adjustedNv * sizeof(unsigned short)); MEM_freeN(adjustedPoly); nv = adjustedNv; allBorderTraversed = 1; - for (i=0; i<dtrisNum; i++) { - if (traversedTris[i]==0) { - //check whether it has border edges - int curpolytri = dtrisBase+i; - for (k=0; k<3; k++) { - unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; - if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { + for (i = 0; i < dtrisNum; i++) { + if (traversedTris[i] == 0) { + /* check whether it has border edges */ + int curpolytri = dtrisBase + i; + for (k = 0; k < 3; k++) { + unsigned short neighbortri = dtris[curpolytri * 3 * 2 + 3 + k]; + if (neighbortri == 0xffff || dtrisToPolysMap[neighbortri] != polyidx + 1) { allBorderTraversed = 0; break; } } - } + } } - if (nv<=vertsPerPoly && allBorderTraversed) { - for (i=0; i<nv; i++) { - polys[polyidx*vertsPerPoly*2+i] = newPoly[i]; + if (nv <= vertsPerPoly && allBorderTraversed) { + for (i = 0; i < nv; i++) { + polys[polyidx * vertsPerPoly * 2 + i] = newPoly[i]; } } @@ -298,21 +299,20 @@ returnLabel: return 1; } -struct SortContext -{ - const int* recastData; - const int* trisToFacesMap; +struct SortContext { + const int *recastData; + const int *trisToFacesMap; }; -static int compareByData(void *ctx, const void * a, const void * b) +static int compareByData(void *ctx, const void *a, const void *b) { - return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)a]] - - ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)b]] ); + return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)a]] - + ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)b]]); } -int buildNavMeshData(const int nverts, const float* verts, +int buildNavMeshData(const int nverts, const float *verts, const int ntris, const unsigned short *tris, - const int* recastData, const int* trisToFacesMap, + const int *recastData, const int *trisToFacesMap, int *ndtris_r, unsigned short **dtris_r, int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) @@ -333,86 +333,86 @@ int buildNavMeshData(const int nverts, const float* verts, return 0; } - trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + trisMapping = MEM_callocN(sizeof(int) * ntris, "buildNavMeshData trisMapping"); - //sort the triangles by polygon idx - for (i=0; i<ntris; i++) - trisMapping[i]=i; + /* sort the triangles by polygon idx */ + for (i = 0; i < ntris; i++) + trisMapping[i] = i; context.recastData = recastData; context.trisToFacesMap = trisToFacesMap; recast_qsort(trisMapping, ntris, sizeof(int), &context, compareByData); - //search first valid triangle - triangle of convex polygon + /* search first valid triangle - triangle of convex polygon */ validTriStart = -1; - for (i=0; i< ntris; i++) { - if (recastData[trisToFacesMap[trisMapping[i]]]>0) { + for (i = 0; i < ntris; i++) { + if (recastData[trisToFacesMap[trisMapping[i]]] > 0) { validTriStart = i; break; } } - if (validTriStart<0) { + if (validTriStart < 0) { printf("Converting navmesh: Error! No valid polygons in mesh\n"); MEM_freeN(trisMapping); return 0; } - ndtris = ntris-validTriStart; - //fill dtris to faces mapping - dtrisToTrisMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToTrisMap"); - memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); + ndtris = ntris - validTriStart; + /* fill dtris to faces mapping */ + dtrisToTrisMap = MEM_callocN(sizeof(int) * ndtris, "buildNavMeshData dtrisToTrisMap"); + memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris * sizeof(int)); MEM_freeN(trisMapping); - //create detailed mesh triangles - copy only valid triangles - //and reserve memory for adjacency info - dtris = MEM_callocN(sizeof(unsigned short)*3*2*ndtris, "buildNavMeshData dtris"); - memset(dtris, 0xffff, sizeof(unsigned short)*3*2*ndtris); - for (i=0; i<ndtris; i++) { - memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3); + /* create detailed mesh triangles - copy only valid triangles + * and reserve memory for adjacency info */ + dtris = MEM_callocN(sizeof(unsigned short) * 3 * 2 * ndtris, "buildNavMeshData dtris"); + memset(dtris, 0xffff, sizeof(unsigned short) * 3 * 2 * ndtris); + for (i = 0; i < ndtris; i++) { + memcpy(dtris + 3 * 2 * i, tris + 3 * dtrisToTrisMap[i], sizeof(unsigned short) * 3); } - //create new recast data corresponded to dtris and renumber for continuous indices + /* create new recast data corresponded to dtris and renumber for continuous indices */ prevPolyIdx = -1; newPolyIdx = 0; - dtrisToPolysMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToPolysMap"); - for (i=0; i<ndtris; i++) { + dtrisToPolysMap = MEM_callocN(sizeof(int) * ndtris, "buildNavMeshData dtrisToPolysMap"); + for (i = 0; i < ndtris; i++) { curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; - if (curPolyIdx!=prevPolyIdx) { + if (curPolyIdx != prevPolyIdx) { newPolyIdx++; - prevPolyIdx=curPolyIdx; + prevPolyIdx = curPolyIdx; } dtrisToPolysMap[i] = newPolyIdx; } - //build adjacency info for detailed mesh triangles + /* build adjacency info for detailed mesh triangles */ recast_buildMeshAdjacency(dtris, ndtris, nverts, 3); - //create detailed mesh description for each navigation polygon - npolys = dtrisToPolysMap[ndtris-1]; - dmeshes = MEM_callocN(sizeof(unsigned short)*npolys*4, "buildNavMeshData dmeshes"); - memset(dmeshes, 0, npolys*4*sizeof(unsigned short)); + /* create detailed mesh description for each navigation polygon */ + npolys = dtrisToPolysMap[ndtris - 1]; + dmeshes = MEM_callocN(sizeof(unsigned short) * npolys * 4, "buildNavMeshData dmeshes"); + memset(dmeshes, 0, npolys * 4 * sizeof(unsigned short)); dmesh = NULL; prevpolyidx = 0; - for (i=0; i<ndtris; i++) { + for (i = 0; i < ndtris; i++) { int curpolyidx = dtrisToPolysMap[i]; - if (curpolyidx!=prevpolyidx) { - if (curpolyidx!=prevpolyidx+1) { + if (curpolyidx != prevpolyidx) { + if (curpolyidx != prevpolyidx + 1) { printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n"); return 0; } - dmesh = dmesh==NULL ? dmeshes : dmesh+4; - dmesh[2] = (unsigned short)i; //tbase - dmesh[3] = 0; //tnum + dmesh = dmesh == NULL ? dmeshes : dmesh + 4; + dmesh[2] = (unsigned short)i; /* tbase */ + dmesh[3] = 0; /* tnum */ prevpolyidx = curpolyidx; } dmesh[3]++; } - //create navigation polygons + /* create navigation polygons */ vertsPerPoly = 6; - polys = MEM_callocN(sizeof(unsigned short)*npolys*vertsPerPoly*2, "buildNavMeshData polys"); - memset(polys, 0xff, sizeof(unsigned short)*vertsPerPoly*2*npolys); + polys = MEM_callocN(sizeof(unsigned short) * npolys * vertsPerPoly * 2, "buildNavMeshData polys"); + memset(polys, 0xff, sizeof(unsigned short) * vertsPerPoly * 2 * npolys); buildPolygonsByDetailedMeshes(vertsPerPoly, npolys, polys, dmeshes, verts, dtris, dtrisToPolysMap); @@ -429,16 +429,16 @@ int buildNavMeshData(const int nverts, const float* verts, } -int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, - int *nverts, float **verts, - int *ndtris, unsigned short **dtris, - int *npolys, unsigned short **dmeshes, - unsigned short **polys, int **dtrisToPolysMap, - int **dtrisToTrisMap, int **trisToFacesMap) +int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, + int *nverts, float **verts, + int *ndtris, unsigned short **dtris, + int *npolys, unsigned short **dmeshes, + unsigned short **polys, int **dtrisToPolysMap, + int **dtrisToTrisMap, int **trisToFacesMap) { int res = 1; - int ntris = 0, *recastData=NULL; - unsigned short *tris=NULL; + int ntris = 0, *recastData = NULL; + unsigned short *tris = NULL; res = buildRawVertIndicesData(dm, nverts, verts, &ntris, &tris, trisToFacesMap, &recastData); if (!res) { @@ -447,8 +447,8 @@ int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, } res = buildNavMeshData(*nverts, *verts, ntris, tris, recastData, *trisToFacesMap, - ndtris, dtris, npolys, dmeshes, polys, vertsPerPoly, - dtrisToPolysMap, dtrisToTrisMap); + ndtris, dtris, npolys, dmeshes, polys, vertsPerPoly, + dtrisToPolysMap, dtrisToTrisMap); if (!res) { printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); goto exit; @@ -461,11 +461,11 @@ exit: return res; } -int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx) +int polyFindVertex(const unsigned short *p, const int vertsPerPoly, unsigned short vertexIdx) { int i, res = -1; - for (i=0; i<vertsPerPoly; i++) { - if (p[i]==0xffff) + for (i = 0; i < vertsPerPoly; i++) { + if (p[i] == 0xffff) break; if (p[i] == vertexIdx) { res = i; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8cede4f51a5..0ff6b7abbca 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -326,10 +326,13 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) ntype->initfunc(ntree, node, ntemp); /* initialize the node name with the node label. - * note: do this after the initfunc so nodes get - * their data set which may be used in naming + * note: do this after the initfunc so nodes get their data set which may be used in naming * (node groups for example) */ - BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR); + /* XXX Do not use nodeLabel() here, it returns translated content, which should *only* be used + * in UI, *never* in data... + * This solution may be a bit rougher than nodeLabel()'s returned string, but it's simpler + * than adding a "no translate" flag to this func (and labelfunc() as well). */ + BLI_strncpy(node->name, node->typeinfo->name, NODE_MAXSTR); nodeUniqueName(ntree, node); ntree->update |= NTREE_UPDATE_NODES; @@ -886,7 +889,7 @@ void ntreeClearPreview(bNodeTree *ntree) /* hack warning! this function is only used for shader previews, and * since it gets called multiple times per pixel for Ztransp we only * add the color once. Preview gets cleared before it starts render though */ -void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage) +void nodeAddToPreview(bNode *node, const float col[4], int x, int y, int do_manage) { bNodePreview *preview = node->preview; if (preview) { @@ -1638,21 +1641,21 @@ int BKE_node_clipboard_get_type(void) /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ -static int node_get_deplist_recurs(bNode *node, bNode ***nsort) +static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort) { bNode *fromnode; - bNodeSocket *sock; + bNodeLink *link; int level = 0xFFF; node->done = TRUE; /* check linked nodes */ - for (sock = node->inputs.first; sock; sock = sock->next) { - if (sock->link) { - fromnode = sock->link->fromnode; + for (link = ntree->links.first; link; link = link->next) { + if (link->tonode == node) { + fromnode = link->fromnode; if (fromnode) { if (fromnode->done == 0) - fromnode->level = node_get_deplist_recurs(fromnode, nsort); + fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort); if (fromnode->level <= level) level = fromnode->level - 1; } @@ -1662,7 +1665,7 @@ static int node_get_deplist_recurs(bNode *node, bNode ***nsort) /* check parent node */ if (node->parent) { if (node->parent->done == 0) - node->parent->level = node_get_deplist_recurs(node->parent, nsort); + node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort); if (node->parent->level <= level) level = node->parent->level - 1; } @@ -1696,7 +1699,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, in /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, &nsort); + node->level = node_get_deplist_recurs(ntree, node, &nsort); } } } @@ -1714,7 +1717,7 @@ static void ntree_update_node_level(bNodeTree *ntree) /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, NULL); + node->level = node_get_deplist_recurs(ntree, node, NULL); } } } @@ -2243,8 +2246,10 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_layer_weight(ttype); register_node_type_sh_tex_coord(ttype); register_node_type_sh_particle_info(ttype); + register_node_type_sh_bump(ttype); register_node_type_sh_background(ttype); + register_node_type_sh_bsdf_anisotropic(ttype); register_node_type_sh_bsdf_diffuse(ttype); register_node_type_sh_bsdf_glossy(ttype); register_node_type_sh_bsdf_glass(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 2e379e10c60..ff778a4b71b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -699,8 +699,8 @@ void BKE_object_unlink(Object *ob) if (so->treestore) { TreeStoreElem *tselem = so->treestore->data; - int a; - for (a = 0; a < so->treestore->usedelem; a++, tselem++) { + int i; + for (i = 0; i < so->treestore->usedelem; i++, tselem++) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } @@ -2310,11 +2310,9 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u bPoseChannel *pchan; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - - if ((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE)) { - /* pass */ - } - else { + /* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment + * (editarmature.c:2592)... Skip in this case too! */ + if (pchan->bone && !((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE))) { mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); minmax_v3v3_v3(min_r, max_r, vec); mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 03342d0f6d1..f16748bf20a 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -238,7 +238,8 @@ void packAll(Main *bmain, ReportList *reports) ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id)); } else if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { - BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported.", ima->id.name + 2); + BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported", + ima->id.name + 2); } } } @@ -323,7 +324,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i if (remove_tmp) { if (ret_value == RET_ERROR) { if (BLI_rename(tempname, name) != 0) { - BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name); + BKE_reportf(reports, RPT_ERROR, "Error restoring temp file. Check files: '%s' '%s'", tempname, name); } } else { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e8af794eaea..60d3b7a8846 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -48,6 +48,7 @@ #include "DNA_dynamicpaint_types.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_kdtree.h" @@ -97,8 +98,8 @@ int count_particles(ParticleSystem *psys) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else tot++; } return tot; @@ -110,8 +111,8 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else if (p % totgr == cur) tot++; } return tot; @@ -1403,7 +1404,8 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /************************************************/ /* interpolate a location on a face based on face coordinates */ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], - float *w, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) + float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; float e1[3], e2[3], s1, s2, t1, t2; @@ -1746,7 +1748,9 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ } /* interprets particle data to get a point on a mesh in object space */ -void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]) +void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float tmpnor[3], mapfw[4]; float (*orcodata)[3]; @@ -1842,7 +1846,9 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /* Particles on a shape */ /************************************************/ /* ready for future use */ -static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float *UNUSED(fuv), float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), + float *UNUSED(fuv), float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { /* TODO */ float zerovec[3] = {0.0f, 0.0f, 0.0f}; @@ -1868,7 +1874,9 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float * /************************************************/ /* Particles on emitter */ /************************************************/ -void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { if (psmd) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { @@ -3298,7 +3306,7 @@ void copy_particle_key(ParticleKey *to, ParticleKey *from, int time) to->time = to_time; } } -void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time) +void psys_get_from_key(ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time) { if (loc) copy_v3_v3(loc, key->co); if (vel) copy_v3_v3(vel, key->vel); @@ -4319,7 +4327,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta if (pa) { if (!always) { if ((cfra < pa->time && (part->flag & PART_UNBORN) == 0) || - (cfra > pa->dietime && (part->flag & PART_DIED) == 0)) + (cfra >= pa->dietime && (part->flag & PART_DIED) == 0)) { return 0; } @@ -4414,7 +4422,9 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } } -void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco) +void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, + ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, + float uv[2], float orco[3]) { MFace *mface; MTFace *mtface; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 8c0d19ba1fd..84301972ddf 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -532,20 +532,31 @@ static int ptcache_smoke_totpoint(void *smoke_v, int UNUSED(cfra)) SmokeDomainSettings *sds = smd->domain; if (sds->fluid) { - return sds->res[0]*sds->res[1]*sds->res[2]; + return sds->base_res[0]*sds->base_res[1]*sds->base_res[2]; } else return 0; } + +#define SMOKE_CACHE_VERSION "1.04" + static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; int ret = 0; + int fluid_fields = smoke_get_data_flags(sds); + + /* version header */ + ptcache_file_write(pf, SMOKE_CACHE_VERSION, 4, sizeof(char)); + ptcache_file_write(pf, &fluid_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->active_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->dx, 1, sizeof(float)); if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); @@ -553,22 +564,40 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int mode=1; // light if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_write(pf, (unsigned char *)sds->shadow, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + if (fluid_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len, out, mode); + } ptcache_file_compressed_write(pf, (unsigned char *)vx, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vy, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vz, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vxold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vyold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vzold, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode); ptcache_file_write(pf, &dt, 1, sizeof(float)); ptcache_file_write(pf, &dx, 1, sizeof(float)); + ptcache_file_write(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_write(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_write(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_write(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_write(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_write(pf, &sds->active_color, 3, sizeof(float)); MEM_freeN(out); @@ -579,7 +608,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int res_big_array[3]; int res_big; int res = sds->res[0]*sds->res[1]*sds->res[2]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned int in_len_big; unsigned char *out; @@ -593,11 +622,20 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) in_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len_big, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len_big, out, mode); + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len_big, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len_big, out, mode); + } MEM_freeN(out); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer"); @@ -615,34 +653,95 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; + char version[4]; + int ch_res[3]; + float ch_dx; + int fluid_fields = smoke_get_data_flags(sds); + int cache_fields = 0; + int active_fields = 0; + int reallocate = 0; + + /* version header */ + ptcache_file_read(pf, version, 4, sizeof(char)); + if (strncmp(version, SMOKE_CACHE_VERSION, 4)) return 0; + /* fluid info */ + ptcache_file_read(pf, &cache_fields, 1, sizeof(int)); + ptcache_file_read(pf, &active_fields, 1, sizeof(int)); + ptcache_file_read(pf, &ch_res, 3, sizeof(int)); + ptcache_file_read(pf, &ch_dx, 1, sizeof(float)); + + /* check if resolution has changed */ + if (sds->res[0] != ch_res[0] || + sds->res[1] != ch_res[1] || + sds->res[2] != ch_res[2]) { + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) + reallocate = 1; + else + return 0; + } + /* check if active fields have changed */ + if (fluid_fields != cache_fields || + active_fields != sds->active_fields) + reallocate = 1; + + /* reallocate fluid if needed*/ + if (reallocate) { + sds->active_fields = active_fields; + smoke_reallocate_fluid(sds, ch_dx, ch_res, 1); + sds->dx = ch_dx; + VECCOPY(sds->res, ch_res); + sds->total_cells = ch_res[0]*ch_res[1]*ch_res[2]; + if(sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, ch_dx, ch_res, 1); + } + } if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int out_len = (unsigned int)res * sizeof(float); - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_read(pf, (unsigned char *)sds->shadow, out_len); ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); + if (cache_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); + } + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char*)flame, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)fuel, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)react, out_len); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char*)r, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)g, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)b, out_len); + } ptcache_file_compressed_read(pf, (unsigned char*)vx, out_len); ptcache_file_compressed_read(pf, (unsigned char*)vy, out_len); ptcache_file_compressed_read(pf, (unsigned char*)vz, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vxold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vyold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vzold, out_len); ptcache_file_compressed_read(pf, (unsigned char*)obstacles, (unsigned int)res); ptcache_file_read(pf, &dt, 1, sizeof(float)); ptcache_file_read(pf, &dx, 1, sizeof(float)); - - if (pf->data_types & (1<<BPHYS_DATA_SMOKE_HIGH) && sds->wt) { + ptcache_file_read(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_read(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_read(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_read(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_read(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_read(pf, &sds->active_color, 3, sizeof(float)); + } + + if (pf->data_types & (1<<BPHYS_DATA_SMOKE_HIGH) && sds->wt) { int res = sds->res[0]*sds->res[1]*sds->res[2]; int res_big, res_big_array[3]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int out_len = sizeof(float)*(unsigned int)res; unsigned int out_len_big; @@ -650,16 +749,23 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) res_big = res_big_array[0]*res_big_array[1]*res_big_array[2]; out_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len_big); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len_big); + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char*)flame, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)fuel, out_len_big); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char*)r, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)g, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)b, out_len_big); + } ptcache_file_compressed_read(pf, (unsigned char*)tcu, out_len); ptcache_file_compressed_read(pf, (unsigned char*)tcv, out_len); ptcache_file_compressed_read(pf, (unsigned char*)tcw, out_len); } - } return 1; } @@ -2466,10 +2572,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) sbFreeSimulation(pid->calldata); else if (pid->type == PTCACHE_TYPE_PARTICLES) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); - else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) + /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset_turbulence(pid->calldata); + smokeModifier_reset_turbulence(pid->calldata);*/ else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); } @@ -3222,8 +3328,9 @@ void BKE_ptcache_load_external(PTCacheID *pid) cache->endframe = end; cache->totpoint = 0; - if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) - ; /*necessary info in every file*/ + if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) { + /* necessary info in every file */ + } /* read totpoint from info file (frame 0) */ else if (info) { pf= ptcache_file_open(pid, PTCACHE_FILE_READ, 0); diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3a66ec23412..d925d736358 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -34,6 +34,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ @@ -44,15 +46,24 @@ static const char *report_type_str(int type) { switch (type) { - case RPT_DEBUG: return "Debug"; - case RPT_INFO: return "Info"; - case RPT_OPERATOR: return "Operator"; - case RPT_WARNING: return "Warning"; - case RPT_ERROR: return "Error"; - case RPT_ERROR_INVALID_INPUT: return "Invalid Input Error"; - case RPT_ERROR_INVALID_CONTEXT: return "Invalid Context Error"; - case RPT_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error"; - default: return "Undefined Type"; + case RPT_DEBUG: + return TIP_("Debug"); + case RPT_INFO: + return TIP_("Info"); + case RPT_OPERATOR: + return TIP_("Operator"); + case RPT_WARNING: + return TIP_("Warning"); + case RPT_ERROR: + return TIP_("Error"); + case RPT_ERROR_INVALID_INPUT: + return TIP_("Invalid Input Error"); + case RPT_ERROR_INVALID_CONTEXT: + return TIP_("Invalid Context Error"); + case RPT_ERROR_OUT_OF_MEMORY: + return TIP_("Out Of Memory Error"); + default: + return TIP_("Undefined Type"); } } @@ -87,10 +98,11 @@ void BKE_reports_clear(ReportList *reports) reports->list.first = reports->list.last = NULL; } -void BKE_report(ReportList *reports, ReportType type, const char *message) +void BKE_report(ReportList *reports, ReportType type, const char *_message) { Report *report; int len; + const char *message = TIP_(_message); /* in background mode always print otherwise there are cases the errors wont be displayed, * but still add to the report list since this is used for python exception handling */ @@ -114,14 +126,16 @@ void BKE_report(ReportList *reports, ReportType type, const char *message) } } -void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) +void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...) { DynStr *ds; Report *report; va_list args; + const char *format = TIP_(_format); if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { - va_start(args, format); + printf("%s: ", report_type_str(type)); + va_start(args, _format); vprintf(format, args); va_end(args); fprintf(stdout, "\n"); /* otherise each report needs to include a \n */ @@ -132,7 +146,7 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) report = MEM_callocN(sizeof(Report), "Report"); ds = BLI_dynstr_new(); - va_start(args, format); + va_start(args, _format); BLI_dynstr_vappendf(ds, format, args); va_end(args); @@ -147,10 +161,11 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) } } -void BKE_reports_prepend(ReportList *reports, const char *prepend) +void BKE_reports_prepend(ReportList *reports, const char *_prepend) { Report *report; DynStr *ds; + const char *prepend = TIP_(_prepend); if (!reports) return; @@ -169,18 +184,19 @@ void BKE_reports_prepend(ReportList *reports, const char *prepend) } } -void BKE_reports_prependf(ReportList *reports, const char *prepend, ...) +void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...) { Report *report; DynStr *ds; va_list args; + const char *prepend = TIP_(_prepend); if (!reports) return; for (report = reports->list.first; report; report = report->next) { ds = BLI_dynstr_new(); - va_start(args, prepend); + va_start(args, _prepend); BLI_dynstr_vappendf(ds, prepend, args); va_end(args); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b519a59b6d6..628a251ed26 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -54,6 +54,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" +#include "BLI_string.h" #include "BKE_anim.h" #include "BKE_animsys.h" @@ -177,6 +178,9 @@ Scene *BKE_scene_copy(Scene *sce, int type) BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings); BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings); BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings); + + BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name, + sizeof(scen->sequencer_colorspace_settings.name)); } /* tool settings */ @@ -357,6 +361,7 @@ Scene *BKE_scene_add(const char *name) Scene *sce; ParticleEditSettings *pset; int a; + const char *colorspace_name; sce = BKE_libblock_alloc(&bmain->scene, ID_SCE, name); sce->lay = sce->layact = 1; @@ -448,6 +453,7 @@ Scene *BKE_scene_add(const char *name) sce->toolsettings->uvcalc_cubesize = 1.0f; sce->toolsettings->uvcalc_mapdir = 1; sce->toolsettings->uvcalc_mapalign = 1; + sce->toolsettings->uvcalc_margin = 0.001f; sce->toolsettings->unwrapper = 1; sce->toolsettings->select_thresh = 0.01f; sce->toolsettings->jointrilimit = 0.8f; @@ -570,8 +576,13 @@ Scene *BKE_scene_add(const char *name) sound_create_scene(sce); + /* color management */ + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER); + BKE_color_managed_display_settings_init(&sce->display_settings); BKE_color_managed_view_settings_init(&sce->view_settings); + BLI_strncpy(sce->sequencer_colorspace_settings.name, colorspace_name, + sizeof(sce->sequencer_colorspace_settings.name)); return sce; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 90c3347a1df..49ed7f80be3 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1965,13 +1965,16 @@ static ImBuf *copy_from_ibuf_still(SeqRenderData context, Sequence *seq, float n static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, ImBuf *ibuf) { + /* warning: ibuf may be NULL if the video fails to load */ if (nr == 0 || nr == seq->len - 1) { /* we have to store a copy, since the passed ibuf * could be preprocessed afterwards (thereby silently * changing the cached image... */ ibuf = IMB_dupImBuf(ibuf); - sequencer_imbuf_assign_spaces(context.scene, ibuf); + if (ibuf) { + sequencer_imbuf_assign_spaces(context.scene, ibuf); + } if (nr == 0) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 5e67e094e43..c8d6ec73d28 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -51,18 +51,7 @@ #include "BLI_kdtree.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" - -#include "BKE_bvhutils.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_collision.h" -#include "BKE_customdata.h" -#include "BKE_DerivedMesh.h" -#include "BKE_effect.h" -#include "BKE_modifier.h" -#include "BKE_particle.h" -#include "BKE_pointcache.h" -#include "BKE_smoke.h" - +#include "BLI_voxel.h" #include "DNA_customdata_types.h" #include "DNA_group_types.h" @@ -75,8 +64,20 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" +#include "BKE_bvhutils.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_collision.h" +#include "BKE_customdata.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_effect.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_smoke.h" +#include "RE_shader_ext.h" + /* UNUSED so far, may be enabled later */ /* #define USE_SMOKE_COLLISION_DM */ @@ -94,38 +95,38 @@ static LARGE_INTEGER liFrequency; static LARGE_INTEGER liStartTime; static LARGE_INTEGER liCurrentTime; -static void tstart ( void ) +static void tstart(void) { - QueryPerformanceFrequency ( &liFrequency ); - QueryPerformanceCounter ( &liStartTime ); + QueryPerformanceFrequency(&liFrequency); + QueryPerformanceCounter(&liStartTime); } -static void tend ( void ) +static void tend(void) { - QueryPerformanceCounter ( &liCurrentTime ); + QueryPerformanceCounter(&liCurrentTime); } -static double UNUSED_FUNCTION(tval)( void ) +static double tval(void) { - return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); + return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart) * (double)1000.0 / (double)liFrequency.QuadPart)); } #else #include <sys/time.h> static struct timeval _tstart, _tend; static struct timezone tz; -static void tstart ( void ) +static void tstart(void) { - gettimeofday ( &_tstart, &tz ); + gettimeofday(&_tstart, &tz); } -static void tend ( void ) +static void tend(void) { - gettimeofday ( &_tend,&tz ); + gettimeofday(&_tend, &tz); } -static double UNUSED_FUNCTION(tval)( void ) +static double UNUSED_FUNCTION(tval) (void) { double t1, t2; - t1 = ( double ) _tstart.tv_sec*1000 + ( double ) _tstart.tv_usec/ ( 1000 ); - t2 = ( double ) _tend.tv_sec*1000 + ( double ) _tend.tv_usec/ ( 1000 ); - return t2-t1; + t1 = ( double ) _tstart.tv_sec * 1000 + ( double ) _tstart.tv_usec / (1000); + t2 = ( double ) _tend.tv_sec * 1000 + ( double ) _tend.tv_usec / (1000); + return t2 - t1; } #endif @@ -134,608 +135,238 @@ struct Scene; struct DerivedMesh; struct SmokeModifierData; -#define TRI_UVOFFSET (1./4.) - // timestep default value for nice appearance 0.1f #define DT_DEFAULT 0.1f -/* forward declerations */ -static void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct); -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs); +#define ADD_IF_LOWER_POS(a, b) (MIN2((a) + (b), MAX2((a), (b)))) +#define ADD_IF_LOWER_NEG(a, b) (MAX2((a) + (b), MIN2((a), (b)))) +#define ADD_IF_LOWER(a, b) (((b) > 0) ? ADD_IF_LOWER_POS((a), (b)) : ADD_IF_LOWER_NEG((a), (b))) #else /* WITH_SMOKE */ /* Stubs to use when smoke is disabled */ -struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } -// struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } +struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } +//struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(dx), float *UNUSED(dtdef), int UNUSED(use_heat), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } void smoke_free(struct FLUID_3D *UNUSED(fluid)) {} float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(strength)) {} -void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli)) {} -long long smoke_get_mem_req(int UNUSED(xres), int UNUSED(yres), int UNUSED(zres), int UNUSED(amplify)) { return 0; } -void smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) {} +void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), + int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), + float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} +struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } +float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; } +void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UNUSED(t1), float UNUSED(t2)) {} #endif /* WITH_SMOKE */ #ifdef WITH_SMOKE -static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) +void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) - { - size_t i; - float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - float size[3]; - MVert *verts = dm->getVertArray(dm); - float scale = 0.0; - int res; - - res = smd->domain->maxres; - - // get BB of domain - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmp[3]; - - copy_v3_v3(tmp, verts[i].co); - mul_m4_v3(ob->obmat, tmp); - - // min BB - min[0] = MIN2(min[0], tmp[0]); - min[1] = MIN2(min[1], tmp[1]); - min[2] = MIN2(min[2], tmp[2]); - - // max BB - max[0] = MAX2(max[0], tmp[0]); - max[1] = MAX2(max[1], tmp[1]); - max[2] = MAX2(max[2], tmp[2]); - } - - copy_v3_v3(smd->domain->p0, min); - copy_v3_v3(smd->domain->p1, max); - - // calc other res with max_res provided - sub_v3_v3v3(size, max, min); - - // prevent crash when initializing a plane as domain - if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) - return 0; - - if(size[0] > size[1]) - { - if(size[0] > size[2]) - { - scale = res / size[0]; - smd->domain->scale = size[0]; - smd->domain->dx = 1.0f / res; - smd->domain->res[0] = res; - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } - } - else { - if(size[1] > size[2]) - { - scale = res / size[1]; - smd->domain->scale = size[1]; - smd->domain->dx = 1.0f / res; - smd->domain->res[1] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } - } - - // TODO: put in failsafe if res<=0 - dg - - // dt max is 0.1 - smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, DT_DEFAULT); - smd->time = scene->r.cfra; - - if(smd->domain->flags & MOD_SMOKE_HIGHRES) - { - smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise); - smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1); - smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1); - smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1); - smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1); - } - - if(!smd->domain->shadow) - smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow"); - - smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta), &(smd->domain->time_scale), &(smd->domain->vorticity), &(smd->domain->border_collisions)); - - if(smd->domain->wt) - { - smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength)); - } - return 1; - } - else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) - { - // handle flow object here - // XXX TODO - - smd->time = scene->r.cfra; - - return 1; - } - else if((smd->type & MOD_SMOKE_TYPE_COLL)) - { - // todo: delete this when loading colls work -dg - - if(!smd->coll) - { - smokeModifier_createType(smd); - } - - if(!smd->coll->points) - { - // init collision points - SmokeCollSettings *scs = smd->coll; - - smd->time = scene->r.cfra; - - // copy obmat - copy_m4_m4(scs->mat, ob->obmat); - copy_m4_m4(scs->mat_old, ob->obmat); - - DM_ensure_tessface(dm); - fill_scs_points(ob, dm, scs); - } - - if(!smd->coll->bvhtree) - { - smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getTessFaceArray(dm), dm->getNumTessFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 ); - } - return 1; + int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); + + if (free_old && sds->fluid) + smoke_free(sds->fluid); + if (!MIN3(res[0], res[1], res[2])) { + sds->fluid = NULL; + return; } - - return 2; + sds->fluid = smoke_init(res, dx, DT_DEFAULT, use_heat, use_fire, use_colors); + smoke_initBlenderRNA(sds->fluid, &(sds->alpha), &(sds->beta), &(sds->time_scale), &(sds->vorticity), &(sds->border_collisions), + &(sds->burning_rate), &(sds->flame_smoke), sds->flame_smoke_color, &(sds->flame_vorticity), &(sds->flame_ignition), &(sds->flame_max_temp)); + + /* reallocate shadow buffer */ + if (sds->shadow) + MEM_freeN(sds->shadow); + sds->shadow = MEM_callocN(sizeof(float) * res[0] * res[1] * res[2], "SmokeDomainShadow"); } -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) +void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int i = 0, divs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - int newdivs = 0; - int quads = 0, facecounter = 0; + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) - { - if(mface[i].v4) - quads++; + if (free_old && sds->wt) + smoke_turbulence_free(sds->wt); + if (!MIN3(res[0], res[1], res[2])) { + sds->wt = NULL; + return; } + sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, use_fire, use_colors); + sds->res_wt[0] = res[0] * (sds->amplify + 1); + sds->res_wt[1] = res[1] * (sds->amplify + 1); + sds->res_wt[2] = res[2] * (sds->amplify + 1); + sds->dx_wt = dx / (sds->amplify + 1); + smoke_initWaveletBlenderRNA(sds->wt, &(sds->strength)); +} - scs->numtris = dm->getNumTessFaces(dm) + quads; - scs->tridivs = NULL; - calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumTessFaces(dm), scs->numtris, &(scs->tridivs), cell_len); +/* convert global position to domain cell space */ +static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3]) +{ + mul_m4_v3(sds->imat, pos); + sub_v3_v3(pos, sds->p0); + pos[0] *= 1.0f / sds->cell_size[0]; + pos[1] *= 1.0f / sds->cell_size[1]; + pos[2] *= 1.0f / sds->cell_size[2]; +} - // count triangle divisions - for(i = 0; i < dm->getNumTessFaces(dm) + quads; i++) - { - divs += (scs->tridivs[3 * i] + 1) * (scs->tridivs[3 * i + 1] + 1) * (scs->tridivs[3 * i + 2] + 1); - } +/* set domain resolution and dimensions from object derivedmesh */ +static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm) +{ + size_t i; + float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + float size[3]; + MVert *verts = dm->getVertArray(dm); + float scale = 0.0; + int res; - scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints"); - scs->points_old = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPointsOld"); + res = sds->maxres; - for(i = 0; i < dm->getNumVerts(dm); i++) + // get BB of domain + for (i = 0; i < dm->getNumVerts(dm); i++) { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[i * 3], tmpvec); + // min BB + min[0] = MIN2(min[0], verts[i].co[0]); + min[1] = MIN2(min[1], verts[i].co[1]); + min[2] = MIN2(min[2], verts[i].co[2]); + + // max BB + max[0] = MAX2(max[0], verts[i].co[0]); + max[1] = MAX2(max[1], verts[i].co[1]); + max[2] = MAX2(max[2], verts[i].co[2]); } - - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) - { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - //int divs3 = scs->tridivs[3 * facecounter + 2]; - float side1[3], side2[3], trinormorg[3], trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); - } - else { - sub_v3_v3v3(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - } - cross_v3_v3v3(trinormorg, side1, side2); - normalize_v3(trinormorg); - copy_v3_v3(trinorm, trinormorg); - mul_v3_fl(trinorm, 0.25 * cell_len); + /* set domain bounds */ + copy_v3_v3(sds->p0, min); + copy_v3_v3(sds->p1, max); + sds->dx = 1.0f / res; - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float p1[3], p2[3], p3[3], p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } + /* calculate domain dimensions */ + sub_v3_v3v3(size, max, min); + copy_v3_v3(sds->cell_size, size); + mul_v3_v3(size, ob->size); + copy_v3_v3(sds->global_size, size); + copy_v3_v3(sds->dp0, min); - copy_v3_v3(p1, mvert[ mface[i].v1 ].co); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(p2, mvert[ mface[i].v3 ].co); - copy_v3_v3(p3, mvert[ mface[i].v4 ].co); - } - else { - copy_v3_v3(p2, mvert[ mface[i].v2 ].co); - copy_v3_v3(p3, mvert[ mface[i].v3 ].co); - } + invert_m4_m4(sds->imat, ob->obmat); - mul_v3_fl(p1, (1.0-uf-vf)); - mul_v3_fl(p2, uf); - mul_v3_fl(p3, vf); - - add_v3_v3v3(p, p1, p2); - add_v3_v3(p, p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(tmpvec, p, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(tmpvec, p); - sub_v3_v3(tmpvec, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; + // prevent crash when initializing a plane as domain + if ((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) + return; - } while(again!=0); + /* define grid resolutions from longest domain side */ + if (size[0] > MAX2(size[1], size[2])) { + scale = res / size[0]; + sds->scale = size[0] / ob->size[0]; + sds->base_res[0] = res; + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = (int)(size[2] * scale + 0.5); } - - scs->numverts = dm->getNumVerts(dm); - // DG TODO: also save triangle count? - - scs->numpoints = dm->getNumVerts(dm) + newdivs; - - for(i = 0; i < scs->numpoints * 3; i++) - { - scs->points_old[i] = scs->points[i]; + else if (size[1] > MAX2(size[0], size[2])) { + scale = res / size[1]; + sds->scale = size[1] / ob->size[1]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = res; + sds->base_res[2] = (int)(size[2] * scale + 0.5); + } + else { + scale = res / size[2]; + sds->scale = size[2] / ob->size[2]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = res; } -} + /* set cell size */ + sds->cell_size[0] /= (float)sds->base_res[0]; + sds->cell_size[1] /= (float)sds->base_res[1]; + sds->cell_size[2] /= (float)sds->base_res[2]; +} -static void fill_scs_points_anim(Object *UNUSED(ob), DerivedMesh *dm, SmokeCollSettings *scs) +static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) { - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int quads = 0, numtris = 0, facecounter = 0; - unsigned int i = 0; - int divs = 0, newdivs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) { - if(mface[i].v4) - quads++; - } + SmokeDomainSettings *sds = smd->domain; + int res[3]; + /* set domain dimensions from derivedmesh */ + smoke_set_domain_from_derivedmesh(sds, ob, dm); + /* reset domain values */ + zero_v3_int(sds->shift); + zero_v3(sds->shift_f); + add_v3_fl(sds->shift_f, 0.5f); + zero_v3(sds->prev_loc); + mul_m4_v3(ob->obmat, sds->prev_loc); + + /* set resolutions */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + res[0] = res[1] = res[2] = 1; /* use minimum res for adaptive init */ + } + else { + VECCOPY(res, sds->base_res); + } + VECCOPY(sds->res, res); + sds->total_cells = sds->res[0] * sds->res[1] * sds->res[2]; + sds->res_min[0] = sds->res_min[1] = sds->res_min[2] = 0; + VECCOPY(sds->res_max, res); - numtris = dm->getNumTessFaces(dm) + quads; + /* allocate fluid */ + smoke_reallocate_fluid(sds, sds->dx, sds->res, 0); - // check if mesh changed topology - if(scs->numtris != numtris) - return; - if(scs->numverts != dm->getNumVerts(dm)) - return; + smd->time = scene->r.cfra; - // update new positions - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - copy_v3_v3(&scs->points[i * 3], tmpvec); - } + /* allocate highres fluid */ + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, sds->res, 0); + } + /* allocate shadow buffer */ + if (!sds->shadow) + sds->shadow = MEM_callocN(sizeof(float) * sds->res[0] * sds->res[1] * sds->res[2], "SmokeDomainShadow"); - // for every triangle // update div points - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) + return 1; + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - float srcside1[3], srcside2[3], destside1[3], destside2[3], src_trinormorg[3], dest_trinormorg[3], src_trinorm[3], dest_trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v4 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v4 * 3], &scs->points[mface[i].v1 * 3]); - } - else { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v2 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v2 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - } - - cross_v3_v3v3(src_trinormorg, srcside1, srcside2); - cross_v3_v3v3(dest_trinormorg, destside1, destside2); - - normalize_v3(src_trinormorg); - normalize_v3(dest_trinormorg); - - copy_v3_v3(src_trinorm, src_trinormorg); - copy_v3_v3(dest_trinorm, dest_trinormorg); - - mul_v3_fl(src_trinorm, 0.25 * cell_len); - mul_v3_fl(dest_trinorm, 0.25 * cell_len); - - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float src_p1[3], src_p2[3], src_p3[3], src_p[3]={0,0,0}; - float dest_p1[3], dest_p2[3], dest_p3[3], dest_p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float src_tmpvec[3], dest_tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } - - copy_v3_v3(src_p1, &scs->points_old[mface[i].v1 * 3]); - copy_v3_v3(dest_p1, &scs->points[mface[i].v1 * 3]); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v3 * 3]); - - copy_v3_v3(src_p3,&scs->points_old[mface[i].v4 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v4 * 3]); - } - else { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v2 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v2 * 3]); - copy_v3_v3(src_p3, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v3 * 3]); - } - - mul_v3_fl(src_p1, (1.0-uf-vf)); - mul_v3_fl(dest_p1, (1.0-uf-vf)); - - mul_v3_fl(src_p2, uf); - mul_v3_fl(dest_p2, uf); - - mul_v3_fl(src_p3, vf); - mul_v3_fl(dest_p3, vf); - - add_v3_v3v3(src_p, src_p1, src_p2); - add_v3_v3v3(dest_p, dest_p1, dest_p2); - - add_v3_v3(src_p, src_p3); - add_v3_v3(dest_p, dest_p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(src_tmpvec, src_p, src_trinorm); - add_v3_v3v3(dest_tmpvec, dest_p, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(src_tmpvec, src_p); - copy_v3_v3(dest_tmpvec, dest_p); - - sub_v3_v3(src_tmpvec, src_trinorm); - sub_v3_v3(dest_tmpvec, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; + smd->time = scene->r.cfra; - } while(again!=0); + return 1; } - - // scs->numpoints = dm->getNumVerts(dm) + newdivs; - -} - -/*! init triangle divisions */ -static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len) -{ - // mTriangleDivs1.resize( faces.size() ); - // mTriangleDivs2.resize( faces.size() ); - // mTriangleDivs3.resize( faces.size() ); - - size_t i = 0, facecounter = 0; - float maxscale[3] = {1,1,1}; // = channelFindMaxVf(mcScale); get max scale value - float maxpart = ABS(maxscale[0]); - float scaleFac = 0; - float fsTri = 0; - if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]); - if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]); - scaleFac = 1.0 / maxpart; - // featureSize = mLevel[mMaxRefine].nodeSize - fsTri = cell_len * 0.75 * scaleFac; // fsTri = cell_len * 0.9; - - if(*tridivs) - MEM_freeN(*tridivs); - - *tridivs = MEM_callocN(sizeof(int) * numtris * 3, "Smoke_Tridivs"); - - for(i = 0, facecounter = 0; i < numfaces; i++) + else if ((smd->type & MOD_SMOKE_TYPE_COLL)) { - float p0[3], p1[3], p2[3]; - float side1[3]; - float side2[3]; - float side3[3]; - int divs1=0, divs2=0, divs3=0; - - copy_v3_v3(p0, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v2].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - - /* - // debug - if(i==0) - printf("b tmp: %f, fsTri: %f, divs2: %d\n", tmp, fsTri, divs2); - */ - + if (!smd->coll) + { + smokeModifier_createType(smd); } - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - - // TODO quad case - if(faces[i].v4) - { - divs1=0, divs2=0, divs3=0; - - facecounter++; - - copy_v3_v3(p0, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v4].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - } + smd->time = scene->r.cfra; - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - } - facecounter++; + return 1; } + + return 2; } #endif /* WITH_SMOKE */ static void smokeModifier_freeDomain(SmokeModifierData *smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) - MEM_freeN(smd->domain->shadow); - smd->domain->shadow = NULL; + if (smd->domain->shadow) + MEM_freeN(smd->domain->shadow); + smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) smoke_free(smd->domain->fluid); - if(smd->domain->wt) + if (smd->domain->wt) smoke_turbulence_free(smd->domain->wt); - if(smd->domain->effector_weights) - MEM_freeN(smd->domain->effector_weights); + if (smd->domain->effector_weights) + MEM_freeN(smd->domain->effector_weights); smd->domain->effector_weights = NULL; BKE_ptcache_free_list(&(smd->domain->ptcaches[0])); @@ -748,16 +379,10 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd) static void smokeModifier_freeFlow(SmokeModifierData *smd) { - if(smd->flow) + if (smd->flow) { -/* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; -*/ + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); MEM_freeN(smd->flow); smd->flow = NULL; } @@ -765,40 +390,22 @@ static void smokeModifier_freeFlow(SmokeModifierData *smd) static void smokeModifier_freeCollision(SmokeModifierData *smd) { - if(smd->coll) + if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints) + if (scs->numverts) { - if(scs->points) + if (scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - } - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } - if(scs->bvhtree) - { - BLI_bvhtree_free(scs->bvhtree); - scs->bvhtree = NULL; - } - -#ifdef USE_SMOKE_COLLISION_DM - if(smd->coll->dm) + if (smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; -#endif MEM_freeN(smd->coll); smd->coll = NULL; @@ -807,7 +414,7 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd) void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) { - if(smd && smd->domain && smd->domain->wt) + if (smd && smd->domain && smd->domain->wt) { smoke_turbulence_free(smd->domain->wt); smd->domain->wt = NULL; @@ -816,15 +423,15 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) void smokeModifier_reset(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) + if (smd->domain->shadow) MEM_freeN(smd->domain->shadow); smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) { smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; @@ -833,39 +440,23 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smokeModifier_reset_turbulence(smd); smd->time = -1; - - // printf("reset domain end\n"); + smd->domain->total_cells = 0; + smd->domain->active_fields = 0; } - else if(smd->flow) + else if (smd->flow) { - /* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; - */ + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; } - else if(smd->coll) + else if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints && scs->points) + if (scs->numverts && scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; - } + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } } @@ -873,7 +464,7 @@ void smokeModifier_reset(struct SmokeModifierData *smd) void smokeModifier_free(SmokeModifierData *smd) { - if(smd) + if (smd) { smokeModifier_freeDomain(smd); smokeModifier_freeFlow(smd); @@ -883,11 +474,11 @@ void smokeModifier_free(SmokeModifierData *smd) void smokeModifier_createType(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - if(smd->domain) + if (smd->domain) smokeModifier_freeDomain(smd); smd->domain = MEM_callocN(sizeof(SmokeDomainSettings), "SmokeDomain"); @@ -903,13 +494,12 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].last = NULL; /* set some standard values */ smd->domain->fluid = NULL; - smd->domain->wt = NULL; + smd->domain->wt = NULL; smd->domain->eff_group = NULL; smd->domain->fluid_group = NULL; smd->domain->coll_group = NULL; smd->domain->maxres = 32; - smd->domain->amplify = 1; - smd->domain->omega = 1.0; + smd->domain->amplify = 1; smd->domain->alpha = -0.001; smd->domain->beta = 0.1; smd->domain->time_scale = 1.0; @@ -919,14 +509,28 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->strength = 2.0; smd->domain->noise = MOD_SMOKE_NOISEWAVE; smd->domain->diss_speed = 5; - // init 3dview buffer + smd->domain->active_fields = 0; + + smd->domain->adapt_margin = 4; + smd->domain->adapt_res = 0; + smd->domain->adapt_threshold = 0.02f; + + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + /* color */ + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; smd->domain->viewsettings = MOD_SMOKE_VIEW_SHOWBIG; smd->domain->effector_weights = BKE_add_effector_weights(NULL); } - else if(smd->type & MOD_SMOKE_TYPE_FLOW) + else if (smd->type & MOD_SMOKE_TYPE_FLOW) { - if(smd->flow) + if (smd->flow) smokeModifier_freeFlow(smd); smd->flow = MEM_callocN(sizeof(SmokeFlowSettings), "SmokeFlow"); @@ -934,31 +538,35 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->flow->smd = smd; /* set some standard values */ - smd->flow->density = 1.0; - smd->flow->temp = 1.0; + smd->flow->density = 1.0f; + smd->flow->fuel_amount = 1.0f; + smd->flow->temp = 1.0f; smd->flow->flags = MOD_SMOKE_FLOW_ABSOLUTE; - smd->flow->vel_multi = 1.0; + smd->flow->vel_multi = 1.0f; + smd->flow->surface_distance = 1.5f; + smd->flow->source = MOD_SMOKE_FLOW_SOURCE_MESH; + smd->flow->texture_size = 1.0f; + + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->dm = NULL; smd->flow->psys = NULL; } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - if(smd->coll) + if (smd->coll) smokeModifier_freeCollision(smd); smd->coll = MEM_callocN(sizeof(SmokeCollSettings), "SmokeColl"); smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->points_old = NULL; - smd->coll->tridivs = NULL; - smd->coll->vel = NULL; - smd->coll->numpoints = 0; - smd->coll->numtris = 0; - smd->coll->bvhtree = NULL; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; smd->coll->type = 0; // static obstacle - smd->coll->dx = 1.0f / 50.0f; + smd->coll->dm = NULL; #ifdef USE_SMOKE_COLLISION_DM smd->coll->dm = NULL; @@ -971,36 +579,65 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData { tsmd->type = smd->type; tsmd->time = smd->time; - + smokeModifier_createType(tsmd); if (tsmd->domain) { - tsmd->domain->maxres = smd->domain->maxres; - tsmd->domain->amplify = smd->domain->amplify; - tsmd->domain->omega = smd->domain->omega; + tsmd->domain->fluid_group = smd->domain->fluid_group; + tsmd->domain->coll_group = smd->domain->coll_group; + + tsmd->domain->adapt_margin = smd->domain->adapt_margin; + tsmd->domain->adapt_res = smd->domain->adapt_res; + tsmd->domain->adapt_threshold = smd->domain->adapt_threshold; + tsmd->domain->alpha = smd->domain->alpha; tsmd->domain->beta = smd->domain->beta; + tsmd->domain->amplify = smd->domain->amplify; + tsmd->domain->maxres = smd->domain->maxres; tsmd->domain->flags = smd->domain->flags; - tsmd->domain->strength = smd->domain->strength; + tsmd->domain->viewsettings = smd->domain->viewsettings; tsmd->domain->noise = smd->domain->noise; tsmd->domain->diss_speed = smd->domain->diss_speed; - tsmd->domain->viewsettings = smd->domain->viewsettings; - tsmd->domain->fluid_group = smd->domain->fluid_group; - tsmd->domain->coll_group = smd->domain->coll_group; + tsmd->domain->strength = smd->domain->strength; + + tsmd->domain->border_collisions = smd->domain->border_collisions; tsmd->domain->vorticity = smd->domain->vorticity; tsmd->domain->time_scale = smd->domain->time_scale; - tsmd->domain->border_collisions = smd->domain->border_collisions; - + + tsmd->domain->burning_rate = smd->domain->burning_rate; + tsmd->domain->flame_smoke = smd->domain->flame_smoke; + tsmd->domain->flame_vorticity = smd->domain->flame_vorticity; + tsmd->domain->flame_ignition = smd->domain->flame_ignition; + tsmd->domain->flame_max_temp = smd->domain->flame_max_temp; + copy_v3_v3(tsmd->domain->flame_smoke_color, smd->domain->flame_smoke_color); + MEM_freeN(tsmd->domain->effector_weights); tsmd->domain->effector_weights = MEM_dupallocN(smd->domain->effector_weights); - } + } else if (tsmd->flow) { + tsmd->flow->psys = smd->flow->psys; + tsmd->flow->noise_texture = smd->flow->noise_texture; + + tsmd->flow->vel_multi = smd->flow->vel_multi; + tsmd->flow->vel_normal = smd->flow->vel_normal; + tsmd->flow->vel_random = smd->flow->vel_random; + tsmd->flow->density = smd->flow->density; + copy_v3_v3(tsmd->flow->color, smd->flow->color); + tsmd->flow->fuel_amount = smd->flow->fuel_amount; tsmd->flow->temp = smd->flow->temp; - tsmd->flow->psys = smd->flow->psys; + tsmd->flow->volume_density = smd->flow->volume_density; + tsmd->flow->surface_distance = smd->flow->surface_distance; + + tsmd->flow->texture_size = smd->flow->texture_size; + tsmd->flow->texture_offset = smd->flow->texture_offset; + BLI_strncpy(tsmd->flow->uvlayer_name, tsmd->flow->uvlayer_name, sizeof(tsmd->flow->uvlayer_name)); + tsmd->flow->vgroup_density = smd->flow->vgroup_density; + tsmd->flow->type = smd->flow->type; + tsmd->flow->source = smd->flow->source; + tsmd->flow->texture_type = smd->flow->texture_type; tsmd->flow->flags = smd->flow->flags; - tsmd->flow->vel_multi = smd->flow->vel_multi; } else if (tsmd->coll) { ; @@ -1011,24 +648,24 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData #ifdef WITH_SMOKE // forward decleration -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene); static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); static int get_lamp(Scene *scene, float *light) -{ - Base *base_tmp = NULL; +{ + Base *base_tmp = NULL; int found_lamp = 0; // try to find a lamp, preferably local - for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) { - if(base_tmp->object->type == OB_LAMP) { + for (base_tmp = scene->base.first; base_tmp; base_tmp = base_tmp->next) { + if (base_tmp->object->type == OB_LAMP) { Lamp *la = base_tmp->object->data; - if(la->type == LA_LOCAL) { + if (la->type == LA_LOCAL) { copy_v3_v3(light, base_tmp->object->obmat[3]); return 1; } - else if(!found_lamp) { + else if (!found_lamp) { copy_v3_v3(light, base_tmp->object->obmat[3]); found_lamp = 1; } @@ -1038,48 +675,131 @@ static int get_lamp(Scene *scene, float *light) return found_lamp; } -static void smoke_calc_domain(Scene *UNUSED(scene), Object *UNUSED(ob), SmokeModifierData *UNUSED(smd)) +static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, float dt) { -#if 0 - SmokeDomainSettings *sds = smd->domain; - GroupObject *go = NULL; - Base *base = NULL; - - /* do collisions, needs to be done before emission, so that smoke isn't emitted inside collision cells */ - if(1) + if (!scs->dm) return; { - unsigned int i; - Object **collobjs = NULL; - unsigned int numcollobj = 0; - collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj); + DerivedMesh *dm = NULL; + MVert *mvert = NULL; + MFace *mface = NULL; + BVHTreeFromMesh treeData = {0}; + int numverts, i, z; + + float surface_distance = 0.6; + + float *vert_vel = NULL; + int has_velocity = 0; + + tstart(); + + dm = CDDM_copy(scs->dm); + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mface = dm->getTessFaceArray(dm); + numverts = dm->getNumVerts(dm); + + // DG TODO + // if(scs->type > SM_COLL_STATIC) + // if line above is used, the code is in trouble if the object moves but is declared as "does not move" - for(i = 0; i < numcollobj; i++) { - Object *collob= collobjs[i]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); - - // check for active smoke modifier - // if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) - // SmokeModifierData *smd2 = (SmokeModifierData *)md; - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) + vert_vel = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_velocity"); + + if (scs->numverts != numverts || !scs->verts_old) { + if (scs->verts_old) MEM_freeN(scs->verts_old); + + scs->verts_old = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_verts_old"); + scs->numverts = numverts; + } + else { + has_velocity = 1; + } + } + + /* Transform collider vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numverts; i++) { + float n[3]; + float co[3]; + + /* vert pos */ + mul_m4_v3(coll_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(coll_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + + /* vert velocity */ + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { - // ??? anything to do here? + sub_v3_v3v3(&vert_vel[i * 3], co, &scs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); + } + copy_v3_v3(&scs->verts_old[i * 3], co); + } + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { + int x, y; + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) { + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + BVHTreeNearest nearest = {0}; + nearest.index = -1; + nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */ + + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + // DG TODO + if (has_velocity) + { + /* apply object velocity */ + { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + velocityX[index] += hit_vel[0]; + velocityY[index] += hit_vel[1]; + velocityZ[index] += hit_vel[2]; + } + } - // TODO: only something to do for ANIMATED obstacles: need to update positions + /* tag obstacle cells */ + obstacle_map[index] = 1; + if (has_velocity) + obstacle_map[index] |= 8; + } + } } } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + dm->release(dm); - if(collobjs) - MEM_freeN(collobjs); + if (vert_vel) MEM_freeN(vert_vel); } - -#endif } /* Animated obstacles: dx_step = ((x_new - x_old) / totalsteps) * substep */ -static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, int substep, int totalsteps) +static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, + int UNUSED(substep), int UNUSED(totalsteps)) { Object **collobjs = NULL; unsigned int numcollobj = 0; @@ -1092,24 +812,20 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velxOrig = smoke_get_velocity_x(sds->fluid); float *velyOrig = smoke_get_velocity_y(sds->fluid); float *velzOrig = smoke_get_velocity_z(sds->fluid); - // float *density = smoke_get_density(sds->fluid); + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *flame = smoke_get_flame(sds->fluid); + float *r = smoke_get_color_r(sds->fluid); + float *g = smoke_get_color_g(sds->fluid); + float *b = smoke_get_color_b(sds->fluid); unsigned int z; smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); // TODO: delete old obstacle flags - for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) { - if(obstacles[z]) - { - // density[z] = 0; - - velxOrig[z] = 0; - velyOrig[z] = 0; - velzOrig[z] = 0; - } - - if(obstacles[z] & 8) // Do not delete static obstacles + if (obstacles[z] & 8) // Do not delete static obstacles { obstacles[z] = 0; } @@ -1119,410 +835,1064 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, velz[z] = 0; } + collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke); // update obstacle tags in cells - for(collIndex = 0; collIndex < numcollobj; collIndex++) + for (collIndex = 0; collIndex < numcollobj; collIndex++) { - Object *collob= collobjs[collIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = collobjs[collIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // DG TODO: check if modifier is active? - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) + + if ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) { SmokeCollSettings *scs = smd2->coll; - unsigned int i; + obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt); + } + } + + if (collobjs) + MEM_freeN(collobjs); + + /* obstacle cells should not contain any velocity from the smoke simulation */ + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + { + if (obstacles[z]) + { + velxOrig[z] = 0; + velyOrig[z] = 0; + velzOrig[z] = 0; + density[z] = 0; + if (fuel) { + fuel[z] = 0; + flame[z] = 0; + } + if (r) { + r[z] = 0; + g[z] = 0; + b[z] = 0; + } + } + } +} + + +typedef struct EmissionMap { + float *influence; + float *velocity; + int min[3], max[3], res[3]; + int total_cells, valid; +} EmissionMap; + +static void em_boundInsert(EmissionMap *em, float point[3]) +{ + int i = 0; + if (!em->valid) { + VECCOPY(em->min, point); + VECCOPY(em->max, point); + em->valid = 1; + } + else { + for (; i < 3; i++) { + if (point[i] < em->min[i]) em->min[i] = (int)floor(point[i]); + if (point[i] > em->max[i]) em->max[i] = (int)ceil(point[i]); + } + } +} - /* - // DG TODO: support static cobstacles, but basicly we could even support static + rigid with one set of code - if(scs->type > SM_COLL_STATIC) - */ +static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3], float *min_vel, float *max_vel, int margin, float dt) +{ + int i; + for (i = 0; i < 3; i++) { + int adapt = (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) ? sds->adapt_res : 0; + /* add margin */ + min[i] -= margin; + max[i] += margin; + + /* adapt to velocity */ + if (min_vel && min_vel[i] < 0.0f) { + min[i] += (int)ceil(min_vel[i] * dt); + } + if (max_vel && max_vel[i] > 0.0f) { + max[i] += (int)ceil(max_vel[i] * dt); + } + + /* clamp within domain max size */ + CLAMP(min[i], -adapt, sds->base_res[i] + adapt); + CLAMP(max[i], -adapt, sds->base_res[i] + adapt); + } +} + +static void em_allocateData(EmissionMap *em, int use_velocity) { + int i, res[3]; + + for (i = 0; i < 3; i++) { + res[i] = em->max[i] - em->min[i]; + if (res[i] <= 0) + return; + } + em->total_cells = res[0] * res[1] * res[2]; + copy_v3_v3_int(em->res, res); - /* Handle collisions */ - for(i = 0; i < scs->numpoints; i++) + + em->influence = MEM_callocN(sizeof(float) * em->total_cells, "smoke_flow_influence"); + if (use_velocity) + em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity"); +} + +static void em_freeData(EmissionMap *em) { + if (em->influence) + MEM_freeN(em->influence); + if (em->velocity) + MEM_freeN(em->velocity); +} + + +static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, Scene *scene, float time, float dt) +{ + if (sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type == PART_EMITTER) // is particle system selected + { + ParticleSimulationData sim; + ParticleSystem *psys = sfs->psys; + float *particle_pos; + float *particle_vel; + int totpart = psys->totpart, totchild; + int p = 0; + int valid_particles = 0; + + sim.scene = scene; + sim.ob = flow_ob; + sim.psys = psys; + + if (psys->part->type == PART_HAIR) + { + // TODO: PART_HAIR not supported whatsoever + totchild = 0; + } + else + totchild = psys->totchild * psys->part->disp / 100; + + particle_pos = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + particle_vel = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + + /* calculate local position for each particle */ + for (p = 0; p < totpart + totchild; p++) + { + ParticleKey state; + float *pos; + if (p < totpart) { + if (psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) + continue; + } + else { + /* handle child particle */ + ChildParticle *cpa = &psys->child[p - totpart]; + if (psys->particles[cpa->parent].flag & (PARS_NO_DISP | PARS_UNEXIST)) + continue; + } + + state.time = time; + if (psys_get_particle_state(&sim, p, &state, 0) == 0) + continue; + + /* location */ + pos = &particle_pos[valid_particles * 3]; + copy_v3_v3(pos, state.co); + smoke_pos_to_cell(sds, pos); + + /* velocity */ + copy_v3_v3(&particle_vel[valid_particles * 3], state.vel); + mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles * 3]); + + /* calculate emission map bounds */ + em_boundInsert(em, pos); + valid_particles++; + } + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, 1, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + for (p = 0; p < valid_particles; p++) + { + int cell[3]; + size_t i = 0; + size_t index = 0; + int badcell = 0; + + /* 1. get corresponding cell */ + cell[0] = floor(particle_pos[p * 3]) - em->min[0]; + cell[1] = floor(particle_pos[p * 3 + 1]) - em->min[1]; + cell[2] = floor(particle_pos[p * 3 + 2]) - em->min[2]; + /* check if cell is valid (in the domain boundary) */ + for (i = 0; i < 3; i++) { + if ((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { + badcell = 1; + break; + } + } + if (badcell) + continue; + /* get cell index */ + index = smoke_get_index(cell[0], em->res[0], cell[1], em->res[1], cell[2]); + /* Add influence to emission map */ + em->influence[index] = 1.0f; + /* Uses particle velocity as initial velocity for smoke */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) { - // 1. get corresponding cell - int cell[3]; - float pos[3], oldpos[3], vel[3]; - float cPos[3], cOldpos[3]; /* current position in substeps */ - int badcell = 0; - size_t index; - int j; - - // translate local points into global positions - copy_v3_v3(cPos, &scs->points[3 * i]); - mul_m4_v3(scs->mat, cPos); - copy_v3_v3(pos, cPos); - - copy_v3_v3(cOldpos, &scs->points_old[3 * i]); - mul_m4_v3(scs->mat_old, cOldpos); - copy_v3_v3(oldpos, cOldpos); - - /* support for rigid bodies, armatures etc */ - { - float tmp[3]; + VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[p * 3], sfs->vel_multi); + } + } // particles loop + + /* free data */ + if (particle_pos) + MEM_freeN(particle_pos); + if (particle_vel) + MEM_freeN(particle_vel); + } +} - /* x_current = x_old + (x_new - x_old) * step_current / steps_total */ - float mulStep = (float)(((float)substep) / ((float)totalsteps)); +static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) +{ + int result_type; + + /* no node textures for now */ + result_type = multitex_ext_safe(texture, tex_co, texres); + + /* if the texture gave an RGB value, we assume it didn't give a valid + * intensity, since this is in the context of modifiers don't use perceptual color conversion. + * if the texture didn't give an RGB value, copy the intensity across + */ + if (result_type & TEX_RGB) { + texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); + } + else { + copy_v3_fl(&texres->tr, texres->tin); + } +} + +static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, float dt) +{ + if (!sfs->dm) return; + { + DerivedMesh *dm = sfs->dm; + int defgrp_index = sfs->vgroup_density - 1; + MDeformVert *dvert = NULL; + MVert *mvert = NULL; + MVert *mvert_orig = NULL; + MFace *mface = NULL; + MTFace *tface = NULL; + BVHTreeFromMesh treeData = {0}; + int numOfVerts, i, z; + float flow_center[3] = {0}; + + float *vert_vel = NULL; + int has_velocity = 0; + + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */ + mface = dm->getTessFaceArray(dm); + numOfVerts = dm->getNumVerts(dm); + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, sfs->uvlayer_name); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + vert_vel = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_velocity"); + + if (sfs->numverts != numOfVerts || !sfs->verts_old) { + if (sfs->verts_old) MEM_freeN(sfs->verts_old); + sfs->verts_old = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_verts_old"); + sfs->numverts = numOfVerts; + } + else { + has_velocity = 1; + } + } - sub_v3_v3v3(tmp, cPos, cOldpos); - mul_v3_fl(tmp, mulStep); - add_v3_v3(cOldpos, tmp); + /* Transform dm vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numOfVerts; i++) { + float n[3]; + /* vert pos */ + mul_m4_v3(flow_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(flow_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + /* vert velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + float co[3]; + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { + sub_v3_v3v3(&vert_vel[i * 3], co, &sfs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); } + copy_v3_v3(&sfs->verts_old[i * 3], co); + } - sub_v3_v3v3(vel, pos, oldpos); - /* Scale velocity to incorperate the object movement during this step */ - mul_v3_fl(vel, 1.0 / (totalsteps * dt * sds->scale)); - // mul_v3_fl(vel, 1.0 / dt); + /* calculate emission map bounds */ + em_boundInsert(em, mvert[i].co); + } + mul_m4_v3(flow_ob->obmat, flow_center); + smoke_pos_to_cell(sds, flow_center); + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, sfs->surface_distance, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = em->min[2]; z < em->max[2]; z++) { + int x, y; + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) { + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + float ray_dir[3] = {1.0f, 0.0f, 0.0f}; + + BVHTreeRayHit hit = {0}; + BVHTreeNearest nearest = {0}; + + float volume_factor = 0.0f; + float sample_str = 0.0f; + + hit.index = -1; + hit.dist = 9999; + nearest.index = -1; + nearest.dist = sfs->surface_distance * sfs->surface_distance; /* find_nearest uses squared distance */ + + /* Check volume collision */ + if (sfs->volume_density) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { + float dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; + /* If ray and hit face normal are facing same direction + * hit point is inside a closed mesh. */ + if (dot >= 0) { + /* Also cast a ray in opposite direction to make sure + * point is at least surrounded by two faces */ + negate_v3(ray_dir); + hit.index = -1; + hit.dist = 9999; + + BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData); + if (hit.index != -1) { + volume_factor = sfs->volume_density; + nearest.dist = hit.dist * hit.dist; + } + } + } + } - // DG TODO: cap velocity to maxVelMag (or maxvel) + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + float n1[3], n2[3], n3[3], hit_normal[3]; + + /* emit from surface based on distance */ + if (sfs->surface_distance) { + sample_str = sqrtf(nearest.dist) / sfs->surface_distance; + CLAMP(sample_str, 0.0f, 1.0f); + sample_str = pow(1.0f - sample_str, 0.5f); + } + else + sample_str = 0.0f; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + /* apply normal directional velocity */ + if (sfs->vel_normal) { + /* interpolate vertex normal vectors to get nearest point normal */ + normal_short_to_float_v3(n1, mvert[v1].no); + normal_short_to_float_v3(n2, mvert[v2].no); + normal_short_to_float_v3(n3, mvert[v3].no); + interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights); + normalize_v3(hit_normal); + /* apply normal directional and random velocity + * - TODO: random disabled for now since it doesnt really work well as pressure calc smoothens it out... */ + em->velocity[index * 3] += hit_normal[0] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 1] += hit_normal[1] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 2] += hit_normal[2] * sfs->vel_normal * 0.25f; + /* TODO: for fire emitted from mesh surface we can use + * Vf = Vs + (Ps/Pf - 1)*S to model gaseous expansion from solid to fuel */ + } + /* apply object velocity */ + if (has_velocity && sfs->vel_multi) { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + em->velocity[index * 3] += hit_vel[0] * sfs->vel_multi; + em->velocity[index * 3 + 1] += hit_vel[1] * sfs->vel_multi; + em->velocity[index * 3 + 2] += hit_vel[2] * sfs->vel_multi; + } + } + + /* apply vertex group influence if used */ + if (defgrp_index >= 0 && dvert) { + float weight_mask = defvert_find_weight(&dvert[v1], defgrp_index) * weights[0] + + defvert_find_weight(&dvert[v2], defgrp_index) * weights[1] + + defvert_find_weight(&dvert[v3], defgrp_index) * weights[2]; + sample_str *= weight_mask; + } + + /* apply emission texture */ + if ((sfs->flags & MOD_SMOKE_FLOW_TEXTUREEMIT) && sfs->noise_texture) { + float tex_co[3] = {0}; + TexResult texres; + + if (sfs->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO) { + tex_co[0] = ((float)(x - flow_center[0]) / sds->base_res[0]) / sfs->texture_size; + tex_co[1] = ((float)(y - flow_center[1]) / sds->base_res[1]) / sfs->texture_size; + tex_co[2] = ((float)(z - flow_center[2]) / sds->base_res[2] - sfs->texture_offset) / sfs->texture_size; + } + else if (tface) { + interp_v2_v2v2v2(tex_co, tface[f_index].uv[0], tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 2 : 1], + tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 3 : 2], weights); + /* map between -1.0f and 1.0f */ + tex_co[0] = tex_co[0] * 2.0f - 1.0f; + tex_co[1] = tex_co[1] * 2.0f - 1.0f; + tex_co[2] = sfs->texture_offset; + } + texres.nor = NULL; + get_texture_value(sfs->noise_texture, tex_co, &texres); + sample_str *= texres.tin; + } + } - // oldpos + velocity * dt = newpos - get_cell(sds->p0, sds->res, sds->dx*sds->scale, cOldpos /* use current position here instead of "pos" */, cell, 0); + /* multiply initial velocity by emitter influence */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + mul_v3_fl(&em->velocity[index * 3], sample_str); + } - // check if cell is valid (in the domain boundary) - for(j = 0; j < 3; j++) - if((cell[j] > sds->res[j] - 1) || (cell[j] < 0)) - { - badcell = 1; - break; + /* apply final influence based on volume factor */ + em->influence[index] = MAX2(volume_factor, sample_str); } - - if(badcell) - continue; + } + } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + /* restore original mverts */ + CustomData_set_layer(&dm->vertData, CD_MVERT, mvert_orig); + if (mvert) + MEM_freeN(mvert); + + if (vert_vel) MEM_freeN(vert_vel); + } +} - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); +static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], EmissionMap *emaps, unsigned int numflowobj, float dt) +{ + int min[3] = {32767, 32767, 32767}, max[3] = {-32767, -32767, -32767}, res[3]; + int total_cells = 1, res_changed = 0, shift_changed = 0; + float min_vel[3], max_vel[3]; + int x, y, z, i; + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *vx = smoke_get_velocity_x(sds->fluid); + float *vy = smoke_get_velocity_y(sds->fluid); + float *vz = smoke_get_velocity_z(sds->fluid); + + INIT_MINMAX(min_vel, max_vel); + + /* Calculate bounds for current domain content */ + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + int xn = x - new_shift[0]; + int yn = y - new_shift[1]; + int zn = z - new_shift[2]; + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); + float max_den = (fuel) ? MAX2(density[index], fuel[index]) : density[index]; + + /* content bounds (use shifted coordinates) */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > xn) min[0] = xn; + if (min[1] > yn) min[1] = yn; + if (min[2] > zn) min[2] = zn; + if (max[0] < xn) max[0] = xn; + if (max[1] < yn) max[1] = yn; + if (max[2] < zn) max[2] = zn; + } + /* velocity bounds */ + if (min_vel[0] > vx[index]) min_vel[0] = vx[index]; + if (min_vel[1] > vy[index]) min_vel[1] = vy[index]; + if (min_vel[2] > vz[index]) min_vel[2] = vz[index]; + if (max_vel[0] < vx[index]) max_vel[0] = vx[index]; + if (max_vel[1] < vy[index]) max_vel[1] = vy[index]; + if (max_vel[2] < vz[index]) max_vel[2] = vz[index]; + } - // Don't overwrite existing obstacles - if(obstacles[index]) - continue; - - // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]); - // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index); - obstacles[index] = 1 | 8 /* ANIMATED */; + /* also apply emission maps */ + for (i = 0; i < numflowobj; i++) + { + EmissionMap *em = &emaps[i]; - if(len_v3(vel) > FLT_EPSILON) + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) + for (z = em->min[2]; z < em->max[2]; z++) { - // Collision object is moving - - velx[index] = vel[0]; // use "+="? - vely[index] = vel[1]; - velz[index] = vel[2]; + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); + float max_den = em->influence[index]; + + /* density bounds */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > x) min[0] = x; + if (min[1] > y) min[1] = y; + if (min[2] > z) min[2] = z; + if (max[0] < x) max[0] = x; + if (max[1] < y) max[1] = y; + if (max[2] < z) max[2] = z; + } + /* velocity bounds */ + if (em->velocity) { + if (min_vel[0] > em->velocity[index * 3]) min_vel[0] = em->velocity[index * 3]; + if (min_vel[1] > em->velocity[index * 3 + 1]) min_vel[1] = em->velocity[index * 3 + 1]; + if (min_vel[2] > em->velocity[index * 3 + 2]) min_vel[2] = em->velocity[index * 3 + 2]; + if (max_vel[0] < em->velocity[index * 3]) max_vel[0] = em->velocity[index * 3]; + if (max_vel[1] < em->velocity[index * 3 + 1]) max_vel[1] = em->velocity[index * 3 + 1]; + if (max_vel[2] < em->velocity[index * 3 + 2]) max_vel[2] = em->velocity[index * 3 + 2]; + } } + } + + /* calculate new bounds based on these values */ + clampBoundsInDomain(sds, min, max, min_vel, max_vel, sds->adapt_margin + 1, dt); + + for (i = 0; i < 3; i++) { + /* calculate new resolution */ + res[i] = max[i] - min[i]; + total_cells *= res[i]; + + if (new_shift[i]) + shift_changed = 1; + + /* if no content set minimum dimensions */ + if (res[i] <= 0) { + int j; + for (j = 0; j < 3; j++) { + min[j] = 0; + max[j] = 1; + res[j] = 1; } + res_changed = 1; + total_cells = 1; + break; } + if (min[i] != sds->res_min[i] || max[i] != sds->res_max[i]) + res_changed = 1; } - if(collobjs) - MEM_freeN(collobjs); + if (res_changed || shift_changed) { + struct FLUID_3D *fluid_old = sds->fluid; + struct WTURBULENCE *turb_old = sds->wt; + /* allocate new fluid data */ + smoke_reallocate_fluid(sds, sds->dx, res, 0); + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, res, 0); + } + + /* copy values from old fluid to new */ + if (sds->total_cells > 1 && total_cells > 1) { + /* low res smoke */ + float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_heatold, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b; + float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_heatold, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b; + float dummy; + unsigned char *dummy_p; + /* high res smoke */ + int wt_res_old[3]; + float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw, *o_wt_r, *o_wt_g, *o_wt_b; + float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw, *n_wt_r, *n_wt_g, *n_wt_b; + + smoke_export(fluid_old, &dummy, &dummy, &o_dens, &o_react, &o_flame, &o_fuel, &o_heat, &o_heatold, &o_vx, &o_vy, &o_vz, &o_r, &o_g, &o_b, &dummy_p); + smoke_export(sds->fluid, &dummy, &dummy, &n_dens, &n_react, &n_flame, &n_fuel, &n_heat, &n_heatold, &n_vx, &n_vy, &n_vz, &n_r, &n_g, &n_b, &dummy_p); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_export(turb_old, &o_wt_dens, &o_wt_react, &o_wt_flame, &o_wt_fuel, &o_wt_r, &o_wt_g, &o_wt_b, &o_wt_tcu, &o_wt_tcv, &o_wt_tcw); + smoke_turbulence_get_res(turb_old, wt_res_old); + smoke_turbulence_export(sds->wt, &n_wt_dens, &n_wt_react, &n_wt_flame, &n_wt_fuel, &n_wt_r, &n_wt_g, &n_wt_b, &n_wt_tcu, &n_wt_tcv, &n_wt_tcw); + } + + + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + /* old grid index */ + int xo = x - sds->res_min[0]; + int yo = y - sds->res_min[1]; + int zo = z - sds->res_min[2]; + int index_old = smoke_get_index(xo, sds->res[0], yo, sds->res[1], zo); + /* new grid index */ + int xn = x - min[0] - new_shift[0]; + int yn = y - min[1] - new_shift[1]; + int zn = z - min[2] - new_shift[2]; + int index_new = smoke_get_index(xn, res[0], yn, res[1], zn); + + /* skip if outside new domain */ + if (xn < 0 || xn >= res[0] || + yn < 0 || yn >= res[1] || + zn < 0 || zn >= res[2]) + continue; + + /* copy data */ + n_dens[index_new] = o_dens[index_old]; + /* heat */ + if (n_heat && o_heat) { + n_heat[index_new] = o_heat[index_old]; + n_heatold[index_new] = o_heatold[index_old]; + } + /* fuel */ + if (n_fuel && o_fuel) { + n_flame[index_new] = o_flame[index_old]; + n_fuel[index_new] = o_fuel[index_old]; + n_react[index_new] = o_react[index_old]; + } + /* color */ + if (o_r && n_r) { + n_r[index_new] = o_r[index_old]; + n_g[index_new] = o_g[index_old]; + n_b[index_new] = o_b[index_old]; + } + n_vx[index_new] = o_vx[index_old]; + n_vy[index_new] = o_vy[index_old]; + n_vz[index_new] = o_vz[index_old]; + + if (sds->flags & MOD_SMOKE_HIGHRES && turb_old) { + int block_size = sds->amplify + 1; + int i, j, k; + /* old grid index */ + int xx_o = xo * block_size; + int yy_o = yo * block_size; + int zz_o = zo * block_size; + /* new grid index */ + int xx_n = xn * block_size; + int yy_n = yn * block_size; + int zz_n = zn * block_size; + + n_wt_tcu[index_new] = o_wt_tcu[index_old]; + n_wt_tcv[index_new] = o_wt_tcv[index_old]; + n_wt_tcw[index_new] = o_wt_tcw[index_old]; + + for (i = 0; i < block_size; i++) + for (j = 0; j < block_size; j++) + for (k = 0; k < block_size; k++) + { + int big_index_old = smoke_get_index(xx_o + i, wt_res_old[0], yy_o + j, wt_res_old[1], zz_o + k); + int big_index_new = smoke_get_index(xx_n + i, sds->res_wt[0], yy_n + j, sds->res_wt[1], zz_n + k); + /* copy data */ + n_wt_dens[big_index_new] = o_wt_dens[big_index_old]; + if (n_wt_flame && o_wt_flame) { + n_wt_flame[big_index_new] = o_wt_flame[big_index_old]; + n_wt_fuel[big_index_new] = o_wt_fuel[big_index_old]; + n_wt_react[big_index_new] = o_wt_react[big_index_old]; + } + if (n_wt_r && o_wt_r) { + n_wt_r[big_index_new] = o_wt_r[big_index_old]; + n_wt_g[big_index_new] = o_wt_g[big_index_old]; + n_wt_b[big_index_new] = o_wt_b[big_index_old]; + } + } + } + } + } + smoke_free(fluid_old); + if (turb_old) + smoke_turbulence_free(turb_old); + + /* set new domain dimensions */ + VECCOPY(sds->res_min, min); + VECCOPY(sds->res_max, max); + VECCOPY(sds->res, res); + sds->total_cells = total_cells; + } +} + +BLI_INLINE void apply_outflow_fields(int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + density[index] = 0.f; + if (heat) { + heat[index] = 0.f; + } + if (fuel) { + fuel[index] = 0.f; + react[index] = 0.f; + } + if (color_r) { + color_r[index] = 0.f; + color_g[index] = 0.f; + color_b[index] = 0.f; + } +} + +BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value, int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + int absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); + float dens_old = density[index]; + // float fuel_old = (fuel) ? fuel[index] : 0.0f; /* UNUSED */ + float dens_flow = (sfs->type == MOD_SMOKE_FLOW_TYPE_FIRE) ? 0.0f : emission_value * sfs->density; + float fuel_flow = emission_value * sfs->fuel_amount; + /* add heat */ + if (heat) { + heat[index] = MAX2(emission_value * sfs->temp, heat[index]); + } + /* absolute */ + if (absolute_flow) { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + if (dens_flow > density[index]) + density[index] = dens_flow; + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && fuel_flow) { + if (fuel_flow > fuel[index]) + fuel[index] = fuel_flow; + } + } + /* additive */ + else { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + density[index] += dens_flow; + CLAMP(density[index], 0.0f, 1.0f); + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && sfs->fuel_amount) { + fuel[index] += fuel_flow; + CLAMP(fuel[index], 0.0f, 10.0f); + } + } + + /* set color */ + if (color_r && dens_flow) { + float total_dens = density[index] / (dens_old + dens_flow); + color_r[index] = (color_r[index] + sfs->color[0] * dens_flow) * total_dens; + color_g[index] = (color_g[index] + sfs->color[1] * dens_flow) * total_dens; + color_b[index] = (color_b[index] + sfs->color[2] * dens_flow) * total_dens; + } + + /* set fire reaction coordinate */ + if (fuel && fuel[index]) { + /* instead of using 1.0 for all new fuel add slight falloff + * to reduce flow blockiness */ + float value = 1.0f - pow(1.0f - emission_value, 2.0f); + + if (value > react[index]) { + float f = fuel_flow / fuel[index]; + react[index] = value * f + (1.0f - f) * react[index]; + } + } } -static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time) +static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time, float dt) { Object **flowobjs = NULL; + EmissionMap *emaps = NULL; unsigned int numflowobj = 0; unsigned int flowIndex; + int new_shift[3] = {0}; + int active_fields = sds->active_fields; + + /* calculate domain shift for current frame if using adaptive domain */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + int total_shift[3]; + float frame_shift_f[3]; + float ob_loc[3] = {0}; + + mul_m4_v3(ob->obmat, ob_loc); + + VECSUB(frame_shift_f, ob_loc, sds->prev_loc); + copy_v3_v3(sds->prev_loc, ob_loc); + /* convert global space shift to local "cell" space */ + mul_mat3_m4_v3(sds->imat, frame_shift_f); + frame_shift_f[0] = frame_shift_f[0] / sds->cell_size[0]; + frame_shift_f[1] = frame_shift_f[1] / sds->cell_size[1]; + frame_shift_f[2] = frame_shift_f[2] / sds->cell_size[2]; + /* add to total shift */ + VECADD(sds->shift_f, sds->shift_f, frame_shift_f); + /* convert to integer */ + total_shift[0] = floor(sds->shift_f[0]); + total_shift[1] = floor(sds->shift_f[1]); + total_shift[2] = floor(sds->shift_f[2]); + VECSUB(new_shift, total_shift, sds->shift); + copy_v3_v3_int(sds->shift, total_shift); + + /* calculate new domain boundary points so that smoke doesnt slide on sub-cell movement */ + sds->p0[0] = sds->dp0[0] - sds->cell_size[0] * (sds->shift_f[0] - total_shift[0] - 0.5f); + sds->p0[1] = sds->dp0[1] - sds->cell_size[1] * (sds->shift_f[1] - total_shift[1] - 0.5f); + sds->p0[2] = sds->dp0[2] - sds->cell_size[2] * (sds->shift_f[2] - total_shift[2] - 0.5f); + sds->p1[0] = sds->p0[0] + sds->cell_size[0] * sds->base_res[0]; + sds->p1[1] = sds->p0[1] + sds->cell_size[1] * sds->base_res[1]; + sds->p1[2] = sds->p0[2] + sds->cell_size[2] * sds->base_res[2]; + } flowobjs = get_collisionobjects(scene, ob, sds->fluid_group, &numflowobj, eModifierType_Smoke); - // update obstacle tags in cells - for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) + /* init emission maps for each flow */ + emaps = MEM_callocN(sizeof(struct EmissionMap) * numflowobj, "smoke_flow_maps"); + + /* Prepare flow emission maps */ + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) { - Object *collob= flowobjs[flowIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // check for initialized smoke object - if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { // we got nice flow object SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; - if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected - { - ParticleSimulationData sim; - ParticleSystem *psys = sfs->psys; - int totpart=psys->totpart, totchild; - int p = 0; - float *density = smoke_get_density(sds->fluid); - float *bigdensity = smoke_turbulence_get_density(sds->wt); - float *heat = smoke_get_heat(sds->fluid); - float *velocity_x = smoke_get_velocity_x(sds->fluid); - float *velocity_y = smoke_get_velocity_y(sds->fluid); - float *velocity_z = smoke_get_velocity_z(sds->fluid); - unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); - int bigres[3]; - short absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); - short high_emission_smoothing = bigdensity ? (sds->flags & MOD_SMOKE_HIGH_SMOOTH) : 0; - - /* - * A temporary volume map used to store whole emissive - * area to be added to smoke density and interpolated - * for high resolution smoke. - */ - float *temp_emission_map = NULL; - - sim.scene = scene; - sim.ob = collob; - sim.psys = psys; - - // initialize temp emission map - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - int i; - temp_emission_map = MEM_callocN(sizeof(float) * sds->res[0]*sds->res[1]*sds->res[2], "SmokeTempEmission"); - // set whole volume to 0.0f - for (i=0; i<sds->res[0]*sds->res[1]*sds->res[2]; i++) { - temp_emission_map[i] = 0.0f; - } - } + if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) { + emit_from_particles(collob, sds, sfs, em, scene, time, dt); + } + else { + emit_from_derivedmesh(collob, sds, sfs, em, dt); + } - // mostly copied from particle code - if(psys->part->type==PART_HAIR) - { - /* - if(psys->childcache) - { - totchild = psys->totchildcache; + /* update required data fields */ + if (em->total_cells && sfs->type != MOD_SMOKE_FLOW_TYPE_OUTFLOW) { + /* activate heat field if flow produces any heat */ + if (sfs->temp) { + active_fields |= SM_ACTIVE_HEAT; + } + /* activate fuel field if flow adds any fuel */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && sfs->fuel_amount) { + active_fields |= SM_ACTIVE_FIRE; + } + /* activate color field if flows add smoke with varying colors */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE && sfs->density) { + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sfs->color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sfs->color)) { + active_fields |= SM_ACTIVE_COLORS; } - else - */ - - // TODO: PART_HAIR not supported whatsoever - totchild=0; } - else - totchild=psys->totchild*psys->part->disp/100; + } + } + } - for(p=0; p<totpart+totchild; p++) - { - int cell[3]; - size_t i = 0; - size_t index = 0; - int badcell = 0; - ParticleKey state; + /* monitor active fields based on domain settings */ + /* if domain has fire, activate new fields if required */ + if (active_fields & SM_ACTIVE_FIRE) { + /* heat is always needed for fire */ + active_fields |= SM_ACTIVE_HEAT; + /* also activate colors if domain smoke color differs from active color */ + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sds->flame_smoke_color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sds->flame_smoke_color)) { + active_fields |= SM_ACTIVE_COLORS; + } + } - if(p < totpart) - { - if(psys->particles[p].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } - else { - /* handle child particle */ - ChildParticle *cpa = &psys->child[p - totpart]; + /* Adjust domain size if needed */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + adjustDomainResolution(sds, new_shift, emaps, numflowobj, dt); + } - if(psys->particles[cpa->parent].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } + /* Initialize new data fields if any */ + if (active_fields & SM_ACTIVE_HEAT) { + smoke_ensure_heat(sds->fluid); + } + if (active_fields & SM_ACTIVE_FIRE) { + smoke_ensure_fire(sds->fluid, sds->wt); + } + if (active_fields & SM_ACTIVE_COLORS) { + /* initialize all smoke with "active_color" */ + smoke_ensure_colors(sds->fluid, sds->wt, sds->active_color[0], sds->active_color[1], sds->active_color[2]); + } + sds->active_fields = active_fields; - state.time = time; - if(psys_get_particle_state(&sim, p, &state, 0) == 0) - continue; + /* Apply emission data */ + if (sds->fluid) { + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) + { + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); - // copy_v3_v3(pos, pa->state.co); - // mul_m4_v3(ob->imat, pos); - // 1. get corresponding cell - get_cell(sds->p0, sds->res, sds->dx*sds->scale, state.co, cell, 0); - // check if cell is valid (in the domain boundary) - for(i = 0; i < 3; i++) - { - if((cell[i] > sds->res[i] - 1) || (cell[i] < 0)) - { - badcell = 1; - break; - } - } - if(badcell) - continue; - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index])) // this is inflow - { - // heat[index] += sfs->temp * 0.1; - // density[index] += sfs->density * 0.1; - heat[index] = sfs->temp; - - // Add emitter density to temp emission map - temp_emission_map[index] = sfs->density; - - // Uses particle velocity as initial velocity for smoke - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) - { - velocity_x[index] = state.vel[0]*sfs->vel_multi; - velocity_y[index] = state.vel[1]*sfs->vel_multi; - velocity_z[index] = state.vel[2]*sfs->vel_multi; - } - } - else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow - { - heat[index] = 0.f; - density[index] = 0.f; - velocity_x[index] = 0.f; - velocity_y[index] = 0.f; - velocity_z[index] = 0.f; - // we need different handling for the high-res feature - if(bigdensity) - { - // init all surrounding cells according to amplification, too - int i, j, k; - smoke_turbulence_get_res(sds->wt, bigres); - - for(i = 0; i < sds->amplify + 1; i++) - for(j = 0; j < sds->amplify + 1; j++) - for(k = 0; k < sds->amplify + 1; k++) - { - index = smoke_get_index((sds->amplify + 1)* cell[0] + i, bigres[0], (sds->amplify + 1)* cell[1] + j, bigres[1], (sds->amplify + 1)* cell[2] + k); - bigdensity[index] = 0.f; - } - } - } - } // particles loop + // check for initialized smoke object + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + { + // we got nice flow object + SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; + + float *density = smoke_get_density(sds->fluid); + float *color_r = smoke_get_color_r(sds->fluid); + float *color_g = smoke_get_color_g(sds->fluid); + float *color_b = smoke_get_color_b(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *react = smoke_get_react(sds->fluid); + float *bigdensity = smoke_turbulence_get_density(sds->wt); + float *bigfuel = smoke_turbulence_get_fuel(sds->wt); + float *bigreact = smoke_turbulence_get_react(sds->wt); + float *bigcolor_r = smoke_turbulence_get_color_r(sds->wt); + float *bigcolor_g = smoke_turbulence_get_color_g(sds->wt); + float *bigcolor_b = smoke_turbulence_get_color_b(sds->wt); + float *heat = smoke_get_heat(sds->fluid); + float *velocity_x = smoke_get_velocity_x(sds->fluid); + float *velocity_y = smoke_get_velocity_y(sds->fluid); + float *velocity_z = smoke_get_velocity_z(sds->fluid); + //unsigned char *obstacle = smoke_get_obstacle(sds->fluid); + // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); + int bigres[3]; + short high_emission_smoothing = (sds->flags & MOD_SMOKE_HIGH_SMOOTH); + float *velocity_map = em->velocity; + float *emission_map = em->influence; - // apply emission values - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - // initialize variables - int ii, jj, kk, x, y, z, block_size; - size_t index, index_big; + int ii, jj, kk, gx, gy, gz, ex, ey, ez, dx, dy, dz, block_size; + size_t e_index, d_index, index_big; - smoke_turbulence_get_res(sds->wt, bigres); - block_size = sds->amplify + 1; // high res block size + // loop through every emission map cell + for (gx = em->min[0]; gx < em->max[0]; gx++) + for (gy = em->min[1]; gy < em->max[1]; gy++) + for (gz = em->min[2]; gz < em->max[2]; gz++) + { + /* get emission map index */ + ex = gx - em->min[0]; + ey = gy - em->min[1]; + ez = gz - em->min[2]; + e_index = smoke_get_index(ex, em->res[0], ey, em->res[1], ez); + if (!emission_map[e_index]) continue; + /* get domain index */ + dx = gx - sds->res_min[0]; + dy = gy - sds->res_min[1]; + dz = gz - sds->res_min[2]; + d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz); + + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b); + } + else { // inflow + apply_inflow_fields(sfs, emission_map[e_index], d_index, density, heat, fuel, react, color_r, color_g, color_b); + + /* initial velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + velocity_x[d_index] = ADD_IF_LOWER(velocity_x[d_index], velocity_map[e_index * 3]); + velocity_y[d_index] = ADD_IF_LOWER(velocity_y[d_index], velocity_map[e_index * 3 + 1]); + velocity_z[d_index] = ADD_IF_LOWER(velocity_z[d_index], velocity_map[e_index * 3 + 2]); + } + } - // loop through every low res cell - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { + /* loop through high res blocks if high res enabled */ + if (bigdensity) { // neighbor cell emission densities (for high resolution smoke smooth interpolation) float c000, c001, c010, c011, c100, c101, c110, c111; - c000 = (x>0 && y>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c001 = (x>0 && y>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z)] : 0; - c010 = (x>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z-1)] : 0; - c011 = (x>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z)] : 0; + smoke_turbulence_get_res(sds->wt, bigres); + block_size = sds->amplify + 1; // high res block size - c100 = (y>0 && z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c101 = (y>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z)] : 0; - c110 = (z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z-1)] : 0; - c111 = temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z)]; // this cell + c000 = (ex > 0 && ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c001 = (ex > 0 && ey > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez)] : 0; + c010 = (ex > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez - 1)] : 0; + c011 = (ex > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez)] : 0; - // get cell index - index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + c100 = (ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c101 = (ey > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez)] : 0; + c110 = (ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez - 1)] : 0; + c111 = emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez)]; // this cell - // add emission to low resolution density - if (absolute_flow) - { - if (temp_emission_map[index]>0) - density[index] = temp_emission_map[index]; - } - else - { - density[index] += temp_emission_map[index]; + for (ii = 0; ii < block_size; ii++) + for (jj = 0; jj < block_size; jj++) + for (kk = 0; kk < block_size; kk++) + { - if (density[index]>1) - density[index]=1.0f; - } + float fx, fy, fz, interpolated_value; + int shift_x, shift_y, shift_z; - smoke_turbulence_get_res(sds->wt, bigres); - /* loop through high res blocks if high res enabled */ - if (bigdensity) - for(ii = 0; ii < block_size; ii++) - for(jj = 0; jj < block_size; jj++) - for(kk = 0; kk < block_size; kk++) + /* + * Do volume interpolation if emitter smoothing + * is enabled + */ + if (high_emission_smoothing) { - - float fx,fy,fz, interpolated_value; - int shift_x, shift_y, shift_z; - - - /* - * Do volume interpolation if emitter smoothing - * is enabled - */ - if (high_emission_smoothing) - { - // convert block position to relative - // for interpolation smoothing - fx = (float)ii/block_size + 0.5f/block_size; - fy = (float)jj/block_size + 0.5f/block_size; - fz = (float)kk/block_size + 0.5f/block_size; - - // calculate trilinear interpolation - interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) + - c100 * fx * (1-fy) * (1-fz) + - c010 * (1-fx) * fy * (1-fz) + - c001 * (1-fx) * (1-fy) * fz + - c101 * fx * (1-fy) * fz + - c011 * (1-fx) * fy * fz + - c110 * fx * fy * (1-fz) + - c111 * fx * fy * fz; - - - // add some contrast / sharpness - // depending on hi-res block size - - interpolated_value = (interpolated_value-0.4f*sfs->density)*(block_size/2) + 0.4f*sfs->density; - if (interpolated_value<0.0f) interpolated_value = 0.0f; - if (interpolated_value>1.0f) interpolated_value = 1.0f; - - // shift smoke block index - // (because pixel center is actually - // in halfway of the low res block) - shift_x = (x < 1) ? 0 : block_size/2; - shift_y = (y < 1) ? 0 : block_size/2; - shift_z = (z < 1) ? 0 : block_size/2; - } - else - { - // without interpolation use same low resolution - // block value for all hi-res blocks - interpolated_value = c111; - shift_x = 0; - shift_y = 0; - shift_z = 0; + /* get relative block position + * for interpolation smoothing */ + fx = (float)ii / block_size + 0.5f / block_size; + fy = (float)jj / block_size + 0.5f / block_size; + fz = (float)kk / block_size + 0.5f / block_size; + + /* calculate trilinear interpolation */ + interpolated_value = c000 * (1 - fx) * (1 - fy) * (1 - fz) + + c100 * fx * (1 - fy) * (1 - fz) + + c010 * (1 - fx) * fy * (1 - fz) + + c001 * (1 - fx) * (1 - fy) * fz + + c101 * fx * (1 - fy) * fz + + c011 * (1 - fx) * fy * fz + + c110 * fx * fy * (1 - fz) + + c111 * fx * fy * fz; + + + /* add some contrast / sharpness + * depending on hi-res block size */ + interpolated_value = (interpolated_value - 0.4f) * (block_size / 2) + 0.4f; + CLAMP(interpolated_value, 0.0f, 1.0f); + + /* shift smoke block index + * (because pixel center is actually + * in halfway of the low res block) */ + shift_x = (dx < 1) ? 0 : block_size / 2; + shift_y = (dy < 1) ? 0 : block_size / 2; + shift_z = (dz < 1) ? 0 : block_size / 2; + } + else { + /* without interpolation use same low resolution + * block value for all hi-res blocks */ + interpolated_value = c111; + shift_x = 0; + shift_y = 0; + shift_z = 0; + } + + /* get shifted index for current high resolution block */ + index_big = smoke_get_index(block_size * dx + ii - shift_x, bigres[0], block_size * dy + jj - shift_y, bigres[1], block_size * dz + kk - shift_z); + + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + if (interpolated_value) { + apply_outflow_fields(index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); } - - // get shifted index for current high resolution block - index_big = smoke_get_index(block_size * x + ii - shift_x, bigres[0], block_size * y + jj - shift_y, bigres[1], block_size * z + kk - shift_z); - - // add emission data to high resolution density - if (absolute_flow) - { - if (interpolated_value > 0) - bigdensity[index_big] = interpolated_value; - } - else - { - bigdensity[index_big] += interpolated_value; - - if (bigdensity[index_big]>1) - bigdensity[index_big]=1.0f; - } - } // end of hires loop - - } // end of low res loop - - // free temporary emission map - if (temp_emission_map) - MEM_freeN(temp_emission_map); - - } // end emission - } + } + else { // inflow + apply_inflow_fields(sfs, interpolated_value, index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); + } + } // hires loop + } // bigdensity + } // low res loop + + // free emission maps + em_freeData(em); + + } // end emission } } - if(flowobjs) + if (flowobjs) MEM_freeN(flowobjs); + if (emaps) + MEM_freeN(emaps); } static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt)) { - ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); + ListBase *effectors; + /* make sure smoke flow influence is 0.0f */ + sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; + effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); - if(effectors) + if (effectors) { float *density = smoke_get_density(sds->fluid); float *force_x = smoke_get_force_x(sds->fluid); @@ -1532,76 +1902,113 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velocity_y = smoke_get_velocity_y(sds->fluid); float *velocity_z = smoke_get_velocity_z(sds->fluid); unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - int x, y, z; + int x; // precalculate wind forces - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { - EffectedPoint epoint; - float voxelCenter[3] = {0,0,0}, vel[3] = {0,0,0}, retvel[3] = {0,0,0}; - unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - - if((density[index] < FLT_EPSILON) || obstacle[index]) - continue; - - vel[0] = velocity_x[index]; - vel[1] = velocity_y[index]; - vel[2] = velocity_z[index]; - - voxelCenter[0] = sds->p0[0] + sds->dx * sds->scale * x + sds->dx * sds->scale * 0.5; - voxelCenter[1] = sds->p0[1] + sds->dx * sds->scale * y + sds->dx * sds->scale * 0.5; - voxelCenter[2] = sds->p0[2] + sds->dx * sds->scale * z + sds->dx * sds->scale * 0.5; - - pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); - pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); - - // TODO dg - do in force! - force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); - force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); - force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + #pragma omp parallel for schedule(static) + for (x = 0; x < sds->res[0]; x++) + { + int y, z; + for (y = 0; y < sds->res[1]; y++) + for (z = 0; z < sds->res[2]; z++) + { + EffectedPoint epoint; + float mag; + float voxelCenter[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0}; + unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + + if ((density[index] < FLT_EPSILON) || obstacle[index]) + continue; + + vel[0] = velocity_x[index]; + vel[1] = velocity_y[index]; + vel[2] = velocity_z[index]; + + /* convert vel to global space */ + mag = len_v3(vel); + mul_mat3_m4_v3(sds->obmat, vel); + normalize_v3(vel); + mul_v3_fl(vel, mag); + + voxelCenter[0] = sds->p0[0] + sds->cell_size[0] * ((float)(x + sds->res_min[0]) + 0.5f); + voxelCenter[1] = sds->p0[1] + sds->cell_size[1] * ((float)(y + sds->res_min[1]) + 0.5f); + voxelCenter[2] = sds->p0[2] + sds->cell_size[2] * ((float)(z + sds->res_min[2]) + 0.5f); + mul_m4_v3(sds->obmat, voxelCenter); + + pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); + pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + + /* convert retvel to local space */ + mag = len_v3(retvel); + mul_mat3_m4_v3(sds->imat, retvel); + normalize_v3(retvel); + mul_v3_fl(retvel, mag); + + // TODO dg - do in force! + force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); + force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); + force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + } } } pdEndEffectors(&effectors); } -static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) +static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps) { + SmokeDomainSettings *sds = smd->domain; /* stability values copied from wturbulence.cpp */ const int maxSubSteps = 25; float maxVel; // maxVel should be 1.5 (1.5 cell max movement) * dx (cell size) - float dt = DT_DEFAULT; + float dt; float maxVelMag = 0.0f; int totalSubsteps; int substep = 0; float dtSubdiv; + float gravity[3] = {0.0f, 0.0f, -1.0f}; + float gravity_mag; - SmokeDomainSettings *sds = smd->domain; - - /* get max velocity and lower the dt value if it is too high */ - size_t size= sds->res[0] * sds->res[1] * sds->res[2]; - +#if 0 /* UNUSED */ + /* get max velocity and lower the dt value if it is too high */ + size_t size = sds->res[0] * sds->res[1] * sds->res[2]; float *velX = smoke_get_velocity_x(sds->fluid); float *velY = smoke_get_velocity_y(sds->fluid); float *velZ = smoke_get_velocity_z(sds->fluid); size_t i; +#endif - /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ - dt *= (25.0f / fps); + /* update object state */ + invert_m4_m4(sds->imat, ob->obmat); + copy_m4_m4(sds->obmat, ob->obmat); + smoke_set_domain_from_derivedmesh(sds, ob, domain_dm); + /* use global gravity if enabled */ + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + copy_v3_v3(gravity, scene->physics_settings.gravity); + /* map default value to 1.0 */ + mul_v3_fl(gravity, 1.0f / 9.810f); + } + /* convert gravity to domain space */ + gravity_mag = len_v3(gravity); + mul_mat3_m4_v3(sds->imat, gravity); + normalize_v3(gravity); + mul_v3_fl(gravity, gravity_mag); + + /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ + dt = DT_DEFAULT * (25.0f / fps); // maximum timestep/"CFL" constraint: dt < 5.0 *dx / maxVel maxVel = (sds->dx * 5.0); - for(i = 0; i < size; i++) - { - float vtemp = (velX[i]*velX[i]+velY[i]*velY[i]+velZ[i]*velZ[i]); - if(vtemp > maxVelMag) +#if 0 + for (i = 0; i < size; i++) { + float vtemp = (velX[i] * velX[i] + velY[i] * velY[i] + velZ[i] * velZ[i]); + if (vtemp > maxVelMag) maxVelMag = vtemp; } +#endif maxVelMag = sqrt(maxVelMag) * dt * sds->time_scale; totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */ @@ -1609,146 +2016,155 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; /* Disable substeps for now, since it results in numerical instability */ - totalSubsteps = 1.0f; + totalSubsteps = 1.0f; dtSubdiv = (float)dt / (float)totalSubsteps; // printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt); - for(substep = 0; substep < totalSubsteps; substep++) + for (substep = 0; substep < totalSubsteps; substep++) { // calc animated obstacle velocities + update_flowsfluids(scene, ob, sds, smd->time, dtSubdiv); update_obstacles(scene, ob, sds, dtSubdiv, substep, totalSubsteps); - update_flowsfluids(scene, ob, sds, smd->time); - update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt - smoke_step(sds->fluid, dtSubdiv); + if (sds->total_cells > 1) { + update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt + smoke_step(sds->fluid, gravity, dtSubdiv); + } + } +} - // move animated obstacle: Done in update_obstacles() */ +static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) +{ + DerivedMesh *result; + MVert *mverts; + MPoly *mpolys; + MLoop *mloops; + float min[3]; + float max[3]; + float *co; + MPoly *mp; + MLoop *ml; + + int num_verts = 8; + int num_faces = 6; + int i; + float ob_loc[3] = {0}; + float ob_cache_loc[3] = {0}; + + /* dont generate any mesh if there isnt any content */ + if (sds->total_cells <= 1) { + num_verts = 0; + num_faces = 0; + } - // where to delete old obstacles from array? Done in update_obstacles() */ + result = CDDM_new(num_verts, 0, 0, num_faces * 4, num_faces); + mverts = CDDM_get_verts(result); + mpolys = CDDM_get_polys(result); + mloops = CDDM_get_loops(result); + + + if (num_verts) { + /* volume bounds */ + VECMADD(min, sds->p0, sds->cell_size, sds->res_min); + VECMADD(max, sds->p0, sds->cell_size, sds->res_max); + + /* set vertices */ + /* top slab */ + co = mverts[0].co; co[0] = min[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[1].co; co[0] = max[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[2].co; co[0] = max[0]; co[1] = max[1]; co[2] = max[2]; + co = mverts[3].co; co[0] = min[0]; co[1] = max[1]; co[2] = max[2]; + /* bottom slab */ + co = mverts[4].co; co[0] = min[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[5].co; co[0] = max[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[6].co; co[0] = max[0]; co[1] = max[1]; co[2] = min[2]; + co = mverts[7].co; co[0] = min[0]; co[1] = max[1]; co[2] = min[2]; + + /* create faces */ + /* top */ + mp = &mpolys[0]; ml = &mloops[0 * 4]; mp->loopstart = 0 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 1; ml[2].v = 2; ml[3].v = 3; + /* right */ + mp = &mpolys[1]; ml = &mloops[1 * 4]; mp->loopstart = 1 * 4; mp->totloop = 4; + ml[0].v = 2; ml[1].v = 1; ml[2].v = 5; ml[3].v = 6; + /* bottom */ + mp = &mpolys[2]; ml = &mloops[2 * 4]; mp->loopstart = 2 * 4; mp->totloop = 4; + ml[0].v = 7; ml[1].v = 6; ml[2].v = 5; ml[3].v = 4; + /* left */ + mp = &mpolys[3]; ml = &mloops[3 * 4]; mp->loopstart = 3 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 3; ml[2].v = 7; ml[3].v = 4; + /* front */ + mp = &mpolys[4]; ml = &mloops[4 * 4]; mp->loopstart = 4 * 4; mp->totloop = 4; + ml[0].v = 3; ml[1].v = 2; ml[2].v = 6; ml[3].v = 7; + /* back */ + mp = &mpolys[5]; ml = &mloops[5 * 4]; mp->loopstart = 5 * 4; mp->totloop = 4; + ml[0].v = 1; ml[1].v = 0; ml[2].v = 4; ml[3].v = 5; + + /* calculate required shift to match domain's global position + * it was originally simulated at (if object moves without smoke step) */ + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_v3(ob->obmat, ob_loc); + mul_m4_v3(sds->obmat, ob_cache_loc); + VECSUB(sds->obj_shift_f, ob_cache_loc, ob_loc); + /* convert shift to local space and apply to vertices */ + mul_mat3_m4_v3(ob->imat, sds->obj_shift_f); + /* apply */ + for (i = 0; i < num_verts; i++) { + add_v3_v3(mverts[i].co, sds->obj_shift_f); + } } + + + CDDM_calc_edges(result); + return result; } -void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) -{ - if((smd->type & MOD_SMOKE_TYPE_FLOW)) +static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +{ + if ((smd->type & MOD_SMOKE_TYPE_FLOW)) { - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + smd->flow->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->flow->dm); + + if (scene->r.cfra > smd->time) { - // XXX TODO smd->time = scene->r.cfra; - - // rigid movement support - /* - copy_m4_m4(smd->flow->mat_old, smd->flow->mat); - copy_m4_m4(smd->flow->mat, ob->obmat); - */ } - else if(scene->r.cfra < smd->time) + else if (scene->r.cfra < smd->time) { smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - /* Check if domain resolution changed */ - /* DG TODO: can this be solved more elegant using dependancy graph? */ - { - SmokeCollSettings *scs = smd->coll; - Base *base = scene->base.first; - int changed = 0; - float dx = FLT_MAX; - float scale = 1.0f; - int haveDomain = 0; - - for ( ; base; base = base->next) - { - SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); - - if (smd2 && (smd2->type & MOD_SMOKE_TYPE_DOMAIN) && smd2->domain) - { - SmokeDomainSettings *sds = smd2->domain; - - if(sds->dx * sds->scale < dx) - { - dx = sds->dx; - scale = sds->scale; - changed = 1; - } - - haveDomain = 1; - } - } - - if(!haveDomain) - return; - - if(changed) - { - if(dx*scale != scs->dx) - { - scs->dx = dx*scale; - smokeModifier_reset(smd); - } - } - } - - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if (smd->coll) { - unsigned int i; - SmokeCollSettings *scs = smd->coll; - float *points_old = scs->points_old; - float *points = scs->points; - unsigned int numpoints = scs->numpoints; - - // XXX TODO <-- DG: what is TODO here? - smd->time = scene->r.cfra; - - // rigid movement support - copy_m4_m4(scs->mat_old, scs->mat); - copy_m4_m4(scs->mat, ob->obmat); - - if(scs->type != SM_COLL_ANIMATED) // if(not_animated) - { - // nothing to do, "mat" is already up to date - } - else - { - // XXX TODO: need to update positions + divs - - if(scs->numverts != dm->getNumVerts(dm)) - { - // DG TODO: reset modifier? - return; - } + if (smd->coll->dm) + smd->coll->dm->release(smd->coll->dm); - for(i = 0; i < numpoints * 3; i++) - { - points_old[i] = points[i]; - } - - DM_ensure_tessface(dm); - fill_scs_points_anim(ob, dm, scs); - } + smd->coll->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->coll->dm); } - else if(scene->r.cfra < smd->time) + + smd->time = scene->r.cfra; + if (scene->r.cfra < smd->time) { - smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + else if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { SmokeDomainSettings *sds = smd->domain; - float light[3]; PointCache *cache = NULL; PTCacheID pid; int startframe, endframe, framenr; @@ -1762,41 +2178,39 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM BKE_ptcache_id_from_smoke(&pid, ob, smd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); - if(!smd->domain->fluid || framenr == startframe) + if (!smd->domain->fluid || framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + smokeModifier_reset(smd); BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; } - if(!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD)==0 && (cache->flag & PTCACHE_BAKED)==0) + if (!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD) == 0 && (cache->flag & PTCACHE_BAKED) == 0) return; smd->domain->flags &= ~MOD_SMOKE_FILE_LOAD; - CLAMP(framenr, startframe, endframe); /* If already viewing a pre/after frame, no need to reload */ if ((smd->time == framenr) && (framenr != scene->r.cfra)) return; - // printf("startframe: %d, framenr: %d\n", startframe, framenr); - - if(smokeModifier_init(smd, ob, scene, dm)==0) + if (smokeModifier_init(smd, ob, scene, dm) == 0) { printf("bad smokeModifier_init\n"); return; } /* try to read from cache */ - if(BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { + if (BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { BKE_ptcache_validate(cache, framenr); smd->time = framenr; return; } - + /* only calculate something when we advanced a single frame */ - if(framenr != (int)smd->time+1) + if (framenr != (int)smd->time + 1) return; /* don't simulate if viewing start frame, but scene frame is not real start frame */ @@ -1805,54 +2219,48 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM tstart(); - smoke_calc_domain(scene, ob, smd); - /* if on second frame, write cache for first frame */ - if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) { + if ((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) { // create shadows straight after domain initialization so we get nice shadows for startframe, too - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt && sds->total_cells > 1) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } BKE_ptcache_write(&pid, startframe); } - + // set new time smd->time = scene->r.cfra; /* do simulation */ - // low res - // simulate the actual smoke (c++ code in intern/smoke) // DG: interesting commenting this line + deactivating loading of noise files - if(framenr!=startframe) + if (framenr != startframe) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - - step(scene, ob, smd, scene->r.frs_sec / scene->r.frs_sec_base); + + step(scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); } // create shadows before writing cache so they get stored - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } - + BKE_ptcache_validate(cache, framenr); - if(framenr != startframe) + if (framenr != startframe) BKE_ptcache_write(&pid, framenr); tend(); @@ -1860,38 +2268,33 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } } -static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) -{ - const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm){ + smokeModifier_process(smd, scene, ob, dm); - // T_ray *= T_vox - *tRay *= exp(input[index]*correct); - - if(result[index] < 0.0f) + /* return generated geometry for adaptive domain */ + if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && + smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && + smd->domain->base_res[0]) { -// #pragma omp critical - result[index] = *tRay; - } - - return *tRay; + return createDomainGeometry(smd->domain, ob); + } + else return CDDM_copy(dm); } -long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) +static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) { - int totalCells = xres * yres * zres; - int amplifiedCells = totalCells * amplify * amplify * amplify; - - // print out memory requirements - long long int coarseSize = sizeof(float) * totalCells * 22 + - sizeof(unsigned char) * totalCells; + const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); - long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids - sizeof(float) * totalCells * 8 + // small grids - sizeof(float) * 128 * 128 * 128; // noise tile + // T_ray *= T_vox + *tRay *= exp(input[index] * correct); - long long int totalMB = (coarseSize + fineSize) / (1024 * 1024); + if (result[index] < 0.0f) + { +// #pragma omp critical + result[index] = *tRay; + } - return totalMB; + return *tRay; } static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct) @@ -1921,7 +2324,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dy2 - l; err_2 = dz2 - l; for (i = 0; i < l; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -1935,12 +2338,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[0] += x_inc; } - } + } else if ((m >= l) && (m >= n)) { err_1 = dx2 - m; err_2 = dz2 - m; for (i = 0; i < m; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[0] += x_inc; @@ -1954,12 +2357,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[1] += y_inc; } - } + } else { err_1 = dy2 - n; err_2 = dx2 - n; for (i = 0; i < n; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -1977,80 +2380,142 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f cb(result, input, res, pixel, tRay, correct); } -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct) +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) { - float tmp[3]; + float bv[6] = {0}; + float light[3]; + int a, z, slabsize = sds->res[0] * sds->res[1], size = sds->res[0] * sds->res[1] * sds->res[2]; + float *density = smoke_get_density(sds->fluid); + float correct = -7.0 * sds->dx; - sub_v3_v3v3(tmp, pos, p0); - mul_v3_fl(tmp, 1.0 / dx); + if (!get_lamp(scene, light)) return; - if (correct) { - cell[0] = MIN2(res[0] - 1, MAX2(0, (int)floor(tmp[0]))); - cell[1] = MIN2(res[1] - 1, MAX2(0, (int)floor(tmp[1]))); - cell[2] = MIN2(res[2] - 1, MAX2(0, (int)floor(tmp[2]))); - } - else { - cell[0] = (int)floor(tmp[0]); - cell[1] = (int)floor(tmp[1]); - cell[2] = (int)floor(tmp[2]); - } -} - -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) -{ - float bv[6]; - int a, z, slabsize=res[0]*res[1], size= res[0]*res[1]*res[2]; + /* convert light pos to sim cell space */ + mul_m4_v3(sds->imat, light); + light[0] = (light[0] - sds->p0[0]) / sds->cell_size[0] - 0.5f - (float)sds->res_min[0]; + light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f - (float)sds->res_min[1]; + light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f - (float)sds->res_min[2]; - for(a=0; a<size; a++) - result[a]= -1.0f; + for (a = 0; a < size; a++) + sds->shadow[a] = -1.0f; - bv[0] = p0[0]; - bv[1] = p1[0]; - // y - bv[2] = p0[1]; - bv[3] = p1[1]; - // z - bv[4] = p0[2]; - bv[5] = p1[2]; + /* calculate domain bounds in sim cell space */ + // 0,2,4 = 0.0f + bv[1] = (float)sds->res[0]; // x + bv[3] = (float)sds->res[1]; // y + bv[5] = (float)sds->res[2]; // z // #pragma omp parallel for schedule(static,1) - for(z = 0; z < res[2]; z++) + for (z = 0; z < sds->res[2]; z++) { - size_t index = z*slabsize; - int x,y; + size_t index = z * slabsize; + int x, y; - for(y = 0; y < res[1]; y++) - for(x = 0; x < res[0]; x++, index++) + for (y = 0; y < sds->res[1]; y++) + for (x = 0; x < sds->res[0]; x++, index++) { float voxelCenter[3]; float pos[3]; int cell[3]; float tRay = 1.0; - if(result[index] >= 0.0f) - continue; - voxelCenter[0] = p0[0] + dx * x + dx * 0.5; - voxelCenter[1] = p0[1] + dx * y + dx * 0.5; - voxelCenter[2] = p0[2] + dx * z + dx * 0.5; + if (sds->shadow[index] >= 0.0f) + continue; + voxelCenter[0] = (float)x; + voxelCenter[1] = (float)y; + voxelCenter[2] = (float)z; - // get starting position (in voxel coords) - if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) + // get starting cell (light pos) + if (BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) { - // we're ouside - get_cell(p0, res, dx, pos, cell, 1); + // we're ouside -> use point on side of domain + cell[0] = (int)floor(pos[0]); + cell[1] = (int)floor(pos[1]); + cell[2] = (int)floor(pos[2]); } else { - // we're inside - get_cell(p0, res, dx, light, cell, 1); + // we're inside -> use light itself + cell[0] = (int)floor(light[0]); + cell[1] = (int)floor(light[1]); + cell[2] = (int)floor(light[2]); } + /* clamp within grid bounds */ + CLAMP(cell[0], 0, sds->res[0] - 1); + CLAMP(cell[1], 0, sds->res[1] - 1); + CLAMP(cell[2], 0, sds->res[2] - 1); - bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct); + bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, calc_voxel_transp, sds->shadow, density, sds->res, correct); // convention -> from a RGBA float array, use G value for tRay // #pragma omp critical - result[index] = tRay; + sds->shadow[index] = tRay; } } } +/* get smoke velocity and density at given coordinates + * returns fluid density or -1.0f if outside domain*/ +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) +{ + SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke); + zero_v3(velocity); + + if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && smd->domain->fluid) { + SmokeDomainSettings *sds = smd->domain; + float time_mult = 25.f * DT_DEFAULT; + float vel_mag; + float *velX = smoke_get_velocity_x(sds->fluid); + float *velY = smoke_get_velocity_y(sds->fluid); + float *velZ = smoke_get_velocity_z(sds->fluid); + float density = 0.0f, fuel = 0.0f; + float pos[3]; + copy_v3_v3(pos, position); + smoke_pos_to_cell(sds, pos); + + /* check if point is outside domain max bounds */ + if (pos[0] < sds->res_min[0] || pos[1] < sds->res_min[1] || pos[2] < sds->res_min[2]) return -1.0f; + if (pos[0] > sds->res_max[0] || pos[1] > sds->res_max[1] || pos[2] > sds->res_max[2]) return -1.0f; + + /* map pos between 0.0 - 1.0 */ + pos[0] = (pos[0] - sds->res_min[0]) / ((float)sds->res[0]); + pos[1] = (pos[1] - sds->res_min[1]) / ((float)sds->res[1]); + pos[2] = (pos[2] - sds->res_min[2]) / ((float)sds->res[2]); + + + /* check if point is outside active area */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) return 0.0f; + if (pos[0] > 1.0f || pos[1] > 1.0f || pos[2] > 1.0f) return 0.0f; + } + + /* get interpolated velocity */ + velocity[0] = BLI_voxel_sample_trilinear(velX, sds->res, pos) * sds->global_size[0] * time_mult; + velocity[1] = BLI_voxel_sample_trilinear(velY, sds->res, pos) * sds->global_size[1] * time_mult; + velocity[2] = BLI_voxel_sample_trilinear(velZ, sds->res, pos) * sds->global_size[2] * time_mult; + + /* convert velocity direction to global space */ + vel_mag = len_v3(velocity); + mul_mat3_m4_v3(sds->obmat, velocity); + normalize_v3(velocity); + mul_v3_fl(velocity, vel_mag); + + /* use max value of fuel or smoke density */ + density = BLI_voxel_sample_trilinear(smoke_get_density(sds->fluid), sds->res, pos); + if (smoke_has_fuel(sds->fluid)) { + fuel = BLI_voxel_sample_trilinear(smoke_get_fuel(sds->fluid), sds->res, pos); + } + return MAX2(density, fuel); + } + return -1.0f; +} + +int smoke_get_data_flags(SmokeDomainSettings *sds) { + int flags = 0; + if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT; + if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE; + if (smoke_has_colors(sds->fluid)) flags |= SM_ACTIVE_COLORS; + + return flags; +} + #endif /* WITH_SMOKE */ diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 9dd83181521..300d272b86b 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -571,7 +571,7 @@ void default_mtex(MTex *mtex) mtex->size[1] = 1.0; mtex->size[2] = 1.0; mtex->tex = NULL; - mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE; + mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE | MTEX_MAPTO_BOUNDS; mtex->colormodel = 0; mtex->r = 1.0; mtex->g = 0.0; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index c9d7ec3964f..0d304482060 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -169,8 +169,6 @@ void BKE_tracking_settings_init(MovieTracking *tracking) tracking->settings.default_minimum_correlation = 0.75; tracking->settings.default_pattern_size = 11; tracking->settings.default_search_size = 61; - tracking->settings.keyframe1 = 1; - tracking->settings.keyframe2 = 30; tracking->settings.dist = 1; tracking->settings.object_distance = 1; @@ -633,7 +631,7 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int } } -void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) { int i = 0, a = 0, b = 0, tot; MovieTrackingMarker *markers; @@ -736,6 +734,8 @@ void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack dst_track->markersnr = i; MEM_freeN(markers); + + BKE_tracking_dopesheet_tag_update(tracking); } MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name) @@ -1179,6 +1179,8 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char tracking->objectnr = BLI_countlist(&tracking->objects) - 1; object->scale = 1.0f; + object->keyframe1 = 1; + object->keyframe2 = 30; BKE_tracking_object_unique_name(tracking, object); @@ -1494,7 +1496,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * ibuf->x, ibuf->y, overscan, ibuf->channels); } - resibuf->userflags |= IB_RECT_INVALID; + if (ibuf->rect) + imb_freerectImBuf(ibuf); } else { if (undistort) { @@ -1512,9 +1515,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * (void) overscan; (void) undistort; - if (ibuf->rect_float) { - resibuf->userflags |= IB_RECT_INVALID; - } + if (ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); #endif return resibuf; @@ -2755,10 +2757,11 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, Movi return flags; } -static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) +static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, MovieTrackingObject *object) { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); int tot = 0; - int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2; + int frame1 = object->keyframe1, frame2 = object->keyframe2; MovieTrackingTrack *track; track = tracksbase->first; @@ -2779,13 +2782,11 @@ static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, L int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) { #ifdef WITH_LIBMV - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); - if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) { /* TODO: check for number of tracks? */ return TRUE; } - else if (reconstruct_count_tracks_on_both_keyframes(tracking, tracksbase) < 8) { + else if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) { BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size); diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index dab44b5463c..9f29cb8b137 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -47,7 +47,11 @@ #include "BKE_report.h" #include "BKE_writeavi.h" -#include "AVI_avi.h" + +/* ********************** general blender movie support ***************************** */ + +#ifdef WITH_AVI +# include "AVI_avi.h" /* callbacks */ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports); @@ -55,30 +59,31 @@ static void end_avi(void); static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports); static void filepath_avi(char *string, RenderData *rd); - -/* ********************** general blender movie support ***************************** */ +#endif /* WITH_AVI */ #ifdef WITH_QUICKTIME -#include "quicktime_export.h" +# include "quicktime_export.h" #endif #ifdef WITH_FFMPEG -#include "BKE_writeffmpeg.h" +# include "BKE_writeffmpeg.h" #endif #include "BKE_writeframeserver.h" bMovieHandle *BKE_movie_handle_get(const char imtype) { - static bMovieHandle mh; + static bMovieHandle mh = {0}; /* set the default handle, as builtin */ +#ifdef WITH_AVI mh.start_movie = start_avi; mh.append_movie = append_avi; mh.end_movie = end_avi; mh.get_next_frame = NULL; mh.get_movie_path = filepath_avi; - +#endif + /* do the platform specific handles */ #ifdef WITH_QUICKTIME if (imtype == R_IMF_IMTYPE_QUICKTIME) { @@ -114,6 +119,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) /* ****************************************************************** */ +#ifdef WITH_AVI + static AviMovie *avi = NULL; static void filepath_avi(char *string, RenderData *rd) @@ -219,6 +226,7 @@ static void end_avi(void) MEM_freeN(avi); avi = NULL; } +#endif /* WITH_AVI */ /* similar to BKE_makepicstring() */ void BKE_movie_filepath_get(char *string, RenderData *rd) diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h index 941a74ec2ab..f068c4c58f0 100644 --- a/source/blender/blenkernel/nla_private.h +++ b/source/blender/blenkernel/nla_private.h @@ -85,4 +85,4 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes); void nladata_flush_channels(ListBase *channels); -#endif // __NLA_PRIVATE_H__ +#endif /* __NLA_PRIVATE_H__ */ diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 74b477bacaf..03b75975af4 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -78,8 +78,6 @@ extern "C" { #include "BLI_rect.h" -#include "BLI_noise.h" - #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 52b839d11a9..a86b362c271 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -64,4 +64,4 @@ void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, st void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -#endif // __BLI_BPATH_H__ +#endif /* __BLI_BPATH_H__ */ diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h index 92356b24403..d04e544376a 100644 --- a/source/blender/blenlib/BLI_dlrbTree.h +++ b/source/blender/blenlib/BLI_dlrbTree.h @@ -158,4 +158,4 @@ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node); /* ********************************************** */ -#endif // __BLI_DLRBTREE_H__ +#endif /* __BLI_DLRBTREE_H__ */ diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h index b747da3b738..4bc6d3828b9 100644 --- a/source/blender/blenlib/BLI_endian_switch_inline.h +++ b/source/blender/blenlib/BLI_endian_switch_inline.h @@ -32,85 +32,63 @@ * \ingroup bli */ +/* note: using a temp char to switch endian is a lot slower, + * use bit shifting instead. */ +/* *** 16 *** */ BLI_INLINE void BLI_endian_switch_int16(short *val) { - char *p_i = (char *)val; - char s_i; + short tval = *val; + *val = (tval >> 8) | + (tval << 8); - s_i = p_i[0]; - p_i[0] = p_i[1]; - p_i[1] = s_i; } - BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; - p_i[0] = p_i[1]; - p_i[1] = s_i; + BLI_endian_switch_int16((short *)val); } + +/* *** 32 *** */ BLI_INLINE void BLI_endian_switch_int32(int *val) { - char *p_i = (char *)val; - char s_i; + int tval = *val; + *val = ((tval >> 24)) | + ((tval << 8) & 0x00ff0000) | + ((tval >> 8) & 0x0000ff00) | + ((tval << 24)); - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; } - BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; + BLI_endian_switch_int32((int *)val); } - BLI_INLINE void BLI_endian_switch_float(float *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; + BLI_endian_switch_int32((int *)val); } + +/* *** 64 *** */ BLI_INLINE void BLI_endian_switch_int64(int64_t *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + int64_t tval = *val; + *val = ((tval >> 56)) | + ((tval << 40) & 0x00ff000000000000ll) | + ((tval << 24) & 0x0000ff0000000000ll) | + ((tval << 8) & 0x000000ff00000000ll) | + ((tval >> 8) & 0x00000000ff000000ll) | + ((tval >> 24) & 0x0000000000ff0000ll) | + ((tval >> 40) & 0x000000000000ff00ll) | + ((tval << 56)); } - BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + BLI_endian_switch_int64((int64_t *)val); } - BLI_INLINE void BLI_endian_switch_double(double *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + BLI_endian_switch_int64((int64_t *)val); } #endif /* __BLI_ENDIAN_SWITCH_INLINE_H__ */ diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index b378f2bb365..9d7e6107f19 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -42,6 +42,7 @@ typedef void (*HeapFreeFP)(void *ptr); /* Creates a new heap. BLI_memarena is used for allocating nodes. Removed nodes * are recycled, so memory usage will not shrink. */ +Heap *BLI_heap_new_ex(unsigned int tot_reserve); Heap *BLI_heap_new(void); void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp); diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 985b5af3b94..8d0d4943ebe 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -75,7 +75,7 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; /* callback must update nearest in case it finds a nearest result */ -typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float *co, BVHTreeNearest *nearest); +typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest); /* callback must update hit in case it finds a nearest successful hit */ typedef void (*BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit); @@ -87,11 +87,11 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); void BLI_bvhtree_free(BVHTree *tree); /* construct: first insert points, then call balance */ -int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints); +int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints); void BLI_bvhtree_balance(BVHTree *tree); /* update: first update points/nodes, then call update_tree to refit the bounding volumes */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints); +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); void BLI_bvhtree_update_tree(BVHTree *tree); /* collision/overlap: check two trees if they overlap, alloc's *overlap with length of the int return value */ @@ -99,19 +99,22 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int float BLI_bvhtree_getepsilon(BVHTree *tree); -/* find nearest node to the given coordinates (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ -int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata); +/* find nearest node to the given coordinates + * (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ +int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, + BVHTree_NearestPointCallback callback, void *userdata); -int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); +int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, + BVHTree_RayCastCallback callback, void *userdata); -float BLI_bvhtree_bb_raycast(const float *bv, const float light_start[3], const float light_end[3], float pos[3]); +float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]); /* range query */ -int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata); +int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, + BVHTree_RangeQuery callback, void *userdata); #ifdef __cplusplus } #endif -#endif // __BLI_KDOPBVH_H__ - +#endif /* __BLI_KDOPBVH_H__ */ diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h index e90566408d4..f9b52f34102 100644 --- a/source/blender/blenlib/BLI_kdtree.h +++ b/source/blender/blenlib/BLI_kdtree.h @@ -56,7 +56,7 @@ void BLI_kdtree_balance(KDTree *tree); /* Find nearest returns index, and -1 if no node is found. * Find n nearest returns number of points found, with results in nearest. * Normal is optional, but if given will limit results to points in normal direction from co. */ -int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest); +int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3], KDTreeNearest *nearest); int BLI_kdtree_find_n_nearest(KDTree *tree, int n, const float co[3], const float nor[3], KDTreeNearest *nearest); /* Range search returns number of points found, with results in nearest */ diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index de1d423bfad..83b07bae53f 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -67,6 +67,7 @@ MINLINE void copy_v2_v2_short(short r[2], const short a[2]); MINLINE void copy_v3_v3_short(short r[3], const short a[3]); MINLINE void copy_v4_v4_short(short r[4], const short a[4]); /* int */ +MINLINE void zero_v3_int(int r[3]); MINLINE void copy_v2_v2_int(int r[2], const int a[2]); MINLINE void copy_v3_v3_int(int r[3], const int a[3]); MINLINE void copy_v4_v4_int(int r[4], const int a[4]); @@ -139,12 +140,16 @@ MINLINE void star_m3_v3(float rmat[3][3], float a[3]); MINLINE float len_squared_v2(const float v[2]); MINLINE float len_squared_v3(const float v[3]); +MINLINE float len_manhattan_v2(const float v[2]); +MINLINE float len_manhattan_v3(const float v[3]); MINLINE float len_v2(const float a[2]); MINLINE float len_v2v2(const float a[2], const float b[2]); MINLINE float len_squared_v2v2(const float a[2], const float b[2]); +MINLINE float len_squared_v3v3(const float a[3], const float b[3]); +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]); +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]); MINLINE float len_v3(const float a[3]); MINLINE float len_v3v3(const float a[3], const float b[3]); -MINLINE float len_squared_v3v3(const float a[3], const float b[3]); MINLINE float normalize_v2(float r[2]); MINLINE float normalize_v2_v2(float r[2], const float a[2]); diff --git a/source/blender/blenlib/BLI_quadric.h b/source/blender/blenlib/BLI_quadric.h new file mode 100644 index 00000000000..aec11ec2b44 --- /dev/null +++ b/source/blender/blenlib/BLI_quadric.h @@ -0,0 +1,56 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Laurence Bourn, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_QUADRIC_H__ +#define __BLI_QUADRIC_H__ + +/** \file BLI_quadric.h + * \ingroup bli + */ + +typedef struct Quadric { + float a2, ab, ac, ad, + b2, bc, bd, + c2, cd, + d2; +} Quadric; + +/* conversion */ +void BLI_quadric_from_v3_dist(Quadric *q, const float v[3], const float offset); +void BLI_quadric_to_tensor_m3(const Quadric *q, float m[3][3]); +void BLI_quadric_to_vector_v3(const Quadric *q, float v[3]); + +void BLI_quadric_clear(Quadric *q); + +/* math */ +void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b); +void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b); +void BLI_quadric_mul(Quadric *a, const float scalar); + +/* solve */ +float BLI_quadric_evaluate(const Quadric *q, const float v[3]); +int BLI_quadric_optimize(const Quadric *q, float v[3]); + +#endif /* __BLI_QUADRIC_H__ */ diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index de4c2cf3a86..f84820e94f3 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -66,9 +66,7 @@ int BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]); int BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y); int BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]); int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]); -#if 0 /* NOT NEEDED YET */ -int BLI_rctf_isect_segment(struct rcti *rect, int s1[2], int s2[2]); -#endif +int BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]); void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2); void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2); void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 666c74ca36f..943597b6688 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -74,7 +74,7 @@ __attribute__((nonnull)) * \param str2 second string for append * \retval Returns dst */ -char *BLI_strdupcat(const char *str1, const char *str2) +char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -91,7 +91,7 @@ __attribute__((nonnull)) * the size of dst) * \retval Returns dst */ -char *BLI_strncpy(char *dst, const char *src, const size_t maxncpy) +char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) #ifdef __GNUC__ __attribute__((nonnull)) #endif @@ -107,7 +107,7 @@ __attribute__((nonnull)) * Assume that the strings returned must be freed afterwards, and that the inputs will contain * data we want... */ -char *BLI_str_quoted_substrN(const char *str, const char *prefix) +char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -124,7 +124,7 @@ __attribute__((nonnull)) * \param newText The text in the string to find and replace * \retval Returns the duplicated string */ -char *BLI_replacestr(char *str, const char *oldText, const char *newText) +char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -134,7 +134,7 @@ __attribute__((nonnull)) /* * Replacement for snprintf */ -size_t BLI_snprintf(char *buffer, size_t len, const char *format, ...) +size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) __attribute__((nonnull)) @@ -144,7 +144,7 @@ __attribute__((nonnull)) /* * Replacement for vsnprintf */ -size_t BLI_vsnprintf(char *buffer, size_t count, const char *format, va_list arg) +size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 0))) #endif @@ -154,7 +154,7 @@ __attribute__ ((format(printf, 3, 0))) * Print formatted string into a newly mallocN'd string * and return it. */ -char *BLI_sprintfN(const char *format, ...) +char *BLI_sprintfN(const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 1, 2))) __attribute__((warn_unused_result)) @@ -162,7 +162,7 @@ __attribute__((nonnull)) #endif ; -size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) +size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxlen) #ifdef __GNUC__ __attribute__((nonnull)) #endif @@ -216,12 +216,12 @@ __attribute__((nonnull)) #endif ; /* time var is global */ -void BLI_ascii_strtolower(char *str, int len) +void BLI_ascii_strtolower(char *str, const size_t len) #ifdef __GNUC__ __attribute__((nonnull)) #endif ; -void BLI_ascii_strtoupper(char *str, int len) +void BLI_ascii_strtoupper(char *str, const size_t len) #ifdef __GNUC__ __attribute__((nonnull)) #endif diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index 56ed4beba53..47980d104fe 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -31,16 +31,16 @@ extern "C" { #endif -char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy); -char *BLI_strncat_utf8(char *dst, const char *src, size_t maxncpy); +char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); +char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); int BLI_utf8_invalid_byte(const char *str, int length); int BLI_utf8_invalid_strip(char *str, int length); int BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */ /* copied from glib */ unsigned int BLI_str_utf8_as_unicode(const char *p); -unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index); -unsigned int BLI_str_utf8_as_unicode_step(const char *p, size_t *index); +unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index); +unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index); size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf); char *BLI_str_find_prev_char_utf8(const char *str, const char *p); @@ -50,8 +50,8 @@ char *BLI_str_prev_char_utf8(const char *p); /* wchar_t functions, copied from blenders own font.c originally */ size_t BLI_wstrlen_utf8(const wchar_t *src); size_t BLI_strlen_utf8(const char *strc); -size_t BLI_strncpy_wchar_as_utf8(char *dst, const wchar_t *src, const size_t maxcpy); -size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst, const char *src, const size_t maxcpy); +size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy); +size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy); #define BLI_UTF8_MAX 6 #define BLI_UTF8_ERR ((unsigned int)-1) diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 29097a4c6c3..47c2256c1e1 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -128,6 +128,10 @@ #endif #endif +/* can be used in simple macros */ +#define CHECK_TYPE_INLINE(val, type) \ + ((void)(((type *)0) != (val))) + #ifndef SWAP # define SWAP(type, a, b) { \ type sw_ap; \ @@ -189,6 +193,11 @@ *(v1 + 1) = *(v2 + 1) + *(v3 + 1) * (fac); \ *(v1 + 2) = *(v2 + 2) + *(v3 + 2) * (fac); \ } (void)0 +#define VECMADD(v1, v2, v3, v4) { \ + *(v1) = *(v2) + *(v3) * (*(v4)); \ + *(v1 + 1) = *(v2 + 1) + *(v3 + 1) * (*(v4 + 1)); \ + *(v1 + 2) = *(v2 + 2) + *(v3 + 2) * (*(v4 + 2)); \ +} (void)0 #define VECSUBFAC(v1, v2, v3, fac) { \ *(v1) = *(v2) - *(v3) * (fac); \ *(v1 + 1) = *(v2 + 1) - *(v3 + 1) * (fac); \ @@ -326,4 +335,4 @@ # define UNLIKELY(x) (x) #endif -#endif // __BLI_UTILDEFINES_H__ +#endif /* __BLI_UTILDEFINES_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index eef0a72d3b2..3aa0ffc3eaa 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -79,6 +79,7 @@ set(SRC intern/noise.c intern/path_util.c intern/pbvh.c + intern/quadric.c intern/rand.c intern/rct.c intern/scanfill.c @@ -91,8 +92,8 @@ set(SRC intern/threads.c intern/time.c intern/uvproject.c - intern/voxel.c intern/voronoi.c + intern/voxel.c intern/winstuff.c BLI_args.h @@ -136,6 +137,7 @@ set(SRC BLI_noise.h BLI_path_util.h BLI_pbvh.h + BLI_quadric.h BLI_rand.h BLI_rect.h BLI_scanfill.h diff --git a/source/blender/blenlib/PIL_time.h b/source/blender/blenlib/PIL_time.h index 288d2fe78e5..b8f895c5c82 100644 --- a/source/blender/blenlib/PIL_time.h +++ b/source/blender/blenlib/PIL_time.h @@ -30,7 +30,6 @@ * \brief Platform independent time functions. */ - #ifndef __PIL_TIME_H__ #define __PIL_TIME_H__ @@ -61,20 +60,24 @@ void PIL_sleep_ms(int ms); double _timeit_##var = PIL_check_seconds_timer(); \ printf("time start (" #var "): " AT "\n"); \ fflush(stdout); \ - { (void)0 \ - + { (void)0 #define TIMEIT_VALUE(var) (float)(PIL_check_seconds_timer() - _timeit_##var) +#define TIMEIT_VALUE_PRINT(var) \ + { \ + printf("time update(" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var));\ + fflush(stdout); \ + } (void)0 #define TIMEIT_END(var) \ } \ - printf("time end (" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var)); \ + printf("time end (" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var)); \ fflush(stdout); \ -} (void)0 \ +} (void)0 #ifdef __cplusplus } #endif -#endif /* !__PIL_TIME_H__ */ +#endif /* !__PIL_TIME_H__ */ diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index ee7d93ea1a9..5e0762a5d68 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -67,16 +67,22 @@ struct Heap { /***/ -Heap *BLI_heap_new(void) +/* use when the size of the heap is known in advance */ +Heap *BLI_heap_new_ex(unsigned int tot_reserve) { Heap *heap = (Heap *)MEM_callocN(sizeof(Heap), __func__); - heap->bufsize = 1; - heap->tree = (HeapNode **)MEM_mallocN(sizeof(HeapNode *), "BLIHeapTree"); + heap->bufsize = tot_reserve; + heap->tree = (HeapNode **)MEM_mallocN(tot_reserve * sizeof(HeapNode *), "BLIHeapTree"); heap->arena = BLI_memarena_new(1 << 16, "heap arena"); return heap; } +Heap *BLI_heap_new(void) +{ + return BLI_heap_new_ex(1); +} + void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) { int i; diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index a86783f3450..46b0cfeaaac 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -921,7 +921,7 @@ void BLI_bvhtree_balance(BVHTree *tree) /* bvhtree_info(tree); */ } -int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) +int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) { int i; BVHNode *node = NULL; @@ -952,7 +952,7 @@ int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) /* call before BLI_bvhtree_update_tree() */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints) +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints) { int i; BVHNode *node = NULL; @@ -1346,7 +1346,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *n /* Determines the distance that the ray must travel to hit the bounding volume of the given node */ -static float ray_nearest_hit(BVHRayCastData *data, const float *bv) +static float ray_nearest_hit(BVHRayCastData *data, const float bv[6]) { int i; @@ -1524,7 +1524,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f return data.hit.index; } -float BLI_bvhtree_bb_raycast(const float *bv, const float light_start[3], const float light_end[3], float pos[3]) +float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]) { BVHRayCastData data; float dist = 0.0; diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 19985c56b84..900580317f2 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -132,7 +132,7 @@ void BLI_kdtree_balance(KDTree *tree) tree->root = kdtree_balance(tree->nodes, tree->totnode, 0); } -static float squared_distance(const float v2[3], const float v1[3], const float *UNUSED(n1), const float *n2) +static float squared_distance(const float v2[3], const float v1[3], const float UNUSED(n1[3]), const float n2[3]) { float d[3], dist; @@ -152,7 +152,7 @@ static float squared_distance(const float v2[3], const float v1[3], const float return dist; } -int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest) +int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3], KDTreeNearest *nearest) { KDTreeNode *root, *node, *min_node; KDTreeNode **stack, *defaultstack[100]; diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index d58ccbbd48e..4fb48d19239 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -108,7 +108,7 @@ void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *v eh->buckets[hash] = e; if (++eh->nentries > eh->nbuckets * 3) { - EdgeEntry *e, **old = eh->buckets; + EdgeEntry **old = eh->buckets; int i, nold = eh->nbuckets; eh->nbuckets = _ehash_hashsizes[++eh->cursize]; diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 1df904f617a..883cdfde426 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -140,6 +140,8 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) } else break; } + + gzclose(gzfile); if (size == 0) { MEM_freeN(mem); diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 85239270541..daedd39d693 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -33,8 +33,8 @@ */ -#ifdef WIN32 -#pragma warning (disable:4244) +#ifdef _MSC_VER +# pragma warning (disable:4244) #endif #include <ft2build.h> diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 97fc431d8fa..21ecfccf9d9 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -59,34 +59,34 @@ MINLINE float saacos(float fac) { if (fac <= -1.0f) return (float)M_PI; else if (fac >= 1.0f) return 0.0; - else return (float)acos(fac); + else return acosf(fac); } MINLINE float saasin(float fac) { if (fac <= -1.0f) return (float)-M_PI / 2.0f; else if (fac >= 1.0f) return (float)M_PI / 2.0f; - else return (float)asin(fac); + else return asinf(fac); } MINLINE float sasqrt(float fac) { if (fac <= 0.0f) return 0.0f; - return (float)sqrt(fac); + return sqrtf(fac); } MINLINE float saacosf(float fac) { if (fac <= -1.0f) return (float)M_PI; else if (fac >= 1.0f) return 0.0f; - else return (float)acosf(fac); + else return acosf(fac); } MINLINE float saasinf(float fac) { if (fac <= -1.0f) return (float)-M_PI / 2.0f; else if (fac >= 1.0f) return (float)M_PI / 2.0f; - else return (float)asinf(fac); + else return asinf(fac); } MINLINE float sasqrtf(float fac) diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 2cfe999e032..191b0e16025 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -121,6 +121,13 @@ MINLINE void copy_v4_v4_char(char r[4], const char a[4]) } /* short */ +MINLINE void zero_v3_int(int r[3]) +{ + r[0] = 0; + r[1] = 0; + r[2] = 0; +} + MINLINE void copy_v2_v2_short(short r[2], const short a[2]) { r[0] = a[0]; @@ -561,6 +568,16 @@ MINLINE float len_squared_v3(const float v[3]) return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; } +MINLINE float len_manhattan_v2(const float v[2]) +{ + return fabsf(v[0]) + fabsf(v[1]); +} + +MINLINE float len_manhattan_v3(const float v[3]) +{ + return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]); +} + MINLINE float len_v2(const float v[2]) { return sqrtf(v[0] * v[0] + v[1] * v[1]); @@ -588,20 +605,36 @@ MINLINE float len_squared_v2v2(const float a[2], const float b[2]) return dot_v2v2(d, d); } -MINLINE float len_v3v3(const float a[3], const float b[3]) +MINLINE float len_squared_v3v3(const float a[3], const float b[3]) { float d[3]; sub_v3_v3v3(d, b, a); - return len_v3(d); + return dot_v3v3(d, d); } -MINLINE float len_squared_v3v3(const float a[3], const float b[3]) +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) +{ + float d[2]; + + sub_v2_v2v2(d, b, a); + return len_manhattan_v2(d); +} + +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]) { float d[3]; sub_v3_v3v3(d, b, a); - return dot_v3v3(d, d); + return len_manhattan_v3(d); +} + +MINLINE float len_v3v3(const float a[3], const float b[3]) +{ + float d[3]; + + sub_v3_v3v3(d, b, a); + return len_v3(d); } MINLINE float normalize_v2_v2(float r[2], const float a[2]) diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 792bf929182..124624ca137 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -31,9 +31,9 @@ */ -#ifdef _WIN32 -#pragma warning (disable : 4244) // "conversion from double to float" -#pragma warning (disable : 4305) // "truncation from const double to float" +#ifdef _MSC_VER +# pragma warning (disable:4244) /* "conversion from double to float" */ +# pragma warning (disable:4305) /* "truncation from const double to float" */ #endif #include <math.h> diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c new file mode 100644 index 00000000000..1c04beacbfb --- /dev/null +++ b/source/blender/blenlib/intern/quadric.c @@ -0,0 +1,131 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Laurence Bourn, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/quadric.c + * \ingroup bli + * + * \note This isn't fully complete, + * possible there are other useful functions to add here. + * + * \note try to follow BLI_math naming convention here. + */ + +//#include <string.h> + +#include "BLI_math.h" +#include "BLI_quadric.h" /* own include */ + + +#define QUADRIC_FLT_TOT (sizeof(Quadric) / sizeof(float)) + +void BLI_quadric_from_v3_dist(Quadric *q, const float v[3], const float offset) +{ + q->a2 = v[0] * v[0]; + q->b2 = v[1] * v[1]; + q->c2 = v[2] * v[2]; + + q->ab = v[0] * v[1]; + q->ac = v[0] * v[2]; + q->bc = v[1] * v[2]; + + q->ad = v[0] * offset; + q->bd = v[1] * offset; + q->cd = v[2] * offset; + + q->d2 = offset * offset; +} + +void BLI_quadric_to_tensor_m3(const Quadric *q, float m[3][3]) +{ + m[0][0] = q->a2; + m[0][1] = q->ab; + m[0][2] = q->ac; + + m[1][0] = q->ab; + m[1][1] = q->b2; + m[1][2] = q->bc; + + m[2][0] = q->ac; + m[2][1] = q->bc; + m[2][2] = q->c2; +} + +void BLI_quadric_to_vector_v3(const Quadric *q, float v[3]) +{ + v[0] = q->ad; + v[1] = q->bd; + v[2] = q->cd; +} + +void BLI_quadric_clear(Quadric *q) +{ + memset(q, 0, sizeof(*q)); +} + +void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b) +{ + add_vn_vn((float *)a, (float *)b, QUADRIC_FLT_TOT); +} + +void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b) +{ + add_vn_vnvn((float *)r, (const float *)a, (const float *)b, QUADRIC_FLT_TOT); +} + +void BLI_quadric_mul(Quadric *a, const float scalar) +{ + mul_vn_fl((float *)a, QUADRIC_FLT_TOT, scalar); +} + +float BLI_quadric_evaluate(const Quadric *q, const float v[3]) +{ + return (v[0] * v[0] * q->a2 + 2.0f * v[0] * v[1] * q->ab + 2.0f * v[0] * v[2] * q->ac + 2.0f * v[0] * q->ad + + v[1] * v[1] * q->b2 + 2.0f * v[1] * v[2] * q->bc + 2.0f * v[1] * q->bd + + v[2] * v[2] * q->c2 + 2.0f * v[2] * q->cd + + q->d2); +} + +int BLI_quadric_optimize(const Quadric *q, float v[3]) +{ + float m[3][3]; + float det; + + BLI_quadric_to_tensor_m3(q, m); + det = determinant_m3(m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); + + if (det != 0.0f) { + invert_m3(m); + BLI_quadric_to_vector_v3(q, v); + mul_m3_v3(m, v); + negate_v3(v); + + return TRUE; + } + else { + return FALSE; + } +} diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 4435e9ce09c..3c22d73d113 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -40,7 +40,7 @@ #include "BLI_threads.h" #include "BLI_rand.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER typedef unsigned __int64 r_uint64; #define MULTIPLIER 0x5DEECE66Di64 diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index cab383b60f3..2e2619df24e 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -102,7 +102,19 @@ int BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2]) } /* based closely on 'isect_line_line_v2_int', but in modified so corner cases are treated as intersections */ -static int isect_segments(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) +static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) +{ + const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); + if (div == 0.0f) { + return 1; /* co-linear */ + } + else { + const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; + return (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f); + } +} +static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); if (div == 0.0f) { @@ -134,14 +146,49 @@ int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2]) /* diagonal: [/] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; - if (isect_segments(s1, s2, tvec1, tvec2)) { + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return 1; + } + + /* diagonal: [\] */ + tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; + tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return 1; + } + + /* no intersection */ + return 0; + } +} + +int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2]) +{ + /* first do outside-bounds check for both points of the segment */ + if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0; + if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0; + if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0; + if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0; + + /* if either points intersect then we definetly intersect */ + if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) { + return 1; + } + else { + /* both points are outside but may insersect the rect */ + float tvec1[2]; + float tvec2[2]; + /* diagonal: [/] */ + tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; + tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return 1; } /* diagonal: [\] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; - if (isect_segments(s1, s2, tvec1, tvec2)) { + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return 1; } diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 8501db7c8b8..4b64a650b52 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -296,11 +296,12 @@ char *BLI_strcasestr(const char *s, const char *find) int BLI_strcasecmp(const char *s1, const char *s2) { - int i; + register int i; + register char c1, c2; for (i = 0;; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); + c1 = tolower(s1[i]); + c2 = tolower(s2[i]); if (c1 < c2) { return -1; @@ -318,11 +319,12 @@ int BLI_strcasecmp(const char *s1, const char *s2) int BLI_strncasecmp(const char *s1, const char *s2, size_t len) { - int i; + register size_t i; + register char c1, c2; for (i = 0; i < len; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); + c1 = tolower(s1[i]); + c2 = tolower(s2[i]); if (c1 < c2) { return -1; @@ -341,15 +343,16 @@ int BLI_strncasecmp(const char *s1, const char *s2, size_t len) /* natural string compare, keeping numbers in order */ int BLI_natstrcmp(const char *s1, const char *s2) { - int d1 = 0, d2 = 0; + register int d1 = 0, d2 = 0; + register char c1, c2; /* if both chars are numeric, to a strtol(). * then increase string deltas as long they are * numeric, else do a tolower and char compare */ while (1) { - char c1 = tolower(s1[d1]); - char c2 = tolower(s2[d2]); + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); if (isdigit(c1) && isdigit(c2) ) { int val1, val2; @@ -419,18 +422,18 @@ size_t BLI_strnlen(const char *str, size_t maxlen) return end ? (size_t) (end - str) : maxlen; } -void BLI_ascii_strtolower(char *str, int len) +void BLI_ascii_strtolower(char *str, const size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 'a' - 'A'; } -void BLI_ascii_strtoupper(char *str, int len) +void BLI_ascii_strtoupper(char *str, const size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) if (str[i] >= 'a' && str[i] <= 'z') diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 74df5211dad..3c5812fa513 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -25,6 +25,7 @@ set(INC . + ../blenfont ../blenkernel ../blenlib ../makesdna @@ -62,4 +63,8 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 20b560744b3..49e8869637e 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' +incs = '. #/intern/guardedalloc ../blenfont ../blenlib ../blenkernel' incs += ' ../makesdna ../editors/include' incs += ' ../render/extern/include ../makesrna ../nodes ../bmesh ../imbuf' @@ -11,6 +11,9 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [167,30]) #, cc_compileflags=['/WX'] ) else: diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b6c793bcdba..97ca210c3d0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -106,6 +106,8 @@ #include "BLI_math.h" #include "BLI_edgehash.h" +#include "BLF_translation.h" + #include "BKE_anim.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -977,13 +979,13 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports) if (fd->flags & FD_FLAGS_FILE_OK) { if (!read_file_dna(fd)) { - BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", incomplete", fd->relabase); + BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', incomplete", fd->relabase); blo_freefiledata(fd); fd = NULL; } } else { - BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", not a blend file", fd->relabase); + BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase); blo_freefiledata(fd); fd = NULL; } @@ -1000,7 +1002,8 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) gzfile = BLI_gzopen(filepath, "rb"); if (gzfile == (gzFile)Z_NULL) { - BKE_reportf(reports, RPT_WARNING, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file"); + BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s", + filepath, errno ? strerror(errno) : TIP_("Unknown error reading file")); return NULL; } else { @@ -1018,7 +1021,7 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports) { if (!mem || memsize<SIZEOFBLENDERHEADER) { - BKE_report(reports, RPT_WARNING, (mem)? "Unable to read": "Unable to open"); + BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read"): TIP_("Unable to open")); return NULL; } else { @@ -3336,6 +3339,8 @@ static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd) { if (pd && pd->tex) pd->tex = newlibadr_us(fd, id->lib, pd->tex); + if (pd && pd->f_source) + pd->f_source = newlibadr_us(fd, id->lib, pd->f_source); } static void lib_link_particlesettings(FileData *fd, Main *main) @@ -3568,10 +3573,10 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->clmd->clothObject = NULL; psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms); - psys->clmd->sim_parms->effector_weights = NULL; psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms); if (psys->clmd->sim_parms) { + psys->clmd->sim_parms->effector_weights = NULL; if (psys->clmd->sim_parms->presets > 10) psys->clmd->sim_parms->presets = 0; } @@ -3625,16 +3630,17 @@ static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata if (layer->type == CD_MTEXPOLY) { MTexPoly *tf= layer->data; - int i; + int j; - for (i = 0; i < totface; i++, tf++) { + for (j = 0; j < totface; j++, tf++) { tf->tpage = newlibadr(fd, me->id.lib, tf->tpage); - if (tf->tpage && tf->tpage->id.us==0) + if (tf->tpage && tf->tpage->id.us == 0) { tf->tpage->id.us = 1; } } } } +} static void lib_link_mesh(FileData *fd, Main *main) { @@ -4318,10 +4324,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) if (smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) { if (smd->domain->point_cache[1]) { PointCache *cache = newdataadr(fd, smd->domain->point_cache[1]); - if (cache->flag & PTCACHE_FAKE_SMOKE) - ; /* Smoke was already saved in "new format" and this cache is a fake one. */ - else + if (cache->flag & PTCACHE_FAKE_SMOKE) { + /* Smoke was already saved in "new format" and this cache is a fake one. */ + } + else { printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n"); + } BKE_ptcache_free(cache); } smd->domain->ptcaches[1].first = NULL; @@ -4334,6 +4342,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->coll = NULL; smd->flow = newdataadr(fd, smd->flow); smd->flow->smd = smd; + smd->flow->dm = NULL; + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; smd->flow->psys = newdataadr(fd, smd->flow->psys); } else if (smd->type == MOD_SMOKE_TYPE_COLL) { @@ -4342,11 +4353,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->coll = newdataadr(fd, smd->coll); if (smd->coll) { smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->numpoints = 0; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; + smd->coll->dm = NULL; } else { smd->type = 0; + smd->flow = NULL; + smd->domain = NULL; + smd->coll = NULL; } } } @@ -4755,8 +4770,7 @@ static void lib_link_scene(FileData *fd, Main *main) base->object = newlibadr_us(fd, sce->id.lib, base->object); if (base->object == NULL) { - BKE_reportf_wrap(fd->reports, RPT_WARNING, - "LIB ERROR: Object lost from scene:'%s\'", + BKE_reportf_wrap(fd->reports, RPT_WARNING, "LIB ERROR: object lost from scene: '%s'", sce->id.name + 2); BLI_remlink(&sce->base, base); if (base == sce->basact) sce->basact = NULL; @@ -6791,7 +6805,7 @@ void convert_tface_mt(FileData *fd, Main *main) G.main = main; if (!(do_version_tface(main, 1))) { - BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem. Error in console"); + BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)"); } //XXX hack, material.c uses G.main allover the place, instead of main @@ -6964,7 +6978,6 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNodeTree *ntree) { bNode *node; - bNodeSocket *sock; for (node = ntree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_OUTPUT_FILE) { @@ -7041,6 +7054,7 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo } else if (node->type==CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED) { NodeImageMultiFile *nimf = node->storage; + bNodeSocket *sock; /* CMP_NODE_OUTPUT_MULTI_FILE has been redeclared as CMP_NODE_OUTPUT_FILE */ node->type = CMP_NODE_OUTPUT_FILE; @@ -7236,6 +7250,21 @@ static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UN node->flag |= NODE_OPTIONS; } +static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + + for (node = ntree->nodes.first; node; node = node->next) { + if (!ELEM(node->type, NODE_GROUP, CMP_NODE_IMAGE)) { + for (sock = node->inputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_DYNAMIC; + for (sock = node->outputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_DYNAMIC; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -7349,9 +7378,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) v3d->bundle_drawtype = OB_PLAINAXES; } else if (sl->spacetype == SPACE_CLIP) { - SpaceClip *sc = (SpaceClip *)sl; - if (sc->scopes.track_preview_height == 0) - sc->scopes.track_preview_height = 120; + SpaceClip *sclip = (SpaceClip *)sl; + if (sclip->scopes.track_preview_height == 0) + sclip->scopes.track_preview_height = 120; } } } @@ -7559,8 +7588,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) prop = BKE_bproperty_object_get(ob, "Text"); if (prop) { BKE_reportf_wrap(fd->reports, RPT_WARNING, - "Game property name conflict in object: \"%s\".\nText objects reserve the " - "[\"Text\"] game property to change their content through Logic Bricks.", + "Game property name conflict in object '%s':\ntext objects reserve the " + "['Text'] game property to change their content through logic bricks", ob->id.name + 2); } } @@ -7753,13 +7782,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 263) { /* Default for old files is to save particle rotations to pointcache */ ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) + for (part = main->particle.first; part; part = part->id.next) { part->flag |= PART_ROTATIONS; - { - /* Default for old files is to save particle rotations to pointcache */ - ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) - part->flag |= PART_ROTATIONS; } } @@ -8205,6 +8229,111 @@ static void do_versions(FileData *fd, Library *lib, Main *main) do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree); } + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 2)) { + MovieClip *clip; + + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object; + + for (tracking_object = tracking->objects.first; + tracking_object; + tracking_object = tracking_object->next) + { + if (tracking_object->keyframe1 == 0 && tracking_object->keyframe2 == 0) { + tracking_object->keyframe1 = tracking->settings.keyframe1; + tracking_object->keyframe2 = tracking->settings.keyframe2; + } + } + } + } + + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 3)) { + /* smoke branch */ + { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { + /* keep branch saves if possible */ + if (!smd->domain->flame_max_temp) { + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + smd->domain->adapt_threshold = 0.02f; + smd->domain->adapt_margin = 4; + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; + } + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (!smd->flow->texture_size) { + smd->flow->fuel_amount = 1.0; + smd->flow->surface_distance = 1.5; + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->texture_size = 1.0f; + } + } + } + } + } + } + + /* render border for viewport */ + { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (v3d->render_border.xmin == 0.0f && v3d->render_border.ymin == 0.0f && + v3d->render_border.xmax == 0.0f && v3d->render_border.ymax == 0.0f) + { + v3d->render_border.xmax = 1.0f; + v3d->render_border.ymax = 1.0f; + } + } + } + } + } + } + } + + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 4)) { + /* Fix for old node flags: Apparently the SOCK_DYNAMIC flag has been in use for other + * purposes before and then removed and later reused for SOCK_DYNAMIC. This socket should + * only be used by certain node types which don't use template lists, cleaning this up here. + */ + bNodeTreeType *ntreetype; + bNodeTree *ntree; + + ntreetype = ntreeGetType(NTREE_COMPOSIT); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + ntreetype = ntreeGetType(NTREE_SHADER); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + ntreetype = ntreeGetType(NTREE_TEXTURE); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_version_node_cleanup_dynamic_sockets_264(NULL, NULL, ntree); + } + /* default values in Freestyle settings */ { Scene *sce; @@ -9800,7 +9929,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (fd == NULL) { /* printf and reports for now... its important users know this */ BKE_reportf_wrap(basefd->reports, RPT_INFO, - "read library: '%s', '%s'", + "Read library: '%s', '%s'", mainptr->curlib->filepath, mainptr->curlib->name); fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); @@ -9854,7 +9983,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (fd == NULL) { BKE_reportf_wrap(basefd->reports, RPT_WARNING, - "Can't find lib '%s'", + "Cannot find lib '%s'", mainptr->curlib->filepath); } } diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index eaf725dda9e..4136f71f050 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -104,7 +104,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) fd = BLI_open(path, O_BINARY | O_RDONLY, 0); if (fd == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", path, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno)); goto cleanup; } @@ -115,15 +115,15 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) datastart = handle_read_msb_int(fd); if (datastart == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (problem seeking)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (problem seeking)", path); goto cleanup; } else if (read(fd, buf, 8) != 8) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (truncated header)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (truncated header)", path); goto cleanup; } else if (memcmp(buf, "BRUNTIME", 8) != 0) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (not a blend file)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (not a blend file)", path); goto cleanup; } else { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e6d68294cf4..99283cf9473 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -731,8 +731,9 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_curvemapping(wd, node->storage); else if (ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) write_curvemapping(wd, node->storage); - else if (ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) - /* pass */; + else if (ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) { + /* pass */ + } else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } @@ -777,13 +778,16 @@ typedef struct RenderInfo { char scene_name[MAX_ID_NAME - 2]; } RenderInfo; -static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon */ +/* was for historic render-deamon feature, + * now write because it can be easily extracted without + * reading the whole blend file */ +static void write_renderinfo(WriteData *wd, Main *mainvar) { bScreen *curscreen; Scene *sce; RenderInfo data; - /* XXX in future, handle multiple windows with multiple screnes? */ + /* XXX in future, handle multiple windows with multiple screens? */ current_screen_compat(mainvar, &curscreen); for (sce= mainvar->scene.first; sce; sce= sce->id.next) { @@ -3235,7 +3239,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if (file == -1) { - BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Cannot open file %s for writing: %s", tempname, strerror(errno)); return 0; } @@ -3286,7 +3290,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (write_flags & G_FILE_HISTORY) { int err_hist = do_history(filepath, reports); if (err_hist) { - BKE_report(reports, RPT_ERROR, "Version backup failed. File saved with @"); + BKE_report(reports, RPT_ERROR, "Version backup failed (file saved with @)"); return 0; } } @@ -3303,23 +3307,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (0==ret) { /* now rename to real file name, and delete temp @ file too */ if (BLI_rename(gzname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @."); + BKE_report(reports, RPT_ERROR, "Cannot change old file (file saved with @)"); return 0; } BLI_delete(tempname, 0, 0); } else if (-1==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .gz file."); + BKE_report(reports, RPT_ERROR, "Failed opening .gz file"); return 0; } else if (-2==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression."); + BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression"); return 0; } } else if (BLI_rename(tempname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @"); + BKE_report(reports, RPT_ERROR, "Cannot change old file (file saved with @)"); return 0; } diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 4bce7a6ff51..1e56314ab6e 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -52,9 +52,11 @@ set(SRC operators/bmo_mirror.c operators/bmo_primitive.c operators/bmo_removedoubles.c + operators/bmo_symmetrize.c operators/bmo_subdivide.c operators/bmo_subdivide.h operators/bmo_triangulate.c + operators/bmo_unsubdivide.c operators/bmo_utils.c operators/bmo_wireframe.c @@ -62,6 +64,8 @@ set(SRC intern/bmesh_construct.h intern/bmesh_core.c intern/bmesh_core.h + intern/bmesh_decimate.c + intern/bmesh_decimate.h intern/bmesh_inline.h intern/bmesh_interp.c intern/bmesh_interp.h diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 955b1a729c5..a672ec0b6a7 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -252,6 +252,7 @@ extern "C" { #include "intern/bmesh_construct.h" #include "intern/bmesh_core.h" +#include "intern/bmesh_decimate.h" #include "intern/bmesh_interp.h" #include "intern/bmesh_iterators.h" #include "intern/bmesh_marking.h" diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index d50c94d5e6a..4e6decfa913 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -810,7 +810,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f int bmesh_loop_reverse(BMesh *bm, BMFace *f) { #ifdef USE_BMESH_HOLES - return bmesh_loop_reverse_loop(bm, f, f->loops.first); + return bm_loop_reverse_loop(bm, f, f->loops.first); #else return bm_loop_reverse_loop(bm, f); #endif @@ -1143,6 +1143,8 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example)) /** * \brief Split Face Make Edge (SFME) * + * \warning this is a low level function, most likely you want to use #BM_face_split() + * * Takes as input two vertices in a single face. An edge is created which divides the original face * into two distinct regions. One of the regions is assigned to the original face and it is closed off. * The second region has a new face assigned to it. @@ -1186,13 +1188,15 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, { #ifdef USE_BMESH_HOLES BMLoopList *lst, *lst2; +#else + int first_loop_f1; #endif BMFace *f2; BMLoop *l_iter, *l_first; BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL; BMEdge *e; - int i, len, f1len, f2len, first_loop_f1; + int i, len, f1len, f2len; /* verify that v1 and v2 are in face */ len = f->len; @@ -1603,10 +1607,10 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou BMESH_ASSERT(edok != FALSE); } - /* deallocate edg */ + /* deallocate edge */ bm_kill_only_edge(bm, ke); - /* deallocate verte */ + /* deallocate vertex */ bm_kill_only_vert(bm, kv); /* Validate disk cycle lengths of ov, tv are unchanged */ @@ -1615,7 +1619,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou edok = bmesh_disk_validate(valence2, tv->e, tv); BMESH_ASSERT(edok != FALSE); - /* Validate loop cycle of all faces attached to oe */ + /* Validate loop cycle of all faces attached to 'oe' */ for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) { BMESH_ASSERT(l->e == oe); edok = bmesh_verts_in_edge(l->v, l->next->v, oe); @@ -1796,8 +1800,12 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) * Merges two verts into one (\a v into \a vtarget). * * \return Success + * + * \warning This does't work for collapsing edges, + * where \a v and \a vtarget are connected by an edge + * (assert checks for this case). */ -int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) +int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target) { BMEdge *e; @@ -1805,26 +1813,29 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) int i, loops_tot; /* verts already spliced */ - if (v == vtarget) { + if (v == v_target) { return FALSE; } /* we can't modify the vert while iterating so first allocate an array of loops */ loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot); - for (i = 0; i < loops_tot; i++) { - loops[i]->v = vtarget; + if (loops) { + for (i = 0; i < loops_tot; i++) { + loops[i]->v = v_target; + } + MEM_freeN(loops); } - MEM_freeN(loops); /* move all the edges from v's disk to vtarget's disk */ while ((e = v->e)) { bmesh_disk_edge_remove(e, v); - bmesh_edge_swapverts(e, v, vtarget); - bmesh_disk_edge_append(e, vtarget); + bmesh_edge_swapverts(e, v, v_target); + bmesh_disk_edge_append(e, v_target); + BLI_assert(e->v1 != e->v2); } BM_CHECK_ELEMENT(v); - BM_CHECK_ELEMENT(vtarget); + BM_CHECK_ELEMENT(v_target); /* v is unused now, and can be killed */ BM_vert_kill(bm, v); @@ -1990,27 +2001,32 @@ int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, * * \note Edges must already have the same vertices. */ -int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget) +int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target) { BMLoop *l; - if (!BM_vert_in_edge(e, etarget->v1) || !BM_vert_in_edge(e, etarget->v2)) { + if (!BM_vert_in_edge(e, e_target->v1) || !BM_vert_in_edge(e, e_target->v2)) { /* not the same vertices can't splice */ + + /* the caller should really make sure this doesn't happen ever + * so assert on release builds */ + BLI_assert(0); + return FALSE; } while (e->l) { l = e->l; - BLI_assert(BM_vert_in_edge(etarget, l->v)); - BLI_assert(BM_vert_in_edge(etarget, l->next->v)); + BLI_assert(BM_vert_in_edge(e_target, l->v)); + BLI_assert(BM_vert_in_edge(e_target, l->next->v)); bmesh_radial_loop_remove(l, e); - bmesh_radial_append(etarget, l); + bmesh_radial_append(e_target, l); } BLI_assert(bmesh_radial_length(e->l) == 0); BM_CHECK_ELEMENT(e); - BM_CHECK_ELEMENT(etarget); + BM_CHECK_ELEMENT(e_target); /* removes from disks too */ BM_edge_kill(bm, e); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 491287993df..0667ed9ea1c 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -41,8 +41,8 @@ void BM_edge_kill(BMesh *bm, BMEdge *e); void BM_vert_kill(BMesh *bm, BMVert *v); int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep); -int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget); -int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget); +int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target); +int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target); int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len); diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c new file mode 100644 index 00000000000..519bdba02a9 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_decimate.c @@ -0,0 +1,599 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/bmesh/intern/bmesh_decimate.c + * \ingroup bmesh + * + * BMesh decimator. + */ + +#include <stddef.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" + +#include "BLI_math.h" +#include "BLI_quadric.h" +#include "BLI_heap.h" + +#include "bmesh.h" +#include "bmesh_structure.h" +#include "bmesh_decimate.h" + +/* defines for testing */ +#define USE_CUSTOMDATA +#define USE_TRIANGULATE + +/* these checks are for rare cases that we can't avoid since they are valid meshes still */ +#define USE_SAFETY_CHECKS + +#define BOUNDARY_PRESERVE_WEIGHT 100.0f + + +/* BMesh Helper Functions + * ********************** */ + +/** + * \param vquadrics must be calloc'd + */ +static void bm_decim_build_quadrics(BMesh *bm, Quadric *vquadrics) +{ + BMIter iter; + BMFace *f; + BMEdge *e; + + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_first; + BMLoop *l_iter; + + const float *co = BM_FACE_FIRST_LOOP(f)->v->co; + const float *no = f->no; + const float offset = -dot_v3v3(no, co); + Quadric q; + + BLI_quadric_from_v3_dist(&q, no, offset); + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(l_iter->v)], &q); + } while ((l_iter = l_iter->next) != l_first); + } + + /* boundary edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (UNLIKELY(BM_edge_is_boundary(e))) { + float edge_vector[3]; + float edge_cross[3]; + sub_v3_v3v3(edge_vector, e->v2->co, e->v1->co); + f = e->l->f; + cross_v3_v3v3(edge_cross, edge_vector, f->no); + + if (normalize_v3(edge_cross) != 0.0f) { + Quadric q; + BLI_quadric_from_v3_dist(&q, edge_vector, -dot_v3v3(edge_cross, e->v1->co)); + BLI_quadric_mul(&q, BOUNDARY_PRESERVE_WEIGHT); + + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(e->v1)], &q); + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(e->v2)], &q); + } + } + } +} + + +static void bm_decim_calc_target_co(BMEdge *e, float optimize_co[3], + const Quadric *vquadrics) +{ + /* compute an edge contration target for edge ei + * this is computed by summing it's vertices quadrics and + * optimizing the result. */ + Quadric q; + + BLI_quadric_add_qu_ququ(&q, + &vquadrics[BM_elem_index_get(e->v1)], + &vquadrics[BM_elem_index_get(e->v2)]); + + + if (BLI_quadric_optimize(&q, optimize_co)) { + return; /* all is good */ + } + else { + mid_v3_v3v3(optimize_co, e->v1->co, e->v2->co); + } +} + +static void bm_decim_build_edge_cost_single(BMEdge *e, + const Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + const Quadric *q1, *q2; + float optimize_co[3]; + float cost; + + if (eheap_table[BM_elem_index_get(e)]) { + BLI_heap_remove(eheap, eheap_table[BM_elem_index_get(e)]); + } + + /* check we can collapse, some edges we better not touch */ + if (BM_edge_is_boundary(e)) { + if (e->l->f->len == 3) { + /* pass */ + } + else { + /* only collapse tri's */ + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + } + else if (BM_edge_is_manifold(e)) { + if ((e->l->f->len == 3) && (e->l->radial_next->f->len == 3)) { + /* pass */ + } + else { + /* only collapse tri's */ + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + } + else { + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + /* end sanity check */ + + + bm_decim_calc_target_co(e, optimize_co, vquadrics); + + q1 = &vquadrics[BM_elem_index_get(e->v1)]; + q2 = &vquadrics[BM_elem_index_get(e->v2)]; + + cost = (BLI_quadric_evaluate(q1, optimize_co) + BLI_quadric_evaluate(q2, optimize_co)); + + eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e); +} + +static void bm_decim_build_edge_cost(BMesh *bm, + const Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + BMIter iter; + BMEdge *e; + unsigned int i; + + BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { + eheap_table[i] = NULL; /* keep sanity check happy */ + bm_decim_build_edge_cost_single(e, vquadrics, eheap, eheap_table); + } +} + +#ifdef USE_TRIANGULATE +/* Temp Triangulation + * ****************** */ + +/** + * To keep things simple we can only collapse edges on triangulated data + * (limitation with edge collapse and error calculation functions). + * + * But to avoid annoying users by only giving triangle results, we can + * triangulate, keeping a reference between the faces, then join after + * if the edges don't collapse, this will also allow more choices when + * collapsing edges so even has some advantage over decimating quads + * directly. + * + * \return TRUE if any faces were triangulated. + */ + +static int bm_decim_triangulate_begin(BMesh *bm) +{ +#ifdef USE_SAFETY_CHECKS + const int check_double_edges = TRUE; +#else + const int check_double_edges = FALSE; +#endif + + BMIter iter; + BMFace *f; + // int has_quad; // could optimize this a little + int has_cut = FALSE; + + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + + /* first clear loop index values */ + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_iter; + BMLoop *l_first; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BM_elem_index_set(l_iter, -1); + } while ((l_iter = l_iter->next) != l_first); + + // has_quad |= (f->len == 4) + } + + /* adding new faces as we loop over faces + * is normally best avoided, however in this case its not so bad because any face touched twice + * will already be triangulated*/ + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (f->len == 4) { + BMLoop *f_l[4]; + BMLoop *l_iter; + BMLoop *l_a, *l_b; + + l_iter = BM_FACE_FIRST_LOOP(f); + + f_l[0] = l_iter; l_iter = l_iter->next; + f_l[1] = l_iter; l_iter = l_iter->next; + f_l[2] = l_iter; l_iter = l_iter->next; + f_l[3] = l_iter; l_iter = l_iter->next; + + if (len_squared_v3v3(f_l[0]->v->co, f_l[2]->v->co) < len_squared_v3v3(f_l[1]->v->co, f_l[3]->v->co)) { + l_a = f_l[0]; + l_b = f_l[2]; + } + else { + l_a = f_l[1]; + l_b = f_l[3]; + } + + { + BMFace *f_new; + BMLoop *l_new; + + /* warning, NO_DOUBLE option here isn't handled as nice as it could be + * - if there is a quad that has a free standing edge joining it along + * where we want to split the face, there isnt a good way we can handle this. + * currently that edge will get removed when joining the tris back into a quad. */ + f_new = BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, check_double_edges); + + if (f_new) { + /* the value of this doesn't matter, only that the 2 loops match and have unique values */ + const int f_index = BM_elem_index_get(f); + + /* since we just split theres only ever 2 loops */ + BLI_assert(BM_edge_is_manifold(l_new->e)); + + BM_elem_index_set(l_new, f_index); + BM_elem_index_set(l_new->radial_next, f_index); + + has_cut = TRUE; + } + } + } + } + + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + + if (has_cut) { + /* now triangulation is done we need to correct index values */ + BM_mesh_elem_index_ensure(bm, BM_EDGE | BM_FACE); + } + + return has_cut; +} + +static void bm_decim_triangulate_end(BMesh *bm) +{ + /* decimation finished, now re-join */ + BMIter iter; + BMEdge *e; + + /* boundary edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMLoop *l_a, *l_b; + if (BM_edge_loop_pair(e, &l_a, &l_b)) { + const int l_a_index = BM_elem_index_get(l_a); + if (l_a_index != -1) { + const int l_b_index = BM_elem_index_get(l_b); + if (l_a_index == l_b_index) { + /* highly unlikely to fail, but prevents possible double-ups */ + if (l_a->f->len == 3 && l_b->f->len == 3) { + BMFace *f[2] = {l_a->f, l_b->f}; + BM_faces_join(bm, f, 2, TRUE); + } + } + } + } + } +} + +#endif /* USE_TRIANGULATE */ + +/* Edge Collapse Functions + * *********************** */ + +/** + * special, highly limited edge collapse function + * intended for speed over flexibiliy. + * can only collapse edges connected to (1, 2) tris. + * + * Important - dont add vert/edge/face data on collapsing! + * + * \param ke_other let caller know what edges we remove besides \a ke + */ +static int bm_edge_collapse(BMesh *bm, BMEdge *ke, BMVert *kv, int ke_other[2], +#ifdef USE_CUSTOMDATA + const float customdata_fac +#else + const float UNUSED(customdata_fac) +#endif + ) +{ + BMVert *v_other = BM_edge_other_vert(ke, kv); + + BLI_assert(v_other != NULL); + + if (BM_edge_is_manifold(ke)) { + BMLoop *l_a, *l_b; + BMEdge *e_a_other[2], *e_b_other[2]; + int ok; + + ok = BM_edge_loop_pair(ke, &l_a, &l_b); + + BLI_assert(ok == TRUE); + BLI_assert(l_a->f->len == 3); + BLI_assert(l_b->f->len == 3); + + /* keep 'kv' 0th */ + if (BM_vert_in_edge(l_a->prev->e, kv)) { + e_a_other[0] = l_a->prev->e; + e_a_other[1] = l_a->next->e; + } + else { + e_a_other[1] = l_a->prev->e; + e_a_other[0] = l_a->next->e; + } + + if (BM_vert_in_edge(l_b->prev->e, kv)) { + e_b_other[0] = l_b->prev->e; + e_b_other[1] = l_b->next->e; + } + else { + e_b_other[1] = l_b->prev->e; + e_b_other[0] = l_b->next->e; + } + + BLI_assert(BM_edge_share_vert(e_a_other[0], e_b_other[0])); + BLI_assert(BM_edge_share_vert(e_a_other[1], e_b_other[1])); + + /* we could assert this case, but better just bail out */ +#if 0 + BLI_assert(e_a_other[0] != e_b_other[0]); + BLI_assert(e_a_other[0] != e_b_other[1]); + BLI_assert(e_b_other[0] != e_a_other[0]); + BLI_assert(e_b_other[0] != e_a_other[1]); +#endif + /* not totally common but we want to avoid */ + if (ELEM(e_a_other[0], e_b_other[0], e_b_other[1]) || + ELEM(e_a_other[1], e_b_other[0], e_b_other[1])) + { + return FALSE; + } + + ke_other[0] = BM_elem_index_get(e_a_other[0]); + ke_other[1] = BM_elem_index_get(e_b_other[0]); + +#ifdef USE_CUSTOMDATA + /* TODO, loops */ + // const float w[2] = {customdata_fac, 1.0f - customdata_fac}; + + /* before killing, do customdata */ + BM_data_interp_from_verts(bm, v_other, kv, v_other, customdata_fac); +#endif + + BM_edge_kill(bm, ke); + + BM_vert_splice(bm, kv, v_other); + + BM_edge_splice(bm, e_a_other[0], e_a_other[1]); + BM_edge_splice(bm, e_b_other[0], e_b_other[1]); + + // BM_mesh_validate(bm); + + return TRUE; + } + else if (BM_edge_is_boundary(ke)) { + /* same as above but only one triangle */ + BMLoop *l_a; + BMEdge *e_a_other[2]; + + l_a = ke->l; + + BLI_assert(l_a->f->len == 3); + + /* keep 'kv' 0th */ + if (BM_vert_in_edge(l_a->prev->e, kv)) { + e_a_other[0] = l_a->prev->e; + e_a_other[1] = l_a->next->e; + } + else { + e_a_other[1] = l_a->prev->e; + e_a_other[0] = l_a->next->e; + } + + ke_other[0] = BM_elem_index_get(e_a_other[0]); + ke_other[1] = -1; + +#ifdef USE_CUSTOMDATA + /* TODO, loops */ + // const float w[2] = {customdata_fac, 1.0f - customdata_fac}; + + /* before killing, do customdata */ + BM_data_interp_from_verts(bm, v_other, kv, v_other, customdata_fac); +#endif + + BM_edge_kill(bm, ke); + + BM_vert_splice(bm, kv, v_other); + + BM_edge_splice(bm, e_a_other[0], e_a_other[1]); + + // BM_mesh_validate(bm); + + return TRUE; + } + else { + return FALSE; + } +} + + +/* collapse e the edge, removing e->v2 */ +static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, + Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + int ke_other[2]; + BMVert *v = e->v1; + int kv_index = BM_elem_index_get(e->v2); /* the vert is removed so only store the index */ + float optimize_co[3]; + float customdata_fac; + + bm_decim_calc_target_co(e, optimize_co, vquadrics); + + /* use for customdata merging */ + customdata_fac = line_point_factor_v3(optimize_co, e->v1->co, e->v2->co); + + if (bm_edge_collapse(bm, e, e->v2, ke_other, customdata_fac)) { + /* update collapse info */ + int i; + + e = NULL; /* paranoid safety check */ + + copy_v3_v3(v->co, optimize_co); + + /* remove eheap */ + for (i = 0; i < 2; i++) { + /* highly unlikely 'eheap_table[ke_other[i]]' would be NULL, but do for sanity sake */ + if ((ke_other[i] != -1) && (eheap_table[ke_other[i]] != NULL)) { + BLI_heap_remove(eheap, eheap_table[ke_other[i]]); + eheap_table[ke_other[i]] = NULL; + } + } + + /* update vertex quadric, add kept vertex from killed vertex */ + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(v)], &vquadrics[kv_index]); + + /* update connected normals */ + BM_vert_normal_update_all(v); + + /* update error costs and the eheap */ + if (LIKELY(v->e)) { + BMEdge *e_iter; + BMEdge *e_first; + e_iter = e_first = v->e; + do { + //BLI_assert(BM_edge_find_double(e_iter) == NULL); +#ifdef USE_SAFETY_CHECKS + /* note! - this check is slow, but we can't avoid it - Campbell */ + BMEdge *e_double; + + e_double = BM_edge_find_double(e_iter); + + if (UNLIKELY(e_double != NULL)) { + int e_index = BM_elem_index_get(e_double); + if (BM_edge_splice(bm, e_double, e_iter)) { + if (eheap_table[e_index]) { + BLI_heap_remove(eheap, eheap_table[e_index]); + eheap_table[e_index] = NULL; + } + } + } + + /* if this happens, the e_double check could be put in a while loop, + * so as to keep removing doubles while they are found. so far this isnt needed */ + BLI_assert(BM_edge_find_double(e_iter) == NULL); +#endif + + bm_decim_build_edge_cost_single(e_iter, vquadrics, eheap, eheap_table); + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + + } + } +} + + +/* Main Decimate Function + * ********************** */ + +void BM_mesh_decimate(BMesh *bm, const float factor) +{ + Heap *eheap; /* edge heap */ + HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ + Quadric *vquadrics; /* vert index aligned quadrics */ + int tot_edge_orig; + int face_tot_target; + int use_triangulate; + + +#ifdef USE_TRIANGULATE + /* temp convert quads to triangles */ + use_triangulate = bm_decim_triangulate_begin(bm); +#endif + + + /* alloc vars */ + vquadrics = MEM_callocN(sizeof(Quadric) * bm->totvert, __func__); + eheap = BLI_heap_new_ex(bm->totedge); + eheap_table = MEM_callocN(sizeof(HeapNode *) * bm->totedge, __func__); + tot_edge_orig = bm->totedge; + + + /* build initial edge collapse cost data */ + bm_decim_build_quadrics(bm, vquadrics); + + bm_decim_build_edge_cost(bm, vquadrics, eheap, eheap_table); + + face_tot_target = bm->totface * factor; + bm->elem_index_dirty |= BM_FACE | BM_EDGE | BM_VERT; + + + /* iterative edge collapse and maintain the eheap */ + while ((bm->totface > face_tot_target) && (BLI_heap_empty(eheap) == FALSE)) { + BMEdge *e = BLI_heap_popmin(eheap); + BLI_assert(BM_elem_index_get(e) < tot_edge_orig); /* handy to detect corruptions elsewhere */ + + /* under normal conditions wont be accessed again, + * but NULL just incase so we don't use freed node */ + eheap_table[BM_elem_index_get(e)] = NULL; + + bm_decim_edge_collapse(bm, e, vquadrics, eheap, eheap_table); + } + + +#ifdef USE_TRIANGULATE + /* its possible we only had triangles, skip this step in that case */ + if (LIKELY(use_triangulate)) { + /* temp convert quads to triangles */ + bm_decim_triangulate_end(bm); + } +#endif + + /* free vars */ + MEM_freeN(vquadrics); + MEM_freeN(eheap_table); + BLI_heap_free(eheap, NULL); + + /* testing only */ + // BM_mesh_validate(bm); +} diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/intern/bmesh_decimate.h new file mode 100644 index 00000000000..e44aa576bda --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_decimate.h @@ -0,0 +1,32 @@ +/* + * ***** 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 ***** + */ + +#ifndef __BMESH_DECIMATE_H__ +#define __BMESH_DECIMATE_H__ + +/** \file blender/bmesh/intern/bmesh_decimate.h + * \ingroup bmesh + */ + +void BM_mesh_decimate(BMesh *bm, const float factor); + +#endif /* __BMESH_DECIMATE_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 726127fdcad..1cb95d94e9b 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -120,6 +120,21 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len) { BMIter iter; + /* we can't rely on coun't being set */ + switch (itype) { + case BM_VERTS_OF_MESH: + iter.count = bm->totvert; + break; + case BM_EDGES_OF_MESH: + iter.count = bm->totedge; + break; + case BM_FACES_OF_MESH: + iter.count = bm->totface; + break; + default: + break; + } + if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) { BMElem *ele; BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__); @@ -190,10 +205,10 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const */ static void init_iterator(BMIter *iter) { - iter->firstvert = iter->nextvert = NULL; - iter->firstedge = iter->nextedge = NULL; - iter->firstloop = iter->nextloop = NULL; - iter->firstpoly = iter->nextpoly = NULL; +// iter->v_first = iter->v_next = NULL; // UNUSED + iter->e_first = iter->e_next = NULL; + iter->l_first = iter->l_next = NULL; +// iter->f_first = iter->f_next = NULL; // UNUSED iter->ldata = NULL; } @@ -229,6 +244,7 @@ void *bmiter__vert_of_mesh_step(BMIter *iter) void bmiter__edge_of_mesh_begin(BMIter *iter) { BLI_mempool_iternew(iter->bm->epool, &iter->pooliter); + iter->count = iter->bm->totedge; /* */ } void *bmiter__edge_of_mesh_step(BMIter *iter) @@ -256,19 +272,19 @@ void bmiter__edge_of_vert_begin(BMIter *iter) { init_iterator(iter); if (iter->vdata->e) { - iter->firstedge = iter->vdata->e; - iter->nextedge = iter->vdata->e; + iter->e_first = iter->vdata->e; + iter->e_next = iter->vdata->e; } } void *bmiter__edge_of_vert_step(BMIter *iter) { - BMEdge *current = iter->nextedge; + BMEdge *current = iter->e_next; - if (iter->nextedge) - iter->nextedge = bmesh_disk_edge_next(iter->nextedge, iter->vdata); + if (iter->e_next) + iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->vdata); - if (iter->nextedge == iter->firstedge) iter->nextedge = NULL; + if (iter->e_next == iter->e_first) iter->e_next = NULL; return current; } @@ -284,27 +300,27 @@ void bmiter__face_of_vert_begin(BMIter *iter) if (iter->vdata->e) iter->count = bmesh_disk_facevert_count(iter->vdata); if (iter->count) { - iter->firstedge = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); - iter->nextedge = iter->firstedge; - iter->firstloop = bmesh_radial_faceloop_find_first(iter->firstedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); + iter->e_next = iter->e_first; + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata); + iter->l_next = iter->l_first; } } void *bmiter__face_of_vert_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->count && iter->nextloop) { + if (iter->count && iter->l_next) { iter->count--; - iter->nextloop = bmesh_radial_faceloop_find_next(iter->nextloop, iter->vdata); - if (iter->nextloop == iter->firstloop) { - iter->nextedge = bmesh_disk_faceedge_find_next(iter->nextedge, iter->vdata); - iter->firstloop = bmesh_radial_faceloop_find_first(iter->nextedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata); + if (iter->l_next == iter->l_first) { + iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata); + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata); + iter->l_next = iter->l_first; } } - if (!iter->count) iter->nextloop = NULL; + if (!iter->count) iter->l_next = NULL; return current ? current->f : NULL; } @@ -322,27 +338,27 @@ void bmiter__loop_of_vert_begin(BMIter *iter) if (iter->vdata->e) iter->count = bmesh_disk_facevert_count(iter->vdata); if (iter->count) { - iter->firstedge = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); - iter->nextedge = iter->firstedge; - iter->firstloop = bmesh_radial_faceloop_find_first(iter->firstedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); + iter->e_next = iter->e_first; + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata); + iter->l_next = iter->l_first; } } void *bmiter__loop_of_vert_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; if (iter->count) { iter->count--; - iter->nextloop = bmesh_radial_faceloop_find_next(iter->nextloop, iter->vdata); - if (iter->nextloop == iter->firstloop) { - iter->nextedge = bmesh_disk_faceedge_find_next(iter->nextedge, iter->vdata); - iter->firstloop = bmesh_radial_faceloop_find_first(iter->nextedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata); + if (iter->l_next == iter->l_first) { + iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata); + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata); + iter->l_next = iter->l_first; } } - if (!iter->count) iter->nextloop = NULL; + if (!iter->count) iter->l_next = NULL; if (current) { @@ -362,19 +378,19 @@ void bmiter__loops_of_edge_begin(BMIter *iter) /* note sure why this sets ldata ... */ init_iterator(iter); - iter->firstloop = iter->nextloop = l; + iter->l_first = iter->l_next = l; } void *bmiter__loops_of_edge_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) { - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) { + iter->l_next = NULL; } if (current) { @@ -393,23 +409,23 @@ void bmiter__loops_of_loop_begin(BMIter *iter) /* note sure why this sets ldata ... */ init_iterator(iter); - iter->firstloop = l; - iter->nextloop = iter->firstloop->radial_next; + iter->l_first = l; + iter->l_next = iter->l_first->radial_next; - if (iter->nextloop == iter->firstloop) - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) + iter->l_next = NULL; } void *bmiter__loops_of_loop_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) { - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) { + iter->l_next = NULL; } if (current) { @@ -428,20 +444,20 @@ void bmiter__face_of_edge_begin(BMIter *iter) init_iterator(iter); if (iter->edata->l) { - iter->firstloop = iter->edata->l; - iter->nextloop = iter->edata->l; + iter->l_first = iter->edata->l; + iter->l_next = iter->edata->l; } } void *bmiter__face_of_edge_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->f : NULL; } @@ -476,15 +492,15 @@ void *bmiter__vert_of_edge_step(BMIter *iter) void bmiter__vert_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__vert_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->v : NULL; } @@ -496,15 +512,15 @@ void *bmiter__vert_of_face_step(BMIter *iter) void bmiter__edge_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__edge_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->e : NULL; } @@ -516,15 +532,15 @@ void *bmiter__edge_of_face_step(BMIter *iter) void bmiter__loop_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__loop_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current; } diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 8d0eeca31ed..3c42b3d610c 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -95,23 +95,27 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX]; for (ele = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++) /* Iterator Structure */ +/* note: some of these vars are not used, + * so they have beem commented to save stack space since this struct is used all over */ typedef struct BMIter { BLI_mempool_iter pooliter; - BMVert *firstvert, *nextvert, *vdata; - BMEdge *firstedge, *nextedge, *edata; - BMLoop *firstloop, *nextloop, *ldata, *l; - BMFace *firstpoly, *nextpoly, *pdata; + BMVert /* *v_first, *v_next, */ *vdata; + BMEdge *e_first, *e_next, *edata; + BMLoop *l_first, *l_next, *ldata; + BMFace /* *f_first, *f_next, */ *pdata; BMesh *bm; void (*begin)(struct BMIter *iter); void *(*step)(struct BMIter *iter); + /* union { void *p; int i; long l; float f; } filter; - int count; + */ + int count; /* note, only some iterators set this, don't rely on it */ char itype; } BMIter; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 0d072da5327..360e2c93de3 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -57,7 +57,7 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER); #ifdef USE_BMESH_HOLES - bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), allocsize[3], allocsize[3], FALSE, FALSE); + bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0); #endif /* allocate one flag pool that we don't get rid of. */ diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 3195899ef01..91ca7124fc2 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -130,6 +130,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) /* this code for handling 2 and 3-valence verts * may be totally bad */ if (keepedge == NULL && len == 3) { +#if 0 /* handle specific case for three-valence. solve it by * increasing valence to four. this may be hackish. . */ BMLoop *loop = e->l; @@ -140,6 +141,13 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) if (!BM_disk_dissolve(bm, v)) { return FALSE; } +#else + BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE); + + if (!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE)) { + return FALSE; + } +#endif return TRUE; } else if (keepedge == NULL && len == 2) { @@ -188,8 +196,9 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) } while (e != v->e); } - /* collapse the verte */ - e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, TRUE, TRUE); + /* collapse the vertex */ + /* note, the baseedge can be a boundary of manifold, use this as join_faces arg */ + e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, !BM_edge_is_boundary(baseedge), TRUE); if (!e) { return FALSE; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 362157ad71b..407e7caae0f 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -698,6 +698,15 @@ static BMOpDefine bmo_triangulate_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +static BMOpDefine bmo_unsubdivide_def = { + "unsubdivide", + {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ + {BMO_OP_SLOT_INT, "iterations"}, + {0} /* null-terminating sentinel */}, + bmo_unsubdivide_exec, + BMO_OP_FLAG_UNTAN_MULTIRES +}; + static BMOpDefine bmo_subdivide_edges_def = { "subdivide_edges", {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, @@ -1182,6 +1191,29 @@ static BMOpDefine bmo_convex_hull_def = { 0 }; +/* + * Symmetrize + * + * Mekes the mesh elements in the "input" slot symmetrical. Unlike + * normal mirroring, it only copies in one direction, as specified by + * the "direction" slot. The edges and faces that cross the plane of + * symmetry are split as needed to enforce symmetry. + * + * All new vertices, edges, and faces are added to the "geomout" slot. + */ +static BMOpDefine bmo_symmetrize_def = { + "symmetrize", + {{BMO_OP_SLOT_ELEMENT_BUF, "input"}, + {BMO_OP_SLOT_INT, "direction"}, + + /* Outputs */ + {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, + + {0} /* null-terminating sentinel */}, + bmo_symmetrize_exec, + 0 +}; + BMOpDefine *opdefines[] = { &bmo_automerge_def, &bmo_average_vert_facedata_def, @@ -1246,10 +1278,12 @@ BMOpDefine *opdefines[] = { &bmo_split_def, &bmo_split_edges_def, &bmo_subdivide_edges_def, + &bmo_symmetrize_def, &bmo_transform_def, &bmo_translate_def, &bmo_triangle_fill_def, &bmo_triangulate_def, + &bmo_unsubdivide_def, &bmo_weld_verts_def, &bmo_wireframe_def, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 0674103162c..a2f4cdc8c6a 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -266,6 +266,16 @@ enum { DEL_ONLYTAGGED }; +typedef enum { + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z, + + BMO_SYMMETRIZE_POSITIVE_X, + BMO_SYMMETRIZE_POSITIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Z, +} BMO_SymmDirection; + void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag); void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag); diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index dc1bdaa4689..d6135efe19a 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -96,10 +96,12 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op); void bmo_split_edges_exec(BMesh *bm, BMOperator *op); void bmo_split_exec(BMesh *bm, BMOperator *op); void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op); +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op); void bmo_transform_exec(BMesh *bm, BMOperator *op); void bmo_translate_exec(BMesh *bm, BMOperator *op); void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op); void bmo_triangulate_exec(BMesh *bm, BMOperator *op); +void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op); void bmo_weld_verts_exec(BMesh *bm, BMOperator *op); void bmo_wireframe_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index d850eb34477..9520b0298d8 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -298,6 +298,14 @@ int BM_edge_in_face(BMFace *f, BMEdge *e) } /** + * Returns whether or not a given edge is is part of a given loop. + */ +int BM_edge_in_loop(BMEdge *e, BMLoop *l) +{ + return (l->e == e || l->prev->e == e); +} + +/** * Returns whether or not two vertices are in * a given edge */ @@ -316,6 +324,44 @@ BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v) } /** + * Given a edge and a loop (assumes the edge is manifold). returns + * the other faces loop, sharing the same vertex. + * + * <pre> + * +-------------------+ + * | | + * | | + * |l_other <-- return | + * +-------------------+ <-- A manifold edge between 2 faces + * |l e <-- edge | + * |^ <-------- loop | + * | | + * +-------------------+ + * </pre> + */ +BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) +{ + BMLoop *l_other; + + BLI_assert(BM_edge_is_manifold(e)); + BLI_assert(BM_vert_in_edge(e, l->v)); + + l_other = (e->l == l) ? l->radial_next : l; + + if (l_other->v == l->v) { + /* pass */ + } + else if (l_other->next->v == l->v) { + l_other = l_other->next; + } + else { + BLI_assert(0); + } + + return l_other; +} + +/** * The function takes a vertex at the center of a fan and returns the opposite edge in the fan. * All edges in the fan must be manifold, otherwise return NULL. * @@ -1018,6 +1064,28 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2) } /** + * Returns an edge sharing the same vertices as this one. + * This isn't an invalid state but tools should clean up these cases before + * returning the mesh to the user. + */ +BMEdge *BM_edge_find_double(BMEdge *e) +{ + BMVert *v = e->v1; + BMVert *v_other = e->v2; + + BMEdge *e_iter; + + e_iter = e; + while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) { + if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) { + return e_iter; + } + } + + return NULL; +} + +/** * Given a set of vertices \a varr, find out if * all those vertices overlap an existing face. * diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 36ffc296759..166b8a54f8a 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -31,6 +31,7 @@ int BM_vert_in_face(BMFace *f, BMVert *v); int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len); int BM_edge_in_face(BMFace *f, BMEdge *e); +int BM_edge_in_loop(BMEdge *e, BMLoop *l); int BM_vert_in_edge(BMEdge *e, BMVert *v); int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e); @@ -39,6 +40,7 @@ float BM_edge_calc_length(BMEdge *e); int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb); int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb); BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v); +BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l); BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v); BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v); BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v); @@ -72,6 +74,7 @@ BMLoop *BM_face_find_shortest_loop(BMFace *f); BMLoop *BM_face_find_longest_loop(BMFace *f); BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2); +BMEdge *BM_edge_find_double(BMEdge *e); int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface); diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index a72bfe47127..225ea6c2ef6 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -499,7 +499,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) BMEdge *e = lwalk->cur, *nexte = NULL; BMLoop *l; BMVert *v; - int i; + int i = 0; owalk = *lwalk; BMW_state_remove(walker); @@ -534,7 +534,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) } else if (l) { /* NORMAL EDGE WITH FACES */ int vert_edge_tot; - int stopi; + int stopi = 0; v = BM_edge_other_vert(e, lwalk->lastv); diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 10a9d511c77..e31df2e4444 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -233,7 +233,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } #if 0 - //a bit of cleaner code that, alas, doens't work. + /* a bit of cleaner code that, alas, doens't work. */ /* build edge tag */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e->v1, BEVEL_FLAG) || BMO_elem_flag_test(bm, e->v2, BEVEL_FLAG)) { diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 7191aa7a7b6..3dbc0d0a5eb 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -199,7 +199,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) { BMIter iter, liter; BMOIter siter; - BMFace *f1, *f2; + BMFace *f; BMLoop *l; BMEdge *e; BLI_array_declare(jedges); @@ -213,15 +213,16 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) int i, totedge; /* flag all edges of all input face */ - BMO_ITER (f1, &siter, bm, op, "faces", BM_FACE) { - BMO_elem_flag_enable(bm, f1, FACE_INPUT); - BM_ITER_ELEM (l, &liter, f1, BM_LOOPS_OF_FACE) { + BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) { + BMO_elem_flag_enable(bm, f, FACE_INPUT); + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { BMO_elem_flag_enable(bm, l->e, EDGE_MARK); } } /* unflag edges that are invalid; e.g. aren't surrounded by triangle */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMFace *f1, *f2; if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) continue; @@ -300,6 +301,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) } BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMFace *f1, *f2; + if (!BMO_elem_flag_test(bm, e, EDGE_CHOSEN)) continue; @@ -310,6 +313,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { + BMFace *f1, *f2; + /* ok, this edge wasn't merged, check if it's * in a 2-tri-pair island, and if so merg */ diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c new file mode 100644 index 00000000000..a428405fb8b --- /dev/null +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -0,0 +1,663 @@ +/* + * ***** 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): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_array.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "bmesh.h" +#include "intern/bmesh_operators_private.h" + +enum { + SYMM_OUTPUT_GEOM = (1 << 0) +}; + +/* Note: don't think there's much need to make these user-adjustable? */ +#define SYMM_AXIS_THRESHOLD 0.00002f +#define SYMM_VERT_THRESHOLD 0.00002f + +typedef enum { + /* Coordinate lies on the side being copied from */ + SYMM_SIDE_KEEP, + /* Coordinate lies on the side being copied from and within the + * axis threshold */ + SYMM_SIDE_AXIS, + /* Coordinate lies on the side being copied to */ + SYMM_SIDE_KILL +} SymmSide; + +typedef struct { + BMesh *bm; + BMOperator *op; + + int axis; + BMO_SymmDirection direction; + + /* Maps from input vertices to their mirrors. If the vertex + * doesn't have a mirror, it's not in this map. If the vertex is + * within the axis threshold, it's mapped to itself. */ + GHash *vert_symm_map; + + /* Edges that cross the symmetry plane and are asymmetric get + * split. This map goes from input edges to output vertices. If an + * edge is not split, it's not in this map. */ + GHash *edge_split_map; +} Symm; + +/* Return which side the coordinate lies on */ +static SymmSide symm_co_side(const Symm *symm, + const float *co) +{ + float comp = co[symm->axis]; + if (ELEM3(symm->direction, + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z)) + { + comp = -comp; + } + + if (comp >= 0) { + if (comp < SYMM_AXIS_THRESHOLD) + return SYMM_SIDE_AXIS; + else + return SYMM_SIDE_KEEP; + } + else + return SYMM_SIDE_KILL; +} + +/* Output vertices and the vert_map array */ +static void symm_verts_mirror(Symm *symm) +{ + BMOIter oiter; + BMVert *src_v, *dst_v; + + symm->vert_symm_map = BLI_ghash_ptr_new(AT); + + BMO_ITER (src_v, &oiter, symm->bm, symm->op, "input", BM_VERT) { + SymmSide side = symm_co_side(symm, src_v->co); + float co[3]; + + switch (side) { + case SYMM_SIDE_KEEP: + /* The vertex is outside the axis area; output its mirror */ + copy_v3_v3(co, src_v->co); + co[symm->axis] = -co[symm->axis]; + + dst_v = BM_vert_create(symm->bm, co, src_v); + BMO_elem_flag_enable(symm->bm, dst_v, SYMM_OUTPUT_GEOM); + BLI_ghash_insert(symm->vert_symm_map, src_v, dst_v); + break; + + case SYMM_SIDE_AXIS: + /* The vertex is within the axis area, snap to center */ + src_v->co[symm->axis] = 0; + /* Vertex isn't copied, map to itself */ + BLI_ghash_insert(symm->vert_symm_map, src_v, src_v); + break; + + case SYMM_SIDE_KILL: + /* The vertex does not lie in the half-space being + * copied from, nothing to do */ + break; + } + } +} + +static int symm_edge_crosses_axis(const Symm *symm, const BMEdge *e) +{ + const int sides[2] = {symm_co_side(symm, e->v1->co), + symm_co_side(symm, e->v2->co)}; + + return ((sides[0] != SYMM_SIDE_AXIS) && + (sides[1] != SYMM_SIDE_AXIS) && + (sides[0] != sides[1])); +} + +/* Output edge split vertices for asymmetric edges and the edge_splits + * mapping array */ +static void symm_split_asymmetric_edges(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + + symm->edge_split_map = BLI_ghash_ptr_new(AT); + + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + float flipped[3]; + + copy_v3_v3(flipped, e->v1->co); + flipped[symm->axis] = -flipped[symm->axis]; + + if (symm_edge_crosses_axis(symm, e) && + (!compare_v3v3(e->v2->co, flipped, SYMM_VERT_THRESHOLD))) + { + /* Endpoints lie on opposite sides and are asymmetric */ + + BMVert *v; + float lambda = 0, edge_dir[3], co[3]; + float plane_co[3][3][3] = { + /* axis == 0 */ + {{0, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + /* axis == 1 */ + {{0, 0, 0}, {1, 0, 0}, {0, 0, 1}}, + /* axis == 2 */ + {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}, + }; + int r; + + /* Find intersection of edge with symmetry plane */ + sub_v3_v3v3(edge_dir, e->v2->co, e->v1->co); + normalize_v3(edge_dir); + r = isect_ray_plane_v3(e->v1->co, + edge_dir, + plane_co[symm->axis][0], + plane_co[symm->axis][1], + plane_co[symm->axis][2], + &lambda, TRUE); + BLI_assert(r); + + madd_v3_v3v3fl(co, e->v1->co, edge_dir, lambda); + co[symm->axis] = 0; + + /* Edge is asymmetric, split it with a new vertex */ + v = BM_vert_create(symm->bm, co, e->v1); + BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM); + BLI_ghash_insert(symm->edge_split_map, e, v); + } + } +} + +static void symm_mirror_edges(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + BMVert *v1 = NULL, *v2 = NULL; + BMEdge *e_new; + + v1 = BLI_ghash_lookup(symm->vert_symm_map, e->v1); + v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2); + + if (v1 && v2) { + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + } + else if (v1 || v2) { + if (BLI_ghash_haskey(symm->edge_split_map, e)) { + BMVert *v_split = BLI_ghash_lookup(symm->edge_split_map, e); + + /* Output the keep side of the split edge */ + if (!v1) { + e_new = BM_edge_create(symm->bm, v_split, e->v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + v1 = v_split; + } + else { + e_new = BM_edge_create(symm->bm, e->v1, v_split, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + v2 = v_split; + } + + /* Output the kill side of the split edge */ + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + } + } + } +} + +/****************************** SymmPoly ******************************/ + +typedef struct { + /* Indices into the source mvert array (or -1 if not in that array) */ + BMVert **src_verts; + /* Indices into the destination mvert array, these are vertices + * created by an edge split (-1 for vertices not created by edge + * split) */ + BMVert **edge_verts; + + /* Number of vertices in the polygon */ + int len; + + /* True only if none of the polygon's edges were split */ + int already_symmetric; +} SymmPoly; + +static void symm_poly_with_splits(const Symm *symm, + BMFace *f, + SymmPoly *out) +{ + BMIter iter; + BMLoop *l; + int i; + + /* Count vertices and check for edge splits */ + out->len = f->len; + out->already_symmetric = TRUE; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + if (BLI_ghash_haskey(symm->edge_split_map, l->e)) { + out->len++; + out->already_symmetric = FALSE; + } + } + + i = 0; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + BMVert *split = BLI_ghash_lookup(symm->edge_split_map, l->e); + + out->src_verts[i] = l->v; + out->edge_verts[i] = NULL; + i++; + + if (split) { + out->src_verts[i] = NULL; + out->edge_verts[i] = split; + i++; + } + } +} + +static const float *symm_poly_co(const SymmPoly *sp, int v) +{ + if (sp->src_verts[v]) + return sp->src_verts[v]->co; + else if (sp->edge_verts[v]) + return sp->edge_verts[v]->co; + else + return NULL; +} + +static SymmSide symm_poly_co_side(const Symm *symm, + const SymmPoly *sp, + int v) +{ + return symm_co_side(symm, symm_poly_co(sp, v)); +} + +/* Return the index of the vertex in the destination array at corner + * 'v' of the polygon, or -1 if not in that array */ +static BMVert *symm_poly_dst(const SymmPoly *sp, int v) +{ + if (sp->edge_verts[v]) + return sp->edge_verts[v]; + else if (sp->src_verts[v]) + return sp->src_verts[v]; + else + return NULL; +} + +/* Same as above, but returns the index of the mirror if available, or + * the same index if on the axis, or -1 otherwise */ +static BMVert *symm_poly_mirror_dst(const Symm *symm, + const SymmPoly *sp, + int v) +{ + if (sp->edge_verts[v]) + return sp->edge_verts[v]; + else if (sp->src_verts[v]) { + if (BLI_ghash_haskey(symm->vert_symm_map, sp->src_verts[v])) + return BLI_ghash_lookup(symm->vert_symm_map, sp->src_verts[v]); + else + return sp->src_verts[v]; + } + else + return NULL; +} + +static int symm_poly_next_crossing(const Symm *symm, + const SymmPoly *sp, + int start, + int *l1, + int *l2) +{ + int i; + + for (i = 0; i < sp->len; i++) { + (*l1) = (start + i) % sp->len; + (*l2) = ((*l1) + 1) % sp->len; + + if ((symm_poly_co_side(symm, sp, *l1) == SYMM_SIDE_KILL) ^ + (symm_poly_co_side(symm, sp, *l2) == SYMM_SIDE_KILL)) + { + return TRUE; + } + } + + BLI_assert(!"symm_poly_next_crossing failed"); + return FALSE; +} + +static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len) +{ + BMFace *f_new; + int i; + + for (i = 0; i < len; i++) { + int j = (i + 1) % len; + fe[i] = BM_edge_exists(fv[i], fv[j]); + if (!fe[i]) { + fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, FALSE); + BMO_elem_flag_enable(bm, fe[i], SYMM_OUTPUT_GEOM); + } + } + f_new = BM_face_create(bm, fv, fe, len, TRUE); + BM_face_select_set(bm, f_new, TRUE); + BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM); + return f_new; +} + +static void symm_mesh_output_poly_zero_splits(Symm *symm, + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) +{ + int i, j; + + j = 0; + + /* Output the keep side of the input polygon */ + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BLI_assert(sp->src_verts[offset]); + fv[j++] = sp->src_verts[offset]; + } + + /* Output the kill side of the polygon */ + for (i = segment_len - 1; i >= 0; i--) { + const int offset = (start + i) % sp->len; + + if (symm_poly_co_side(symm, sp, offset) == SYMM_SIDE_KEEP) { + BLI_assert(sp->src_verts[offset]); + fv[j++] = BLI_ghash_lookup(symm->vert_symm_map, + sp->src_verts[offset]); + } + } + + symm_face_create_v(symm->bm, fv, fe, j); +} + +static void symm_mesh_output_poly_with_splits(Symm *symm, + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) +{ + int i; + + /* Output the keep side of the input polygon */ + + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BMVert *v = symm_poly_dst(sp, offset); + + BLI_assert(v); + + fv[i] = v; + } + + symm_face_create_v(symm->bm, fv, fe, segment_len); + + /* Output the kill side of the input polygon */ + + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BMVert *v = symm_poly_mirror_dst(symm, sp, offset); + + fv[segment_len - i - 1] = v; + + } + + symm_face_create_v(symm->bm, fv, fe, segment_len); +} + +static void symm_mirror_polygons(Symm *symm) +{ + BMOIter oiter; + BMFace *f; + BMVert **pv = NULL; + BMVert **fv = NULL; + BMEdge **fe = NULL; + BLI_array_declare(pv); + BLI_array_declare(fv); + BLI_array_declare(fe); + + BMO_ITER (f, &oiter, symm->bm, symm->op, "input", BM_FACE) { + BMIter iter; + BMLoop *l; + int mirror_all = TRUE, ignore_all = TRUE; + + /* Check if entire polygon can be mirrored or ignored */ + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + const SymmSide side = symm_co_side(symm, l->v->co); + if (side == SYMM_SIDE_KILL) + mirror_all = FALSE; + else if (side == SYMM_SIDE_KEEP) + ignore_all = FALSE; + } + + if (mirror_all) { + int i; + + /* Make a mirrored copy of the polygon */ + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, f->len); + BLI_array_grow_items(fe, f->len); + + i = f->len; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + i--; + + if (symm_co_side(symm, l->v->co) == SYMM_SIDE_KEEP) + fv[i] = BLI_ghash_lookup(symm->vert_symm_map, l->v); + else + fv[i] = l->v; + } + + symm_face_create_v(symm->bm, fv, fe, f->len); + } + else if (ignore_all) { + BM_face_kill(symm->bm, f); + } + else { + SymmPoly sp; + int l1, l2, l3, l4; + int double_l2, double_l3; + int segment_len; + + BLI_array_empty(pv); + BLI_array_grow_items(pv, f->len * 4); + sp.src_verts = pv; + sp.edge_verts = pv + f->len * 2; + symm_poly_with_splits(symm, f, &sp); + + /* Find first loop edge crossing the axis */ + symm_poly_next_crossing(symm, &sp, 0, &l1, &l2); + + /* If crossing isn't kill to keep, find the next one */ + if (symm_poly_co_side(symm, &sp, l1) != SYMM_SIDE_KILL) { + symm_poly_next_crossing(symm, &sp, l2, &l1, &l2); + } + + /* Find next crossing (keep to kill) */ + symm_poly_next_crossing(symm, &sp, l2, &l3, &l4); + + if (l2 == l3) + segment_len = 0; + else if (l2 < l3) + segment_len = l3 - l2 + 1; + else + segment_len = (sp.len - l2 + 1) + l3; + + double_l2 = symm_poly_co_side(symm, &sp, l2) == SYMM_SIDE_KEEP; + double_l3 = symm_poly_co_side(symm, &sp, l3) == SYMM_SIDE_KEEP; + + /* Calculate number of new polygons/loops */ + if (segment_len == 0) { + } + else if (sp.already_symmetric) { + int new_loops; + + if (double_l2 && double_l3) + new_loops = segment_len * 2; + else if (!double_l2 && !double_l3) + new_loops = segment_len * 2 - 2; + else + new_loops = segment_len * 2 - 1; + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, new_loops); + BLI_array_grow_items(fe, new_loops); + + symm_mesh_output_poly_zero_splits(symm, &sp, + fv, fe, + segment_len, l2); + BM_face_kill(symm->bm, f); + } + else if (!double_l2 && !double_l3) { + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, segment_len); + BLI_array_grow_items(fe, segment_len); + + symm_mesh_output_poly_with_splits(symm, &sp, + fv, fe, + segment_len, + l2); + + BM_face_kill(symm->bm, f); + } + else { + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, segment_len); + BLI_array_grow_items(fe, segment_len); + + symm_mesh_output_poly_with_splits(symm, &sp, + fv, fe, + segment_len, + l2); + + BM_face_kill(symm->bm, f); + + /* Output bridge triangle */ + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, 3); + BLI_array_grow_items(fe, 3); + + if (double_l2) { + fv[0] = symm_poly_dst(&sp, l2); + fv[1] = symm_poly_mirror_dst(symm, &sp, l2); + fv[2] = symm_poly_dst(&sp, l3); + } + else if (double_l3) { + fv[0] = symm_poly_dst(&sp, l3); + fv[1] = symm_poly_mirror_dst(symm, &sp, l3); + fv[2] = symm_poly_dst(&sp, l2); + } + + BLI_assert(fv[0] && fv[1] && fv[2]); + + symm_face_create_v(symm->bm, fv, fe, 3); + } + } + } + + BLI_array_free(pv); + BLI_array_free(fv); + BLI_array_free(fe); +} + +/* Remove unused edges and vertices from the side being copied to */ +static void symm_kill_unused(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + BMVert *v; + + /* Kill unused edges */ + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + const int crosses = symm_edge_crosses_axis(symm, e); + const int symmetric = (crosses && + (!BLI_ghash_haskey(symm->edge_split_map, e))); + + if (((symm_co_side(symm, e->v1->co) == SYMM_SIDE_KILL) || + (symm_co_side(symm, e->v2->co) == SYMM_SIDE_KILL)) && + !symmetric) + { + /* The edge might be used by a face outside the input set */ + if (BM_edge_face_count(e) == 0) + BM_edge_kill(symm->bm, e); + } + } + + /* Kill unused vertices */ + BMO_ITER (v, &oiter, symm->bm, symm->op, "input", BM_VERT) { + if (symm_co_side(symm, v->co) == SYMM_SIDE_KILL) { + if (BM_vert_edge_count(v) == 0) + BM_vert_kill(symm->bm, v); + } + } +} + +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) +{ + Symm symm; + BMO_SymmDirection direction = BMO_slot_int_get(op, "direction"); + + symm.bm = bm; + symm.op = op; + symm.axis = (ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_POSITIVE_X) ? 0 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Y) ? 1 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Z, + BMO_SYMMETRIZE_POSITIVE_Z) ? 2 : 0); + symm.direction = direction; + + symm_verts_mirror(&symm); + symm_split_asymmetric_edges(&symm); + symm_mirror_edges(&symm); + symm_mirror_polygons(&symm); + symm_kill_unused(&symm); + + BLI_ghash_free(symm.vert_symm_map, NULL, NULL); + BLI_ghash_free(symm.edge_split_map, NULL, NULL); + + BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_ALL, + SYMM_OUTPUT_GEOM); +} diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c new file mode 100644 index 00000000000..64b7151aee5 --- /dev/null +++ b/source/blender/bmesh/operators/bmo_unsubdivide.c @@ -0,0 +1,348 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/bmesh/operators/bmo_unsubdivide.c + * \ingroup bmesh + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "bmesh.h" + +#include "intern/bmesh_operators_private.h" /* own include */ + + +static int bm_vert_dissolve_fan_test(BMVert *v) +{ + /* check if we should walk over these verts */ + BMIter iter; + BMEdge *e; + + unsigned int tot_edge = 0; + unsigned int tot_edge_boundary = 0; + unsigned int tot_edge_manifold = 0; + unsigned int tot_edge_wire = 0; + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + if (BM_edge_is_boundary(e)) { + tot_edge_boundary++; + } + else if (BM_edge_is_manifold(e)) { + tot_edge_manifold++; + } + else if (BM_edge_is_wire(e)) { + tot_edge_wire++; + } + tot_edge++; + } + + if ((tot_edge == 4) && (tot_edge_boundary == 0) && (tot_edge_manifold == 4)) { + return TRUE; + } + else if ((tot_edge == 3) && (tot_edge_boundary == 0) && (tot_edge_manifold == 3)) { + return TRUE; + } + else if ((tot_edge == 3) && (tot_edge_boundary == 2) && (tot_edge_manifold == 1)) { + return TRUE; + } + else if ((tot_edge == 2) && (tot_edge_wire == 2)) { + return TRUE; + } + return FALSE; +} + +static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v) +{ + /* collapse under 2 conditions. + * - vert connects to 4 manifold edges (and 4 faces). + * - vert connecrs to 1 manifold edge, 2 boundary edges (and 2 faces). + * + * This covers boundary verts of a quad grid and center verts. + * note that surrounding faces dont have to be quads. + */ + + BMIter iter; + BMEdge *e; + + unsigned int tot_loop = 0; + unsigned int tot_edge = 0; + unsigned int tot_edge_boundary = 0; + unsigned int tot_edge_manifold = 0; + unsigned int tot_edge_wire = 0; + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + if (BM_edge_is_boundary(e)) { + tot_edge_boundary++; + } + else if (BM_edge_is_manifold(e)) { + tot_edge_manifold++; + } + else if (BM_edge_is_wire(e)) { + tot_edge_wire++; + } + tot_edge++; + } + + if (tot_edge == 2) { + /* check for 2 wire verts only */ + if (tot_edge_wire == 2) { + return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL); + } + } + else if (tot_edge == 4) { + /* check for 4 faces surrounding */ + if (tot_edge_boundary == 0 && tot_edge_manifold == 4) { + /* good to go! */ + tot_loop = 4; + } + } + else if (tot_edge == 3) { + /* check for 2 faces surrounding at a boundary */ + if (tot_edge_boundary == 2 && tot_edge_manifold == 1) { + /* good to go! */ + tot_loop = 2; + } + else if (tot_edge_boundary == 0 && tot_edge_manifold == 3) { + /* good to go! */ + tot_loop = 3; + } + } + + if (tot_loop) { + BMLoop *f_loop[4]; + unsigned int i; + + /* ensure there are exactly tot_loop loops */ + BLI_assert(BM_iter_at_index(bm, BM_LOOPS_OF_VERT, v, tot_loop) == NULL); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)f_loop, tot_loop); + + for (i = 0; i < tot_loop; i++) { + BMLoop *l = f_loop[i]; + if (l->f->len > 3) { + BLI_assert(l->prev->v != l->next->v); + BM_face_split(bm, l->f, l->prev->v, l->next->v, NULL, NULL, TRUE); + } + } + + return BM_vert_dissolve(bm, v); + } + + return FALSE; +} + +enum { + VERT_INDEX_DO_COLLAPSE = -1, + VERT_INDEX_INIT = 0, + VERT_INDEX_IGNORE = 1 +}; + +// #define USE_WALKER /* gives uneven results, disable for now */ +// #define USE_ALL_VERTS + +/* - BMVert.flag & BM_ELEM_TAG: shows we touched this vert + * - BMVert.index == -1: shows we will remove this vert + */ +void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op) +{ +#ifdef USE_WALKER +# define ELE_VERT_TAG 1 +#else + BMVert **vert_seek_a = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + BMVert **vert_seek_b = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + unsigned vert_seek_a_tot = 0; + unsigned vert_seek_b_tot = 0; +#endif + + BMVert *v; + BMIter iter; + + const unsigned int offset = 0; + const unsigned int nth = 2; + + const int iterations = maxi(1, BMO_slot_int_get(op, "iterations")); + int iter_step; + +#ifdef USE_ALL_VERTS + (void)op; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_enable(v, BM_ELEM_TAG); + } +#else /* USE_ALL_VERTS */ + BMOpSlot *vinput = BMO_slot_get(op, "verts"); + BMVert **vinput_arr = (BMVert **)vinput->data.p; + int v_index; + + /* tag verts */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_disable(v, BM_ELEM_TAG); + } + for (v_index = 0; v_index < vinput->len; v_index++) { + v = vinput_arr[v_index]; + BM_elem_flag_enable(v, BM_ELEM_TAG); + } +#endif /* USE_ALL_VERTS */ + + + for (iter_step = 0; iter_step < iterations; iter_step++) { + int iter_done; + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG) && bm_vert_dissolve_fan_test(v)) { +#ifdef USE_WALKER + BMO_elem_flag_enable(bm, v, ELE_VERT_TAG); +#endif + BM_elem_index_set(v, VERT_INDEX_INIT); /* set_dirty! */ + } + else { + BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ + } + } + /* done with selecting tagged verts */ + + + /* main loop, keep tagging until we can't tag any more islands */ + while (TRUE) { +#ifdef USE_WALKER + BMWalker walker; +#else + unsigned int depth = 1; + unsigned int i; +#endif + BMVert *v_first = NULL; + BMVert *v; + + /* we could avoid iterating from the start each time */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (v->e && (BM_elem_index_get(v) == VERT_INDEX_INIT)) { +#ifdef USE_WALKER + if (BMO_elem_flag_test(bm, v, ELE_VERT_TAG)) +#endif + { + /* check again incase the topology changed */ + if (bm_vert_dissolve_fan_test(v)) { + v_first = v; + } + break; + } + } + } + if (v_first == NULL) { + break; + } + +#ifdef USE_WALKER + /* Walk over selected elements starting at active */ + BMW_init(&walker, bm, BMW_CONNECTED_VERTEX, + ELE_VERT_TAG, BMW_MASK_NOP, BMW_MASK_NOP, + BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */ + BMW_NIL_LAY); + + BLI_assert(walker.order == BMW_BREADTH_FIRST); + for (v = BMW_begin(&walker, v_first); v != NULL; v = BMW_step(&walker)) { + /* Deselect elements that aren't at "nth" depth from active */ + if (BM_elem_index_get(v) == VERT_INDEX_INIT) { + if ((offset + BMW_current_depth(&walker)) % nth) { + /* tag for removal */ + BM_elem_index_set(v, VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + } + else { + /* works better to allow these verts to be checked again */ + //BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ + } + } + } + BMW_end(&walker); +#else + + BM_elem_index_set(v_first, (offset + depth) % nth ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + + vert_seek_b_tot = 0; + vert_seek_b[vert_seek_b_tot++] = v_first; + + while (TRUE) { + BMEdge *e; + + if ((offset + depth) % nth) { + vert_seek_a_tot = 0; + for (i = 0; i < vert_seek_b_tot; i++) { + v = vert_seek_b[i]; + BLI_assert(BM_elem_index_get(v) == VERT_INDEX_IGNORE); + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == VERT_INDEX_INIT) { + BM_elem_index_set(v_other, VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + vert_seek_a[vert_seek_a_tot++] = v_other; + } + } + } + if (vert_seek_a_tot == 0) { + break; + } + } + else { + vert_seek_b_tot = 0; + for (i = 0; i < vert_seek_a_tot; i++) { + v = vert_seek_a[i]; + BLI_assert(BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE); + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == VERT_INDEX_INIT) { + BM_elem_index_set(v_other, VERT_INDEX_IGNORE); /* set_dirty! */ + vert_seek_b[vert_seek_b_tot++] = v_other; + } + } + } + if (vert_seek_b_tot == 0) { + break; + } + } + + depth++; + } +#endif /* USE_WALKER */ + + } + + /* now we tagged all verts -1 for removal, lets loop over and rebuild faces */ + iter_done = FALSE; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE) { + iter_done |= bm_vert_dissolve_fan(bm, v); + } + } + + if (iter_done == FALSE) { + break; + } + } + + bm->elem_index_dirty |= BM_VERT; + +#ifndef USE_WALKER + MEM_freeN(vert_seek_a); + MEM_freeN(vert_seek_b); +#endif + +} + diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 72e55b2700c..3d792205d08 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -1033,10 +1033,9 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op) void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) { - BMOIter fs_iter; /* selected faces iterator */ - BMFace *fs; /* current face */ - BMIter l_iter; /* iteration loop */ - // int n; + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ int dir = BMO_slot_int_get(op, "dir"); @@ -1091,7 +1090,6 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) } } } - } /**************************************************************************** * @@ -1140,10 +1138,9 @@ void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op) void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op) { - BMOIter fs_iter; /* selected faces iterator */ - BMFace *fs; /* current face */ - BMIter l_iter; /* iteration loop */ - // int n; + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ int dir = BMO_slot_int_get(op, "dir"); diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 7683ec1e9cd..bd7ad16dabd 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -160,7 +160,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce) clear_global_id_map(); COLLADABU::NativeString native_filename = - COLLADABU::NativeString(std::string(this->export_settings->filepath)); + COLLADABU::NativeString(std::string(this->export_settings->filepath), COLLADABU::NativeString::ENCODING_UTF8); COLLADASW::StreamWriter sw(native_filename); fprintf(stdout, "Collada export: %s\n", this->export_settings->filepath); diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index a13717c9d86..57ff5c5c838 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -25,6 +25,7 @@ #include <sstream> #include "PIL_time.h" +#include "BLI_utildefines.h" #include "BKE_node.h" #include "COM_Converter.h" @@ -50,7 +51,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re this->m_context.setbNodeTree(editingtree); this->m_context.setFastCalculation(fastcalculation); bNode *gnode; - for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = (bNode *)gnode->next) { + for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = gnode->next) { if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { this->m_context.setActivegNode(gnode); break; @@ -240,12 +241,32 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) } } +#ifndef NDEBUG +/* if this fails, there are still connection to/from this node, + * which have not been properly relinked to operations! + */ +static void debug_check_node_connections(Node *node) +{ + for (int i = 0; i < node->getNumberOfInputSockets(); ++i) { + BLI_assert(!node->getInputSocket(i)->isConnected()); + } + for (int i = 0; i < node->getNumberOfOutputSockets(); ++i) { + BLI_assert(!node->getOutputSocket(i)->isConnected()); + } +} +#else +/* stub */ +#define debug_check_node_connections(node) +#endif + void ExecutionSystem::convertToOperations() { unsigned int index; for (index = 0; index < this->m_nodes.size(); index++) { Node *node = (Node *)this->m_nodes[index]; node->convertToOperations(this, &this->m_context); + + debug_check_node_connections(node); } for (index = 0; index < this->m_connections.size(); index++) { diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 33a5cafebbe..506bd42ace3 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -51,7 +51,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star while (node != NULL) { Node *nnode = addNode(nodes, node, isActiveGroup, system.getContext().isFastCalculation()); nnode->setbNodeGroup(groupnode); - node = (bNode *)node->next; + node = node->next; } NodeRange node_range(nodes.begin() + nodes_start, nodes.end()); @@ -60,7 +60,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star bNodeLink *nodelink = (bNodeLink *)tree->links.first; while (nodelink != NULL) { addNodeLink(node_range, links, nodelink); - nodelink = (bNodeLink *)nodelink->next; + nodelink = nodelink->next; } /* Expand group nodes */ diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 5922b0e6b08..300d7ef1952 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -51,7 +51,7 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() if (input->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addInputSocket(dt, (InputSocketResizeMode)input->resizemode, input); - input = (bNodeSocket *)input->next; + input = input->next; } bNodeSocket *output = (bNodeSocket *)editorNode->outputs.first; while (output != NULL) { @@ -60,14 +60,14 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() if (output->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addOutputSocket(dt, output); - output = (bNodeSocket *)output->next; + output = output->next; } } } void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); SetValueOperation *operation = new SetValueOperation(); bNodeSocketValueFloat *val = (bNodeSocketValueFloat *)bSock->default_value; operation->setValue(val->value); @@ -114,7 +114,7 @@ SocketConnection *Node::addLink(ExecutionSystem *graph, OutputSocket *outputSock void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); SetColorOperation *operation = new SetColorOperation(); bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)bSock->default_value; operation->setChannel1(val->value[0]); @@ -127,7 +127,7 @@ void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); bNodeSocketValueVector *val = (bNodeSocketValueVector *)bSock->default_value; SetVectorOperation *operation = new SetVectorOperation(); operation->setX(val->value[0]); diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index e8fd936e749..468a95ed434 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Node_h -#define _COM_Node_h +#ifndef __COM_NODE_H__ +#define __COM_NODE_H__ #include "COM_NodeBase.h" #include "COM_InputSocket.h" @@ -152,4 +152,4 @@ protected: private: }; -#endif +#endif /* __COM_NODE_H__ */ diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index 64d669b5e9a..e386b5e08a0 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_NodeBase_h -#define _COM_NodeBase_h +#ifndef __COM_NODEBASE_H__ +#define __COM_NODEBASE_H__ #include "COM_InputSocket.h" #include "COM_OutputSocket.h" @@ -166,4 +166,4 @@ protected: #endif }; -#endif +#endif /* __COM_NODEBASE_H__ */ diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index d23ed245844..d5da079c9fd 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -74,7 +74,7 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, { cl_int error; - MemoryBuffer *result = (MemoryBuffer *)reader->getInputMemoryBuffer(inputMemoryBuffers); + MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers); const cl_image_format imageFormat = { CL_RGBA, diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h index 4efb06c9f87..29c6000a245 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ChannelMatteNODE_H +#endif /* COM_ChannelMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h index ddd350aab40..bf5302ccdbb 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ChromaMatteNODE_H +#endif /* COM_ChromaMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h index cdad02fc831..30d22ef2e63 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorBalanceNODE_H +#endif /* COM_ColorBalanceNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h index 92a4fa79408..3386476bc85 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorMatteNODE_H +#endif /* COM_ColorMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h index 6c256c09e68..3f00e1c2190 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ b/source/blender/compositor/nodes/COM_ColorRampNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorRampNODE_H +#endif /* COM_ColorRampNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h index 1d976fc65ae..01722fac826 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorSpillNODE_H +#endif /* COM_ColorSpillNODE_H */ diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h index 191b7361c3c..0b571889571 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_DifferenceMatteNODE_H +#endif /* COM_DifferenceMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 5cfc29ecce2..0fb7ea7d264 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -79,7 +79,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont CompositorQuality quality = context->getQuality(); /* initialize node data */ - NodeBlurData *data = (NodeBlurData *)&this->m_alpha_blur; + NodeBlurData *data = &this->m_alpha_blur; memset(data, 0, sizeof(*data)); data->filtertype = R_FILTER_GAUSS; diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h index 4e6682424e8..46ceae7c4f4 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_DistanceMatteNODE_H +#endif /* COM_DistanceMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h index d65166944d8..9be3bb02494 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.h +++ b/source/blender/compositor/nodes/COM_FilterNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_FilterNode_h_ -#define _COM_FilterNode_h_ +#ifndef __COM_FILTERNODE_H__ +#define __COM_FILTERNODE_H__ #include "COM_Node.h" @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_FilterNode_h_ +#endif /* __COM_FILTERNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 6bc9afba32c..51ea2913e65 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -151,7 +151,7 @@ OutputSocket *KeyingNode::setupFeather(ExecutionSystem *graph, CompositorContext CompositorQuality quality = context->getQuality(); /* initialize node data */ - NodeBlurData *data = (NodeBlurData *)&this->m_alpha_blur; + NodeBlurData *data = &this->m_alpha_blur; memset(data, 0, sizeof(*data)); data->filtertype = R_FILTER_GAUSS; diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h index 37f3c31113f..a71e68cf636 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_LuminanceMatteNode_h_ -#define _COM_LuminanceMatteNode_h_ +#ifndef __COM_LUMINANCEMATTENODE_H__ +#define __COM_LUMINANCEMATTENODE_H__ #include "COM_Node.h" @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_LuminanceMatteNode_h_ +#endif /* __COM_LUMINANCEMATTENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h index 22aa5459ec0..bd8e3d08e9c 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.h +++ b/source/blender/compositor/nodes/COM_MapValueNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MapValueNode_h_ -#define _COM_MapValueNode_h_ +#ifndef __COM_MAPVALUENODE_H__ +#define __COM_MAPVALUENODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_MapValueNode_h_ +#endif /* __COM_MAPVALUENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h index cdd5d3c362e..9ef3e5deb50 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.h +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_MaskNode_h_ -#define _COM_MaskNode_h_ +#ifndef __COM_MASKNODE_H__ +#define __COM_MASKNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -38,4 +38,4 @@ public: }; -#endif // _COM_MaskNode_h_ +#endif /* __COM_MASKNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h index 52ea11ea8e9..2fb38860a34 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.h +++ b/source/blender/compositor/nodes/COM_MovieClipNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MovieClipNode_h_ -#define _COM_MovieClipNode_h_ +#ifndef __COM_MOVIECLIPNODE_H__ +#define __COM_MOVIECLIPNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -36,4 +36,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_MovieClipNode_h_ +#endif /* __COM_MOVIECLIPNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h index 660d90040bd..64d4e3a3656 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ b/source/blender/compositor/nodes/COM_NormalNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_NormalNODE_H +#endif /* COM_NormalNODE_H */ diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h index 57a7a0229ec..666f2da775e 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.h +++ b/source/blender/compositor/nodes/COM_TransformNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TransformNode_h_ -#define _COM_TransformNode_h_ +#ifndef __COM_TRANSFORMNODE_H__ +#define __COM_TRANSFORMNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -36,4 +36,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_TransformNode_h_ +#endif /* __COM_TRANSFORMNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index 6bb873e0dec..a515bfc7f47 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -24,6 +24,7 @@ #include "COM_ExecutionSystem.h" #include "COM_CalculateMeanOperation.h" #include "COM_CalculateStandardDeviationOperation.h" +#include "COM_SetValueOperation.h" ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode) { @@ -64,5 +65,18 @@ void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorConte graph->addOperation(operation); } } + else { + SetValueOperation *meanOutput = new SetValueOperation(); + SetValueOperation *stdDevOutput = new SetValueOperation(); + + meanOutput->setValue(0.0f); + stdDevOutput->setValue(0.0f); + + this->getOutputSocket(0)->relinkConnections(meanOutput->getOutputSocket()); + this->getOutputSocket(1)->relinkConnections(stdDevOutput->getOutputSocket()); + + graph->addOperation(meanOutput); + graph->addOperation(stdDevOutput); + } } diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index 88289f12ebb..f6b23f6afd2 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -64,8 +64,8 @@ void ConvertDepthToRadiusOperation::initExecution() this->m_inverseFocalDistance = 1.0f / focalDistance; this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop; - float minsz = min(getWidth(), getHeight()); - this->m_dof_sp = (float)minsz / ((cam_sensor / 2.0f) / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); + const float minsz = min(getWidth(), getHeight()); + this->m_dof_sp = minsz / ((cam_sensor / 2.0f) / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); if (this->m_blurPostOperation) { m_blurPostOperation->setSigma(min(m_aperture * 128.0f, this->m_maxRadius)); diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 2b2928c98db..262252f7d8c 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -128,8 +128,8 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign // XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels, // so just skiping blur along faulty direction if src's def is below that limit! - if (src_width < 3) xy &= ~(int) 1; - if (src_height < 3) xy &= ~(int) 2; + if (src_width < 3) xy &= ~1; + if (src_height < 3) xy &= ~2; if (xy < 1) return; // see "Recursive Gabor Filtering" by Young/VanVliet diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index ace04237b29..c4f8b3a0ddb 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -79,9 +79,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No sc = 2.13; isc = -0.97; for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { - v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + v = ((float)y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { - u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + u = ((float)x + 0.5f) / (float)gbuf->getWidth(); s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f; tbuf1->readCubic(c, s * gbuf->getWidth(), t * gbuf->getHeight()); sm = smoothMask(s, t); @@ -100,9 +100,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); for (n = 1; n < settings->iter && (!breaked); n++) { for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { - v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + v = ((float)y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { - u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + u = ((float)x + 0.5f) / (float)gbuf->getWidth(); tc[0] = tc[1] = tc[2] = 0.f; for (p = 0; p < 4; p++) { np = (n << 2) + p; diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp index 9125783c222..60d37fb8145 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -81,11 +81,9 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, float *sourcebuffer = tsrc->getBuffer(); float factor = 1.f / (float)(6 - settings->iter); - for (int i = 0; i < size4; i++) { - data[i] += sourcebuffer[i] * factor; - } - for (int i = 0; i < size; i++) { - data[i * 4 + 3] = 1.0f; + for (int i = 0; i < size4; i += 4) { + madd_v3_v3fl(&data[i], &sourcebuffer[i], factor); + data[i + 3] = 1.0f; } tdst->clear(); diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 36b3f2023ae..ba1059c4eb5 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -73,7 +73,7 @@ void MaskOperation::initExecution() for (masklay = (MaskLayer *)mask_temp->masklayers.first; masklay; - masklay = (MaskLayer *)masklay->next) + masklay = masklay->next) { masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_frame_number); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index b492d06a697..febfa9662c6 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -45,7 +45,7 @@ protected: */ MathBaseOperation(); - void clampIfNeeded(float *color); + void clampIfNeeded(float color[4]); public: /** * the inner loop of this program diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h index 4b466d193d6..88d1d00c2bf 100644 --- a/source/blender/compositor/operations/COM_MixBaseOperation.h +++ b/source/blender/compositor/operations/COM_MixBaseOperation.h @@ -40,7 +40,7 @@ protected: bool m_valueAlphaMultiply; bool m_useClamp; - inline void clampIfNeeded(float *color) + inline void clampIfNeeded(float color[4]) { if (m_useClamp) { CLAMP(color[0], 0.0f, 1.0f); diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index f3eeb2f48ba..93cc555fdbc 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -115,10 +115,10 @@ public: if (!this->m_bufferCalculated[offset]) { //float overscan = 0.0f; - float w = (float)this->m_width /* / (1 + overscan) */; - float h = (float)this->m_height /* / (1 + overscan) */; - float aspx = (float)w / this->m_calibration_width; - float aspy = (float)h / this->m_calibration_height; + const float w = (float)this->m_width /* / (1 + overscan) */; + const float h = (float)this->m_height /* / (1 + overscan) */; + const float aspx = w / (float)this->m_calibration_width; + const float aspy = h / (float)this->m_calibration_height; float in[2]; float out[2]; diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index 193ab669f40..fd9cc1fddcb 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -98,7 +98,7 @@ void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, const float sd = 1.0f / (float)ds; for (z = 0; z < ds; ++z) { - const float tz = ((float)z + (jit ? BLI_frand() : 0.5f)) * sd; + const float tz = (z + (jit ? BLI_frand() : 0.5f)) * sd; t = 1.0f - (this->m_kr4 + tz * this->m_drg) * uv_dot; d = 1.0f / (1.0f + sqrtf(t)); const float nx = (u * d + 0.5f) * width - 0.5f; @@ -116,7 +116,7 @@ void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, const float sd = 1.0f / (float)ds; for (z = 0; z < ds; ++z) { - const float tz = ((float)z + (jit ? BLI_frand() : 0.5f)) * sd; + const float tz = (z + (jit ? BLI_frand() : 0.5f)) * sd; t = 1.0f - (this->m_kg4 + tz * this->m_dgb) * uv_dot; d = 1.0f / (1.0f + sqrtf(t)); const float nx = (u * d + 0.5f) * width - 0.5f; diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 7ccc91072bc..b8e15934c30 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -192,7 +192,7 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device, cl_int maxBlur; cl_float threshold = this->m_threshold; - MemoryBuffer *sizeMemoryBuffer = (MemoryBuffer *)this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); + MemoryBuffer *sizeMemoryBuffer = this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); const float max_dim = max(m_width, m_height); cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f; diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index d9ca131721f..55a001530ee 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -107,7 +107,7 @@ void ViewerBaseOperation:: updateImage(rcti *rect) { IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0, this->m_viewSettings, this->m_displaySettings, - rect->xmin, rect->ymin, rect->xmax, rect->ymax); + rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE); WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); } diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index eb7bc68ff8f..9b88c307cb6 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -994,6 +994,27 @@ static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id) return 1; } +/* Check if F-Curve has errors and/or is disabled + * > returns: (bool) True if F-Curve has errors/is disabled + */ +static short fcurve_has_errors(FCurve *fcu) +{ + /* F-Curve disabled - path eval error */ + if (fcu->flag & FCURVE_DISABLED) { + return 1; + } + + /* driver? */ + if (fcu->driver) { + /* for now, just check if the entire thing got disabled... */ + if (fcu->driver->flag & DRIVER_FLAG_INVALID) + return 1; + } + + /* no errors found */ + return 0; +} + /* find the next F-Curve that is usable for inclusion */ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id) { @@ -1032,6 +1053,13 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro continue; } + /* error-based filtering... */ + if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) { + /* skip if no errors... */ + if (fcurve_has_errors(fcu) == 0) + continue; + } + /* this F-Curve can be used, so return it */ return fcu; } diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index bc07bf091de..54c7f7ea30f 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -82,4 +82,4 @@ void ANIM_OT_driver_button_remove(struct wmOperatorType *ot); void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); -#endif // __ANIM_INTERN_H__ +#endif /* __ANIM_INTERN_H__ */ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index f2711ec3bb5..ca036a8540e 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -172,7 +172,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot) ot->poll = change_frame_poll; /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO; + ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_POINTER; /* rna */ RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 672e11ac613..38f9119104b 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -147,7 +147,7 @@ short ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int ar RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -310,7 +310,7 @@ short ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int a RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not find Driver to copy, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -357,14 +357,14 @@ short ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not paste Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } /* if the buffer is empty, cannot paste... */ if (channeldriver_copypaste_buf == NULL) { - BKE_report(reports, RPT_ERROR, "Paste Driver: No Driver to paste"); + BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste"); return 0; } diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 30e4d8570cb..a591b51b0b3 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -111,6 +111,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s uiBlock *block; uiBut *but; PointerRNA ptr; + short bwidth = width - 30; /* max button width */ /* init the RNA-pointer */ RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr); @@ -119,10 +120,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s /* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */ block = uiLayoutGetBlock(layout); uiBlockBeginAlign(block); - but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); + but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); - - uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); + + uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); uiBlockEndAlign(block); /* now add settings for individual modes */ @@ -132,50 +133,62 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s float *cp = NULL; char xval[32]; unsigned int i; + int maxXWidth; /* draw polynomial order selector */ row = uiLayoutRow(layout, FALSE); block = uiLayoutGetBlock(row); - but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, width - 30, 19, + but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, bwidth, 20, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + /* calculate maximum width of label for "x^n" labels */ + if (data->arraysize > 2) { + BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize); + maxXWidth = UI_GetStringWidth(xval) + 10; /* XXX: UI_GetStringWidth is not accurate */ + } + else { + /* basic size (just "x") */ + maxXWidth = 15; + } + /* draw controls for each coefficient and a + sign at end of row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); cp = data->coefficients; for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { - /* To align with first line */ + /* To align with first line... */ if (i) - uiDefBut(block, LABEL, 1, " ", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, " ", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); else - uiDefBut(block, LABEL, 1, "y =", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "y =", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* coefficient */ - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 150, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth/2, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient for polynomial")); /* 'x' param (and '+' if necessary) */ if (i == 0) - strcpy(xval, ""); + BLI_strncpy(xval, "", sizeof(xval)); else if (i == 1) - strcpy(xval, "x"); + BLI_strncpy(xval, "x", sizeof(xval)); else - sprintf(xval, "x^%u", i); - uiDefBut(block, LABEL, 1, xval, 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); + BLI_snprintf(xval, sizeof(xval), "x^%u", i); + uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) { - uiDefBut(block, LABEL, 1, "+", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "+", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, ""); /* next coefficient on a new row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); } else { - /* For alignement in UI! */ - uiDefBut(block, LABEL, 1, " ", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* For alignment in UI! */ + uiDefBut(block, LABEL, 1, " ", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, ""); } } break; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 0454e88e320..f0c5f063e57 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -43,6 +43,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" @@ -787,14 +789,15 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p /* F-Curve not editable? */ if (fcurve_is_keyframable(fcu) == 0) { BKE_reportf(reports, RPT_ERROR, - "F-Curve with path = '%s' [%d] cannot be keyframed. Ensure that it is not locked or sampled. Also, try removing F-Modifiers", + "F-Curve with path = '%s' [%d] cannot be keyframed, ensure that it is not locked or sampled, " + "and try removing F-Modifiers", fcu->rna_path, fcu->array_index); return 0; } /* if no property given yet, try to validate from F-Curve info */ if ((ptr.id.data == NULL) && (ptr.data == NULL)) { - BKE_report(reports, RPT_ERROR, "No RNA-pointer available to retrieve values for keyframing from"); + BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from"); return 0; } if (prop == NULL) { @@ -803,10 +806,10 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p /* try to get property we should be affecting */ if ((RNA_path_resolve(&ptr, fcu->rna_path, &tmp_ptr, &prop) == 0) || (prop == NULL)) { /* property not found... */ - const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : "<No ID-Pointer>"; + const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>"); BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", idname, fcu->rna_path); return 0; } @@ -906,15 +909,15 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* validate pointer first - exit if failure */ if (id == NULL) { - BKE_reportf(reports, RPT_ERROR, "No ID-block to insert keyframe in (Path = %s)", rna_path); + BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path); return 0; } RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", - (id) ? id->name : "<Missing ID-Block>", rna_path); + "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + (id) ? id->name : TIP_("<Missing ID block>"), rna_path); return 0; } @@ -927,7 +930,7 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou if (act == NULL) { BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as this type does not support animation data (ID = %s, Path = %s)", + "Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -997,14 +1000,16 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* sanity checks */ if (ELEM(NULL, id, adt)) { - BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from"); + BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from"); return 0; } /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - BKE_reportf(reports, RPT_ERROR, "Could not delete keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path); + BKE_reportf(reports, RPT_ERROR, + "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + id->name, rna_path); return 0; } @@ -1023,7 +1028,7 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } else { - BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name); + BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name); return 0; } } @@ -1096,14 +1101,16 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha /* sanity checks */ if (ELEM(NULL, id, adt)) { - BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from"); + BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from"); return 0; } /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - BKE_reportf(reports, RPT_ERROR, "Could not clear keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path); + BKE_reportf(reports, RPT_ERROR, + "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + id->name, rna_path); return 0; } @@ -1119,7 +1126,7 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha act = adt->action; } else { - BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name); + BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name); return 0; } } @@ -1222,30 +1229,30 @@ static int insert_key_exec(bContext *C, wmOperator *op) /* report failures */ if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No active keying set"); return OPERATOR_CANCELLED; } /* try to insert keyframes for the channels specified by KeyingSet */ success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); if (G.debug & G_DEBUG) - BKE_reportf(op->reports, RPT_INFO, "KeyingSet '%s' - Successfully added %d Keyframes\n", ks->name, success); + BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes\n", ks->name, success); /* report failure or do updates? */ if (success == MODIFYKEY_INVALID_CONTEXT) { - BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set"); return OPERATOR_CANCELLED; } else if (success) { /* if the appropriate properties have been set, make a note that we've inserted something */ if (RNA_boolean_get(op->ptr, "confirm_success")) - BKE_reportf(op->reports, RPT_INFO, "Successfully added %d Keyframes for KeyingSet '%s'", success, ks->name); + BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes"); + BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes"); /* send updates */ DAG_ids_flush_update(bmain, 0); @@ -1389,19 +1396,19 @@ static int delete_key_exec(bContext *C, wmOperator *op) /* report failure or do updates? */ if (success == MODIFYKEY_INVALID_CONTEXT) { - BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set"); return OPERATOR_CANCELLED; } else if (success) { /* if the appropriate properties have been set, make a note that we've inserted something */ if (RNA_boolean_get(op->ptr, "confirm_success")) - BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d Keyframes for KeyingSet '%s'", success, ks->name); + BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes"); + BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes"); /* send updates */ DAG_ids_flush_update(bmain, 0); @@ -1626,7 +1633,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) else { if (G.debug & G_DEBUG) printf("Button Insert-Key: no path to property\n"); - BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property. Try using a Keying Set instead"); + BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property, try using a keying set instead"); } } else if (G.debug & G_DEBUG) { diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 04fd7f677b0..5844bd6708f 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -161,11 +161,11 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot remove built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set"); return OPERATOR_CANCELLED; } else @@ -209,7 +209,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to"); return OPERATOR_CANCELLED; } else @@ -258,12 +258,12 @@ static int remove_active_ks_path_exec(bContext *C, wmOperator *op) ks->active_path--; } else { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove"); + BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove"); return OPERATOR_CANCELLED; } } else { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from"); return OPERATOR_CANCELLED; } @@ -322,7 +322,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op) scene->active_keyingset = BLI_countlist(&scene->keyingsets); } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set"); return OPERATOR_CANCELLED; } else @@ -404,11 +404,11 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set"); return OPERATOR_CANCELLED; } else @@ -947,7 +947,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe /* skip path if no ID pointer is specified */ if (ksp->id == NULL) { BKE_reportf(reports, RPT_WARNING, - "Skipping path in Keying Set, as it has no ID (KS = '%s', Path = '%s'[%d])", + "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s'[%d])", ks->name, ksp->rna_path, ksp->array_index); continue; } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 707594ff590..8a75d07a678 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -654,17 +654,19 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) if (ob->type != OB_ARMATURE) return OPERATOR_CANCELLED; if (BKE_object_obdata_is_libdata(ob)) { - BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); //error_libdata(); + BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); /* error_libdata(); */ return OPERATOR_CANCELLED; } /* helpful warnings... */ /* TODO: add warnings to be careful about actions, applying deforms first, etc. */ if (ob->adt && ob->adt->action) - BKE_report(op->reports, RPT_WARNING, "Actions on this armature will be destroyed by this new rest pose as the transforms stored are relative to the old rest pose"); + BKE_report(op->reports, RPT_WARNING, + "Actions on this armature will be destroyed by this new rest pose as the " + "transforms stored are relative to the old rest pose"); /* Get editbones of active armature to alter */ - ED_armature_to_edit(ob); + ED_armature_to_edit(ob); /* get pose of active object and move it out of posemode */ pose = ob->pose; @@ -1591,7 +1593,8 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot) /* does bones and points */ /* note that BONE ROOT only gets drawn for root bones (or without IK) */ -static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], ListBase *edbo, int findunsel, int *selmask) +static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], + ListBase *edbo, int findunsel, int *selmask) { EditBone *ebone; rcti rect; @@ -2096,7 +2099,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) } sub_v3_v3v3(nor, ebone->tail, ebone->head); - vec_roll_to_mat3(nor, ebone->roll, mat); + vec_roll_to_mat3(nor, ebone->roll, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ @@ -2556,7 +2559,8 @@ void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob } -EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob) +EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, + Object *src_ob, Object *dst_ob) { EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone"); @@ -2965,7 +2969,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) } } else { - // FIXME.. figure out a method for multiple bones + /* FIXME.. figure out a method for multiple bones */ BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d\n", count); BLI_freelistN(&points); return OPERATOR_CANCELLED; @@ -3036,7 +3040,8 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone newbone->parent = start->parent; /* TODO, copy more things to the new bone */ - newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE); + newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | + BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE); /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge * - potentially several tips for side chains leading to some tree exist... @@ -3357,12 +3362,17 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) if (EBONE_VISIBLE(arm, ebone)) { /* we extrude per definition the tip */ do_extrude = FALSE; - if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) + if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) { do_extrude = TRUE; + } else if (ebone->flag & BONE_ROOTSEL) { /* but, a bone with parent deselected we do the root... */ - if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) ; - else do_extrude = 2; + if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) { + /* pass */ + } + else { + do_extrude = 2; + } } if (do_extrude) { @@ -3813,7 +3823,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) /* there must be an active bone */ if (actbone == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } else if (arm->flag & ARM_MIRROR_EDIT) { @@ -4207,7 +4217,7 @@ static int armature_select_similar_exec(bContext *C, wmOperator *op) /* Check for active bone */ if (ebone_act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } @@ -4399,7 +4409,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) /* there must be an active bone */ if (actbone == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } else if (arm->flag & ARM_MIRROR_EDIT) { @@ -4476,7 +4486,8 @@ void ARMATURE_OT_align(wmOperatorType *ot) /* ***************** Pose tools ********************* */ -// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer +/* XXX bone_looper is only to be used when we want to access settings + * (i.e. editability/visibility/selected) that context doesn't offer */ static int bone_looper(Object *ob, Bone *bone, void *data, int (*bone_func)(Object *, Bone *, void *)) { @@ -4506,7 +4517,8 @@ static int bone_looper(Object *ob, Bone *bone, void *data, /* called from editview.c, for mode-less pose selection */ /* assumes scene obact and basact is still on old situation */ -int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend, short deselect, short toggle) +int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, + short extend, short deselect, short toggle) { Object *ob = base->object; Bone *nearBone; @@ -4752,7 +4764,9 @@ static void add_vgroups__mapFunc(void *userData, int index, const float co[3], copy_v3_v3(verts[index], co); } -static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, float scale) +static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, + bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, + float (*root)[3], float (*tip)[3], int *selected, float scale) { /* Create vertex group weights from envelopes */ @@ -5138,7 +5152,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index fad06f0d020..196d03020e7 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -1962,7 +1962,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, ReebArcIterator arc_iter; BArcIterator *iter = (BArcIterator *)&arc_iter; RigEdge *edge; - EmbedBucket *bucket = NULL; ReebNode *node_start, *node_end; ReebArc *earc = iarc->link_mesh; float angle_weight = 1.0; // GET FROM CONTEXT @@ -1996,8 +1995,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, /* equal number of joints and potential position, just fill them in */ if (nb_joints == earc->bcount) { - int i; - /* init with first values */ for (i = 0; i < nb_joints; i++) { best_positions[i] = i + 1; @@ -2011,7 +2008,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, MemoNode *result; #endif float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache"); - int i; positions_cache[0] = node_start->p; positions_cache[nb_positions + 1] = node_end->p; @@ -2053,7 +2049,7 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, { float *no = NULL; if (i < nb_joints) { - bucket = IT_peek(iter, best_positions[i]); + EmbedBucket *bucket = IT_peek(iter, best_positions[i]); vec1 = bucket->p; no = bucket->no; } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 5ba4a232250..68d8a8d721e 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -646,7 +646,7 @@ static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], in short pval[2]; int pdist; - if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -682,7 +682,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { copy_v3_v3(vec, bone->head); mul_m4_v3(ob->obmat, vec); - if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -699,7 +699,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, copy_v3_v3(vec, bone->tail); mul_m4_v3(ob->obmat, vec); - if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -939,7 +939,7 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr initgrabz(ar->regiondata, fp[0], fp[1], fp[2]); /* method taken from editview.c - mouse_cursor() */ - if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { VECSUB2D(mval_f, cval, dd->mval); ED_view3d_win_to_delta(ar, mval_f, dvec); sub_v3_v3v3(vec, fp, dvec); @@ -1793,8 +1793,8 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc short start_val[2], end_val[2]; short dist; - if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 522622ec5c4..82fef00b1e6 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1221,7 +1221,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r else normal_quad_v3(no, face[0], face[1], face[2], face[3]); - dist = len_v3v3(ray->origin, co)/len_v3(isec->vec); + dist = len_v3v3(ray->origin, co) / len_v3(isec->vec); if (dist < hit->dist) { hit->index = index; hit->dist = dist; @@ -1254,8 +1254,10 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float hit.index = -1; hit.dist = FLT_MAX; - if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) { - len= isect_mdef.labda; + if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, + 0.0, &hit, harmonic_ray_callback, data) != -1) + { + len = isect_mdef.labda; isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index cdcb3ab4683..31398948b82 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -631,6 +631,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt) switch (evt->type) { case LEFTMOUSE: /* confirm */ + case RETKEY: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index eea7424c59a..a05a98c58ca 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -298,7 +298,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op) /* validate action */ if (act == NULL) { - BKE_report(op->reports, RPT_WARNING, "No Action to validate"); + BKE_report(op->reports, RPT_WARNING, "No action to validate"); return OPERATOR_CANCELLED; } @@ -547,7 +547,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } @@ -562,7 +562,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, marker_index); if (marker == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Invalid Pose specified %d", marker_index); + BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index); return OPERATOR_CANCELLED; } @@ -628,14 +628,14 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, act->active_marker - 1); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_report(op->reports, RPT_ERROR, "Invalid index for pose"); return OPERATOR_CANCELLED; } else { @@ -657,14 +657,14 @@ static int poselib_rename_exec(bContext *C, wmOperator *op) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose")); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_report(op->reports, RPT_ERROR, "Invalid index for pose"); return OPERATOR_CANCELLED; } @@ -1424,12 +1424,12 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op) /* check if valid poselib */ if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) { - BKE_report(op->reports, RPT_ERROR, "PoseLib is only for Armatures in PoseMode"); + BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode"); pld->state = PL_PREVIEW_ERROR; return; } if (pld->act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have a valid PoseLib"); + BKE_report(op->reports, RPT_ERROR, "Object does not have a valid pose lib"); pld->state = PL_PREVIEW_ERROR; return; } @@ -1438,10 +1438,10 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op) /* just use first one then... */ pld->marker = pld->act->markers.first; if (pose_index > -2) - BKE_report(op->reports, RPT_WARNING, "PoseLib had no active pose"); + BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose"); } else { - BKE_report(op->reports, RPT_ERROR, "PoseLib has no poses to preview/apply"); + BKE_report(op->reports, RPT_ERROR, "Pose lib has no poses to preview/apply"); pld->state = PL_PREVIEW_ERROR; return; } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 189b2e977c2..99de90bc9fa 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -105,7 +105,7 @@ void ED_armature_enter_posemode(bContext *C, Base *base) Object *ob = base->object; if (ob->id.lib) { - BKE_report(reports, RPT_WARNING, "Can't pose libdata"); + BKE_report(reports, RPT_WARNING, "Cannot pose libdata"); return; } @@ -1236,7 +1236,7 @@ static int pose_copy_exec(bContext *C, wmOperator *op) /* sanity checking */ if (ELEM(NULL, ob, ob->pose)) { - BKE_report(op->reports, RPT_ERROR, "No Pose to Copy"); + BKE_report(op->reports, RPT_ERROR, "No pose to copy"); return OPERATOR_CANCELLED; } @@ -1399,7 +1399,7 @@ void POSE_OT_group_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove Bone Group"; ot->idname = "POSE_OT_group_remove"; - ot->description = "Removes the active bone group"; + ot->description = "Remove the active bone group"; /* api callbacks */ ot->exec = pose_group_remove_exec; @@ -1511,7 +1511,7 @@ void POSE_OT_group_assign(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_int(ot->srna, "type", 0, 0, 10, "Bone Group Index", "", 0, INT_MAX); + RNA_def_int(ot->srna, "type", 0, 0, INT_MAX, "Bone Group Index", "", 0, 10); } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index afd6bc4c4b5..874b31dd1ca 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1579,8 +1579,9 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag) BPoint *bp, *bpn, *newbp; int a, b, newu, newv, sel; - if (obedit->type == OB_SURF) ; - else return OPERATOR_CANCELLED; + if (obedit->type != OB_SURF) { + return OPERATOR_CANCELLED; + } cu->lastsel = NULL; @@ -1593,8 +1594,12 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag) a = nu->pntsu * nu->pntsv; while (a) { a--; - if (bp->f1 & flag) ; - else break; + if (bp->f1 & flag) { + /* pass */ + } + else { + break; + } bp++; } if (a == 0) { @@ -1715,8 +1720,12 @@ static short extrudeflagNurb(EditNurb *editnurb, int flag) bp = nu->bp; a = nu->pntsu; while (a) { - if (bp->f1 & flag) ; - else break; + if (bp->f1 & flag) { + /* pass */ + } + else { + break; + } bp++; a--; } @@ -3217,12 +3226,12 @@ void CURVE_OT_subdivide(wmOperatorType *ot) /******************** find nearest ************************/ -static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { - struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } *data = userData; + struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } *data = userData; short flag; - short temp; + float dist_test; if (bp) { flag = bp->f1; @@ -3239,12 +3248,12 @@ static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, } } - temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); - if ((flag & 1) == data->select) temp += 5; - if (bezt && beztindex == 1) temp += 3; /* middle points get a small disadvantage */ + dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); + if ((flag & SELECT) == data->select) dist_test += 5.0f; + if (bezt && beztindex == 1) dist_test += 3.0f; /* middle points get a small disadvantage */ - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->bp = bp; data->bezt = bezt; @@ -3258,16 +3267,16 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2], /* (sel == 1): selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ /* return 0 1 2: handlepunt */ - struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } data = {NULL}; + struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } data = {NULL}; data.dist = 100; data.hpoint = 0; data.select = sel; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data); + nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); *nurb = data.nurb; *bezt = data.bezt; @@ -3762,20 +3771,28 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu /* first nurbs: u = resolu-1 selected */ - if (is_u_selected(nu1, nu1->pntsu - 1) ) ; + if (is_u_selected(nu1, nu1->pntsu - 1) ) { + /* pass */ + } else { /* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */ /* but after rotating (orderu = 0) will be confusing. */ if (nu1->orderv == 0) nu1->orderv = 1; rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { /* rotate again, now its OK! */ if (nu1->pntsv != 1) rotate_direction_nurb(nu1); @@ -3786,17 +3803,25 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu } /* 2nd nurbs: u = 0 selected */ - if (is_u_selected(nu2, 0) ) ; + if (is_u_selected(nu2, 0) ) { + /* pass */ + } else { if (nu2->orderv == 0) nu2->orderv = 1; rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { /* rotate again, now its OK! */ if (nu1->pntsu == 1) rotate_direction_nurb(nu1); @@ -3892,15 +3917,27 @@ static int merge_nurb(bContext *C, wmOperator *op) /* resolution match, to avoid uv rotations */ if (nus1->nu->pntsv == 1) { - if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) ; - else ok = 0; + if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) { + /* pass */ + } + else { + ok = 0; + } } else if (nus2->nu->pntsv == 1) { - if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) ; - else ok = 0; + if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) { + /* pass */ + } + else { + ok = 0; + } + } + else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) { + /* pass */ + } + else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) { + /* pass */ } - else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) ; - else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) ; else { ok = 0; } @@ -3949,8 +3986,12 @@ static int make_segment_exec(bContext *C, wmOperator *op) if (isNurbsel_count(cu, nu) == 1) { /* only 1 selected, not first or last, a little complex, but intuitive */ if (nu->pntsv == 1) { - if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) ; - else break; + if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) { + /* pass */ + } + else { + break; + } } } } @@ -4380,7 +4421,7 @@ void CURVE_OT_spin(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } /***************** add vertex operator **********************/ @@ -5611,7 +5652,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); } /********************** add duplicate operator *********************/ @@ -5684,8 +5725,12 @@ static int delete_exec(bContext *C, wmOperator *op) a = nu->pntsu; if (a) { while (a) { - if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) ; - else break; + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + /* pass */ + } + else { + break; + } a--; bezt++; } @@ -5704,8 +5749,12 @@ static int delete_exec(bContext *C, wmOperator *op) a = nu->pntsu * nu->pntsv; if (a) { while (a) { - if (bp->f1 & SELECT) ; - else break; + if (bp->f1 & SELECT) { + /* pass */ + } + else { + break; + } a--; bp++; } @@ -6437,12 +6486,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type vec[0] = vec[1] = 0.0; vec[2] = -grid; - if (newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) { - /* pass */ - } - else { - mul_mat3_m4_v3(mat, vec); - } + mul_mat3_m4_v3(mat, vec); translateflagNurb(editnurb, 1, vec); extrudeflagNurb(cu->editnurb, 1); @@ -6603,7 +6647,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) if (newob && enter_editmode) ED_undo_push(C, "Enter Editmode"); - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, TRUE); nu = add_nurbs_primitive(C, obedit, mat, type, newob); editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index b11d640256c..b379ce6e5cf 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -441,8 +441,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float obedit = BKE_object_add(scene, OB_FONT); base = scene->basact; - - ED_object_base_init_transform(C, base, NULL, rot); /* seems to assume view align ? TODO - look into this, could be an operator option */ + /* seems to assume view align ? TODO - look into this, could be an operator option */ + ED_object_base_init_transform(C, base, NULL, rot); + BKE_object_where_is_calc(scene, obedit); obedit->loc[0] += offset[0]; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 5ff4ccbd126..3b26c46a410 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -149,7 +149,8 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn /* ----- Existing Strokes Drawing (3D and Point) ------ */ /* draw a given stroke - just a single dot (only one point) */ -static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, int offsx, int offsy, int winx, int winy) +static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, + int offsx, int offsy, int winx, int winy) { /* draw point */ if (sflag & GP_STROKE_3DSPACE) { @@ -508,7 +509,8 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int glDepthMask(0); glEnable(GL_DEPTH_TEST); - /* first arg is normally rv3d->dist, but this isn't available here and seems to work quite well without */ + /* first arg is normally rv3d->dist, but this isn't + * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); @@ -579,7 +581,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, /* draw 'onionskins' (frame left + right) */ if (gpl->flag & GP_LAYER_ONIONSKIN) { - /* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/ + /* drawing method - only immediately surrounding (gstep = 0), + * or within a frame range on either side (gstep > 0)*/ if (gpl->gstep) { bGPDframe *gf; float fac; @@ -640,7 +643,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) && (gpf->flag & GP_FRAME_PAINT)) { - /* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */ + /* Buffer stroke needs to be drawn with a different linestyle + * to help differentiate them from normal strokes. */ gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); } } @@ -724,8 +728,8 @@ void draw_gpencil_2dimage(const bContext *C) } /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes - */ + * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, + * second time with onlyv2d=0 for screen-aligned strokes */ void draw_gpencil_view2d(const bContext *C, short onlyv2d) { ScrArea *sa = CTX_wm_area(C); @@ -750,9 +754,8 @@ void draw_gpencil_view2d(const bContext *C, short onlyv2d) } /* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, second time with only3d=0 for screen-aligned strokes - */ - + * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, + * second time with only3d=0 for screen-aligned strokes */ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d) { bGPdata *gpd; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index de7c2c41a6d..e5afbdba50b 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -279,7 +279,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] /* method taken from editview.c - mouse_cursor() */ /* TODO, use ED_view3d_project_float_global */ - if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { VECSUB2D(mval_f, mval_prj, mval); ED_view3d_win_to_delta(p->ar, mval_f, dvec); sub_v3_v3v3(out, rvec, dvec); @@ -395,8 +395,10 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure) pts = &gps->points[gps->totpoints - 1]; - /* special case for poly lines: normally, depth is needed only when creating new stroke from buffer, - * but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates + /* special case for poly lines: normally, + * depth is needed only when creating new stroke from buffer, + * but poly lines are converting to stroke instantly, + * so initialize depth buffer before converting coordinates */ if (gpencil_project_check(p)) { View3D *v3d = p->sa->spacedata.first; @@ -785,13 +787,49 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv int rad, int x0, int y0, int x1, int y1) { /* simple within-radius check for now */ - if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1)) - return 1; + const float mval_fl[2] = {mval[0], mval[1]}; + const float screen_co_a[2] = {x0, y0}; + const float screen_co_b[2] = {x1, y1}; + + if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) { + return TRUE; + } /* not inside */ - return 0; + return FALSE; } +static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt, + int *r_x, int *r_y) +{ + int xyval[2]; + + if (gps->flag & GP_STROKE_3DSPACE) { + if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + *r_x = xyval[0]; + *r_y = xyval[1]; + } + else { + *r_x = V2D_IS_CLIPPED; + *r_y = V2D_IS_CLIPPED; + } + } + else if (gps->flag & GP_STROKE_2DSPACE) { + UI_view2d_view_to_region(v2d, pt->x, pt->y, r_x, r_y); + } + else { + if (subrect == NULL) { /* normal 3D view */ + *r_x = (int)(pt->x / 100 * ar->winx); + *r_y = (int)(pt->y / 100 * ar->winy); + } + else { /* camera view, use subrect */ + *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin; + *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin; + } + } +} + + /* eraser tool - evaluation per stroke */ // TODO: this could really do with some optimization (KD-Tree/BVH?) static void gp_stroke_eraser_dostroke(tGPsdata *p, @@ -800,7 +838,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, { bGPDspoint *pt1, *pt2; int x0 = 0, y0 = 0, x1 = 0, y1 = 0; - int xyval[2]; int i; if (gps->totpoints == 0) { @@ -810,33 +847,11 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, BLI_freelinkN(&gpf->strokes, gps); } else if (gps->totpoints == 1) { - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(p->ar, &gps->points->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x0 = xyval[0]; - y0 = xyval[1]; - } - else { - x0 = V2D_IS_CLIPPED; - y0 = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0); - } - else { - if (p->subrect == NULL) { /* normal 3D view */ - x0 = (int)(gps->points->x / 100 * p->ar->winx); - y0 = (int)(gps->points->y / 100 * p->ar->winy); - } - else { /* camera view, use subrect */ - x0 = (int)((gps->points->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y0 = (int)((gps->points->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - } - } + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0); /* do boundbox check first */ - if (BLI_rcti_isect_pt(rect, x0, y0)) { + + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { /* only check if point is inside */ if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) { /* free stroke */ @@ -853,48 +868,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* get points to work with */ pt1 = gps->points + i; pt2 = gps->points + i + 1; - - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(p->ar, &pt1->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x0 = xyval[0]; - y0 = xyval[1]; - } - else { - x0 = V2D_IS_CLIPPED; - y0 = V2D_IS_CLIPPED; - } - if (ED_view3d_project_int_global(p->ar, &pt2->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x1 = xyval[0]; - y1 = xyval[1]; - } - else { - x1 = V2D_IS_CLIPPED; - y1 = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0); - - UI_view2d_view_to_region(p->v2d, pt2->x, pt2->y, &x1, &y1); - } - else { - if (p->subrect == NULL) { /* normal 3D view */ - x0 = (int)(pt1->x / 100 * p->ar->winx); - y0 = (int)(pt1->y / 100 * p->ar->winy); - x1 = (int)(pt2->x / 100 * p->ar->winx); - y1 = (int)(pt2->y / 100 * p->ar->winy); - } - else { /* camera view, use subrect */ - x0 = (int)((pt1->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y0 = (int)((pt1->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - x1 = (int)((pt2->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y1 = (int)((pt2->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - } - } - + + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0); + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1); + /* check that point segment of the boundbox of the eraser stroke */ - if (BLI_rcti_isect_pt(rect, x0, y0) || BLI_rcti_isect_pt(rect, x1, y1)) { + if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || + ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) { /* check if point segment of stroke had anything to do with * eraser region (either within stroke painted, or on its lines) * - this assumes that linewidth is irrelevant @@ -1423,13 +1403,17 @@ static void gpencil_draw_status_indicators(tGPsdata *p) /* print status info */ switch (p->paintmode) { case GP_PAINTMODE_ERASER: - ED_area_headerprint(p->sa, "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase | ESC/Enter to end"); + ED_area_headerprint(p->sa, + "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase |" + " ESC/Enter to end"); break; case GP_PAINTMODE_DRAW_STRAIGHT: - ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | ESC/Enter to end"); + ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | " + "ESC/Enter to end"); break; case GP_PAINTMODE_DRAW: - ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | ESC/Enter to end"); + ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | " + "ESC/Enter to end"); break; default: /* unhandled future cases */ @@ -1705,7 +1689,8 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) //printf("\t\tGP - start stroke\n"); /* we may need to set up paint env again if we're resuming */ - /* XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions */ + /* XXX: watch it with the paintmode! in future, + * it'd be nice to allow changing paint-mode when in sketching-sessions */ /* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */ if (gp_session_initdata(C, p)) @@ -1889,7 +1874,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH: /* event doesn't need to be handled */ - //printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#if 0 + printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", + event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#endif break; } @@ -1900,10 +1888,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) /* ------------------------------- */ static EnumPropertyItem prop_gpencil_drawmodes[] = { - {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", ""}, - {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", ""}, - {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", ""}, - {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""}, + {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", "Draw freehand stroke(s)"}, + {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", "Draw straight line segment(s)"}, + {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", "Click to place endpoints of straight line segments (connected)"}, + {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", "Erase Grease Pencil strokes"}, {0, NULL, 0, NULL, NULL} }; @@ -1925,7 +1913,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* settings for drawing */ - RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); + ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index fbddd26c959..fba42a33f88 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -233,29 +233,29 @@ typedef enum eAnimFilter_Flags { /* Dopesheet only */ /* 'Scene' channels */ -#define SEL_SCEC(sce) ((sce->flag & SCE_DS_SELECTED)) -#define EXPANDED_SCEC(sce) ((sce->flag & SCE_DS_COLLAPSED) == 0) +#define SEL_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_SELECTED))) +#define EXPANDED_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_COLLAPSED) == 0)) /* 'Sub-Scene' channels (flags stored in Data block) */ -#define FILTER_WOR_SCED(wo) ((wo->flag & WO_DS_EXPAND)) +#define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World), (wo->flag & WO_DS_EXPAND)) #define FILTER_LS_SCED(linestyle) ((linestyle->flag & LS_DS_EXPAND)) /* 'Object' channels */ -#define SEL_OBJC(base) ((base->flag & SELECT)) -#define EXPANDED_OBJC(ob) ((ob->nlaflag & OB_ADS_COLLAPSED) == 0) +#define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base), ((base->flag & SELECT))) +#define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0)) /* 'Sub-object' channels (flags stored in Data block) */ -#define FILTER_SKE_OBJD(key) ((key->flag & KEY_DS_EXPAND)) -#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND)) -#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND)) -#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND)) -#define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND)) -#define FILTER_PART_OBJD(part) ((part->flag & PART_DS_EXPAND)) -#define FILTER_MBALL_OBJD(mb) ((mb->flag2 & MB_DS_EXPAND)) -#define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND)) -#define FILTER_MESH_OBJD(me) ((me->flag & ME_DS_EXPAND)) -#define FILTER_LATTICE_OBJD(lt) ((lt->flag & LT_DS_EXPAND)) -#define FILTER_SPK_OBJD(spk) ((spk->flag & SPK_DS_EXPAND)) +#define FILTER_SKE_OBJD(key) (CHECK_TYPE_INLINE(key, Key), ((key->flag & KEY_DS_EXPAND))) +#define FILTER_MAT_OBJD(ma) (CHECK_TYPE_INLINE(ma, Material), ((ma->flag & MA_DS_EXPAND))) +#define FILTER_LAM_OBJD(la) (CHECK_TYPE_INLINE(la, Lamp), ((la->flag & LA_DS_EXPAND))) +#define FILTER_CAM_OBJD(ca) (CHECK_TYPE_INLINE(ca, Camera), ((ca->flag & CAM_DS_EXPAND))) +#define FILTER_CUR_OBJD(cu) (CHECK_TYPE_INLINE(cu, Curve), ((cu->flag & CU_DS_EXPAND))) +#define FILTER_PART_OBJD(part) (CHECK_TYPE_INLINE(part, ParticleSettings), ((part->flag & PART_DS_EXPAND))) +#define FILTER_MBALL_OBJD(mb) (CHECK_TYPE_INLINE(mb, MetaBall), ((mb->flag2 & MB_DS_EXPAND))) +#define FILTER_ARM_OBJD(arm) (CHECK_TYPE_INLINE(arm, bArmature), ((arm->flag & ARM_DS_EXPAND))) +#define FILTER_MESH_OBJD(me) (CHECK_TYPE_INLINE(me, Mesh), ((me->flag & ME_DS_EXPAND))) +#define FILTER_LATTICE_OBJD(lt) (CHECK_TYPE_INLINE(lt, Lattice), ((lt->flag & LT_DS_EXPAND))) +#define FILTER_SPK_OBJD(spk) (CHECK_TYPE_INLINE(spk, Speaker), ((spk->flag & SPK_DS_EXPAND))) /* Variable use expanders */ -#define FILTER_NTREE_DATA(ntree) ((ntree->flag & NTREE_DS_EXPAND)) -#define FILTER_TEX_DATA(tex) ((tex->flag & TEX_DS_EXPAND)) +#define FILTER_NTREE_DATA(ntree) (CHECK_TYPE_INLINE(ntree, bNodeTree), ((ntree->flag & NTREE_DS_EXPAND))) +#define FILTER_TEX_DATA(tex) (CHECK_TYPE_INLINE(tex, Tex), ((tex->flag & TEX_DS_EXPAND))) /* 'Sub-object/Action' channels (flags stored in Action) */ #define SEL_ACTC(actc) ((actc->flag & ACT_SELECTED)) diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index b9996c87194..efd10f3cb6b 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -93,9 +93,18 @@ typedef struct EditBone { #define BONESEL_NOSEL (1 << 31) /* Indicates a negative number */ /* useful macros */ -#define EBONE_VISIBLE(arm, ebone) (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) +#define EBONE_VISIBLE(arm, ebone) ( \ + CHECK_TYPE_INLINE(arm, bArmature), \ + CHECK_TYPE_INLINE(ebone, EditBone), \ + (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) \ + ) + #define EBONE_SELECTABLE(arm, ebone) (EBONE_VISIBLE(arm, ebone) && !(ebone->flag & BONE_UNSELECTABLE)) -#define EBONE_EDITABLE(ebone) (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) + +#define EBONE_EDITABLE(ebone) ( \ + CHECK_TYPE_INLINE(ebone, EditBone), \ + (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) \ + ) /* used in bone_select_hierachy() */ #define BONE_SELECT_PARENT 0 diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 8a65699f404..ffee46e30c6 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -157,4 +157,3 @@ short compare_ab_cfraPtr(void *node, void *data); short actkeyblock_is_valid(ActKeyBlock *ab, struct DLRBT_Tree *keys); #endif /* __ED_KEYFRAMES_DRAW_H__ */ - diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 5ce6db97305..1321765588d 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -38,7 +38,7 @@ struct wmKeyConfig; void ED_operatortypes_metaball(void); void ED_keymap_metaball(struct wmKeyConfig *keyconf); -struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newname); +struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type, int newname); int mouse_mball(struct bContext *C, const int mval[2], int extend, int deselect, int toggle); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 093872c79f6..f55f7755668 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -142,9 +142,9 @@ int EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2] short xmin, short ymin, short xmax, short ymax); int EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); -struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, int *dist, short sel, short strict); -struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, int *dist); -struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, int *dist); +struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist, const short sel, const short strict); +struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist); +struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist); int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short deselect, short toggle); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9836d690e53..d6ac9eb750d 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -35,22 +35,31 @@ extern "C" { #endif +struct BMEdge; +struct BMFace; +struct BMVert; +struct BPoint; struct Base; -struct bConstraint; -struct bContext; -struct bPoseChannel; +struct BezTriple; struct Curve; +struct EditBone; struct EnumPropertyItem; struct ID; struct KeyBlock; struct Lattice; struct Main; struct Mesh; +struct MetaElem; struct ModifierData; +struct Nurb; struct Object; struct ReportList; struct Scene; struct View3D; +struct ViewContext; +struct bConstraint; +struct bContext; +struct bPoseChannel; struct wmEvent; struct wmKeyConfig; struct wmKeyMap; @@ -82,8 +91,10 @@ typedef enum eParentType { PAR_TRIA } eParentType; +#ifdef __RNA_TYPES_H__ extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; +#endif int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype, int xmirror, int keep_transform); @@ -123,7 +134,8 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]); void ED_object_rotation_from_view(struct bContext *C, float rot[3]); void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]); float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob, - const float loc[3], const float rot[3], float primmat[][4]); + const float loc[3], const float rot[3], float primmat[][4], + int apply_diameter); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, float loc[3], float rot[3], @@ -183,7 +195,7 @@ int ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, int include int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); -/* ibject_select.c */ +/* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); #ifdef __cplusplus diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index b81e08ed7ef..fc24f68f2d1 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -37,6 +37,7 @@ struct BMEdge; struct BMFace; struct BMVert; struct BPoint; +struct Base; struct BezTriple; struct BezTriple; struct BoundBox; @@ -50,9 +51,12 @@ struct Nurb; struct Object; struct RegionView3D; struct Scene; +struct ScrArea; struct View3D; struct ViewContext; struct bContext; +struct bPoseChannel; +struct bScreen; struct bglMats; struct rcti; struct wmOperator; @@ -80,24 +84,8 @@ typedef struct ViewDepths { char damaged; } ViewDepths; -/* enum for passing to foreach functions to test RV3D_CLIPPING */ -typedef enum eV3DClipTest { - V3D_CLIP_TEST_OFF = 0, /* clipping is off */ - V3D_CLIP_TEST_RV3D_CLIPPING = 1, /* clip single points */ - V3D_CLIP_TEST_REGION = 2 /* use for edges to check if both verts are in the view, but not RV3D_CLIPPING */ -} eV3DClipTest; - float *give_cursor(struct Scene *scene, struct View3D *v3d); -int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); - -void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); -void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]); -void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]); -void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]); -void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]); - -void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]); void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist); void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist); @@ -119,7 +107,7 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* return values for ED_view3d_project_...() */ typedef enum { - V3D_PROJ_RET_SUCCESS = 0, + V3D_PROJ_RET_OK = 0, V3D_PROJ_RET_CLIP_NEAR = 1, /* can't avoid this when in perspective mode, (can't avoid) */ V3D_PROJ_RET_CLIP_BB = 2, /* bounding box clip - RV3D_CLIPPING */ V3D_PROJ_RET_CLIP_WIN = 3, /* outside window bounds */ @@ -133,50 +121,96 @@ typedef enum { V3D_PROJ_TEST_CLIP_WIN = (1 << 1), } eV3DProjTest; +#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) +#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) + + +/* view3d_iterators.c */ + +/* foreach iterators */ +void mesh_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), + void *userData, const eV3DProjTest clip_flag); +void mesh_foreachScreenEdge( + struct ViewContext *vc, + void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], + int index), + void *userData, const eV3DProjTest clip_flag); +void mesh_foreachScreenFace( + struct ViewContext *vc, + void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), + void *userData, const eV3DProjTest clip_flag); +void nurbs_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, + int beztindex, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void lattice_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BPoint *bp, + const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag); +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag); +/* *** end iterators *** */ + + +/* view3d_project.c */ +void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); +void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); + +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); /* *** short *** */ eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); + const float co[3], short r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag); /* *** int *** */ eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); + const float co[3], int r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag); /* *** float *** */ eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); + const float co[3], float r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); -void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); -void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); +int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); +void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]); +void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]); +void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); +void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]); +void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]); +void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]); +void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); +void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z); + +/* end */ -/* Base's get their own function since its a common operation */ -eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); -void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z); int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend); int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend); -void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift); void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); -/* drawobject.c iterators */ -void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData); -void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData); -void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, int x, int y), void *userData); -void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData); -void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), void *userData); -void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), void *userData); - - void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]); int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local); @@ -191,7 +225,8 @@ void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); /* backbuffer select and draw support */ void view3d_validate_backbuf(struct ViewContext *vc); struct ImBuf *view3d_read_backbuf(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); -unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, +unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, + unsigned int min, unsigned int max, float *dist, short strict, void *handle, unsigned int (*indextest)(void *handle, unsigned int index)); unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y); @@ -215,7 +250,7 @@ int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], cons void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats); /* XXX should move to BLI_math */ -int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, int y2); +int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]); /* get 3d region from context, also if mouse is in header or toolbar */ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index ef7b8ed3a41..8f50edd1240 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -450,8 +450,8 @@ DEF_ICON(FORCE_CURVE) DEF_ICON(FORCE_BOID) DEF_ICON(FORCE_TURBULENCE) DEF_ICON(FORCE_DRAG) +DEF_ICON(FORCE_SMOKEFLOW) #ifndef DEF_ICON_BLANK_SKIP - DEF_ICON(BLANK672) DEF_ICON(BLANK673) DEF_ICON(BLANK674) DEF_ICON(BLANK675) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2c00e39766c..fcde4186778 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1152,9 +1152,15 @@ static void ui_is_but_sel(uiBut *but, double *value) } } - if (is_push == 2) ; - else if (is_push == 1) but->flag |= UI_SELECT; - else but->flag &= ~UI_SELECT; + if (is_push == 2) { + /* pass */ + } + else if (is_push == 1) { + but->flag |= UI_SELECT; + } + else { + but->flag &= ~UI_SELECT; + } } static uiBut *ui_find_inlink(uiBlock *block, void *poin) @@ -1522,7 +1528,9 @@ void ui_set_but_val(uiBut *but, double value) * so leave this unset */ value = UI_BUT_VALUE_UNSET; } - else if (but->pointype == 0) ; + else if (but->pointype == 0) { + /* pass */ + } else if (but->type == HSVSLI) { float *fp, hsv[3]; @@ -1715,8 +1723,9 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen) BLI_strncpy(str, but->poin, maxlen); return; } - else if (ui_but_anim_expression_get(but, str, maxlen)) - ; /* driver expression */ + else if (ui_but_anim_expression_get(but, str, maxlen)) { + /* driver expression */ + } else { /* number editing */ double value; @@ -2474,7 +2483,9 @@ static void ui_block_do_align_but(uiBut *first, short nr) if (rows > 0) { uiBut *bt = but; while (bt && bt->alignnr == nr) { - if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) break; + if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) { + break; + } bt = bt->next; } if (bt == NULL || bt->alignnr != nr) flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT; @@ -2708,9 +2719,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } /* keep track of UI_interface.h */ - if (ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM)) ; - else if (ELEM(but->type, SCROLL, SEPR /* , FTPREVIEW */ )) ; - else if (but->type >= SEARCH_MENU) ; + if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {} + else if (but->type >= SEARCH_MENU) {} else but->flag |= UI_BUT_UNDO; BLI_addtail(&block->buttons, but); @@ -2744,7 +2754,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, - int x, int y, short width, short height, + int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { @@ -3863,12 +3873,41 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) } } else if (ELEM3(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) { + PointerRNA *ptr = NULL; + PropertyRNA *prop = NULL; + int value = 0; + + /* get the enum property... */ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { + /* enum property */ + ptr = &but->rnapoin; + prop = but->rnaprop; + value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); + } + else if (but->optype) { + PointerRNA *opptr = uiButGetOperatorPtrRNA(but); + wmOperatorType *ot = but->optype; + + /* if the default property of the operator is enum and it is set, + * fetch the tooltip of the selected value so that "Snap" and "Mirror" + * operator menus in the Anim Editors will show tooltips for the different + * operations instead of the meaningless generic operator tooltip + */ + if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { + if (RNA_struct_contains_property(opptr, ot->prop)) { + ptr = opptr; + prop = ot->prop; + value = RNA_property_enum_get(opptr, ot->prop); + } + } + } + + /* get strings from matching enum item */ + if (ptr && prop) { if (!item) { int i; - int value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); - RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &items, &totitems, &free_items); - + + RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items); for (i = 0, item = items; i < totitems; i++, item++) { if (item->identifier[0] && item->value == value) break; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 60e4c2aa90f..c4440cf07ed 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -704,7 +704,9 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event) BLI_rcti_rctf_copy(&rect, &but->rect); - if (but->imb) ; /* use button size itself */ + if (but->imb) { + /* use button size itself */ + } else if (but->flag & UI_ICON_LEFT) { rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } @@ -1184,7 +1186,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* numeric value */ if (ELEM4(but->type, NUM, NUMABS, NUMSLI, HSVSLI)) { - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { ui_get_but_string(but, buf, sizeof(buf)); WM_clipboard_text_set(buf, 0); @@ -1205,7 +1209,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else if (but->type == COLOR) { float rgb[3]; - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { ui_get_but_vectorf(but, rgb); @@ -1234,7 +1240,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { uiHandleButtonData *active_data = but->active; - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR); @@ -2297,7 +2305,9 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton { if (data->state == BUTTON_STATE_HIGHLIGHT) { if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { - if (but->dt == UI_EMBOSSN && !event->ctrl) ; + if (but->dt == UI_EMBOSSN && !event->ctrl) { + /* pass */ + } else { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); return WM_UI_HANDLER_BREAK; @@ -6611,7 +6621,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle } } - if (menu->menuretval) ; + if (menu->menuretval) { + /* pass */ + } else if (event->type == ESCKEY && event->val == KM_PRESS) { /* esc cancels this and all preceding menus */ menu->menuretval = UI_RETURN_CANCEL; @@ -6763,9 +6775,13 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa /* now handle events for our own menu */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { if (submenu && submenu->menuretval) { + int do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT); retval = ui_handle_menu_return_submenu(C, event, menu); - /* we may wan't to quit the submenu and handle the even in this menu */ - if ((retval == WM_UI_HANDLER_BREAK) && (submenu->menuretval & UI_RETURN_OUT_PARENT)) { + submenu = NULL; /* hint not to use this, it may be freed by call above */ + (void)submenu; + /* we may wan't to quit the submenu and handle the even in this menu, + * if its important to use it, check 'data->menu' first */ + if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) { retval = ui_handle_menu_event(C, event, menu, level); } } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 7a369019ac4..8e30b31f3fe 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -835,8 +835,9 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname bt = block->buttons.last; bt->flag = UI_TEXT_LEFT; } - else /* XXX bug here, collums draw bottom item badly */ + else { /* XXX bug here, colums draw bottom item badly */ uiItemS(column); + } } } @@ -2515,8 +2516,12 @@ static void ui_item_align(uiLayout *litem, short nr) if (!bitem->but->alignnr) bitem->but->alignnr = nr; } - else if (item->type == ITEM_LAYOUT_ABSOLUTE) ; - else if (item->type == ITEM_LAYOUT_OVERLAP) ; + else if (item->type == ITEM_LAYOUT_ABSOLUTE) { + /* pass */ + } + else if (item->type == ITEM_LAYOUT_OVERLAP) { + /* pass */ + } else if (item->type == ITEM_LAYOUT_BOX) { box = (uiLayoutItemBx *)item; box->roundbox->alignnr = nr; diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 1ee06b1ff64..017ffdcfb14 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -216,7 +216,7 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3 /* set sample from accumulated values */ static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) { - float col[4]; + float col[3]; mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); eyedropper_color_set(C, eye, col); } @@ -807,8 +807,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, } if (text == NULL) { - BKE_reportf(op->reports, RPT_WARNING, - "file: '%s' can't be opened", filepath); + BKE_reportf(op->reports, RPT_WARNING, "File: '%s' can't be opened", filepath); return OPERATOR_CANCELLED; } else { @@ -820,8 +819,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, st->text = text; } else { - BKE_reportf(op->reports, RPT_INFO, - "See '%s' in the text editor", text->id.name + 2); + BKE_reportf(op->reports, RPT_INFO, "See '%s' in the text editor", text->id.name + 2); } txt_move_toline(text, line - 1, FALSE); @@ -857,8 +855,8 @@ static int editsource_exec(bContext *C, wmOperator *op) !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi)) { - uiBut *but = BLI_ghashIterator_getKey(&ghi); - if (but && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but)) { + uiBut *but_key = BLI_ghashIterator_getKey(&ghi); + if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) { but_store = BLI_ghashIterator_getValue(&ghi); break; } @@ -872,14 +870,12 @@ static int editsource_exec(bContext *C, wmOperator *op) but_store->py_dbg_ln); } else { - BKE_report(op->reports, RPT_ERROR, - "Active button isn't from a script, cant edit source."); + BKE_report(op->reports, RPT_ERROR, "Active button isn't from a script, cant edit source"); ret = OPERATOR_CANCELLED; } } else { - BKE_report(op->reports, RPT_ERROR, - "Active button match can't be found."); + BKE_report(op->reports, RPT_ERROR, "Active button match can't be found"); ret = OPERATOR_CANCELLED; } @@ -978,19 +974,19 @@ static int edittranslation_exec(bContext *C, wmOperator *op) if (!BLI_is_dir(root)) { BKE_report(op->reports, RPT_ERROR, "Please set your User Preferences' \"Translation Branches " - "Directory\" path to a valid directory."); + "Directory\" path to a valid directory"); return OPERATOR_CANCELLED; } if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) { BKE_reportf(op->reports, RPT_ERROR, "Could not find operator \"%s\"! Please enable ui_translate addon " - "in the User Preferences.", EDTSRC_I18N_OP_NAME); + "in the User Preferences", EDTSRC_I18N_OP_NAME); return OPERATOR_CANCELLED; } /* Try to find a valid po file for current language... */ edittranslation_find_po_file(root, uilng, popath, FILE_MAX); /* printf("po path: %s\n", popath);*/ if (popath[0] == '\0') { - BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s.", uilng, root); + BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 4dafb4b2d4b..14cb1cbe85a 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2674,14 +2674,18 @@ void uiPupMenuReports(bContext *C, ReportList *reports) ds = BLI_dynstr_new(); for (report = reports->list.first; report; report = report->next) { - if (report->type < reports->printlevel) - ; /* pass */ - else if (report->type >= RPT_ERROR) + if (report->type < reports->printlevel) { + /* pass */ + } + else if (report->type >= RPT_ERROR) { BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message); - else if (report->type >= RPT_WARNING) + } + else if (report->type >= RPT_WARNING) { BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message); - else if (report->type >= RPT_INFO) + } + else if (report->type >= RPT_INFO) { BLI_dynstr_appendf(ds, "Info %%i%d%%t|%s", ICON_INFO, report->message); + } } str = BLI_dynstr_get_cstring(ds); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 3fc20309264..3203237496f 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -891,8 +891,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect /* calculate blend color */ if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) { - if (but->flag & UI_SELECT) ; - else if (but->flag & UI_ACTIVE) ; + if (but->flag & UI_SELECT) {} + else if (but->flag & UI_ACTIVE) {} else alpha = 0.5f; } @@ -3094,14 +3094,10 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) if (but->active) { int direction = ui_button_open_menu_direction(but); - if (direction == UI_TOP) - roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_TOP_LEFT); - else if (direction == UI_DOWN) - roundbox &= ~(UI_CNR_BOTTOM_RIGHT|UI_CNR_BOTTOM_LEFT); - else if (direction == UI_LEFT) - roundbox &= ~(UI_CNR_TOP_LEFT|UI_CNR_BOTTOM_LEFT); - else if (direction == UI_RIGHT) - roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_BOTTOM_RIGHT); + if (direction == UI_TOP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); + else if (direction == UI_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); } return roundbox; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 5ac20829480..12e04d392b4 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -827,6 +827,11 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) dx = RNA_float_get(op->ptr, "deltax"); dy = RNA_float_get(op->ptr, "deltay"); + if (U.uiflag & USER_ZOOM_INVERT) { + dx *= -1; + dy *= -1; + } + /* continuous zoom shouldn't move that fast... */ if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop? double time = PIL_check_seconds_timer(); @@ -849,12 +854,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dx) - (mval_faci * dx); - v2d->cur.xmin += ofs - dx; - v2d->cur.xmax += ofs + dx; + v2d->cur.xmin += ofs + dx; + v2d->cur.xmax += ofs - dx; } else { - v2d->cur.xmin -= dx; - v2d->cur.xmax += dx; + v2d->cur.xmin += dx; + v2d->cur.xmax -= dx; } } } @@ -868,12 +873,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dy) - (mval_faci * dy); - v2d->cur.ymin += ofs - dy; - v2d->cur.ymax += ofs + dy; + v2d->cur.ymin += ofs + dy; + v2d->cur.ymax += ofs - dy; } else { - v2d->cur.ymin -= dy; - v2d->cur.ymax += dy; + v2d->cur.ymin += dy; + v2d->cur.ymax -= dy; } } } @@ -1044,14 +1049,9 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event) } /* set transform amount, and add current deltas to stored total delta (for redo) */ - if (U.uiflag & USER_ZOOM_INVERT) { - RNA_float_set(op->ptr, "deltax", -dx); - RNA_float_set(op->ptr, "deltay", -dy); - } - else { - RNA_float_set(op->ptr, "deltax", dx); - RNA_float_set(op->ptr, "deltay", dy); - } + RNA_float_set(op->ptr, "deltax", dx); + RNA_float_set(op->ptr, "deltay", dy); + vzd->dx += dx; vzd->dy += dy; diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 0ec99325752..ba93206e63a 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -143,7 +143,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - BKE_report(op->reports, RPT_WARNING, "Export file not created."); + BKE_report(op->reports, RPT_WARNING, "Export file not created"); return OPERATOR_CANCELLED; } } @@ -307,7 +307,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", filename); if (collada_import(C, filename)) return OPERATOR_FINISHED; - BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document. Please see console for error log."); + BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)"); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index a254a6a9278..e43c8a2b53b 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -46,6 +46,7 @@ #include "WM_types.h" #include "ED_mask.h" /* own include */ +#include "ED_screen.h" #include "RNA_access.h" #include "RNA_define.h" @@ -97,7 +98,7 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no &tot_diff_point); if (diff_points) { - int i, tot_point; + int j, tot_point; unsigned int tot_feather_point; float *feather_points = NULL, *points; @@ -114,26 +115,26 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no tot_point = tot_diff_point; } - for (i = 0; i < tot_point - 1; i++) { + for (j = 0; j < tot_point - 1; j++) { float cur_dist, a[2], b[2]; - a[0] = points[2 * i] * scalex; - a[1] = points[2 * i + 1] * scaley; + a[0] = points[2 * j] * scalex; + a[1] = points[2 * j + 1] * scaley; - b[0] = points[2 * i + 2] * scalex; - b[1] = points[2 * i + 3] * scaley; + b[0] = points[2 * j + 2] * scalex; + b[1] = points[2 * j + 3] * scaley; cur_dist = dist_to_line_segment_v2(co, a, b); if (cur_dist < dist) { if (tangent) - sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]); point_masklay = masklay; point_spline = spline; point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point; dist = cur_dist; - u = (float)i / tot_point; + u = (float)j / tot_point; } } @@ -562,6 +563,11 @@ static int add_vertex_exec(bContext *C, wmOperator *op) float co[2]; + if (mask == NULL) { + /* if there's no active mask, create one */ + mask = ED_mask_new(C, NULL); + } + masklay = BKE_mask_layer_active(mask); if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { @@ -647,7 +653,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot) /* api callbacks */ ot->exec = add_vertex_exec; ot->invoke = add_vertex_invoke; - ot->poll = ED_maskedit_mask_poll; + ot->poll = ED_operator_mask; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index a60b771d179..490389c6d0c 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -20,6 +20,7 @@ * * * Contributor(s): Blender Foundation, + * Campbell Barton, * Sergey Sharybin * * ***** END GPL LICENSE BLOCK ***** @@ -41,7 +42,9 @@ #include "DNA_mask_types.h" #include "DNA_screen_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_space_types.h" +#include "ED_clip.h" #include "ED_mask.h" /* own include */ #include "ED_space_api.h" #include "BIF_gl.h" @@ -120,13 +123,22 @@ static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) } #endif +static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], float co[2]) +{ + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, r_co, co); + ED_clip_point_undistorted_pos(sc, r_co, r_co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co); +} + /* return non-zero if spline is selected */ -static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, +static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char UNUSED(draw_flag), const char draw_type) { const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + SpaceClip *sc = CTX_wm_space_clip(C); + int undistort = FALSE; int i, hsize, tot_feather_point; float (*feather_points)[2], (*fp)[2]; @@ -134,6 +146,9 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, if (!spline->tot_point) return; + if (sc) + undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; + /* TODO, add this to sequence editor */ hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */ @@ -151,8 +166,14 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, int j; for (j = 0; j < point->tot_uw + 1; j++) { + float feather_point[2]; int sel = FALSE; + copy_v2_v2(feather_point, *fp); + + if (undistort) + mask_point_undistort_pos(sc, feather_point, feather_point); + if (j == 0) { sel = MASKPOINT_ISSEL_ANY(point); } @@ -171,7 +192,7 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, } glBegin(GL_POINTS); - glVertex2fv(*fp); + glVertex2fv(feather_point); glEnd(); fp++; @@ -188,11 +209,17 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, BezTriple *bezt = &point_deform->bezt; float handle[2]; - float *vert = bezt->vec[1]; + float vert[2]; int has_handle = BKE_mask_point_has_handle(point); + copy_v2_v2(vert, bezt->vec[1]); BKE_mask_point_handle(point_deform, handle); + if (undistort) { + mask_point_undistort_pos(sc, vert, vert); + mask_point_undistort_pos(sc, handle, handle); + } + /* draw handle segment */ if (has_handle) { @@ -265,7 +292,7 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r } } -static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, +static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*orig_points)[2], int tot_point, const short is_feather, const short is_smooth, const short is_active, const unsigned char rgb_spline[4], const char draw_type) { @@ -273,6 +300,22 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff}; // const unsigned char rgb_white[4] = {0xff, 0xff, 0xff, 0xff}; unsigned char rgb_tmp[4]; + SpaceClip *sc = CTX_wm_space_clip(C); + float (*points)[2] = orig_points; + + if (sc) { + int undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; + + if (undistort) { + int i; + + points = MEM_callocN(2 * tot_point * sizeof(float), "undistorthed mask curve"); + + for (i = 0; i < tot_point; i++) { + mask_point_undistort_pos(sc, points[i], orig_points[i]); + } + } + } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, points); @@ -347,8 +390,6 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(draw_method, 0, tot_point); - glDrawArrays(draw_method, 0, tot_point); - if (is_smooth == FALSE && is_feather) { glDisable(GL_BLEND); } @@ -358,9 +399,11 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glDisableClientState(GL_VERTEX_ARRAY); + if (points != orig_points) + MEM_freeN(points); } -static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, +static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type, const short is_active, int width, int height) @@ -395,7 +438,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw feather */ mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); - mask_draw_curve_type(spline, feather_points, tot_feather_point, + mask_draw_curve_type(C, spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); @@ -414,7 +457,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, } /* same as above */ - mask_draw_curve_type(spline, feather_points, tot_feather_point, + mask_draw_curve_type(C, spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); } @@ -423,7 +466,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw main curve */ mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); - mask_draw_curve_type(spline, diff_points, tot_diff_point, + mask_draw_curve_type(C, spline, diff_points, tot_diff_point, FALSE, is_smooth, is_active, rgb_tmp, draw_type); MEM_freeN(diff_points); @@ -436,7 +479,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, (void)draw_type; } -static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type, +static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag,const char draw_type, int width, int height) { MaskLayer *masklay; @@ -453,13 +496,13 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type for (spline = masklay->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); + draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) { /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(masklay, spline, draw_flag, draw_type); + draw_spline_points(C, masklay, spline, draw_flag, draw_type); } /* show undeform for testing */ @@ -467,9 +510,9 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); + draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); - draw_spline_points(masklay, spline, draw_flag, draw_type); + draw_spline_points(C, masklay, spline, draw_flag, draw_type); spline->points_deform = back; } } @@ -489,7 +532,7 @@ void ED_mask_draw(const bContext *C, ED_mask_get_size(sa, &width, &height); - draw_masklays(mask, draw_flag, draw_type, width, height); + draw_masklays(C, mask, draw_flag, draw_type, width, height); } /* sets up the opengl context. @@ -500,7 +543,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, const float aspx, const float aspy, const short do_scale_applied, const short do_post_draw, float stabmat[4][4], /* optional - only used by clip */ - const bContext *C /* optional - only used when do_post_draw is set */ + const bContext *C /* optional - only used when do_post_draw is set or called from clip editor */ ) { struct View2D *v2d = &ar->v2d; @@ -559,7 +602,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, } /* draw! */ - draw_masklays(mask, draw_flag, draw_type, width, height); + draw_masklays(C, mask, draw_flag, draw_type, width, height); if (do_post_draw) { ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index ffd4afca182..fcfcfb237e9 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -33,6 +33,7 @@ #define __MASK_INTERN_H__ struct bContext; +struct Mask; struct wmEvent; struct wmOperatorType; @@ -43,6 +44,8 @@ void MASK_OT_add_vertex(struct wmOperatorType *ot); void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); /* mask_ops.c */ +struct Mask *ED_mask_new(struct bContext *C, const char *name); + void MASK_OT_new(struct wmOperatorType *ot); void MASK_OT_layer_new(struct wmOperatorType *ot); void MASK_OT_layer_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 88fbb91edfb..35f85f3faee 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -258,13 +258,10 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[ /******************** create new mask *********************/ -static int mask_new_exec(bContext *C, wmOperator *op) +Mask *ED_mask_new(bContext *C, const char *name) { ScrArea *sa = CTX_wm_area(C); Mask *mask; - char name[MAX_ID_NAME - 2]; - - RNA_string_get(op->ptr, "name", name); mask = BKE_mask_new(name); @@ -290,6 +287,17 @@ static int mask_new_exec(bContext *C, wmOperator *op) } } + return mask; +} + +static int mask_new_exec(bContext *C, wmOperator *op) +{ + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + ED_mask_new(C, name); + return OPERATOR_FINISHED; } @@ -483,15 +491,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata->uw = uw; if (uw) { - float co[2]; + float co_uw[2]; float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u); customdata->weight = uw->w; customdata->weight_scalar = weight_scalar; - BKE_mask_point_segment_co(spline, point, uw->u, co); + BKE_mask_point_segment_co(spline, point, uw->u, co_uw); BKE_mask_point_normal(spline, point, uw->u, customdata->no); - madd_v2_v2v2fl(customdata->feather, co, customdata->no, uw->w * weight_scalar); + madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar); } else { BezTriple *bezt = &point->bezt; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 69cfdf4e51b..dc204909577 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -557,7 +557,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_mask(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 246c323213c..9aa3f3633f3 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC ../include ../uvedit + ../../blenfont ../../blenkernel ../../blenlib ../../blenloader @@ -68,4 +69,8 @@ if(WITH_GAMEENGINE) ) endif() +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index b3aba977b21..923bb3f9057 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') defs = [] -incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' +incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../gpu ../../blenloader' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' @@ -24,4 +24,7 @@ if env['WITH_BF_GAMEENGINE']: else: sources.remove('mesh_navmesh.c') +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), defs, libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 5fd848ccb13..429b2148894 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -214,7 +214,9 @@ static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int ind /* fill array by selection */ mp = me->mpoly; for (a = 0; a < me->totpoly; a++, mp++) { - if (mp->flag & ME_HIDE) ; + if (mp->flag & ME_HIDE) { + /* pass */ + } else if (mp->flag & ME_FACE_SEL) { hash_add_face(ehash, mp, me->mloop + mp->loopstart); linkflag[a] = 1; @@ -572,7 +574,9 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend) mpoly = me->mpoly; for (a = 1; a <= me->totpoly; a++, mpoly++) { if (selar[a]) { - if (mpoly->flag & ME_HIDE) ; + if (mpoly->flag & ME_HIDE) { + /* pass */ + } else { if (select) mpoly->flag |= ME_FACE_SEL; else mpoly->flag &= ~ME_FACE_SEL; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 0cf4ac48bf7..99ed86d7a06 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -73,7 +73,7 @@ static Object *make_prim_init(bContext *C, const char *idname, *state = 1; } - *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE); return obedit; } @@ -200,7 +200,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, mat)) { return OPERATOR_CANCELLED; @@ -256,10 +256,10 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", RNA_int_get(op->ptr, "vertices"), - RNA_float_get(op->ptr, "radius"), - RNA_float_get(op->ptr, "radius"), + RNA_float_get(op->ptr, "radius") * dia, + RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, - RNA_float_get(op->ptr, "depth"), mat)) + RNA_float_get(op->ptr, "depth") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -315,8 +315,8 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf( em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"), - RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat)) + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1") * dia, + RNA_float_get(op->ptr, "radius2") * dia, cap_end, cap_tri, RNA_float_get(op->ptr, "depth") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -421,6 +421,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) rot[0] += (float)M_PI / 2.0f; obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer); + mat[0][0] *= dia; + mat[1][1] *= dia; + mat[2][2] *= dia; + em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) { @@ -465,7 +469,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4", RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), - RNA_float_get(op->ptr, "size"), mat)) + RNA_float_get(op->ptr, "size") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -517,7 +521,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) em, op, "vertout", "create_icosphere subdivisions=%i diameter=%f mat=%m4", RNA_int_get(op->ptr, "subdivisions"), - RNA_float_get(op->ptr, "size"), mat)) + RNA_float_get(op->ptr, "size") * dia, mat)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index c249d764ac1..e84fa90fe5c 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -371,9 +371,9 @@ int BMBVH_VertVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d) } #endif -static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *hitout, BMEdge *e) +static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *r_hitout, BMEdge *e) { - BMFace *f = BMBVH_RayCast(tree, co, dir, hitout, NULL); + BMFace *f = BMBVH_RayCast(tree, co, dir, r_hitout, NULL); if (f && BM_edge_in_face(f, e)) return NULL; @@ -392,7 +392,7 @@ static void scale_point(float c1[3], const float p[3], const float s) int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, ARegion *ar, View3D *v3d, Object *obedit) { BMFace *f; - float co1[3], co2[3], co3[3], dir1[4], dir2[4], dir3[4]; + float co1[3], co2[3], co3[3], dir1[3], dir2[3], dir3[3]; float origin[3], invmat[4][4]; float epsilon = 0.01f; float end[3]; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 4f4fc27582c..1d19d35ca34 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1418,7 +1418,7 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2], static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space) { BMFace *f; - int dist = KMAXDIST; + float dist = KMAXDIST; float origin[3]; float ray[3]; diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index c0a36e24015..98fae2cc701 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -416,7 +416,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) Object *obedit = CTX_data_edit_object(C); RingSelOpData *lcd; BMEdge *edge; - int dist = 75; + float dist = 75.0f; if (modifiers_isDeformedByLattice(obedit) || modifiers_isDeformedByArmature(obedit)) BKE_report(op->reports, RPT_WARNING, "Loop cut doesn't work well on deformed edit mesh display"); @@ -513,7 +513,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) ED_region_tag_redraw(lcd->ar); break; case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ - int dist = 75; + float dist = 75.0f; BMEdge *edge; lcd->vc.mval[0] = event->mval[0]; diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 001d584416f..8fe2aa4b1a7 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -55,19 +55,59 @@ #include "mesh_intern.h" -/* helper to find edge for edge_rip */ -static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], - const float co1[3], const float co2[3], const float mvalf[2]) +/** + * helper to find edge for edge_rip, + * + * \param inset is used so we get some useful distance + * when comparing multiple edges that meet at the same + * point and would result in teh same distance. + */ +#define INSET_DEFAULT 0.00001f +static float edbm_rip_edgedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2], + const float inset) { - float vec1[3], vec2[3]; + float vec1[2], vec2[2]; ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); + if (inset != 0.0f) { + const float dist = inset / len_v2v2(vec1, vec2); + interp_v2_v2v2(vec1, vec1, vec2, dist); + interp_v2_v2v2(vec2, vec2, vec1, dist); + } + /* TODO: use dist_squared_to_line_segment_v2() looks like we only ever use for comparison */ return dist_to_line_segment_v2(mvalf, vec1, vec2); } +#if 0 +static float edbm_rip_linedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2]) +{ + float vec1[2], vec2[2]; + + ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); + ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); + + return dist_to_line_v2(mvalf, vec1, vec2); +} +#endif + +/* calculaters a point along the loop tangent which can be used to measure against edges */ +static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3]) +{ + BM_loop_calc_face_tangent(l, l_mid_co); + + /* scale to average of surrounding edge size, only needs to be approx, but should + * be roughly equivalent to the check below which uses the middle of the edge. */ + mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f); + + add_v3_v3(l_mid_co, l->v->co); +} + + static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l, ARegion *ar, float projectMat[4][4], const float fmval[2]) @@ -237,7 +277,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) uid_start = uid; while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) { - BM_elem_flag_disable(e, BM_ELEM_SMOOTH); v_step = BM_edge_other_vert((e_step = e), v_step); uid++; /* only different line */ tot++; @@ -254,7 +293,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) v_step = e_first->v1; while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) { - BM_elem_flag_disable(e, BM_ELEM_SMOOTH); v_step = BM_edge_other_vert((e_step = e), v_step); uid--; /* only different line */ tot++; @@ -344,6 +382,145 @@ static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs, } /* --- end 'ripsel' selection handling code --- */ + +/* --- face-fill code --- */ +/** + * return an un-ordered array of loop pairs + * use for rebuilding face-fill + * + * \note the method currenly used fails for edges with 3+ face users and gives + * nasty holes in the mesh, there isnt a good way of knowing ahead of time + * which loops will be split apart (its possible to figure out but quite involved). + * So for now this is a known limitation of current rip-fill option. + */ + +typedef struct UnorderedLoopPair { + BMLoop *l_pair[2]; + char flag; +} UnorderedLoopPair; +enum { + ULP_FLIP_0 = (1 << 0), + ULP_FLIP_1 = (1 << 1) +}; + +static UnorderedLoopPair *edbm_tagged_loop_pairs_to_fill(BMesh *bm) +{ + BMIter iter; + BMEdge *e; + + unsigned int total_tag = 0; + /* count tags, could be pre-calculated */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + total_tag++; + } + } + + if (total_tag) { + UnorderedLoopPair *uloop_pairs = MEM_mallocN(total_tag * sizeof(UnorderedLoopPair), __func__); + UnorderedLoopPair *ulp = uloop_pairs; + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + BMLoop *l1, *l2; + if (BM_edge_loop_pair(e, &l1, &l2)) { + BMVert *v_cmp = l1->e->v1; + ulp->flag = (((l1->v != v_cmp) ? ULP_FLIP_0 : 0) | + ((l2->v == v_cmp) ? ULP_FLIP_1 : 0)); + } + else { + ulp->flag = 0; + } + ulp->l_pair[0] = l1; + ulp->l_pair[1] = l2; + + ulp++; + } + } + + return uloop_pairs; + } + else { + return NULL; + } +} + +static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *uloop_pairs) +{ + UnorderedLoopPair *ulp; + unsigned int total_tag = MEM_allocN_len(uloop_pairs) / sizeof(UnorderedLoopPair); + unsigned int i; + + for (i = 0, ulp = uloop_pairs; i < total_tag; i++, ulp++) { + if ((ulp->l_pair[0] && ulp->l_pair[1]) && + (ulp->l_pair[0]->e != ulp->l_pair[1]->e)) + { + /* time has come to make a face! */ + BMVert *v_shared = BM_edge_share_vert(ulp->l_pair[0]->e, ulp->l_pair[1]->e); + BMFace *f, *f_example = ulp->l_pair[0]->f; + BMLoop *l_iter; + BMVert *f_verts[4]; + + if (v_shared == NULL) { + /* quad */ + f_verts[0] = ulp->l_pair[0]->e->v1; + f_verts[1] = ulp->l_pair[1]->e->v1; + f_verts[2] = ulp->l_pair[1]->e->v2; + f_verts[3] = ulp->l_pair[0]->e->v2; + + if (ulp->flag & ULP_FLIP_0) { + SWAP(BMVert *, f_verts[0], f_verts[3]); + } + if (ulp->flag & ULP_FLIP_1) { + SWAP(BMVert *, f_verts[1], f_verts[2]); + } + } + else { + /* tri */ + f_verts[0] = v_shared; + f_verts[1] = BM_edge_other_vert(ulp->l_pair[0]->e, v_shared); + f_verts[2] = BM_edge_other_vert(ulp->l_pair[1]->e, v_shared); + f_verts[3] = NULL; + + /* don't use the flip flags */ + if (v_shared == ulp->l_pair[0]->v) { + SWAP(BMVert *, f_verts[0], f_verts[1]); + } + } + + /* face should never exist */ + BLI_assert(BM_face_exists(bm, f_verts, f_verts[3] ? 4 : 3, &f) == FALSE); + + f = BM_face_create_quad_tri_v(bm, f_verts, f_verts[3] ? 4 : 3, f_example, FALSE); + + l_iter = BM_FACE_FIRST_LOOP(f); + + if (f_verts[3]) { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); + } + else { + if (v_shared == f_verts[0]) { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); + } + else { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); + } + } + + } + } +} + +/* --- end 'face-fill' code --- */ + + static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) { BMOperator bmop; @@ -366,6 +543,8 @@ static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) */ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) { + const int do_fill = RNA_boolean_get(op->ptr, "use_fill"); + UnorderedLoopPair *fill_uloop_pairs = NULL; Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -388,7 +567,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); /* find selected vert - same some time and check history first */ - if (BM_select_history_active_get(em->bm, &ese) && ese.htype == BM_VERT) { + if (BM_select_history_active_get(bm, &ese) && ese.htype == BM_VERT) { v = (BMVert *)ese.ele; } else { @@ -417,7 +596,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e)); if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { if (is_boundary == FALSE && BM_edge_is_manifold(e)) { - d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval); + d = edbm_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; e2 = e; @@ -426,6 +605,42 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) } } + /* if we are ripping a single vertex from 3 faces, + * then measure the distance to the face corner as well as the edge */ + if (BM_vert_face_count(v) == 3 && + BM_vert_edge_count(v) == 3) + { + BMEdge *e_all[3]; + BMLoop *l_all[3]; + int i1, i2; + + BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3); + + /* not do a loop similar to the one above, but test against loops */ + for (i1 = 0; i1 < 3; i1++) { + /* consider wire as boundary for this purpose, + * otherwise we can't a face away from a wire edge */ + float l_mid_co[3]; + l = l_all[i1]; + edbm_calc_loop_co(l, l_mid_co); + d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); + + if (d < dist) { + dist = d; + + /* find the edge that is not in this loop */ + e2 = NULL; + for (i2 = 0; i2 < 3; i2++) { + if (!BM_edge_in_loop(e_all[i2], l)) { + e2 = e_all[i2]; + break; + } + } + BLI_assert(e2 != NULL); + } + } + } } /* should we go ahead with edge rip or do we need to do special case, split off vertex?: @@ -459,7 +674,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) int vi_best = 0; if (ese.ele) { - BM_select_history_remove(em->bm, ese.ele); + BM_select_history_remove(bm, ese.ele); } dist = FLT_MAX; @@ -473,14 +688,9 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) { if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) { float l_mid_co[3]; - BM_loop_calc_face_tangent(l, l_mid_co); + edbm_calc_loop_co(l, l_mid_co); - /* scale to average of surrounding edge size, only needs to be approx, but should - * be roughly equivalent to the check below which uses the middle of the edge. */ - mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f); - add_v3_v3(l_mid_co, v->co); - - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval); + d = edbm_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -496,7 +706,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float e_mid_co[3]; mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co); - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval); + d = edbm_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -512,7 +722,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) BM_vert_select_set(bm, v, TRUE); if (ese.ele) { - BM_select_history_store(em->bm, v); + BM_select_history_store(bm, v); } /* splice all others back together */ @@ -543,39 +753,65 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } + /* *** Execute the split! *** */ + /* unlike edge split, for single vertex split we only use the operator in one of the cases + * but both allocate fill */ + /* rip two adjacent edges */ if (BM_edge_is_boundary(e2) || BM_vert_face_count(v) == 2) { + /* Don't run the edge split operator in this case */ + + BM_elem_flag_enable(e2, BM_ELEM_TAG); /* only for face-fill (we don't call the operator) */ + + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + l = e2->l; ripvert = BM_face_vert_separate(bm, l->f, v); BLI_assert(ripvert); if (!ripvert) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); return OPERATOR_CANCELLED; } } - else if (BM_edge_is_manifold(e2)) { - l = e2->l; - e = BM_face_other_edge_loop(l->f, e2, v)->e; - BM_elem_flag_enable(e, BM_ELEM_TAG); + else { + if (BM_edge_is_manifold(e2)) { + l = e2->l; + e = BM_face_other_edge_loop(l->f, e2, v)->e; + BM_elem_flag_enable(e, BM_ELEM_TAG); + + l = e2->l->radial_next; + e = BM_face_other_edge_loop(l->f, e2, v)->e; + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + else { + /* looks like there are no split edges, we could just return/report-error? - Campbell */ + } + + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } - l = e2->l->radial_next; - e = BM_face_other_edge_loop(l->f, e2, v)->e; - BM_elem_flag_enable(e, BM_ELEM_TAG); + if (!edbm_rip_call_edgesplit(em, op)) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); + return OPERATOR_CANCELLED; + } } dist = FLT_MAX; - if (!edbm_rip_call_edgesplit(em, op)) { - return OPERATOR_CANCELLED; - } - else { + { /* --- select which vert --- */ BMVert *v_best = NULL; float l_prev_co[3], l_next_co[3], l_corner_co[3]; float scale; dist = FLT_MAX; - BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { /* disable by default, re-enable winner at end */ BM_vert_select_set(bm, v, FALSE); @@ -593,7 +829,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) add_v3_v3v3(l_corner_co, l_prev_co, l_next_co); add_v3_v3(l_corner_co, l->v->co); - d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval); + d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT); if (d < dist) { v_best = v; dist = d; @@ -605,11 +841,17 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) if (v_best) { BM_vert_select_set(bm, v_best, TRUE); if (ese.ele) { - BM_select_history_store(em->bm, v_best); + BM_select_history_store(bm, v_best); } } } + if (do_fill && fill_uloop_pairs) { + edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); + MEM_freeN(fill_uloop_pairs); + } + + if (totvert_orig == bm->totvert) { BKE_report(op->reports, RPT_ERROR, "No vertices could be ripped"); return OPERATOR_CANCELLED; @@ -623,6 +865,8 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) */ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) { + const int do_fill = RNA_boolean_get(op->ptr, "use_fill"); + UnorderedLoopPair *fill_uloop_pairs = NULL; Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -633,25 +877,25 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) BMEdge *e, *e2; BMVert *v; const int totedge_orig = bm->totedge; - int i; float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]}; - int totedge; - int all_minifold; - EdgeLoopPair *eloop_pairs; ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); - /* important this runs on the original selection, before tempering with tagging */ + /* important this runs on the original selection, before tampering with tagging */ eloop_pairs = edbm_ripsel_looptag_helper(bm); /* expand edge selection */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + int all_manifold; + int totedge_manifold; /* manifold, visible edges */ + int i; + e2 = NULL; i = 0; - totedge = 0; - all_minifold = TRUE; + totedge_manifold = 0; + all_manifold = TRUE; BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { if (!BM_edge_is_wire(e) && @@ -663,22 +907,25 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) e2 = e; i++; } - totedge++; + totedge_manifold++; } /** #BM_vert_other_disk_edge has no hidden checks so don't check hidden here */ - if ((all_minifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) { - all_minifold = FALSE; + if ((all_manifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) { + all_manifold = FALSE; } } /* single edge, extend */ if (i == 1 && e2->l) { - if ((totedge == 4) || (all_minifold == FALSE)) { + /* note: if the case of 3 edges has one change in loop stepping, + * if this becomes more involved we may be better off splitting + * the 3 edge case into its own else-if branch */ + if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == FALSE)) { BMLoop *l_a = e2->l; BMLoop *l_b = l_a->radial_next; - /* find the best face to follow, this what the edge won't point away from + /* find the best face to follow, this way the edge won't point away from * the mouse when there are more then 4 (takes the shortest face fan around) */ l = (edbm_rip_edge_side_measure(e2, l_a, ar, projectMat, fmval) < edbm_rip_edge_side_measure(e2, l_b, ar, projectMat, fmval)) ? l_a : l_b; @@ -688,9 +935,12 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) * not crashing but adds duplicate edge. */ if (BM_edge_is_manifold(l->e)) { l = l->radial_next; - l = BM_face_other_edge_loop(l->f, l->e, v); + + if (totedge_manifold != 3) + l = BM_face_other_edge_loop(l->f, l->e, v); if (l) { + BLI_assert(!BM_elem_flag_test(l->e, BM_ELEM_TAG)); BM_elem_flag_enable(l->e, BM_ELEM_TAG); } } @@ -699,13 +949,20 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) e = BM_vert_other_disk_edge(v, e2); if (e) { + BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG)); BM_elem_flag_enable(e, BM_ELEM_TAG); } } } } + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + if (!edbm_rip_call_edgesplit(em, op)) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); return OPERATOR_CANCELLED; } @@ -718,6 +975,11 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) ar, projectMat, fmval); MEM_freeN(eloop_pairs); + if (do_fill && fill_uloop_pairs) { + edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); + MEM_freeN(fill_uloop_pairs); + } + if (totedge_orig == bm->totedge) { BKE_report(op->reports, RPT_ERROR, "No edges could be ripped"); return OPERATOR_CANCELLED; @@ -740,7 +1002,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) int ret; /* running in face mode hardly makes sense, so convert to region loop and rip */ - if (em->bm->totfacesel) { + if (bm->totfacesel) { /* highly nifty but hard to support since the operator can fail and we're left * with modified selection */ // WM_operator_name_call(C, "MESH_OT_region_to_loop", WM_OP_INVOKE_DEFAULT, NULL); @@ -760,7 +1022,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) */ /* BM_ELEM_SELECT --> BM_ELEM_TAG */ - BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT)); } @@ -804,5 +1066,6 @@ void MESH_OT_rip(wmOperatorType *ot) /* to give to transform */ Transform_Properties(ot, P_PROPORTIONAL); - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); + RNA_def_boolean(ot->srna, "mirror", FALSE, "Mirror Editing", ""); + RNA_def_boolean(ot->srna, "use_fill", FALSE, "Fill", "Fill the ripped region"); } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index ae2d090fef3..bc792037443 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -57,6 +57,7 @@ #include "ED_mesh.h" #include "ED_screen.h" #include "ED_uvedit.h" +#include "ED_object.h" #include "ED_view3d.h" #include "BIF_gl.h" @@ -330,9 +331,9 @@ int EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) } -static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y, int index) +static void findnearestvert__doClosest(void *userData, BMVert *eve, const float screen_co[2], int index) { - struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } *data = userData; + struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } *data = userData; if (data->pass == 0) { if (index <= data->lastIndex) @@ -344,18 +345,18 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y } if (data->dist > 3) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); if (BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->select) { if (data->strict == 1) { return; } else { - temp += 5; + dist_test += 5; } } - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->closest = eve; data->closestIndex = index; } @@ -382,10 +383,10 @@ static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int * if 0, unselected vertice are given the bias * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased */ -BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short strict) +BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const short sel, const short strict) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { - int distance; + float distance; unsigned int index; BMVert *eve; @@ -400,8 +401,8 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri eve = BM_vert_at_index(vc->em->bm, index - 1); - if (eve && distance < *dist) { - *dist = distance; + if (eve && distance < *r_dist) { + *r_dist = distance; return eve; } else { @@ -410,7 +411,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } else { - struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } data; + struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } data; static int lastSelectedIndex = 0; static BMVert *lastSelected = NULL; @@ -420,10 +421,10 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } data.lastIndex = lastSelectedIndex; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; data.select = sel; - data.dist = *dist; + data.dist = *r_dist; data.strict = strict; data.closest = NULL; data.closestIndex = 0; @@ -432,14 +433,14 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.dist > 3) { data.pass = 1; - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } - *dist = data.dist; + *r_dist = data.dist; lastSelected = data.closest; lastSelectedIndex = data.closestIndex; @@ -462,18 +463,12 @@ float labda_PdistVL2Dfl(const float v1[2], const float v2[2], const float v3[2]) } /* note; uses v3d, so needs active 3d window */ -static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) +static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) { - struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } *data = userData; - float v1[2], v2[2]; + struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } *data = userData; int distance; - - v1[0] = x0; - v1[1] = y0; - v2[0] = x1; - v2[1] = y1; - - distance = dist_to_line_segment_v2(data->mval, v1, v2); + + distance = dist_to_line_segment_v2(data->mval_fl, screen_co_a, screen_co_b); if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { distance += 5; @@ -481,7 +476,7 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int if (distance < data->dist) { if (data->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = labda_PdistVL2Dfl(data->mval, v1, v2); + float labda = labda_PdistVL2Dfl(data->mval_fl, screen_co_a, screen_co_b); float vec[3]; vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]); @@ -499,11 +494,11 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int } } } -BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) +BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { - int distance; + float distance; unsigned int index; BMEdge *eed; @@ -512,8 +507,8 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL); eed = BM_edge_at_index(vc->em->bm, index - 1); - if (eed && distance < *dist) { - *dist = distance; + if (eed && distance < *r_dist) { + *r_dist = distance; return eed; } else { @@ -521,36 +516,37 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) } } else { - struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } data; + struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } data; data.vc = *vc; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; - data.dist = *dist; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; + data.dist = *r_dist; data.closest = NULL; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_CLIP_TEST_REGION); + mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_PROJ_TEST_CLIP_WIN); - *dist = data.dist; + *r_dist = data.dist; return data.closest; } } -static void findnearestface__getDistance(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void findnearestface__getDistance(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { - struct { short mval[2]; int dist; BMFace *toFace; } *data = userData; + struct { float mval_fl[2]; float dist; BMFace *toFace; } *data = userData; if (efa == data->toFace) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (temp < data->dist) - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; + } } } -static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y, int index) +static void findnearestface__doClosest(void *userData, BMFace *efa, const float screen_co[2], int index) { - struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } *data = userData; + struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } *data = userData; if (data->pass == 0) { if (index <= data->lastIndex) @@ -562,17 +558,17 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y } if (data->dist > 3) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->closest = efa; data->closestIndex = index; } } } -BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) +BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { @@ -585,17 +581,17 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) efa = BM_face_at_index(vc->em->bm, index - 1); if (efa) { - struct { short mval[2]; int dist; BMFace *toFace; } data; + struct { float mval_fl[2]; float dist; BMFace *toFace; } data; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; data.dist = 0x7FFF; /* largest short */ data.toFace = efa; - mesh_foreachScreenFace(vc, findnearestface__getDistance, &data); + mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (vc->em->selectmode == SCE_SELECT_FACE || data.dist < *dist) { /* only faces, no dist check */ - *dist = data.dist; + if ((vc->em->selectmode == SCE_SELECT_FACE) || (data.dist < *r_dist)) { /* only faces, no dist check */ + *r_dist = data.dist; return efa; } } @@ -603,7 +599,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) return NULL; } else { - struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } data; + struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } data; static int lastSelectedIndex = 0; static BMFace *lastSelected = NULL; @@ -613,23 +609,23 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) } data.lastIndex = lastSelectedIndex; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; - data.dist = *dist; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; + data.dist = *r_dist; data.closest = NULL; data.closestIndex = 0; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); data.pass = 0; - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (data.dist > 3) { + if (data.dist > 3.0f) { data.pass = 1; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } - *dist = data.dist; + *r_dist = data.dist; lastSelected = data.closest; lastSelectedIndex = data.closestIndex; @@ -645,7 +641,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { BMEditMesh *em = vc->em; - int dist = 75; + float dist = 75.0f; *r_eve = NULL; *r_eed = NULL; @@ -1006,7 +1002,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) BMEditMesh *em; BMEdge *eed; int select = TRUE; - int dist = 50; + float dist = 50.0f; float mvalf[2]; em_setup_viewcontext(C, &vc); @@ -1061,11 +1057,11 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) /* We can't be sure this has already been set... */ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); - if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { length_1 = len_squared_v2v2(mvalf, v1_co); } - if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { length_2 = len_squared_v2v2(mvalf, v2_co); } #if 0 @@ -1092,7 +1088,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) float co[2], tdist; BM_face_calc_center_mean(f, cent); - if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { tdist = len_squared_v2v2(mvalf, co); if (tdist < best_dist) { /* printf("Best face: %p (%f)\n", f, tdist);*/ @@ -1399,7 +1395,7 @@ static int mouse_mesh_shortest_path(bContext *C, int mval[2]) ViewContext vc; BMEditMesh *em; BMEdge *e; - int dist = 50; + float dist = 75.0f; em_setup_viewcontext(C, &vc); vc.mval[0] = mval[0]; @@ -2179,11 +2175,19 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */ BMW_NIL_LAY); + /* use tag to avoid touching the same verts twice */ + BM_ITER_MESH (ele, &iter, bm, itertype) { + BM_elem_flag_disable(ele, BM_ELEM_TAG); + } + BLI_assert(walker.order == BMW_BREADTH_FIRST); for (ele = BMW_begin(&walker, h_act); ele != NULL; ele = BMW_step(&walker)) { - /* Deselect elements that aren't at "nth" depth from active */ - if ((offset + BMW_current_depth(&walker)) % nth) { - BM_elem_select_set(bm, ele, FALSE); + if (!BM_elem_flag_test(ele, BM_ELEM_TAG)) { + /* Deselect elements that aren't at "nth" depth from active */ + if ((offset + BMW_current_depth(&walker)) % nth) { + BM_elem_select_set(bm, ele, FALSE); + } + BM_elem_flag_enable(ele, BM_ELEM_TAG); } } BMW_end(&walker); @@ -2306,8 +2310,8 @@ void MESH_OT_select_nth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); - RNA_def_int(ot->srna, "offset", 0, 0, 100, "Offset", "", 0, INT_MAX); + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); + RNA_def_int(ot->srna, "offset", 0, 0, INT_MAX, "Offset", "", 0, 100); } void em_setup_viewcontext(bContext *C, ViewContext *vc) diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index e42b95c6013..d370b5a881e 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -34,6 +34,8 @@ #include "BLI_array.h" #include "BLI_math.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_report.h" #include "BKE_tessmesh.h" @@ -113,11 +115,11 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Custom data */ VertexSlideOp *vso; - const char *header_str = "Vertex Slide: Hover over an edge and left-click to select slide edge. " - "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap&Merge"; + const char *header_str = TIP_("Vertex Slide: Hover over an edge and left-click to select slide edge. " + "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap & Merge"); if (!obedit) { - BKE_report(op->reports, RPT_ERROR, "Vertex Slide Error: Not object in context"); + BKE_report(op->reports, RPT_ERROR, "Vertex slide error: no object in context"); return FALSE; } @@ -126,7 +128,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Is there a starting vertex ? */ if (ese == NULL || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex"); return FALSE; } @@ -177,7 +179,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Init frame */ if (!vtx_slide_set_frame(vso)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide: Can't find starting vertex!"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: cannot find starting vertex!"); vtx_slide_exit(C, op); return FALSE; } @@ -390,8 +392,8 @@ static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2]) mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co); /* we could use ED_view3d_project_float_object here, but for now dont since we dont have the context */ - if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); if (dist < min_dist) { @@ -409,7 +411,8 @@ static void vtx_slide_find_edge(VertexSlideOp *vso, wmEvent *event) /* Nearest edge */ BMEdge *nst_edge = NULL; - const float mval_float[] = { (float)event->mval[0], (float)event->mval[1]}; + const float mval_float[2] = {(float)event->mval[0], + (float)event->mval[1]}; /* Set mouse coords */ copy_v2_v2_int(vso->view_context->mval, event->mval); @@ -458,8 +461,8 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co); mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co); - if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || - (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) || + (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK)) { /* not much we can do here */ return; @@ -718,7 +721,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u /* Is there a starting vertex ? */ if ((ese == NULL) || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index d73e7d81b9f..ee615093c86 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -41,7 +41,9 @@ #include "RNA_define.h" #include "RNA_access.h" +#include "BLI_array.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_rand.h" @@ -49,6 +51,7 @@ #include "BKE_context.h" #include "BKE_cdderivedmesh.h" #include "BKE_depsgraph.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_report.h" #include "BKE_texture.h" @@ -72,6 +75,8 @@ #include "mesh_intern.h" +#define MVAL_PIXEL_MARGIN 5.0f + /* allow accumulated normals to form a new direction but don't * accept direct opposite directions else they will cancel each other out */ static void add_normal_aligned(float nor[3], const float add[3]) @@ -153,6 +158,51 @@ void MESH_OT_subdivide(wmOperatorType *ot) } +static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMOperator bmop; + + int iterations = RNA_int_get(op->ptr, "iterations"); + + EDBM_op_init(em, &bmop, op, + "unsubdivide verts=%hv iterations=%i", BM_ELEM_SELECT, iterations); + + BMO_op_exec(em->bm, &bmop); + + if (!EDBM_op_finish(em, &bmop, op, TRUE)) { + return 0; + } + + if ((em->selectmode & SCE_SELECT_VERTEX) == 0) { + EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* need to flush vert->face first */ + } + EDBM_selectmode_flush(em); + + EDBM_update_generic(C, em, TRUE); + + return OPERATOR_FINISHED; +} + +void MESH_OT_unsubdivide(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Un-Subdivide"; + ot->description = "UnSubdivide selected edges & faces"; + ot->idname = "MESH_OT_unsubdivide"; + + /* api callbacks */ + ot->exec = edbm_unsubdivide_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_int(ot->srna, "iterations", 2, 1, INT_MAX, "Iterations", "Number of times to unsubdivide", 1, 100); +} + void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) { Object *obedit = em->ob; @@ -165,7 +215,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { float mval[2], co_proj[3], no_dummy[3]; int dist_dummy; - if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsContext(C, mval, &dist_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) { mul_v3_m4v3(eve->co, obedit->imat, co_proj); } @@ -429,8 +479,8 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ - RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX); - RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX); + RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, FLT_MAX, "Offset", "", 0.0f, 100.0f); + RNA_def_int(ot->srna, "steps", 10, 0, INT_MAX, "Steps", "", 0, 180); } /* generic extern called extruder */ @@ -765,10 +815,10 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent done = FALSE; BM_ITER_MESH (eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float co1[3], co2[3]; + float co1[2], co2[2]; - if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { /* 2D rotate by 90d while adding. * (x, y) = (y, -x) @@ -1215,11 +1265,14 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; } + else { + EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ EDBM_update_generic(C, em, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } +} void MESH_OT_vert_connect(wmOperatorType *ot) { @@ -1607,7 +1660,7 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX); + RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Number of times to smooth the mesh", "", 1, 100); RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis"); RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis"); RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis"); @@ -2080,7 +2133,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) } count = totvert_orig - em->bm->totvert; - BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s", count, (count == 1) ? "ex" : "ices"); + BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); EDBM_update_generic(C, em, TRUE); @@ -2165,7 +2218,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) } if (svert == NULL || evert == NULL) { - BKE_report(op->reports, RPT_WARNING, "Path Selection requires that two vertices be selected"); + BKE_report(op->reports, RPT_WARNING, "Path selection requires two vertices to be selected"); return OPERATOR_CANCELLED; } @@ -2772,7 +2825,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__); BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) { - if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { copy_v2_fl(*sco, FLT_MAX); /* set error value */ } BM_elem_index_set(bv, i); /* set_ok */ @@ -3078,7 +3131,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) } else { if (type == 0) { - BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode"); + BKE_report(op->reports, RPT_ERROR, "Selection not supported in object mode"); return OPERATOR_CANCELLED; } @@ -3542,7 +3595,7 @@ void MESH_OT_spin(wmOperatorType *ot) RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f); RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } @@ -3666,8 +3719,8 @@ void MESH_OT_screw(wmOperatorType *ot) RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, - "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, + "Axis", "Axis in global view space", -1.0f, 1.0f); } static int edbm_select_by_number_vertices_exec(bContext *C, wmOperator *op) @@ -3851,8 +3904,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob, char *pblock[3] = {NULL, NULL, NULL}, *pb; BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb; int *map[3] = {NULL, NULL, NULL}, *mp; - int totelem[3] = {0, 0, 0}, tot; - int affected[3] = {0, 0, 0}, aff; + int totelem[3] = {0, 0, 0}; + int affected[3] = {0, 0, 0}; int i, j; if (!(types && flag && action)) @@ -4227,8 +4280,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob, if (pb && sb && !map[j]) { char *p_blk; BMElemSort *s_blk; - tot = totelem[j]; - aff = affected[j]; + int tot = totelem[j]; + int aff = affected[j]; qsort(sb, aff, sizeof(BMElemSort), bmelemsort_comp); @@ -4277,7 +4330,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) { if (rv3d == NULL) { - BKE_report(op->reports, RPT_ERROR, "View not found, can't sort by view axis"); + BKE_report(op->reports, RPT_ERROR, "View not found, cannot sort by view axis"); return OPERATOR_CANCELLED; } } @@ -4465,6 +4518,7 @@ typedef struct { int li; int mcenter[2]; float initial_length; + float pixel_size; /* use when mouse input is interpreted as spatial distance */ int is_modal; NumInput num_input; float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */ @@ -4662,8 +4716,10 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) { /* TODO make modal keymap (see fly mode) */ + RegionView3D *rv3d = CTX_wm_region_view3d(C); BevelData *opdata; float mlen[2]; + float center_3d[3]; if (!edbm_bevel_init(C, op, TRUE)) { return OPERATOR_CANCELLED; @@ -4672,7 +4728,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata = op->customdata; /* initialize mouse values */ - if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; @@ -4680,6 +4736,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); + opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_bevel_update_header(op, C); @@ -4693,6 +4750,44 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event) +{ + BevelData *opdata = op->customdata; + int use_dist = RNA_boolean_get(op->ptr, "use_dist"); + float mdiff[2]; + float factor; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + if (use_dist) { + factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size; + } + else { + factor = (len_v2(mdiff) - MVAL_PIXEL_MARGIN) / opdata->initial_length; + factor = factor - 1.0f; /* a different kind of buffer where nothing happens */ + } + + /* Fake shift-transform... */ + if (event->shift) { + if (opdata->shift_factor < 0.0f) + opdata->shift_factor = RNA_float_get(op->ptr, "percent"); + factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; + } + else if (opdata->shift_factor >= 0.0f) + opdata->shift_factor = -1.0f; + + /* clamp differently based on distance/factor */ + if (use_dist) { + if (factor < 0.0f) factor = 0.0f; + } + else { + CLAMP(factor, 0.0f, 1.0f); + } + + return factor; +} + static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) { BevelData *opdata = op->customdata; @@ -4720,25 +4815,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) case MOUSEMOVE: if (!hasNumInput(&opdata->num_input)) { - float factor; - float mdiff[2]; - - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; - - factor = opdata->initial_length / -len_v2(mdiff) + 1.0f; - - /* Fake shift-transform... */ - if (event->shift) { - if (opdata->shift_factor < 0.0f) - opdata->shift_factor = RNA_float_get(op->ptr, "percent"); - factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; - } - else if (opdata->shift_factor >= 0.0f) - opdata->shift_factor = -1.0f; - - CLAMP(factor, 0.0f, 1.0f); - + const float factor = edbm_bevel_mval_factor(op, event); RNA_float_set(op->ptr, "percent", factor); edbm_bevel_calc(C, op); @@ -4768,6 +4845,11 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) int use_dist = RNA_boolean_get(op->ptr, "use_dist"); RNA_boolean_set(op->ptr, "use_dist", !use_dist); + { + const float factor = edbm_bevel_mval_factor(op, event); + RNA_float_set(op->ptr, "percent", factor); + } + edbm_bevel_calc(C, op); edbm_bevel_update_header(op, C); } @@ -4794,6 +4876,7 @@ void MESH_OT_bevel(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; + /* take note, used as a factor _and_ a distance depending on 'use_dist' */ RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f); /* XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. */ /* RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); */ @@ -4858,8 +4941,9 @@ typedef struct { float old_depth; int mcenter[2]; int modify_depth; - int is_modal; float initial_length; + float pixel_size; /* use when mouse input is interpreted as spatial distance */ + int is_modal; int shift; float shift_amount; BMBackup backup; @@ -5025,15 +5109,17 @@ static int edbm_inset_exec(bContext *C, wmOperator *op) static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) { + RegionView3D *rv3d = CTX_wm_region_view3d(C); InsetData *opdata; float mlen[2]; + float center_3d[3]; edbm_inset_init(C, op, TRUE); opdata = op->customdata; /* initialize mouse values */ - if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; @@ -5041,6 +5127,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); + opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_inset_calc(C, op); @@ -5090,9 +5177,9 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) mdiff[1] = opdata->mcenter[1] - event->mval[1]; if (opdata->modify_depth) - amount = opdata->old_depth + opdata->initial_length / len_v2(mdiff) - 1.0f; + amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); else - amount = opdata->old_thickness - opdata->initial_length / len_v2(mdiff) + 1.0f; + amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); /* Fake shift-transform... */ if (opdata->shift) @@ -5393,6 +5480,57 @@ void MESH_OT_convex_hull(wmOperatorType *ot) join_triangle_props(ot); } +static int mesh_symmetrize_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMOperator bmop; + + EDBM_op_init(em, &bmop, op, "symmetrize input=%hvef direction=%i", + BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction")); + BMO_op_exec(em->bm, &bmop); + + if (!EDBM_op_finish(em, &bmop, op, TRUE)) { + return OPERATOR_CANCELLED; + } + else { + EDBM_update_generic(C, em, TRUE); + EDBM_selectmode_flush(em); + return OPERATOR_FINISHED; + } +} + +void MESH_OT_symmetrize(struct wmOperatorType *ot) +{ + static EnumPropertyItem axis_direction_items[] = { + {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""}, + {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""}, + + {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""}, + {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""}, + + {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""}, + {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Symmetrize"; + ot->description = "Enforce symmetry (both form and topological) across an axis"; + ot->idname = "MESH_OT_symmetrize"; + + /* api callbacks */ + ot->exec = mesh_symmetrize_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items, + BMO_SYMMETRIZE_NEGATIVE_X, + "Direction", "Which sides to copy from and to"); +} + static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 735492cb553..4adf37a14c3 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -593,7 +593,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) /* Check context */ if (base == NULL || base->object->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh"); + BKE_report(op->reports, RPT_ERROR, "Not an object or mesh"); return OPERATOR_CANCELLED; } @@ -610,7 +610,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) } if (!ima) { - BKE_report(op->reports, RPT_ERROR, "Not an Image"); + BKE_report(op->reports, RPT_ERROR, "Not an image"); return OPERATOR_CANCELLED; } @@ -1124,7 +1124,7 @@ static void mesh_remove_faces(Mesh *mesh, int len) void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add geometry in edit mode"); return; } @@ -1140,12 +1140,12 @@ void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessfaces in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessfaces in edit mode"); return; } if (mesh->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessfaces to a mesh that already has polygons"); + BKE_report(reports, RPT_ERROR, "Cannot add tessfaces to a mesh that already has polygons"); return; } @@ -1155,7 +1155,7 @@ void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add edges in edit mode"); return; } @@ -1165,7 +1165,7 @@ void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add vertices in edit mode"); return; } @@ -1175,11 +1175,11 @@ void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove faces in edit mode"); return; } else if (count > mesh->totface) { - BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more faces than the mesh contains"); return; } @@ -1189,11 +1189,11 @@ void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove edges in edit mode"); return; } else if (count > mesh->totedge) { - BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more edges than the mesh contains"); return; } @@ -1203,11 +1203,11 @@ void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode"); return; } else if (count > mesh->totvert) { - BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains"); return; } @@ -1217,7 +1217,7 @@ void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add loops in edit mode."); + BKE_report(reports, RPT_ERROR, "Cannot add loops in edit mode"); return; } @@ -1227,7 +1227,7 @@ void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add polys in edit mode."); + BKE_report(reports, RPT_ERROR, "Cannot add polygons in edit mode"); return; } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index b68c1836992..835b1ccd52d 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -145,6 +145,7 @@ extern struct EnumPropertyItem *corner_type_items; void MESH_OT_merge(struct wmOperatorType *ot); void MESH_OT_subdivide(struct wmOperatorType *ot); +void MESH_OT_unsubdivide(struct wmOperatorType *ot); void MESH_OT_remove_doubles(struct wmOperatorType *ot); void MESH_OT_spin(struct wmOperatorType *ot); void MESH_OT_screw(struct wmOperatorType *ot); @@ -216,6 +217,8 @@ void MESH_OT_vert_slide(struct wmOperatorType *ot); void MESH_OT_convex_hull(struct wmOperatorType *ot); +void MESH_OT_symmetrize(struct wmOperatorType *ot); + /* ******************* mesh_navmesh.c */ void MESH_OT_navmesh_make(struct wmOperatorType *ot); void MESH_OT_navmesh_face_copy(struct wmOperatorType *ot); @@ -223,5 +226,4 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot); void MESH_OT_navmesh_reset(struct wmOperatorType *ot); void MESH_OT_navmesh_clear(struct wmOperatorType *ot); -#endif // __MESH_INTERN_H__ - +#endif /* __MESH_INTERN_H__ */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index ccf91958e08..d06142d2654 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -74,6 +74,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_normals_make_consistent); WM_operatortype_append(MESH_OT_merge); WM_operatortype_append(MESH_OT_subdivide); + WM_operatortype_append(MESH_OT_unsubdivide); WM_operatortype_append(MESH_OT_faces_select_linked_flat); WM_operatortype_append(MESH_OT_edges_select_sharp); WM_operatortype_append(MESH_OT_primitive_plane_add); @@ -168,6 +169,8 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_convex_hull); + WM_operatortype_append(MESH_OT_symmetrize); + #ifdef WITH_GAMEENGINE WM_operatortype_append(MESH_OT_navmesh_make); WM_operatortype_append(MESH_OT_navmesh_face_copy); @@ -211,7 +214,17 @@ void ED_operatormacros_mesh(void) ot = WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", "Rip polygons and move the result", OPTYPE_UNDO | OPTYPE_REGISTER); - WM_operatortype_macro_define(ot, "MESH_OT_rip"); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip"); + RNA_boolean_set(otmacro->ptr, "use_fill", FALSE); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); + + /* annoying we can't pass 'use_fill' through the macro */ + ot = WM_operatortype_append_macro("MESH_OT_rip_move_fill", "Rip Fill", "Rip-fill polygons and move the result", + OPTYPE_UNDO | OPTYPE_REGISTER); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip"); + RNA_boolean_set(otmacro->ptr, "use_fill", TRUE); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_boolean_set(otmacro->ptr, "mirror", FALSE); @@ -326,6 +339,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_rip_move", VKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_rip_move_fill", VKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 42d82fff38e..d8793505608 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -113,7 +113,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) CustomData vdata, edata, fdata, ldata, pdata; if (scene->obedit) { - BKE_report(op->reports, RPT_WARNING, "Cant join while in editmode"); + BKE_report(op->reports, RPT_WARNING, "Cannot join while in editmode"); return OPERATOR_CANCELLED; } @@ -161,8 +161,8 @@ int join_mesh_exec(bContext *C, wmOperator *op) } if (totvert > MESH_MAX_VERTS) { - BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is " STRINGIFY(MESH_MAX_VERTS), totvert); - return OPERATOR_CANCELLED; + BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is %ld", totvert, MESH_MAX_VERTS); + return OPERATOR_CANCELLED; } /* new material indices and material array */ @@ -1192,7 +1192,7 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in /* sample rect to increase chances of selecting, so that when clicking * on an edge in the backbuf, we can still select a face */ - int dummy_dist; + float dummy_dist; *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist, 0, NULL, NULL); } else { @@ -1237,7 +1237,7 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], const int v_idx = me->mloop[mp->loopstart + fidx].v; dm->getVertCo(dm, v_idx, co); mul_m4_v3(ob->obmat, co); - if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { len = len_squared_v2v2(mval_f, sco); if (len < len_best) { len_best = len; @@ -1277,7 +1277,7 @@ int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *in /* sample rect to increase chances of selecting, so that when clicking * on an face in the backbuf, we can still select a vert */ - int dummy_dist; + float dummy_dist; *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL); } else { diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index e9063687506..b9018914633 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -98,7 +98,7 @@ void load_editMball(Object *UNUSED(obedit)) } /* Add metaelem primitive to metaball object (which is in edit mode) */ -MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], int type, int UNUSED(newname)) +MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type, int UNUSED(newname)) { MetaBall *mball = (MetaBall *)obedit->data; MetaElem *ml; @@ -111,6 +111,7 @@ MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[ } ml = BKE_mball_element_add(mball, type); + ml->rad *= dia; copy_v3_v3(&ml->x, mat[3]); ml->flag |= SELECT; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 43a32cd662e..9a2915a5d55 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -136,6 +136,7 @@ static EnumPropertyItem field_type_items[] = { {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, + {PFIELD_SMOKEFLOW, "SMOKE", ICON_FORCE_SMOKEFLOW, "Smoke Flow", ""}, {0, NULL, 0, NULL, NULL} }; @@ -185,7 +186,8 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], /* Uses context to figure out transform for primitive. * Returns standard diameter. */ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, - const float loc[3], const float rot[3], float primmat[][4]) + const float loc[3], const float rot[3], float primmat[][4], + int apply_diameter) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -208,8 +210,17 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); - if (v3d) - return ED_view3d_grid_scale(scene, v3d, NULL); + if (v3d) { + float dia = ED_view3d_grid_scale(scene, v3d, NULL); + + if (apply_diameter) { + primmat[0][0] *= dia; + primmat[1][1] *= dia; + primmat[2][2] *= dia; + } + + return dia; + } return 1.0f; } @@ -356,7 +367,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa Scene *scene = CTX_data_scene(C); Object *ob; - /* For as long scene has editmode... */ + /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */ @@ -441,7 +452,7 @@ static int effector_add_exec(bContext *C, wmOperator *op) rename_id(&ob->id, "CurveGuide"); ((Curve *)ob->data)->flag |= CU_PATH | CU_3D; ED_object_enter_editmode(C, 0); - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE); BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1)); if (!enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); @@ -546,6 +557,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; float mat[4][4]; + float dia; if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; @@ -557,9 +569,9 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE); - add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); + add_metaball_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"), newob); /* userdef */ if (newob && !enter_editmode) { diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 6d124377821..bc5d289d04c 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -900,7 +900,7 @@ static void finish_images(MultiresBakeRender *bkr) RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter); - ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;; + ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; if (ibuf->rect_float) ibuf->userflags |= IB_RECT_INVALID; @@ -937,7 +937,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ob = base->object; if (ob->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh"); + BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); ok = 0; break; @@ -985,7 +985,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); if (!ibuf) { - BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer"); + BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); ok = 0; } @@ -1366,20 +1366,23 @@ static void finish_bake_internal(BakeRender *bkr) if (bkr->prev_r_raytrace == 0) bkr->scene->r.mode &= ~R_RAYTRACE; - /* force OpenGL reload and mipmap recalc */ for (ima = G.main->image.first; ima; ima = ima->id.next) { ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); - if (bkr->result == BAKE_RESULT_OK) { - if (ima->ok == IMA_OK_LOADED) { - if (ibuf) { - if (ibuf->userflags & IB_BITMAPDIRTY) { - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - GPU_free_image(ima); - imb_freemipmapImBuf(ibuf); - } + /* some of the images could have been changed during bake, + * so recreate mipmaps regardless bake result status + */ + if (ima->ok == IMA_OK_LOADED) { + if (ibuf) { + if (ibuf->userflags & IB_BITMAPDIRTY) { + GPU_free_image(ima); + imb_freemipmapImBuf(ibuf); } + + /* invalidate display buffers for changed images */ + if (ibuf->userflags & IB_BITMAPDIRTY) + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 56f2426b1b0..80993d6cca7 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -853,7 +853,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op) bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; if (data == NULL) { - BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found"); return OPERATOR_CANCELLED; } @@ -1073,7 +1073,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op) bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; if (data == NULL) { - BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index a6afe6b2d04..8bc249974f2 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -442,7 +442,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); if (!ok) { - BKE_report(reports, RPT_ERROR, "Requires selected vertices or active Vertex Group"); + BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group"); return FALSE; } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 4c83f6ef2ce..0be9c92897e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -138,6 +138,7 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); /* object_lattice.c */ void LATTICE_OT_select_all(struct wmOperatorType *ot); void LATTICE_OT_make_regular(struct wmOperatorType *ot); +void LATTICE_OT_flip(struct wmOperatorType *ot); /* object_group.c */ void GROUP_OT_create(struct wmOperatorType *ot); @@ -204,6 +205,7 @@ void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); @@ -214,6 +216,7 @@ void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 1f7be0bf9a6..ac9c4f7adee 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "RNA_access.h" +#include "RNA_define.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -167,7 +168,7 @@ void load_editLatt(Object *obedit) } } -/************************** Operators *************************/ +/************************** Select All Operator *************************/ void ED_setflagsLatt(Object *obedit, int flag) { @@ -254,6 +255,8 @@ void LATTICE_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/************************** Make Regular Operator *************************/ + static int make_regular_poll(bContext *C) { Object *ob; @@ -300,18 +303,265 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/************************** Flip Verts Operator *************************/ + +/* flipping options */ +typedef enum eLattice_FlipAxes { + LATTICE_FLIP_U = 0, + LATTICE_FLIP_V = 1, + LATTICE_FLIP_W = 2 +} eLattice_FlipAxes; + +/* Helper macro for accessing item at index (u, v, w) + * < lt: (Lattice) + * < U: (int) u-axis coordinate of point + * < V: (int) v-axis coordinate of point + * < W: (int) w-axis coordinate of point + * < dimU: (int) number of points per row or number of columns (U-Axis) + * < dimV: (int) number of rows (V-Axis) + * > returns: (BPoint *) pointer to BPoint at this index + */ +#define LATTICE_PT(lt, U, V, W, dimU, dimV) \ + ( (lt)->def + \ + ((dimU) * (dimV)) * (W) + \ + (dimU) * (V) + \ + (U) \ + ) + +/* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained + * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) + * - Helper for lattice_flip_exec() + */ +static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bp; + float diff; + + /* just the point in the middle (unpaired) */ + bp = LATTICE_PT(lt, u, v, w, lt->pntsu, lt->pntsv); + + /* flip over axis */ + diff = mid - bp->vec[axis]; + bp->vec[axis] = mid + diff; +} + +/* Swap pairs of lattice points along a specified axis + * - Helper for lattice_flip_exec() + */ +static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bpA, *bpB; + + int numU = lt->pntsu; + int numV = lt->pntsv; + int numW = lt->pntsw; + + int u0 = u, u1 = u; + int v0 = v, v1 = v; + int w0 = w, w1 = w; + + /* get pair index by just overriding the relevant pair-value + * - "-1" else buffer overflow + */ + switch (axis) { + case LATTICE_FLIP_U: + u1 = numU - u - 1; + break; + case LATTICE_FLIP_V: + v1 = numV - v - 1; + break; + case LATTICE_FLIP_W: + w1 = numW - w - 1; + break; + } + + /* get points to operate on */ + bpA = LATTICE_PT(lt, u0, v0, w0, numU, numV); + bpB = LATTICE_PT(lt, u1, v1, w1, numU, numV); + + /* Swap all coordinates, so that flipped coordinates belong to + * the indices on the correct side of the lattice. + * + * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + swap_v3_v3(bpA->vec, bpB->vec); + + /* However, we need to mirror the coordinate values on the axis we're dealing with, + * otherwise we'd have effectively only rotated the points around. If we don't do this, + * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms + * such as flipped normals, etc. + * + * Coords: (3 4) |0| (-2 4) --\ + * \-> (-3 4) |0| (2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + lattice_flip_point_value(lt, u0, v0, w0, mid, axis); + lattice_flip_point_value(lt, u1, v1, w1, mid, axis); +} + +static int lattice_flip_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt; + + eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis"); + int numU, numV, numW; + int totP; + + float mid = 0.0f; + short isOdd = 0; + + /* get lattice - we need the "edit lattice" from the lattice... confusing... */ + lt = (Lattice *)obedit->data; + lt = lt->editlatt->latt; + + numU = lt->pntsu; + numV = lt->pntsv; + numW = lt->pntsw; + totP = numU * numV * numW; + + /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */ + switch (axis) { + case LATTICE_FLIP_U: + isOdd = numU & 1; + break; + case LATTICE_FLIP_V: + isOdd = numV & 1; + break; + case LATTICE_FLIP_W: + isOdd = numW & 1; + break; + + default: + printf("lattice_flip(): Unknown flipping axis (%d)\n", axis); + return OPERATOR_CANCELLED; + } + + if (isOdd) { + BPoint *bp; + float avgInv = 1.0f / (float)totP; + int i; + + /* midpoint calculation - assuming that u/v/w are axis-aligned */ + for (i = 0, bp = lt->def; i < totP; i++, bp++) { + mid += bp->vec[axis] * avgInv; + } + } + + /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */ + switch (axis) { + case LATTICE_FLIP_U: + { + int u, v, w; + + /* v/w strips - front to back, top to bottom */ + for (w = 0; w < numW; w++) { + for (v = 0; v < numV; v++) { + /* swap coordinates of pairs of vertices on u */ + for (u = 0; u < (numU / 2); u++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip u-coordinate of midpoint (i.e. unpaired point on u) */ + if (isOdd) { + u = (numU / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + case LATTICE_FLIP_V: + { + int u, v, w; + + /* u/w strips - front to back, left to right */ + for (w = 0; w < numW; w++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on v */ + for (v = 0; v < (numV / 2); v++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip v-coordinate of midpoint (i.e. unpaired point on v) */ + if (isOdd) { + v = (numV / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + case LATTICE_FLIP_W: + { + int u, v, w; + + for (v = 0; v < numV; v++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on w */ + for (w = 0; w < (numW / 2); w++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip w-coordinate of midpoint (i.e. unpaired point on w) */ + if (isOdd) { + w = (numW / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + + default: /* shouldn't happen, but just in case */ + break; + } + + /* updates */ + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_flip(wmOperatorType *ot) +{ + static EnumPropertyItem flip_items[] = { + {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""}, + {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""}, + {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name = "Flip (Distortion Free)"; + ot->description = "Mirror all control points without inverting the lattice deform"; + ot->idname = "LATTICE_OT_flip"; + + /* api callbacks */ + ot->poll = ED_operator_editlattice; + ot->invoke = WM_menu_invoke; + ot->exec = lattice_flip_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped"); +} + /****************************** Mouse Selection *************************/ -static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y) +static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2]) { - struct { BPoint *bp; short dist, select; int mval[2]; } *data = userData; - float temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData; + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if ((bp->f1 & SELECT) == data->select) - temp += 5; + if ((bp->f1 & SELECT) && data->select) + dist_test += 5.0f; - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->bp = bp; } @@ -322,15 +572,15 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) /* sel==1: selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ /* return 0 1 2: handlepunt */ - struct { BPoint *bp; short dist, select; int mval[2]; } data = {NULL}; + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL}; data.dist = 100; data.select = sel; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); + lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return data.bp; } @@ -341,7 +591,7 @@ int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int BPoint *bp = NULL; view3d_set_viewcontext(C, &vc); - bp = findnearestLattvert(&vc, mval, 1); + bp = findnearestLattvert(&vc, mval, TRUE); if (bp) { if (extend) { diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index d75ef78fc4c..02070506937 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1242,7 +1242,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (!secondob) { - BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from"); + BKE_report(op->reports, RPT_ERROR, "Second selected mesh object required to copy shape from"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index fa40d579e2b..b6d3594c826 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -178,6 +178,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_select); WM_operatortype_append(OBJECT_OT_vertex_group_deselect); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); + WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected); WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); @@ -188,6 +189,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_levels); WM_operatortype_append(OBJECT_OT_vertex_group_blend); WM_operatortype_append(OBJECT_OT_vertex_group_clean); + WM_operatortype_append(OBJECT_OT_vertex_group_limit_total); WM_operatortype_append(OBJECT_OT_vertex_group_mirror); WM_operatortype_append(OBJECT_OT_vertex_group_set_active); WM_operatortype_append(OBJECT_OT_vertex_group_sort); @@ -209,6 +211,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(LATTICE_OT_select_all); WM_operatortype_append(LATTICE_OT_make_regular); + WM_operatortype_append(LATTICE_OT_flip); WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_link); @@ -422,6 +425,8 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0); + /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 446c0a51ed5..447ba29e203 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -423,29 +423,92 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot) /********************** Clear Parent Operator ******************* */ +typedef enum eObClearParentTypes { + CLEAR_PARENT_ALL = 0, + CLEAR_PARENT_KEEP_TRANSFORM, + CLEAR_PARENT_INVERSE +} eObClearParentTypes; + EnumPropertyItem prop_clear_parent_types[] = { - {0, "CLEAR", 0, "Clear Parent", ""}, - {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, - {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, + {CLEAR_PARENT_ALL, "CLEAR", 0, "Clear Parent", ""}, + {CLEAR_PARENT_KEEP_TRANSFORM, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, + {CLEAR_PARENT_INVERSE, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, {0, NULL, 0, NULL, NULL} }; -void ED_object_parent_clear(Object *ob, int type) +/* Helper for ED_object_parent_clear() - Remove deform-modifiers associated with parent */ +static void object_remove_parent_deform_modifiers(Object *ob, const Object *par) { + if (ELEM3(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) { + ModifierData *md, *mdn; + + /* assume that we only need to remove the first instance of matching deform modifier here */ + for (md = ob->modifiers.first; md; md = mdn) { + short free = FALSE; + + mdn = md->next; + + /* need to match types (modifier + parent) and references */ + if ((md->type == eModifierType_Armature) && (par->type == OB_ARMATURE)) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->object == par) { + free = TRUE; + } + } + else if ((md->type == eModifierType_Lattice) && (par->type == OB_LATTICE)) { + LatticeModifierData *lmd = (LatticeModifierData *)md; + if (lmd->object == par) { + free = TRUE; + } + } + else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVE)) { + CurveModifierData *cmd = (CurveModifierData *)md; + if (cmd->object == par) { + free = TRUE; + } + } + + /* free modifier if match */ + if (free) { + BLI_remlink(&ob->modifiers, md); + modifier_free(md); + } + } + } +} +void ED_object_parent_clear(Object *ob, int type) +{ if (ob->parent == NULL) return; + + switch (type) { + case CLEAR_PARENT_ALL: + { + /* for deformers, remove corresponding modifiers to prevent a large number of modifiers building up */ + object_remove_parent_deform_modifiers(ob, ob->parent); + + /* clear parenting relationship completely */ + ob->parent = NULL; + } + break; - if (type == 0) { - ob->parent = NULL; - } - else if (type == 1) { - ob->parent = NULL; - BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); - } - else if (type == 2) - unit_m4(ob->parentinv); + case CLEAR_PARENT_KEEP_TRANSFORM: + { + /* remove parent, and apply the parented transform result as object's local transforms */ + ob->parent = NULL; + BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); + } + break; + case CLEAR_PARENT_INVERSE: + { + /* object stays parented, but the parent inverse (i.e. offset from parent to retain binding state) is cleared */ + unit_m4(ob->parentinv); + } + break; + } + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; } @@ -606,23 +669,38 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object ob->partype = PAROBJECT; /* note, dna define, not operator property */ //ob->partype= PARSKEL; /* note, dna define, not operator property */ - /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */ + /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses + * - We need to ensure that the modifier we're adding doesn't already exist, so we check this by + * assuming that the parent is selected too... + */ // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { ModifierData *md; switch (partype) { case PAR_CURVE: /* curve deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); - ((CurveModifierData *)md)->object = par; + if ( modifiers_isDeformedByCurve(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); + if (md) { + ((CurveModifierData *)md)->object = par; + } + } break; case PAR_LATTICE: /* lattice deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); - ((LatticeModifierData *)md)->object = par; + if (modifiers_isDeformedByLattice(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); + if (md) { + ((LatticeModifierData *)md)->object = par; + } + } break; default: /* armature deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); - ((ArmatureModifierData *)md)->object = par; + if (modifiers_isDeformedByArmature(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); + if (md) { + ((ArmatureModifierData *)md)->object = par; + } + } break; } } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index cfd4945688b..86a55a9b278 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -162,15 +162,15 @@ static int object_shape_key_mirror(bContext *C, Object *ob) kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { - int i1, i2; - float *fp1, *fp2; - float tvec[3]; char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror"); if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mv; + int i1, i2; + float *fp1, *fp2; + float tvec[3]; mesh_octree_table(ob, NULL, NULL, 's'); diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 9129d651d4d..4c95884a51a 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -217,7 +217,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or Keying Set Name"); return OPERATOR_CANCELLED; } @@ -381,8 +381,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - float rsmat[3][3], tmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; - int a, change = 1; + float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; + int change = 1; /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -417,7 +417,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo cu = ob->data; if (!(cu->flag & CU_3D) && (apply_rot || apply_loc)) { - BKE_report(reports, RPT_ERROR, "Neither rotation nor location could be applied to a 2d curve, doing nothing"); + BKE_report(reports, RPT_ERROR, + "Neither rotation nor location could be applied to a 2D curve, doing nothing"); change = 0; } if (cu->key) { @@ -464,6 +465,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo copy_v3_v3(mat[3], ob->loc); if (!(apply_scale && apply_rot)) { + float tmat[3][3]; /* correct for scale and rotation that is still applied */ BKE_object_to_mat3(ob, obmat); invert_m3_m3(iobmat, obmat); @@ -476,6 +478,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mvert; + int a; if (apply_scale) multiresModifier_scale_disp(scene, ob); @@ -518,6 +521,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo Nurb *nu; BPoint *bp; BezTriple *bezt; + int a; scale = mat3_to_scale(rsmat); @@ -896,6 +900,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { + CollectionPointerLink *ctx_link_other; + /* was the object data modified * note: the functions above must set 'cent' */ copy_v3_v3(centn, cent); @@ -910,8 +916,16 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ignore_parent_tx(bmain, scene, ob); /* other users? */ - CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //{ + + /* use existing context looper */ + for (ctx_link_other = ctx_data_list.first; + ctx_link_other; + ctx_link_other = ctx_link_other->next) { + Object *ob_other = ctx_link_other->ptr.data; + if ((ob_other->flag & OB_DONE) == 0 && ((ob->data && (ob->data == ob_other->data)) || (ob->dup_group == ob_other->dup_group && @@ -931,7 +945,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ignore_parent_tx(bmain, scene, ob_other); } } - CTX_DATA_END; + //CTX_DATA_END; } } } @@ -948,9 +962,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* Warn if any errors occurred */ if (tot_lib_error + tot_multiuser_arm_error) { - BKE_reportf(op->reports, RPT_WARNING, "%i Object(s) Not Centered, %i Changed:", tot_lib_error + tot_multiuser_arm_error, tot_change); + BKE_reportf(op->reports, RPT_WARNING, "%i object(s) not centered, %i changed:", tot_lib_error + tot_multiuser_arm_error, tot_change); if (tot_lib_error) - BKE_reportf(op->reports, RPT_WARNING, "|%i linked library objects", tot_lib_error); + BKE_reportf(op->reports, RPT_WARNING, "|%i linked library object(s)", tot_lib_error); if (tot_multiuser_arm_error) BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)", tot_multiuser_arm_error); } @@ -962,8 +976,10 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) { static EnumPropertyItem prop_set_center_types[] = { {GEOMETRY_TO_ORIGIN, "GEOMETRY_ORIGIN", 0, "Geometry to Origin", "Move object geometry to object origin"}, - {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", "Move object origin to center of object geometry"}, - {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", "Move object origin to position of the 3d cursor"}, + {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", + "Move object origin to center of object geometry"}, + {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", + "Move object origin to position of the 3D cursor"}, {0, NULL, 0, NULL, NULL} }; @@ -975,7 +991,7 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) /* identifiers */ ot->name = "Set Origin"; - ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3d cursor"; + ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3D cursor"; ot->idname = "OBJECT_OT_origin_set"; /* api callbacks */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b31d2b8b076..1be09847ef2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -20,7 +20,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Ove M Henriksen. * * ***** END GPL LICENSE BLOCK ***** */ @@ -29,7 +29,6 @@ * \ingroup edobj */ - #include <string.h> #include <stddef.h> #include <math.h> @@ -83,6 +82,19 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup); static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg); static void vgroup_delete_all(Object *ob); +static int vertex_group_use_vert_sel(Object *ob) +{ + if (ob->mode == OB_MODE_EDIT) { + return TRUE; + } + else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) { + return TRUE; + } + else { + return FALSE; + } +} + static Lattice *vgroup_edit_lattice(Object *ob) { Lattice *lt = ob->data; @@ -377,6 +389,332 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } +/***********************Start weight transfer (WT)*********************************/ + +typedef enum WT_VertexGroupMode { + WT_REPLACE_ACTIVE_VERTEX_GROUP = 1, + WT_REPLACE_ALL_VERTEX_GROUPS = 2 +} WT_VertexGroupMode; + +typedef enum WT_Method { + WT_BY_INDEX = 1, + WT_BY_NEAREST_VERTEX = 2, + WT_BY_NEAREST_FACE = 3, + WT_BY_NEAREST_VERTEX_IN_FACE = 4 +} WT_Method; + +typedef enum WT_ReplaceMode { + WT_REPLACE_ALL_WEIGHTS = 1, + WT_REPLACE_EMPTY_WEIGHTS = 2, +} WT_ReplaceMode; + +static EnumPropertyItem WT_vertex_group_mode_item[] = { + {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, + {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem WT_method_item[] = { + {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, + {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, + {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, + {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem WT_replace_mode_item[] = { + {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, + {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, + {0, NULL, 0, NULL, NULL} +}; + +/*copy weight*/ +static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode) +{ + switch (replace_mode) { + case WT_REPLACE_ALL_WEIGHTS: + *r_weight_dst = weight_src; + break; + + case WT_REPLACE_EMPTY_WEIGHTS: + if (*r_weight_dst == 0.0f) { + *r_weight_dst = weight_src; + } + break; + + default: + BLI_assert(0); + break; + } +} + +/* could be exposed externally */ +static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, + WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) +{ + bDeformGroup *dg_dst; + Mesh *me_dst, *me_src; + DerivedMesh *dmesh_src; + BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL}; + MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst; + MVert *mv_dst, *mv_src; + MFace *mface_src, *mf; + BVHTreeNearest nearest; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex; + unsigned int f_index; + float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; + const int use_vert_sel = vertex_group_use_vert_sel(ob_dst); + + /* create new and overwrite vertex group on destination without data */ + if (!defgroup_find_name(ob_dst, dg_src->name)) { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } + + /* get destination deformgroup */ + dg_dst = defgroup_find_name(ob_dst, dg_src->name); + + /* get meshes */ + dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH); + me_dst = ob_dst->data; + me_src = ob_src->data; + + /* sanity check */ + if (!me_src->dvert) { + BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)"); + return 0; + } + + /* create data in memory when nothing there */ + if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); + + /* get vertex group arrays */ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel); + + /* get indexes of vertex groups */ + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); + + /* get vertices */ + mv_dst = me_dst->mvert; + mv_src = dmesh_src->getVertArray(dmesh_src); + + /* prepare transformation matrix */ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + + /* clear weights */ + if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { + + if (*dv_dst == NULL) continue; + + dw_dst = defvert_find_index(*dv_dst, index_dst); + /* remove vertex from group */ + if (dw_dst) defvert_remove_group(*dv_dst, dw_dst); + } + } + + switch (method) { + + case WT_BY_INDEX: + /* check if indices are matching, delete and return if not */ + if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src || + dv_array_src == NULL || dv_array_dst == NULL) + { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + if (dv_array_src) MEM_freeN(dv_array_src); + if (dv_array_dst) MEM_freeN(dv_array_dst); + dmesh_src->release(dmesh_src); + BKE_report(op->reports, RPT_ERROR, "Transfer failed (indices are not matching)"); + return 0; + } + + /* loop through the vertices*/ + for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { + + if (*dv_dst == NULL) { + continue; + } + + /* copy weight */ + dw_src = defvert_find_index(*dv_src, index_src); + if (dw_src && dw_src->weight) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); + } + } + break; + + case WT_BY_NEAREST_VERTEX: + /* make node tree */ + bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); + + /* loop trough vertices */ + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + + if (*dv_dst == NULL) { + continue; + } + + /* reset nearest */ + nearest.dist = FLT_MAX; + /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + nearest.index = -1; + + /* transform into target space */ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /* node tree accelerated search for closest vetex */ + BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, + &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); + + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); + if (dw_src && dw_src->weight) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); + } + } + + /* free memory */ + free_bvhtree_from_mesh(&tree_mesh_vertices_src); + break; + + case WT_BY_NEAREST_FACE: + /* get faces */ + DM_ensure_tessface(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /* make node tree */ + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); + + /* loop through the vertices */ + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + + if (*dv_dst == NULL) { + continue; + } + + /* reset nearest */ + nearest.dist = FLT_MAX; + /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + nearest.index = -1; + + /* transform into target space */ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /* node tree accelerated search for closest face */ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + index_nearest = nearest.index; + + /* project onto face */ + mf = &mface_src[index_nearest]; + normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co); + project_v3_plane(tmp_co, normal, mv_src[mf->v1].co); + + /* interpolate weights over face*/ + f_index = mf->v4 ? 3 : 2; + if (f_index == 3) { + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co); + } + else { + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co); + } + + /* get weights from face*/ + weight = 0; + do { + v_index = (&mf->v1)[f_index]; + weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); + } while (f_index--); + + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + if (weight > 0) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); + } + } + + /* free memory */ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + break; + + case WT_BY_NEAREST_VERTEX_IN_FACE: + /* get faces */ + DM_ensure_tessface(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /* make node tree */ + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); + + /* loop through the vertices */ + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + + if (*dv_dst == NULL) { + continue; + } + + /* reset nearest */ + nearest.dist = FLT_MAX; + /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + nearest.index = -1; + + /* transform into target space */ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /* node tree accelerated search for closest face */ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + index_nearest = nearest.index; + + /* get distances */ + mf = &mface_src[index_nearest]; + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co); + + /* get closest vertex */ + f_index = mf->v4 ? 3 : 2; + if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1; + else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2; + else index_nearest_vertex = mf->v3; + if (f_index == 3) { + dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co); + if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { + index_nearest_vertex = mf->v4; + } + } + + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); + if (dw_src && dw_src->weight) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); + } + } + + /* free memory */ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + break; + + default: + BLI_assert(0); + break; + } + + /*free memory*/ + if (dv_array_src) MEM_freeN(dv_array_src); + if (dv_array_dst) MEM_freeN(dv_array_dst); + dmesh_src->release(dmesh_src); + + return 1; +} + +/***********************End weight transfer (WT)***********************************/ /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -580,7 +918,6 @@ void ED_vgroup_select_by_name(Object *ob, const char *name) static void vgroup_select_verts(Object *ob, int select) { const int def_nr = ob->actdef - 1; - MDeformVert *dv; if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -596,7 +933,7 @@ static void vgroup_select_verts(Object *ob, int select) BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); if (defvert_find_index(dv, def_nr)) { BM_vert_select_set(em->bm, eve, select); } @@ -633,6 +970,7 @@ static void vgroup_select_verts(Object *ob, int select) Lattice *lt = vgroup_edit_lattice(ob); if (lt->dvert) { + MDeformVert *dv; BPoint *bp; int a, tot; @@ -704,7 +1042,7 @@ static void vgroup_normalize(Object *ob) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1109,7 +1447,7 @@ static void vgroup_levels(Object *ob, float offset, float gain) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1143,7 +1481,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1221,7 +1559,7 @@ static void vgroup_invert(Object *ob, const short auto_assign, const short auto_ MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1389,13 +1727,119 @@ static void vgroup_blend(Object *ob, const float fac) } } +static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2) +{ + /* qsort sorts in ascending order. We want descending order to save a memcopy + * so this compare function is inverted from the standard greater than comparison qsort needs. + * A normal compare function is called with two pointer arguments and should return an integer less than, equal to, + * or greater than zero corresponding to whether its first argument is considered less than, equal to, + * or greater than its second argument. This does the opposite. */ + const struct MDeformWeight *dw1 = a1, *dw2 = a2; + + if (dw1->weight < dw2->weight) return 1; + else if (dw1->weight > dw2->weight) return -1; + else if (&dw1 < &dw2) return 1; /* compare addresses so we have a stable sort algorithm */ + else return -1; +} + +/* Used for limiting the number of influencing bones per vertex when exporting + * skinned meshes. if all_deform_weights is True, limit all deform modifiers + * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/ +static int vertex_group_limit_total(Object *ob, + const int max_weights, + const int all_deform_weights) +{ + MDeformVert *dv, **dvert_array = NULL; + int i, dvert_tot = 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); + int is_change = FALSE; + + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + + if (dvert_array) { + int defbase_tot = BLI_countlist(&ob->defbase); + const char *vgroup_validmap = (all_deform_weights == FALSE) ? + BKE_objdef_validmap_get(ob, defbase_tot) : + NULL; + int num_to_drop = 0; + + /* only the active group */ + for (i = 0; i < dvert_tot; i++) { + + /* in case its not selected */ + if (!(dv = dvert_array[i])) { + continue; + } + + if (all_deform_weights) { + /* keep only the largest weights, discarding the rest + * qsort will put array in descending order because of invCompare function */ + num_to_drop = dv->totweight - max_weights; + if (num_to_drop > 0) { + qsort(dv->dw, dv->totweight, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); + dv->dw = MEM_reallocN(dv->dw, sizeof(MDeformWeight) * max_weights); + dv->totweight = max_weights; + is_change = TRUE; + } + } + else { + MDeformWeight *dw_temp; + int bone_count = 0, non_bone_count = 0; + int j; + /* only consider vgroups with bone modifiers attached (in vgroup_validmap) */ + + num_to_drop = dv->totweight - max_weights; + + /* first check if we even need to test further */ + if (num_to_drop > 0) { + /* re-pack dw array so that non-bone weights are first, bone-weighted verts at end + * sort the tail, then copy only the truncated array back to dv->dw */ + dw_temp = MEM_mallocN(sizeof(MDeformWeight) * (dv->totweight), __func__); + bone_count = 0; non_bone_count = 0; + for (j = 0; j < dv->totweight; j++) { + BLI_assert(dv->dw[j].def_nr < defbase_tot); + if (!vgroup_validmap[(dv->dw[j]).def_nr]) { + dw_temp[non_bone_count] = dv->dw[j]; + non_bone_count += 1; + } + else { + dw_temp[dv->totweight - 1 - bone_count] = dv->dw[j]; + bone_count += 1; + } + } + BLI_assert(bone_count + non_bone_count == dv->totweight); + num_to_drop = bone_count - max_weights; + if (num_to_drop > 0) { + qsort(&dw_temp[non_bone_count], bone_count, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); + dv->totweight -= num_to_drop; + /* Do we want to clean/normalize here? */ + MEM_freeN(dv->dw); + dv->dw = MEM_reallocN(dw_temp, sizeof(MDeformWeight) * dv->totweight); + is_change = TRUE; + } + else { + MEM_freeN(dw_temp); + } + } + } + } + MEM_freeN(dvert_array); + + if (vgroup_validmap) { + MEM_freeN((void *)vgroup_validmap); + } + } + + return is_change; +} + static void vgroup_clean(Object *ob, const float epsilon, int keep_single) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1431,7 +1875,7 @@ static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_sin { MDeformVert **dvert_array = NULL; int i, dvert_tot = 0; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); @@ -2007,7 +2451,6 @@ static void vgroup_delete_all(Object *ob) /* only in editmode */ static void vgroup_assign_verts(Object *ob, const float weight) { - MDeformVert *dv; const int def_nr = ob->actdef - 1; if (!BLI_findlink(&ob->defbase, def_nr)) @@ -2027,6 +2470,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MDeformVert *dv; MDeformWeight *dw; dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); /* can be NULL */ dw = defvert_verify_index(dv, def_nr); @@ -2061,6 +2505,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) } else if (ob->type == OB_LATTICE) { Lattice *lt = vgroup_edit_lattice(ob); + MDeformVert *dv; BPoint *bp; int a, tot; @@ -2665,6 +3110,47 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) "Keep verts assigned to at least one group when cleaning"); } +static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + + const int limit = RNA_int_get(op->ptr, "limit"); + const int all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights"); + + if (vertex_group_limit_total(ob, limit, all_deform_weights)) { + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_WARNING, "No vertex groups limited"); + + /* note, would normally return cancelled, except we want the redo + * UI to show up for users to change */ + return OPERATOR_FINISHED; + } +} + +void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Limit Number of Weights per Vertex"; + ot->idname = "OBJECT_OT_vertex_group_limit_total"; + ot->description = "Limits deform weights associated with a vertex to a specified number by removing lowest weights"; + + /* api callbacks */ + ot->poll = vertex_group_poll; + ot->exec = vertex_group_limit_total_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32); + RNA_def_boolean(ot->srna, "all_deform_weights", FALSE, "All Deform Weights", "Cull all deform weights, not just bones"); +} static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { @@ -2762,14 +3248,13 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", + "Copy VGroups to Selected warning, %d done, %d failed (object data must have matching indices)", change, fail); } return OPERATOR_FINISHED; } - void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -2785,6 +3270,86 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *ob_act = CTX_data_active_object(C); + bDeformGroup *dg_src; + int fail = 0; + + WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "WT_vertex_group_mode"); + WT_Method method = RNA_enum_get(op->ptr, "WT_method"); + WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode"); + + /* Macro to loop through selected objects and perform operation depending on function, option and method */ + CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects) + { + + if (ob_act != ob_slc && ob_slc->defbase.first) { + switch (vertex_group_mode) { + + case WT_REPLACE_ACTIVE_VERTEX_GROUP: + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, + BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), + scene, method, replace_mode, op)) + { + fail++; + } + break; + + case WT_REPLACE_ALL_VERTEX_GROUPS: + for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, + dg_src, scene, method, replace_mode, op)) + { + fail++; + } + } + break; + + default: + BLI_assert(0); + break; + } + } + } + + /* Event notifiers for correct display of data */ + DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data); + + CTX_DATA_END; + + if (fail != 0) { + return OPERATOR_CANCELLED; + } + else { + return OPERATOR_FINISHED; + } +} + +/* transfers weight from active to selected */ +void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Transfer Weights"; + ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; + ot->description = "Transfer weight paint to active from selected mesh"; + + /* api callbacks */ + ot->poll = vertex_group_poll; + ot->exec = vertex_group_transfer_weight_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", ""); +} + static EnumPropertyItem vgroup_items[] = { {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 70fe87e5c01..467ad5c6ff9 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -73,9 +73,9 @@ static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) /* set preview for this surface only and set active */ canvas->active_sur = 0; - for (surface=surface->prev; surface; surface=surface->prev) { - surface->flags &= ~MOD_DPAINT_PREVIEW; - canvas->active_sur++; + for (surface = surface->prev; surface; surface = surface->prev) { + surface->flags &= ~MOD_DPAINT_PREVIEW; + canvas->active_sur++; } return OPERATOR_FINISHED; @@ -94,26 +94,26 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = ED_object_context(C); + Object *obj_ctx = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; - int id=0; + int id = 0; /* Make sure we're dealing with a canvas */ - pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); + pmd = (DynamicPaintModifierData *)modifiers_findByType(obj_ctx, eModifierType_DynamicPaint); if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; canvas = pmd->canvas; surface = canvas->surfaces.first; /* find active surface and remove it */ - for (; surface; surface=surface->next) { + for (; surface; surface = surface->next) { if (id == canvas->active_sur) { canvas->active_sur -= 1; dynamicPaint_freeSurface(surface); @@ -123,8 +123,8 @@ static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) } dynamicPaint_resetPreview(canvas); - DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject); + DAG_id_tag_update(&obj_ctx->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obj_ctx); return OPERATOR_FINISHED; } @@ -142,7 +142,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int type_toggle_exec(bContext *C, wmOperator *op) @@ -151,7 +151,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) Object *cObject = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); - int type= RNA_enum_get(op->ptr, "type"); + int type = RNA_enum_get(op->ptr, "type"); if (!pmd) return OPERATOR_CANCELLED; @@ -170,7 +170,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) /* update dependency */ DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject); DAG_scene_sort(CTX_data_main(C), scene); return OPERATOR_FINISHED; @@ -190,10 +190,10 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); + prop = RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); ot->prop = prop; } @@ -203,7 +203,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); DynamicPaintSurface *surface; DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); - int output= RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ + int output = RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; surface = get_activeSurface(pmd->canvas); @@ -258,7 +258,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ ot->prop = RNA_def_enum(ot->srna, "output", prop_output_toggle_types, 0, "Output Toggle", ""); @@ -274,7 +274,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surface, Object *cObject) { DynamicPaintCanvasSettings *canvas = surface->canvas; - Scene *scene= CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); wmWindow *win = CTX_wm_window(C); int frame = 1; int frames; @@ -291,7 +291,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf if (!dynamicPaint_createUVSurface(surface)) return 0; /* Loop through selected frames */ - for (frame=surface->start_frame; frame<=surface->end_frame; frame++) { + for (frame = surface->start_frame; frame <= surface->end_frame; frame++) { float progress = (frame - surface->start_frame) / (float)frames * 100; surface->current_frame = frame; @@ -346,7 +346,6 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); - char result_str[80]; DynamicPaintSurface *surface; /* @@ -354,14 +353,14 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) */ pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); if (!pmd) { - BKE_report(op->reports, RPT_ERROR, "Bake Failed: No Dynamic Paint modifier found."); + BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found"); return 0; } /* Make sure we're dealing with a canvas */ canvas = pmd->canvas; if (!canvas) { - BKE_report(op->reports, RPT_ERROR, "Bake Failed: Invalid Canvas."); + BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas"); return 0; } surface = get_activeSurface(canvas); @@ -381,23 +380,20 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) /* Bake was successful: * Report for ended bake and how long it took */ if (status) { - /* Format time string */ + /* Format time string */ char time_str[30]; double time = PIL_check_seconds_timer() - timer; BLI_timestr(time, time_str); /* Show bake info */ - BLI_snprintf(result_str, sizeof(result_str), "Bake Complete! (%s)", time_str); - BKE_report(op->reports, RPT_INFO, result_str); + BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str); } else { - if (strlen(canvas->error)) { /* If an error occured */ - BLI_snprintf(result_str, sizeof(result_str), "Bake Failed: %s", canvas->error); - BKE_report(op->reports, RPT_ERROR, result_str); + if (strlen(canvas->error)) { /* If an error occurred */ + BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); } - else { /* User canceled the bake */ - BLI_strncpy(result_str, "Baking Cancelled!", sizeof(result_str)); - BKE_report(op->reports, RPT_WARNING, result_str); + else { /* User canceled the bake */ + BKE_report(op->reports, RPT_WARNING, "Baking canceled!"); } } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index ee2b5e08520..7343a44470a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -411,7 +411,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2 /* used to calculate here but all callers have the screen_co already, so pass as arg */ #if 0 if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -448,7 +448,7 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float * int screen_co[2]; /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -473,7 +473,7 @@ static int key_inside_rect(PEData *data, const float co[3]) { int screen_co[2]; - if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -1665,7 +1665,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short LOOP_KEYS { copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { @@ -1685,7 +1685,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { @@ -2414,7 +2414,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) if (totremoved == 0) return OPERATOR_CANCELLED; - BKE_reportf(op->reports, RPT_INFO, "Remove %d double particles", totremoved); + BKE_reportf(op->reports, RPT_INFO, "Removed %d double particles", totremoved); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); @@ -2797,7 +2797,7 @@ static void brush_cut(PEData *data, int pa_index) if (edit->points[pa_index].flag & PEP_HIDE) return; - if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) + if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) return; rad2= data->rad * data->rad; @@ -2822,7 +2822,7 @@ static void brush_cut(PEData *data, int pa_index) /* calculate path time closest to root that was inside the circle */ for (k=1, key++; k<=keys; k++, key++) { - if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || + if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) || key_test_depth(data, key->co, screen_co) == 0) { x0 = (float)screen_co[0]; @@ -3989,7 +3989,9 @@ void PE_undo_step(Scene *scene, int step) } else if (step==1) { - if (edit->curundo==NULL || edit->curundo->prev==NULL); + if (edit->curundo==NULL || edit->curundo->prev==NULL) { + /* pass */ + } else { if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name); edit->curundo= edit->curundo->prev; @@ -3999,7 +4001,9 @@ void PE_undo_step(Scene *scene, int step) else { /* curundo has to remain current situation! */ - if (edit->curundo==NULL || edit->curundo->next==NULL); + if (edit->curundo==NULL || edit->curundo->next==NULL) { + /* pass */ + } else { get_PTCacheUndo(edit, edit->curundo->next); edit->curundo= edit->curundo->next; diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 218ae628d3f..bbce94b6215 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -325,9 +325,9 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) for (pid=pidlist.first; pid; pid=pid->next) { if (pid->cache == cache) { - PointCache *cache = BKE_ptcache_add(pid->ptcaches); - cache->step = pid->default_step; - *(pid->cache_ptr) = cache; + PointCache *cache_new = BKE_ptcache_add(pid->ptcaches); + cache_new->step = pid->default_step; + *(pid->cache_ptr) = cache_new; break; } } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index c08ea2b6429..b61280f14ce 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -80,7 +80,6 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat float *rectf = NULL; int ymin, ymax, xmin, xmax; int rymin, rxmin; - /* unsigned char *rectc; */ /* UNUSED */ /* if renrect argument, we only refresh scanlines */ if (renrect) { @@ -143,11 +142,10 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat imb_addrectImBuf(ibuf); rectf += 4 * (rr->rectx * ymin + xmin); - /* rectc = (unsigned char *)(ibuf->rect + ibuf->x * rymin + rxmin); */ /* UNUSED */ IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin, &scene->view_settings, &scene->display_settings, - rxmin, rymin, rxmin + xmax, rymin + ymax); + rxmin, rymin, rxmin + xmax, rymin + ymax, TRUE); } /* ****************************** render invoking ***************** */ diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 85ae923f881..1d0e5bb6d44 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -342,7 +342,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) ofs = GPU_offscreen_create(sizex, sizey, err_out); if (!ofs) { - BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer, %s", err_out); + BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); return 0; } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 817067422af..694d2302fbd 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -273,16 +273,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre /* exception: don't apply render part of display transform for texture previews or icons */ if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) { - ColorManagedDisplaySettings *display_settings = &sce->display_settings; - ColorManagedViewSettings *view_settings = &sce->view_settings; - - const char *default_view_name = IMB_colormanagement_view_get_default_name(display_settings->display_device); - - view_settings->exposure = 0.0f; - view_settings->gamma = 1.0f; - view_settings->flag &= ~COLORMANAGE_VIEW_USE_CURVES; - - BLI_strncpy(view_settings->view_transform, default_view_name, sizeof(view_settings->view_transform)); + BKE_scene_disable_color_management(sce); } if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO) @@ -550,7 +541,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int * color managed as well? */ IMB_buffer_byte_from_float(rect_byte, rres.rectf, - 4, dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, do_predivide, + 4, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, do_predivide, rres.rectx, rres.recty, rres.rectx, rres.rectx); } @@ -818,7 +809,7 @@ static void shader_preview_free(void *customdata) /* get rid of copied world */ BLI_remlink(&pr_main->world, sp->worldcopy); - BKE_world_free_ex(sp->worldcopy, FALSE); + BKE_world_free_ex(sp->worldcopy, TRUE); /* [#32865] - we need to unlink the texture copies, unlike for materials */ properties = IDP_GetProperties((ID *)sp->worldcopy, FALSE); if (properties) { diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index b1b27e1424a..ebbdc90ab04 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -1362,7 +1362,11 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; /* no undo since this doesnt modify the env-map */ /* properties */ - prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f); + prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, + "File layout", + "Flat array describing the X,Y position of each cube face in the output image, " + "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " + "(use -1 to skip a face)", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_HIDDEN); WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 08ccf37265b..5b1c03f65df 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -74,12 +74,19 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) bScreen *sc; ScrArea *sa; ARegion *ar; + static int recursive_check = FALSE; /* don't do this render engine update if we're updating the scene from * other threads doing e.g. rendering or baking jobs */ if (!BLI_thread_is_main()) return; + /* don't call this recursively for frame updates */ + if(recursive_check) + return; + + recursive_check = TRUE; + C = CTX_create(); CTX_data_main_set(C, bmain); CTX_data_scene_set(C, scene); @@ -114,6 +121,8 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) } CTX_free(C); + + recursive_check = FALSE; } void ED_render_engine_area_exit(ScrArea *sa) @@ -224,8 +233,12 @@ static void material_changed(Main *bmain, Material *ma) /* find node materials using this */ for (parent = bmain->mat.first; parent; parent = parent->id.next) { - if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) ; - else continue; + if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&parent->id)); @@ -247,9 +260,15 @@ static void texture_changed(Main *bmain, Tex *tex) /* find materials */ for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) ; - else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) ; - else continue; + if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&ma->id)); @@ -259,18 +278,30 @@ static void texture_changed(Main *bmain, Tex *tex) /* find lamps */ for (la = bmain->lamp.first; la; la = la->id.next) { - if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) ; - else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) ; - else continue; + if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&la->id)); } /* find worlds */ for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) ; - else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) ; - else continue; + if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&wo->id)); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 01a5304451a..ad9b0f61eb1 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -407,8 +407,12 @@ void region_scissor_winrct(ARegion *ar, rcti *winrct) ar = ar->prev; if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { - if (ar->flag & RGN_FLAG_HIDDEN) ; - else if (ar->alignment & RGN_SPLIT_PREV) ; + if (ar->flag & RGN_FLAG_HIDDEN) { + /* pass */ + } + else if (ar->alignment & RGN_SPLIT_PREV) { + /* pass */ + } else if (ar->alignment == RGN_OVERLAP_LEFT) { winrct->xmin = ar->winrct.xmax + 1; } @@ -935,20 +939,25 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int /* prefsize, for header we stick to exception */ prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex; - if (ar->regiontype == RGN_TYPE_HEADER) + if (ar->regiontype == RGN_TYPE_HEADER) { prefsizey = ar->type->prefsizey; + } else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } - else + else { prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey; - - /* hidden is user flag */ - if (ar->flag & RGN_FLAG_HIDDEN) ; - /* XXX floating area region, not handled yet here */ - else if (alignment == RGN_ALIGN_FLOAT) ; - /* remainder is too small for any usage */ + } + + + if (ar->flag & RGN_FLAG_HIDDEN) { + /* hidden is user flag */ + } + else if (alignment == RGN_ALIGN_FLOAT) { + /* XXX floating area region, not handled yet here */ + } else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) { + /* remainder is too small for any usage */ ar->flag |= RGN_FLAG_TOO_SMALL; } else if (alignment == RGN_ALIGN_NONE) { @@ -1517,7 +1526,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D, editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y, &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, - TIP_("Display current editor type (click for menu of available types)")); + TIP_("Display current editor type (click for a menu of available types)")); uiButSetFunc(but, spacefunc, NULL, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c64a4a37f3a..5eac841dec6 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2716,6 +2716,8 @@ static int region_quadview_exec(bContext *C, wmOperator *op) /* lock views and set them */ if (sa->spacetype == SPACE_VIEW3D) { + View3D *v3d = sa->spacedata.first; + /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set, * otherwise when restoring rv3d->localvd the 'viewquat' won't * match the 'view', set on entering localview See: [#26315], @@ -2743,7 +2745,15 @@ static int region_quadview_exec(bContext *C, wmOperator *op) ar = ar->next; rv3d = ar->regiondata; - rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB; + + /* check if we have a camera */ + if (v3d->camera) { + rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB; + } + else { + rv3d->view = RV3D_VIEW_PERSPORTHO; rv3d->persp = RV3D_PERSP; + } + ED_view3d_lock(rv3d); view3d_localview_update_rv3d(rv3d); } diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 6120229190d..5e23a144408 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -322,8 +322,8 @@ static int project_brush_radius(ViewContext *vc, add_v3_v3v3(offset, location, ortho); /* project the center of the brush, and the tangent point to the view onto the screen */ - if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { /* the distance between these points is the size of the projected brush in pixels */ return len_v2v2(p1, p2); @@ -340,7 +340,6 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, { Scene *scene = CTX_data_scene(C); Paint *paint = paint_get_active_from_context(C); - Brush *brush = paint_brush(paint); float window[2]; int hit; @@ -350,6 +349,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, if (vc->obact->sculpt && vc->obact->sculpt->pbvh && sculpt_stroke_get_location(C, location, window)) { + Brush *brush = paint_brush(paint); *pixel_radius = project_brush_radius(vc, BKE_brush_unprojected_radius_get(scene, brush), diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index c6aaae6b879..34ff5efacc9 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -2554,7 +2554,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float (*outset_uv)[2] = ps->faceSeamUVs[face_index]; float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */ - float fac; float *vCoSS[4]; /* vertex screenspace coords */ float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */ @@ -2636,6 +2635,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* test we're inside uvspace bucket and triangle bounds */ if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) { + float fac; /* We need to find the closest point along the face edge, * getting the screen_px_from_*** wont work because our actual location @@ -2670,9 +2670,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i #if 1 /* get the UV on the line since we want to copy the pixels from there for bleeding */ float uv_close[2]; - float fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]); - if (fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]); - else if (fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]); + float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]); + if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]); + else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]); if (side) { barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w); @@ -2683,16 +2683,16 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i #else /* this is buggy with quads, don't use for now */ /* Cheat, we know where we are along the edge so work out the weights from that */ - fac = fac1 + (fac * (fac2 - fac1)); + uv_fac = fac1 + (uv_fac * (fac2 - fac1)); w[0] = w[1] = w[2] = 0.0; if (side) { - w[fidx1 ? fidx1 - 1 : 0] = 1.0f - fac; - w[fidx2 ? fidx2 - 1 : 0] = fac; + w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac; + w[fidx2 ? fidx2 - 1 : 0] = uv_fac; } else { - w[fidx1] = 1.0f - fac; - w[fidx2] = fac; + w[fidx1] = 1.0f - uv_fac; + w[fidx2] = uv_fac; } #endif } @@ -4249,7 +4249,7 @@ static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect, ibuf->x, 0, 0, &scene->view_settings, &scene->display_settings, imapaintpartial.x1, imapaintpartial.y1, - imapaintpartial.x2, imapaintpartial.y2); + imapaintpartial.x2, imapaintpartial.y2, FALSE); } else { ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; @@ -5890,7 +5890,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ - BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer: %s", err_out); + BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 794e7755636..162e2fa15d6 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -51,7 +51,7 @@ struct wmOperator; struct wmOperatorType; /* paint_stroke.c */ -typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], float mouse[2]); +typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]); typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]); typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr); typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 7fabaf7f23d..2ae24db7c33 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -139,13 +139,13 @@ static float event_tablet_data(wmEvent *event, int *pen_flip) } /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */ -static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) +static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, const float mouse_in[2]) { Scene *scene = CTX_data_scene(C); Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); PaintStroke *stroke = op->customdata; - float mouse[3]; + float mouse_out[2]; PointerRNA itemptr; float location[3]; float pressure; @@ -159,24 +159,24 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev if (stroke->vc.obact->sculpt) { float delta[2]; - BKE_brush_jitter_pos(scene, brush, mouse_in, mouse); + BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out); /* XXX: meh, this is round about because * BKE_brush_jitter_pos isn't written in the best way to * be reused here */ if (brush->flag & BRUSH_JITTER_PRESSURE) { - sub_v2_v2v2(delta, mouse, mouse_in); + sub_v2_v2v2(delta, mouse_out, mouse_in); mul_v2_fl(delta, pressure); - add_v2_v2v2(mouse, mouse_in, delta); + add_v2_v2v2(mouse_out, mouse_in, delta); } } else { - copy_v2_v2(mouse, mouse_in); + copy_v2_v2(mouse_out, mouse_in); } /* TODO: can remove the if statement once all modes have this */ if (stroke->get_location) - stroke->get_location(C, location, mouse); + stroke->get_location(C, location, mouse_out); else zero_v3(location); @@ -184,12 +184,11 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev RNA_collection_add(op->ptr, "stroke", &itemptr); RNA_float_set_array(&itemptr, "location", location); - RNA_float_set_array(&itemptr, "mouse", mouse); + RNA_float_set_array(&itemptr, "mouse", mouse_out); RNA_boolean_set(&itemptr, "pen_flip", pen_flip); RNA_float_set(&itemptr, "pressure", pressure); - stroke->last_mouse_position[0] = mouse[0]; - stroke->last_mouse_position[1] = mouse[1]; + copy_v2_v2(stroke->last_mouse_position, mouse_out); stroke->update_step(C, stroke, &itemptr); } diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c index f5b9aa742c6..e406d4f5c3b 100644 --- a/source/blender/editors/sculpt_paint/paint_undo.c +++ b/source/blender/editors/sculpt_paint/paint_undo.c @@ -152,7 +152,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char * UndoElem *undo; if (step == 1) { - if (stack->current == NULL) ; + if (stack->current == NULL) { + /* pass */ + } else { if (!name || strcmp(stack->current->name, name) == 0) { if (G.debug & G_DEBUG_WM) { @@ -165,7 +167,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char * } } else if (step == -1) { - if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) ; + if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) { + /* pass */ + } else { if (!name || strcmp(stack->current->name, name) == 0) { undo = (stack->current && stack->current->next) ? stack->current->next : stack->elems.first; @@ -254,7 +258,9 @@ int ED_undo_paint_valid(int type, const char *name) else return 0; - if (stack->current == NULL) ; + if (stack->current == NULL) { + /* pass */ + } else { if (name && strcmp(stack->current->name, name) == 0) return 1; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 5a79368ac49..bb931dd1ff2 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -848,7 +848,7 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n { float vertco[2]; - if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { float delta[2]; float dist_squared; @@ -1535,7 +1535,6 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, } else { /* reset the weights */ - unsigned int i; MDeformWeight *dw_old = odv->dw; MDeformWeight *dw_new = ndv->dw; @@ -2049,7 +2048,6 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU Object *ob = CTX_data_active_object(C); struct WPaintData *wpd; Mesh *me; - bDeformGroup *dg; float mat[4][4], imat[4][4]; @@ -2098,12 +2096,14 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU return FALSE; } - /* check if we are attempting to paint onto a locked vertex group, - * and other options disallow it from doing anything useful */ - dg = BLI_findlink(&ob->defbase, (ob->actdef - 1)); - if (dg->flag & DG_LOCK_WEIGHT) { - BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); - return FALSE; + { + /* check if we are attempting to paint onto a locked vertex group, + * and other options disallow it from doing anything useful */ + bDeformGroup *dg = BLI_findlink(&ob->defbase, (ob->actdef - 1)); + if (dg->flag & DG_LOCK_WEIGHT) { + BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); + return FALSE; + } } /* ALLOCATIONS! no return after this line */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3d3e86d2acb..092ec32e724 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3536,8 +3536,6 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); - int dx, dy; - /* RNA_float_get_array(ptr, "location", cache->traced_location); */ if (cache->first_time || @@ -3606,8 +3604,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, if (brush->flag & BRUSH_ANCHORED) { int hit = 0; - dx = cache->mouse[0] - cache->initial_mouse[0]; - dy = cache->mouse[1] - cache->initial_mouse[1]; + const float dx = cache->mouse[0] - cache->initial_mouse[0]; + const float dy = cache->mouse[1] - cache->initial_mouse[1]; sd->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy); @@ -3617,8 +3615,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, float halfway[2]; float out[3]; - halfway[0] = (float)dx * 0.5f + cache->initial_mouse[0]; - halfway[1] = (float)dy * 0.5f + cache->initial_mouse[1]; + halfway[0] = dx * 0.5f + cache->initial_mouse[0]; + halfway[1] = dy * 0.5f + cache->initial_mouse[1]; if (sculpt_stroke_get_location(C, out, halfway)) { copy_v3_v3(sd->anchored_location, out); @@ -3665,8 +3663,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, sculpt_update_brush_delta(sd, ob, brush); if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) { - dx = cache->mouse[0] - cache->initial_mouse[0]; - dy = cache->mouse[1] - cache->initial_mouse[1]; + const float dx = cache->mouse[0] - cache->initial_mouse[0]; + const float dy = cache->mouse[1] - cache->initial_mouse[1]; cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength; @@ -3738,7 +3736,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) * (This allows us to ignore the GL depth buffer) * Returns 0 if the ray doesn't hit the mesh, non-zero otherwise */ -int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]) +int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) { ViewContext vc; Object *ob; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 0852378974e..acb906e4a91 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -65,7 +65,7 @@ void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct void free_sculptsession_deformMats(struct SculptSession *ss); /* Stroke */ -int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]); +int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]); /* Undo */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 7635f85a37e..eeb297b7f57 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -976,8 +976,8 @@ void ACTION_OT_sample(wmOperatorType *ot) /* defines for set extrapolation-type for selected keyframes tool */ static EnumPropertyItem prop_actkeys_expo_types[] = { - {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""}, - {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""}, + {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"}, + {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"}, {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"}, {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"}, @@ -1353,9 +1353,9 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) void ACTION_OT_frame_jump(wmOperatorType *ot) { /* identifiers */ - ot->name = "Jump to Frame"; + ot->name = "Jump to Keyframes"; ot->idname = "ACTION_OT_frame_jump"; - ot->description = "Set the current frame to the average frame of the selected keyframes"; + ot->description = "Set the current frame to the average frame value of selected keyframes"; /* api callbacks */ ot->exec = actkeys_framejump_exec; @@ -1369,10 +1369,14 @@ void ACTION_OT_frame_jump(wmOperatorType *ot) /* defines for snap keyframes tool */ static EnumPropertyItem prop_actkeys_snap_types[] = { - {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", ""}, - {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? - {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? - {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, + {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", + "Snap selected keyframes to the current frame"}, + {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", + "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"}, + {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", + "Snap selected keyframes to the nearest second"}, + {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", + "Snap selected keyframes to the nearest marker"}, {0, NULL, 0, NULL, NULL} }; @@ -1473,9 +1477,12 @@ void ACTION_OT_snap(wmOperatorType *ot) /* defines for mirror keyframes tool */ static EnumPropertyItem prop_actkeys_mirror_types[] = { - {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", ""}, - {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""}, - {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""}, + {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", + "Flip times of selected keyframes using the current frame as the mirror line"}, + {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", + "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, + {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", + "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} }; @@ -1497,12 +1504,8 @@ static void mirror_action_keys(bAnimContext *ac, short mode) /* for 'first selected marker' mode, need to find first selected marker first! */ // XXX should this be made into a helper func in the API? if (mode == ACTKEYS_MIRROR_MARKER) { - TimeMarker *marker = NULL; + TimeMarker *marker = ED_markers_get_first_selected(ac->markers); - /* find first selected marker */ - marker = ED_markers_get_first_selected(ac->markers); - - /* store marker's time (if available) */ if (marker) ked.f1 = (float)marker->frame; else diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index e4a161e3e22..cca71bb1331 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -168,9 +168,8 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* action_edit.c */ - /* snap - current frame to selected keys */ - // TODO: maybe since this is called jump, we're better to have it on <something>-J? - WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* jump to selected keyframes */ + WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0); /* menu + single-step transform */ WM_keymap_add_item(keymap, "ACTION_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index c41d2521ee8..7e232a02536 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -900,7 +900,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r } else { /* get settings from active particle system instead */ - PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSystem); + ptr = get_pointer_type(path, &RNA_ParticleSystem); if (ptr && ptr->data) { ParticleSettings *part = ((ParticleSystem *)ptr->data)->part; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index c8cf69e3e17..9a7284de660 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -207,7 +207,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) * user-prefs exception - campbell */ if (RNA_struct_find_property(op->ptr, "relative_path")) { if (!RNA_struct_property_is_set(op->ptr, "relative_path")) { - /* annoying exception!, if were dealign with the user prefs, default relative to be off */ + /* annoying exception!, if were dealing with the user prefs, default relative to be off */ RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); } } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 5e940df2a30..d7936c1e2e8 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -117,6 +117,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); @@ -218,8 +219,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* solver keyframes */ glColor4ub(175, 255, 0, 255); - draw_keyframe(tracking->settings.keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); - draw_keyframe(tracking->settings.keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 167353e7cb7..b495ca32813 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -44,6 +44,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLI_rect.h" #include "GPU_extensions.h" @@ -692,7 +693,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsign context->start_frame = clip->start_frame; context->frame_offset = clip->frame_offset; - strcpy(context->colorspace, clip->colorspace_settings.name); + BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace)); } else { /* displaying exactly the same image which was loaded t oa texture, diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 5c338f3e6f1..37eb0bcb7c1 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -41,6 +41,8 @@ #include "BLI_math.h" #include "BLI_rect.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" @@ -180,7 +182,7 @@ static int open_exec(bContext *C, wmOperator *op) BLI_join_dirfile(str, sizeof(str), dir_only, file_only); } else { - BKE_reportf(op->reports, RPT_ERROR, "No files selected to be opened"); + BKE_report(op->reports, RPT_ERROR, "No files selected to be opened"); return OPERATOR_CANCELLED; } @@ -195,8 +197,8 @@ static int open_exec(bContext *C, wmOperator *op) if (op->customdata) MEM_freeN(op->customdata); - BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, - errno ? strerror(errno) : "Unsupported movie clip format"); + BKE_reportf(op->reports, RPT_ERROR, "Can't read \"%s\": %s", str, + errno ? strerror(errno) : TIP_("Unsupported movie clip format")); return OPERATOR_CANCELLED; } @@ -514,9 +516,14 @@ static int view_zoom_exec(bContext *C, wmOperator *op) static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (event->type == MOUSEZOOM) { - float factor; + float delta, factor; + + delta = event->x - event->prevx + event->y - event->prevy; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; - factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f; + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set_factor_exec(C, event, factor); @@ -533,11 +540,16 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewZoomData *vpd = op->customdata; - float factor; + float delta, factor; switch (event->type) { case MOUSEMOVE: - factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f; + delta = event->x - vpd->x + event->y - vpd->y; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set(C, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -579,7 +591,7 @@ void CLIP_OT_view_zoom(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; /* properties */ - RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); } @@ -700,7 +712,7 @@ void CLIP_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = ED_space_clip_view_clip_poll; /* properties */ - RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 97f7d7bf132..c061125b4d5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -154,7 +154,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Location of marker on frame", -1.0f, 1.0f); } @@ -1343,7 +1343,6 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op MovieClip *clip = ED_space_clip_get_clip(sc); Scene *scene = CTX_data_scene(C); MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &clip->tracking.settings; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int width, height; @@ -1359,7 +1358,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op scj->user = sc->user; scj->context = BKE_tracking_reconstruction_context_new(tracking, object, - settings->keyframe1, settings->keyframe2, width, height); + object->keyframe1, object->keyframe2, width, height); tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); @@ -1401,7 +1400,7 @@ static void solve_camera_freejob(void *scv) if (!solved) BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details"); else - BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error %.3f", tracking->reconstruction.error); + BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error: %.3f", tracking->reconstruction.error); /* set currently solved clip as active for scene */ if (scene->clip) @@ -2767,7 +2766,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op) next = track->next; if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) { - BKE_tracking_tracks_join(act_track, track); + BKE_tracking_tracks_join(tracking, act_track, track); if (tracking->stabilization.rot_track == track) tracking->stabilization.rot_track = act_track; @@ -2859,14 +2858,14 @@ static int set_solver_keyframe_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int keyframe = RNA_enum_get(op->ptr, "keyframe"); int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); if (keyframe == 0) - settings->keyframe1 = framenr; + object->keyframe1 = framenr; else - settings->keyframe2 = framenr; + object->keyframe2 = framenr; WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 4f62d3fdc2f..feb523237ba 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -291,7 +291,6 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) MovieTrackingTrack *track = tracking_marker_check_slide(C, event, NULL, NULL, NULL); if (track) { - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); clip->tracking.act_track = track; @@ -477,7 +476,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_marker(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 4c2f0ac73d4..c4a5c2a0154 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -94,12 +94,14 @@ void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_du { /* fake the edit line being in the scroll buffer */ ConsoleLine *cl = sc->history.last; + int prompt_len = strlen(sc->prompt); + cl_dummy->type = CONSOLE_LINE_INPUT; - cl_dummy->len = cl_dummy->len_alloc = strlen(sc->prompt) + cl->len; + cl_dummy->len = prompt_len + cl->len; cl_dummy->len_alloc = cl_dummy->len + 1; cl_dummy->line = MEM_mallocN(cl_dummy->len_alloc, "cl_dummy"); - memcpy(cl_dummy->line, sc->prompt, (cl_dummy->len_alloc - cl->len)); - memcpy(cl_dummy->line + ((cl_dummy->len_alloc - cl->len)) - 1, cl->line, cl->len + 1); + memcpy(cl_dummy->line, sc->prompt, prompt_len); + memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1); BLI_addtail(&sc->scrollback, cl_dummy); } void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy) @@ -158,12 +160,13 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha const ConsoleLine *cl = (ConsoleLine *)sc->history.last; const int prompt_len = strlen(sc->prompt); const int cursor_loc = cl->cursor + prompt_len; + const int line_len = cl->len + prompt_len; int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN}; int pen[2]; xy[1] += tvc->lheight / 6; /* account for wrapping */ - if (cl->len < tvc->console_width) { + if (line_len < tvc->console_width) { /* simple case, no wrapping */ pen[0] = tvc->cwidth * cursor_loc; pen[1] = -2; @@ -171,7 +174,7 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha else { /* wrap */ pen[0] = tvc->cwidth * (cursor_loc % tvc->console_width); - pen[1] = -2 + (((cl->len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight); + pen[1] = -2 + (((line_len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight); } /* cursor */ diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 7efcbcceb3c..ecd9e316cef 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -580,7 +580,7 @@ static int console_delete_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - console_select_offset(sc, -1); + console_select_offset(sc, -stride); } console_textview_update_rect(sc, ar); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index fcbeb064e4d..7a364eb8685 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -307,7 +307,7 @@ void FILE_OT_select_border(wmOperatorType *ot) ot->poll = ED_operator_file_active; ot->cancel = WM_border_select_cancel; - /* rna */ + /* properties */ WM_operator_properties_gesture_border(ot, 1); } @@ -347,6 +347,8 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) void FILE_OT_select(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Activate/Select File"; ot->description = "Activate/select file"; @@ -356,10 +358,13 @@ void FILE_OT_select(wmOperatorType *ot) ot->invoke = file_select_invoke; ot->poll = ED_operator_file_active; - /* rna */ - RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); - RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection"); - RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it"); + /* properties */ + prop = RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op)) @@ -404,9 +409,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) ot->exec = file_select_all_exec; ot->poll = ED_operator_file_active; - /* rna */ - - + /* properties */ } /* ---------- BOOKMARKS ----------- */ @@ -432,6 +435,8 @@ static int bookmark_select_exec(bContext *C, wmOperator *op) void FILE_OT_select_bookmark(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Select Directory"; ot->description = "Select a bookmarked directory"; @@ -441,7 +446,9 @@ void FILE_OT_select_bookmark(wmOperatorType *ot) ot->exec = bookmark_select_exec; ot->poll = ED_operator_file_active; - RNA_def_string(ot->srna, "dir", "", 256, "Dir", ""); + /* properties */ + prop = RNA_def_string(ot->srna, "dir", "", FILE_MAXDIR, "Dir", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) @@ -498,6 +505,8 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op) void FILE_OT_delete_bookmark(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Delete Bookmark"; ot->description = "Delete selected bookmark"; @@ -507,7 +516,9 @@ void FILE_OT_delete_bookmark(wmOperatorType *ot) ot->exec = bookmark_delete_exec; ot->poll = ED_operator_file_active; - RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); + /* properties */ + prop = RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) @@ -819,7 +830,8 @@ void FILE_OT_execute(struct wmOperatorType *ot) /* api callbacks */ ot->exec = file_exec; ot->poll = file_operator_poll; - + + /* properties */ prop = RNA_def_boolean(ot->srna, "need_active", 0, "Need Active", "Only execute if there's an active selected file in the file list"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); @@ -1123,6 +1135,8 @@ int file_directory_new_exec(bContext *C, wmOperator *op) void FILE_OT_directory_new(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Create New Directory"; ot->description = "Create a new directory"; @@ -1133,7 +1147,8 @@ void FILE_OT_directory_new(struct wmOperatorType *ot) ot->exec = file_directory_new_exec; ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ - RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); + prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 699cb9b4feb..1408e8b801b 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -748,7 +748,9 @@ static int file_is_blend_backup(const char *str) a = strlen(str); b = 7; - if (a == 0 || b >= a) ; + if (a == 0 || b >= a) { + /* pass */ + } else { char *loc; @@ -1224,11 +1226,12 @@ void filelist_from_main(struct FileList *filelist) if (ok) { if (!filelist->hide_dot || id->name[2] != '.') { memset(files, 0, sizeof(struct direntry)); - if (id->lib == NULL) + if (id->lib == NULL) { files->relname = BLI_strdup(id->name + 2); + } else { - files->relname = MEM_mallocN(FILE_MAX + 32, "filename for lib"); - sprintf(files->relname, "%s | %s", id->lib->name, id->name + 2); + files->relname = MEM_mallocN(FILE_MAX + (MAX_ID_NAME - 2), "filename for lib"); + BLI_snprintf(files->relname, FILE_MAX + (MAX_ID_NAME - 2) + 3, "%s | %s", id->lib->name, id->name + 2); } files->type |= S_IFREG; #if 0 // XXXXX TODO show the selection status of the objects @@ -1238,7 +1241,7 @@ void filelist_from_main(struct FileList *filelist) } else if (idcode == ID_SCE) { if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE; - } + } } #endif files->nr = totbl + 1; @@ -1247,10 +1250,10 @@ void filelist_from_main(struct FileList *filelist) if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) { files->flags |= IMAGEFILE; } - if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); - else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); - else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); - else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); + if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); + else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); + else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); + else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); if (id->lib) { if (totlib == 0) firstlib = files; diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 0d56b02e086..3e8f6f1c7fc 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -148,6 +148,7 @@ static void graph_panel_view(const bContext *C, Panel *pa) row = uiLayoutSplit(sub, 0.7f, TRUE); uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA); + row = uiLayoutSplit(sub, 0.7f, TRUE); uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE); @@ -308,44 +309,43 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) * - we use the button-versions of the calls so that we can attach special update handlers * and unit conversion magic that cannot be achieved using a purely RNA-approach */ - // XXX: col = uiLayoutColumn(layout, TRUE); /* keyframe itself */ { uiItemL(col, IFACE_("Key:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); uiButSetUnitType(but, unit); } - + /* previous handle - only if previous was Bezier interpolation */ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) { uiItemL(col, IFACE_("Left Handle:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); uiButSetUnitType(but, unit); } - + /* next handle - only if current is Bezier interpolation */ if (bezt->ipo == BEZT_IPO_BEZ) { uiItemL(col, IFACE_("Right Handle:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); @@ -437,7 +437,7 @@ static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSE ChannelDriver *driver = fcu->driver; /* clear invalid flags */ - fcu->flag &= ~FCURVE_DISABLED; // XXX? + fcu->flag &= ~FCURVE_DISABLED; driver->flag &= ~DRIVER_FLAG_INVALID; } @@ -467,7 +467,6 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:")); /* Target Property */ - // TODO: make this less technical... if (dtar->id) { PointerRNA root_ptr; @@ -630,12 +629,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) - uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR); + uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR); } else { /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) - uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR); + uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR); } col = uiLayoutColumn(pa->layout, TRUE); @@ -706,15 +705,15 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) graph_panel_driverVar__transChan(box, ale->id, dvar); break; } - + /* value of variable */ if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { char valBuf[32]; - + box = uiLayoutBox(col); row = uiLayoutRow(box, TRUE); uiItemL(row, IFACE_("Value:"), ICON_NONE); - + BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); uiItemL(row, valBuf, ICON_NONE); } @@ -724,8 +723,8 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) MEM_freeN(ale); } -/* ******************* f-modifiers ******************************** */ -/* all the drawing code is in editors/animation/fmodifier_ui.c */ +/* ******************* F-Modifiers ******************************** */ +/* All the drawing code is in editors/animation/fmodifier_ui.c */ #define B_FMODIFIER_REDRAW 20 @@ -757,7 +756,9 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) row = uiLayoutRow(pa->layout, FALSE); block = uiLayoutGetBlock(row); - // XXX for now, this will be a operator button which calls a 'add modifier' operator + /* this is an operator button which calls a 'add modifier' operator... + * a menu might be nicer but would be tricky as we need some custom filtering + */ uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20, TIP_("Adds a new F-Curve Modifier for the active F-Curve")); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 7107a6a2369..30ec32ec0aa 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1309,8 +1309,8 @@ void GRAPH_OT_sample(wmOperatorType *ot) /* defines for set extrapolation-type for selected keyframes tool */ static EnumPropertyItem prop_graphkeys_expo_types[] = { - {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""}, - {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""}, + {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"}, + {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"}, {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"}, {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"}, @@ -1808,9 +1808,9 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) void GRAPH_OT_frame_jump(wmOperatorType *ot) { /* identifiers */ - ot->name = "Jump to Frame"; + ot->name = "Jump to Keyframes"; ot->idname = "GRAPH_OT_frame_jump"; - ot->description = "Set the current frame to the average frame of the selected keyframes"; + ot->description = "Place the cursor on the midpoint of selected keyframes"; /* api callbacks */ ot->exec = graphkeys_framejump_exec; @@ -1824,12 +1824,18 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot) /* defines for snap keyframes tool */ static EnumPropertyItem prop_graphkeys_snap_types[] = { - {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", ""}, - {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", ""}, - {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? - {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? - {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, - {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", ""}, + {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", + "Snap selected keyframes to the current frame"}, + {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", + "Set values of selected keyframes to the cursor value (Y/Horizontal component)"}, + {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", + "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"}, + {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", + "Snap selected keyframes to the nearest second"}, + {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", + "Snap selected keyframes to the nearest marker"}, + {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", + "Flatten handles for a smoother transition"}, {0, NULL, 0, NULL, NULL} }; @@ -1932,11 +1938,16 @@ void GRAPH_OT_snap(wmOperatorType *ot) /* defines for mirror keyframes tool */ static EnumPropertyItem prop_graphkeys_mirror_types[] = { - {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", ""}, - {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", ""}, - {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", ""}, - {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""}, - {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""}, + {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", + "Flip times of selected keyframes using the current frame as the mirror line"}, + {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", + "Flip values of selected keyframes using the cursor value (Y/Horizontal component) as the mirror line"}, + {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", + "Flip times of selected keyframes, effectively reversing the order they appear in"}, + {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", + "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, + {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", + "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 08b13b49f55..9b031c015a9 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -346,9 +346,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* graph_edit.c */ - /* snap - current frame to selected keys */ - // TODO: maybe since this is called jump, we're better to have it on <something>-J? - WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* jump to selected keyframes */ + WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0); /* menu + single-step transform */ WM_keymap_add_item(keymap, "GRAPH_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 4f57b2249d1..4793f995d98 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -430,11 +430,16 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) if (event->type == MOUSEZOOM) { SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); - float factor, location[2]; + float delta, factor, location[2]; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); - factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f; + delta = event->x - event->prevx + event->y - event->prevy; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sima_zoom_set(sima, ar, sima->zoom * factor, location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -452,11 +457,16 @@ static int image_view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); ViewZoomData *vpd = op->customdata; - float factor; + float delta, factor; switch (event->type) { case MOUSEMOVE: - factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f; + delta = event->x - vpd->x + event->y - vpd->y; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sima_zoom_set(sima, ar, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -496,7 +506,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING; /* properties */ - RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); } @@ -800,7 +810,7 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = space_image_main_area_poll; /* properties */ - RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } @@ -1259,8 +1269,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI BKE_image_release_renderresult(scene, ima); } else { - if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) - { + if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) { ok = TRUE; } } @@ -1549,7 +1558,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op) BLI_strncpy(di, ibuf->name, FILE_MAX); BLI_splitdirstring(di, fi); - BKE_reportf(op->reports, RPT_INFO, "%d Image(s) will be saved in %s", tot, di); + BKE_reportf(op->reports, RPT_INFO, "%d image(s) will be saved in %s", tot, di); for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next) { if (ibuf->userflags & IB_BITMAPDIRTY) { diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 31cb6d91889..7f53f378042 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -414,8 +414,9 @@ static void image_refresh(const bContext *C, ScrArea *sa) /* don't need to check for pin here, see above */ sima->image = tf->tpage; - if (sima->flag & SI_EDITTILE) ; - else sima->curtile = tf->tile; + if ((sima->flag & SI_EDITTILE) == 0) { + sima->curtile = tf->tile; + } } } } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 805ff1794c9..bb2d55fa0f6 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -124,7 +124,7 @@ static const EnumPropertyItem unpack_all_method_items[] = { {PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write files to current directory (overwrite existing files)", ""}, {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""}, {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""}, - {PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""}, + {PF_KEEP, "KEEP", 0, "Disable Auto-pack, keep all packed files", ""}, /* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */ {0, NULL, 0, NULL, NULL}}; @@ -150,7 +150,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event) count = countPackedFiles(bmain); if (!count) { - BKE_report(op->reports, RPT_WARNING, "No packed files. Autopack disabled"); + BKE_report(op->reports, RPT_WARNING, "No packed files (auto-pack disabled)"); G.fileflags &= ~G_AUTOPACK; return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 4ba196276da..cfab2542756 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -128,7 +128,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str return 1; } - if (str_len > cdc->console_width) { /* wrap? */ + if (tot_lines > 1) { /* wrap? */ const int initial_offset = ((tot_lines - 1) * cdc->console_width); const char *line_stride = str + initial_offset; /* advance to the last line and draw it first */ diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 92f014fd804..5c8e7e99a8c 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -849,8 +849,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw NLA-action line 'status-icons' - only when there's an action */ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) { - AnimData *adt = ale->adt; - offset += 16; /* now draw some indicator icons */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 950060dde5f..e0e5007aff0 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -121,7 +121,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) /* if no blocks, popup error? */ if (anim_data.first == NULL) { - BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for"); + BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for"); return OPERATOR_CANCELLED; } @@ -147,7 +147,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); } else { - BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweakmode on"); + BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweak mode on"); return OPERATOR_CANCELLED; } @@ -190,7 +190,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op) /* if no blocks, popup error? */ if (anim_data.first == NULL) { - BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for"); + BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for"); return OPERATOR_CANCELLED; } @@ -405,7 +405,9 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, - "Action '%s' does not specify what datablocks it can be used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for this Action to avoid future problems", + "Action '%s' does not specify what datablocks it can be used on " + "(try setting the 'ID Root Type' setting from the Datablocks Editor " + "for this Action to avoid future problems)", act->id.name + 2); } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 470f82195a4..67508f2087a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3098,7 +3098,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf) { - SpaceNode *snode = CTX_wm_space_node(C); float x, y; unsigned char *display_buffer; void *cache_handle; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 64a8d96a74f..f0afc647ed5 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1935,7 +1935,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) bNodeTree *ntree = snode->edittree; bNode *gnode = node_tree_get_editgroup(snode->nodetree); float gnode_x = 0.0f, gnode_y = 0.0f; - bNode *node, *new_node; + bNode *node; bNodeLink *link, *newlink; ED_preview_kill_jobs(C); @@ -1950,6 +1950,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) for (node = ntree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { + bNode *new_node; new_node = nodeCopyNode(NULL, node); BKE_node_clipboard_add_node(new_node); } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index b76cc05af5c..19a678a9c6e 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -583,7 +583,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) ntreeUpdateTree(snode->nodetree); } else { - BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); + BKE_report(op->reports, RPT_WARNING, "Cannot ungroup"); return OPERATOR_CANCELLED; } @@ -755,13 +755,13 @@ static int node_group_separate_exec(bContext *C, wmOperator *op) switch (type) { case NODE_GS_COPY: if (!node_group_separate_selected(snode->nodetree, gnode, 1)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes"); return OPERATOR_CANCELLED; } break; case NODE_GS_MOVE: if (!node_group_separate_selected(snode->nodetree, gnode, 0)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes"); return OPERATOR_CANCELLED; } break; @@ -1036,7 +1036,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (snode->edittree != snode->nodetree) { - BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot add a new group in a group"); return OPERATOR_CANCELLED; } @@ -1049,7 +1049,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) } if (gnode) { - BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot add a Render Layers node in a group"); return OPERATOR_CANCELLED; } } @@ -1062,21 +1062,21 @@ static int node_group_make_exec(bContext *C, wmOperator *op) gnode = node_group_make_from_selected(snode->nodetree); } else { - BKE_report(op->reports, RPT_WARNING, "Can not make Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot make group"); return OPERATOR_CANCELLED; } break; case NODE_GM_INSERT: gnode = nodeGetActive(snode->nodetree); if (!gnode || gnode->type != NODE_GROUP) { - BKE_report(op->reports, RPT_WARNING, "No active Group node"); + BKE_report(op->reports, RPT_WARNING, "No active group node"); return OPERATOR_CANCELLED; } if (node_group_make_test(snode->nodetree, gnode)) { node_group_make_insert_selected(snode->nodetree, gnode); } else { - BKE_report(op->reports, RPT_WARNING, "Can not insert into Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot insert into group"); return OPERATOR_CANCELLED; } break; diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index b0916a50c37..a3efa15c54a 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -593,7 +593,7 @@ static int node_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_node(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 3d93a6c14a1..42480c0c2d9 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -147,7 +147,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num) { bNode *node_from; - bNodeSocket *sock_from; + bNodeSocket *sock_from_tmp; bNode *node_prev = NULL; /* unlink existing node */ @@ -183,8 +183,8 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t nodeSetActive(ntree, node_from); /* add link */ - sock_from = BLI_findlink(&node_from->outputs, sock_num); - nodeAddLink(ntree, node_from, sock_from, node_to, sock_to); + sock_from_tmp = BLI_findlink(&node_from->outputs, sock_num); + nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to); /* copy input sockets from previous node */ if (node_prev && node_from != node_prev) { diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index b70d66f60b4..76d1357a83c 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -254,6 +254,15 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) } } break; + + case NC_MOVIECLIP: + if (wmn->action == NA_EDITED) { + if (type == NTREE_COMPOSIT) { + if (nodeUpdateID(snode->nodetree, wmn->reference)) + ED_area_tag_refresh(sa); + } + } + break; } } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index a05588495e9..d2e47427b94 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -783,7 +783,9 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo wmKeyMapItem *kmi = te->directdata; /* modal map? */ - if (kmi->propvalue) ; + if (kmi->propvalue) { + /* pass */ + } else { uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, "Assign new Operator"); } @@ -1409,11 +1411,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* closed item, we draw the icons, not when it's a scene, or master-server list though */ if (!TSELEM_OPEN(tselem, soops)) { if (te->subtree.first) { - if (tselem->type == 0 && te->idcode == ID_SCE) ; - else if (tselem->type != TSE_R_LAYER) { /* this tree element always has same amount of branches, so don't draw */ + if (tselem->type == 0 && te->idcode == ID_SCE) { + /* pass */ + } + else if (tselem->type != TSE_R_LAYER) { + /* this tree element always has same amount of branches, so don't draw */ + int tempx = startx + offsx; - // divider + /* divider */ UI_ThemeColorShade(TH_BACK, -40); glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4); @@ -1525,7 +1531,7 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio { TreeElement *te; int starty, startx; - float col[4]; + float col[3]; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 2ec23091019..8f059b0a735 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -368,12 +368,14 @@ void group_toggle_visibility_cb(bContext *UNUSED(C), Scene *scene, TreeElement * static int outliner_toggle_visibility_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); + DAG_id_type_tag(bmain, ID_OB); WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene); ED_region_tag_redraw(ar); @@ -464,11 +466,13 @@ void group_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElemen static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); + DAG_id_type_tag(bmain, ID_OB); WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene); return OPERATOR_FINISHED; @@ -1340,7 +1344,7 @@ static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op) /* check for invalid states */ if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set"); return OPERATOR_CANCELLED; } if (soutliner == NULL) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index bf76fdda61e..e4cd971dbd5 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -811,7 +811,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Unlink world"); break; default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); + BKE_report(op->reports, RPT_WARNING, "Not yet"); break; } } @@ -844,7 +844,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); + BKE_report(op->reports, RPT_WARNING, "Not yet"); break; } } @@ -980,9 +980,9 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op) else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, - "Action '%s' does not specify what datablocks it can be used on. " - "Try setting the 'ID Root Type' setting from the Datablocks Editor " - "for this Action to avoid future problems", + "Action '%s' does not specify what datablocks it can be used on " + "(try setting the 'ID Root Type' setting from the Datablocks Editor " + "for this Action to avoid future problems)", act->id.name + 2); } @@ -1160,37 +1160,49 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op) event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); - if (datalevel == TSE_POSE_CHANNEL) { - if (event > 0) { + if (event <= 0) + return OPERATOR_CANCELLED; + + switch (datalevel) { + case TSE_POSE_CHANNEL: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "PoseChannel operation"); } - } - else if (datalevel == TSE_BONE) { - if (event > 0) { + break; + + case TSE_BONE: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "Bone operation"); } - } - else if (datalevel == TSE_EBONE) { - if (event > 0) { + break; + + case TSE_EBONE: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "EditBone operation"); } - } - else if (datalevel == TSE_SEQUENCE) { - if (event > 0) { + break; + + case TSE_SEQUENCE: + { Scene *scene = CTX_data_scene(C); outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene); } - } - else if (datalevel == TSE_RNA_STRUCT) { - if (event == 5) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); - } + break; + + case TSE_RNA_STRUCT: + if (event == 5) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); + } + break; + + default: + break; } return OPERATOR_FINISHED; @@ -1262,12 +1274,15 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S else { if (datalevel == TSE_ANIM_DATA) WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL); - else if (datalevel == TSE_DRIVER_BASE) - /* do nothing... no special ops needed yet */; - else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) - /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/; - else + else if (datalevel == TSE_DRIVER_BASE) { + /* do nothing... no special ops needed yet */ + } + else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { + /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ + } + else { WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); + } } } @@ -1289,11 +1304,13 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *even SpaceOops *soops = CTX_wm_space_outliner(C); TreeElement *te; float fmval[2]; - + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1); for (te = soops->tree.first; te; te = te->next) { - if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) break; + if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) { + break; + } } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 3e1ce1fea6e..ef0542130ea 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -769,7 +769,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor else { /* do not extend Armature when we have posemode */ tselem = TREESTORE(te->parent); - if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) ; + if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) { + /* pass */ + } else { Bone *curBone; for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) { @@ -811,9 +813,15 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->parent = parent; te->index = index; // for data arays - if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) ; - else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) ; - else if (type == TSE_ANIM_DATA) ; + if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) { + /* pass */ + } + else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + /* pass */ + } + else if (type == TSE_ANIM_DATA) { + /* pass */ + } else { te->name = id->name + 2; // default, can be overridden by Library or non-ID data te->idcode = GS(id->name); @@ -1055,8 +1063,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (key[0]) { wmOperatorType *ot = NULL; - if (kmi->propvalue) ; - else ot = WM_operatortype_find(kmi->idname, 0); + if (kmi->propvalue) { + /* pass */ + } + else { + ot = WM_operatortype_find(kmi->idname, 0); + } if (ot || kmi->propvalue) { TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 204930e82a6..82d08be4da2 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -579,7 +579,9 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) seq2 = del_seq_find_replace_recurs(scene, seq->seq2); seq3 = del_seq_find_replace_recurs(scene, seq->seq3); - if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) ; + if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) { + /* pass */ + } else if (seq1 || seq2 || seq3) { seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3; seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3; @@ -1572,7 +1574,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt) Scene *scene = (Scene *)arg_pt; char name[sizeof(seq->name) - 2]; - strcpy(name, seq->name + 2); + BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); BKE_sequencer_dupe_animdata(scene, name, seq->name + 2); return 1; @@ -1851,7 +1853,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "length", 1, 1, 1000, "Length", "Length of each frame", 1, INT_MAX); + RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000); } @@ -2186,7 +2188,7 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = ED_operator_sequencer_active; /* properties */ - RNA_def_float(ot->srna, "ratio", 1.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 1.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } @@ -2618,7 +2620,6 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, FALSE); - Sequence *seq; ListBase nseqbase = {NULL, NULL}; @@ -2654,8 +2655,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) seqbase_clipboard_frame = scene->r.cfra; /* Need to remove anything that references the current scene */ - for (seq = seqbase_clipboard.first; seq; seq = seq->next) { - seq_copy_del_sound(scene, seq); + { + Sequence *seq; + for (seq = seqbase_clipboard.first; seq; seq = seq->next) { + seq_copy_del_sound(scene, seq); + } } return OPERATOR_FINISHED; @@ -2738,7 +2742,7 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) const char *error_msg; if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) { - BKE_report(op->reports, RPT_ERROR, "Must select 2 strips"); + BKE_report(op->reports, RPT_ERROR, "Please select two strips"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 5111d20b8ee..a68524fcdd6 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1741,6 +1741,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) char linenr[12]; int i, x, y, winx, linecount = 0, lineno = 0; int wraplinecount = 0, wrap_skip = 0; + int margin_column_x; if (st->lheight) st->viewlines = (int)ar->winy / st->lheight; else st->viewlines = 0; @@ -1845,10 +1846,14 @@ void draw_text_main(SpaceText *st, ARegion *ar) if (st->flags & ST_SHOW_MARGIN) { UI_ThemeColor(TH_HILITE); - glBegin(GL_LINES); - glVertex2i(x + st->cwidth * st->margin_column, 0); - glVertex2i(x + st->cwidth * st->margin_column, ar->winy - 2); - glEnd(); + margin_column_x = x + st->cwidth * (st->margin_column - st->left); + + if (margin_column_x >= x) { + glBegin(GL_LINES); + glVertex2i(margin_column_x, 0); + glVertex2i(margin_column_x, ar->winy - 2); + glEnd(); + } } /* draw other stuff */ diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 75b8e2f218d..b2fb16ff7fe 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -3352,7 +3352,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot) /* identifiers */ ot->name = "To 3D Object"; ot->idname = "TEXT_OT_to_3d_object"; - ot->description = "Create 3d text object from active text data block"; + ot->description = "Create 3D text object from active text data block"; /* api callbacks */ ot->exec = text_to_3d_object_exec; diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 1bba237ed5c..35dd88c3209 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -51,7 +51,9 @@ set(SRC view3d_edit.c view3d_fly.c view3d_header.c + view3d_iterators.c view3d_ops.c + view3d_project.c view3d_select.c view3d_snap.c view3d_toolbar.c diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index ecce12b8cba..31df13343ce 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -2226,9 +2226,16 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) } /* restore */ - if (index != -1) glLoadName(-1); - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) ; - else if (dt > OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f); + if (index != -1) { + glLoadName(-1); + } + + if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { + /* pass */ + } + else if (dt > OB_WIRE) { + bglPolygonOffset(rv3d->dist, 0.0f); + } /* finally names and axes */ if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) { diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index e4c21a9c2c8..cded7bbbdfc 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -533,8 +533,7 @@ static void update_tface_color_layer(DerivedMesh *dm) } else { float col[3]; - Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1); - + if (ma) { if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index df04cc33e71..ec54ae09fd2 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -27,10 +27,6 @@ * \ingroup spview3d */ - -#include <string.h> -#include <math.h> - #include "MEM_guardedalloc.h" #include "DNA_camera_types.h" @@ -40,21 +36,14 @@ #include "DNA_lattice_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_meta_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" -#include "DNA_speaker_types.h" #include "DNA_world_types.h" -#include "DNA_armature_types.h" #include "DNA_object_types.h" -#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_edgehash.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" #include "BKE_anim.h" /* for the where_on_path function */ #include "BKE_armature.h" @@ -79,13 +68,10 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_unit.h" -#include "BKE_movieclip.h" #include "BKE_tracking.h" #include "BKE_tessmesh.h" -#include "smoke_API.h" - #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -100,16 +86,13 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_types.h" -#include "ED_curve.h" /* for curve_editnurbs */ -#include "ED_armature.h" #include "UI_resources.h" #include "WM_api.h" -#include "wm_subwindow.h" #include "BLF_api.h" -#include "view3d_intern.h" /* own include */ +#include "view3d_intern.h" /* bad level include */ typedef enum eWireDrawMode { OBDRAW_WIRE_OFF = 0, @@ -117,28 +100,6 @@ typedef enum eWireDrawMode { OBDRAW_WIRE_ON_DEPTH = 2 } eWireDrawMode; -/* user data structures for derived mesh callbacks */ -typedef struct foreachScreenVert_userData { - void (*func)(void *userData, BMVert *eve, int x, int y, int index); - void *userData; - ViewContext vc; - eV3DClipTest clipVerts; -} foreachScreenVert_userData; - -typedef struct foreachScreenEdge_userData { - void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); - void *userData; - ViewContext vc; - rcti win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ - eV3DClipTest clipVerts; -} foreachScreenEdge_userData; - -typedef struct foreachScreenFace_userData { - void (*func)(void *userData, BMFace *efa, int x, int y, int index); - void *userData; - ViewContext vc; -} foreachScreenFace_userData; - typedef struct drawDMVerts_userData { BMEditMesh *em; /* BMESH BRANCH ONLY */ @@ -784,10 +745,10 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa mul_m4_v3(mat, vos->vec); if (ED_view3d_project_short_ex(ar, - (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, - vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, + (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, + vos->vec, vos->sco, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { tot++; } @@ -858,7 +819,9 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa if (depth_write) { if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } - else glDepthMask(1); + else { + glDepthMask(1); + } glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -900,7 +863,7 @@ static void drawcube(void) glEnd(); } -/* draws a cube on given the scaling of the cube, assuming that +/* draws a cube on given the scaling of the cube, assuming that * all required matrices have been set (used for drawing empties) */ static void drawcube_size(float size) @@ -1284,8 +1247,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glVertex3fv(tvec); glEnd(); } - else circ(0.0, 0.0, fabsf(z)); - + else { + circ(0.0, 0.0, fabsf(z)); + } + /* draw the circle/square representing spotbl */ if (la->type == LA_SPOT) { float spotblcirc = fabs(z) * (1 - pow(la->spotblend, 2)); @@ -1429,7 +1394,7 @@ static void draw_limit_line(float sta, float end, unsigned int col) glVertex3f(0.0, 0.0, -end); glEnd(); glPointSize(1.0); -} +} /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */ @@ -1870,29 +1835,6 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel) bglEnd(); } -void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, int x, int y), void *userData) -{ - Object *obedit = vc->obedit; - Lattice *lt = obedit->data; - BPoint *bp = lt->editlatt->latt->def; - DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); - float *co = dl ? dl->verts : NULL; - int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - - ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ - - for (i = 0; i < N; i++, bp++, co += 3) { - if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, bp, screen_co[0], screen_co[1]); - } - } - } -} - static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int use_wcol) { int index = ((w * lt->pntsv + v) * lt->pntsu) + u; @@ -1979,53 +1921,6 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) /* ***************** ******************** */ -/* Note! - foreach funcs should be called while drawing or directly after - * if not, ED_view3d_init_mats_rv3d() can be used for selection tools - * but would not give correct results with dupli's for eg. which don't - * use the object matrix in the usual way */ -static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - foreachScreenVert_userData *data = userData; - BMVert *eve = EDBM_vert_at_index(data->vc.em, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? - V3D_PROJ_TEST_NOP : - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; - int screen_co[2]; - - if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) { - return; - } - - data->func(data->userData, eve, screen_co[0], screen_co[1], index); - } -} - -void mesh_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, BMVert *eve, int x, int y, int index), - void *userData, eV3DClipTest clipVerts) -{ - foreachScreenVert_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - data.func = func; - data.userData = userData; - data.clipVerts = clipVerts; - - if (clipVerts != V3D_CLIP_TEST_OFF) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - EDBM_index_arrays_init(vc->em, 1, 0, 0); - dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - /* draw callback */ static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) @@ -2054,286 +1949,9 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) glEnd(); } -static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) -{ - foreachScreenEdge_userData *data = userData; - BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - int screen_co_a[2]; - int screen_co_b[2]; - - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : - V3D_PROJ_TEST_NOP; - - if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_SUCCESS) { - return; - } - if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) { - return; - } - - if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { - /* pass */ - } - else { - if (data->clipVerts == V3D_CLIP_TEST_REGION) { - if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { - return; - } - } - } - - data->func(data->userData, eed, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1], index); - } -} - -void mesh_foreachScreenEdge( - ViewContext *vc, - void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index), - void *userData, eV3DClipTest clipVerts) -{ - foreachScreenEdge_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - - data.win_rect.xmin = 0; - data.win_rect.ymin = 0; - data.win_rect.xmax = vc->ar->winx; - data.win_rect.ymax = vc->ar->winy; - - data.func = func; - data.userData = userData; - data.clipVerts = clipVerts; - - if (clipVerts != V3D_CLIP_TEST_OFF) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - EDBM_index_arrays_init(vc->em, 0, 1, 0); - dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - -static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) -{ - foreachScreenFace_userData *data = userData; - BMFace *efa = EDBM_face_at_index(data->vc.em, index); - - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - int screen_co[2]; - if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - data->func(data->userData, efa, screen_co[0], screen_co[1], index); - } - } -} - -void mesh_foreachScreenFace( - ViewContext *vc, - void (*func)(void *userData, BMFace *efa, int x, int y, int index), - void *userData) -{ - foreachScreenFace_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - data.func = func; - data.userData = userData; - - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - - EDBM_index_arrays_init(vc->em, 0, 0, 1); - dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - -void nurbs_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), - void *userData) -{ - Curve *cu = vc->obedit->data; - Nurb *nu; - int i; - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - for (nu = nurbs->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - for (i = 0; i < nu->pntsu; i++) { - BezTriple *bezt = &nu->bezt[i]; - - if (bezt->hide == 0) { - int screen_co[2]; - - if (cu->drawflag & CU_HIDE_HANDLES) { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); - } - } - else { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]); - } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); - } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]); - } - } - } - } - } - else { - for (i = 0; i < nu->pntsu * nu->pntsv; i++) { - BPoint *bp = &nu->bp[i]; - - if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]); - } - } - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void mball_foreachScreenElem( - struct ViewContext *vc, - void (*func)(void *userData, struct MetaElem *ml, int x, int y), - void *userData) -{ - MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; - - for (ml = mb->editelems->first; ml; ml = ml->next) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - func(userData, ml, screen_co[0], screen_co[1]); - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void armature_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), - void *userData) -{ - bArmature *arm = vc->obedit->data; - EditBone *ebone; - - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone)) { - int screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, ebone, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -/* almost _exact_ copy of #armature_foreachScreenBone */ -void pose_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), - void *userData) -{ - bArmature *arm = vc->obact->data; - bPose *pose = vc->obact->pose; - bPoseChannel *pchan; - - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if (PBONE_VISIBLE(arm, pchan->bone)) { - int screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, pchan, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); - } - } - } -} - /* ************** DRAW MESH ****************** */ -/* First section is all the "simple" draw routines, +/* First section is all the "simple" draw routines, * ones that just pass some sort of primitive to GL, * with perhaps various options to control lighting, * color, etc. @@ -2568,7 +2186,7 @@ static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) return DM_DRAW_OPTION_SKIP; } } -static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, +static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) { drawDMEdgesSel_userData data; @@ -2590,7 +2208,7 @@ static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) return DM_DRAW_OPTION_NORMAL; } -static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) +static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) { dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em); } @@ -2729,7 +2347,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int } /* also draws the active face */ -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *markCol, unsigned char *actCol, BMFace *efa_act) { drawDMFacesSel_userData data; @@ -2827,9 +2445,9 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) /* EditMesh drawing routines*/ -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, +static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act, - RegionView3D *rv3d) + RegionView3D *rv3d) { ToolSettings *ts = scene->toolsettings; int sel; @@ -2949,7 +2567,7 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, glEnable(GL_DEPTH_TEST); } } -} +} static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit) { @@ -3214,7 +2832,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, if (ese->type == BM_FACE) { efa_act = (BMFace *)ese->data; } - else + else #endif if (ese->htype == BM_EDGE) { eed_act = (BMEdge *)ese->ele; @@ -3397,13 +3015,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) { - if ((v3d->transp == FALSE) && /* not when we draw the transparent pass */ (ob->mode & OB_MODE_ALL_PAINT) == FALSE) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(0); - + /* if transparent, we cannot draw the edges for solid select... edges have no material info. * drawFacesSolid() doesn't draw the transparent faces */ if (ob->dtx & OB_DRAWTRANSP) { @@ -5896,7 +5513,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[][4], int star glEnd(); } -/* draws a circle on x-z plane given the scaling of the circle, assuming that +/* draws a circle on x-z plane given the scaling of the circle, assuming that * all required matrices have been set (used for drawing empties) */ static void drawcircle_size(float size) @@ -7041,72 +6658,76 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* only draw domains */ - if (smd->domain && smd->domain->fluid) { - if (CFRA < smd->domain->point_cache[0]->startframe) { - /* don't show smoke before simulation starts, this could be made an option in the future */ - } - else if (!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { -// #if 0 - smd->domain->tex = NULL; - GPU_create_smoke(smd, 0); - draw_volume(ar, smd->domain->tex, - smd->domain->p0, smd->domain->p1, - smd->domain->res, smd->domain->dx, - smd->domain->tex_shadow); - GPU_free_smoke(smd); -// #endif -#if 0 - int x, y, z; - float *density = smoke_get_density(smd->domain->fluid); + if (smd->domain) { + SmokeDomainSettings *sds = smd->domain; + float p0[3], p1[3], viewnormal[3]; + BoundBox bb; - glLoadMatrixf(rv3d->viewmat); - // glMultMatrixf(ob->obmat); + glLoadMatrixf(rv3d->viewmat); + glMultMatrixf(ob->obmat); - if (col || (ob->flag & SELECT)) cpack(0xFFFFFF); - glDepthMask(GL_FALSE); - glEnable(GL_BLEND); - + /* draw adaptive domain bounds */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + /* draw domain max bounds */ + VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res); + VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res); + BKE_boundbox_init_from_minmax(&bb, p0, p1); + draw_box(bb.vec); - // glPointSize(3.0); - bglBegin(GL_POINTS); + /* draw base resolution bounds */ +#if 0 + BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1); + draw_box(bb.vec); +#endif + } - for (x = 0; x < smd->domain->res[0]; x++) { - for (y = 0; y < smd->domain->res[1]; y++) { - for (z = 0; z < smd->domain->res[2]; z++) { - float tmp[3]; - int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z); - - if (density[index] > FLT_EPSILON) { - float color[3]; - copy_v3_v3(tmp, smd->domain->p0); - tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5; - tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5; - tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5; - color[0] = color[1] = color[2] = density[index]; - glColor3fv(color); - bglVertex3fv(tmp); - } - } - } + /* don't show smoke before simulation starts, this could be made an option in the future */ + if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) { + + // get view vector + copy_v3_v3(viewnormal, rv3d->viewinv[2]); + mul_mat3_m4_v3(ob->imat, viewnormal); + normalize_v3(viewnormal); + + /* set dynamic boundaries to draw the volume */ + p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]; + p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]; + p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]; + p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]; + p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]; + p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]; + + /* scale cube to global space to equalize volume slicing on all axises + * (its scaled back before drawing) */ + mul_v3_v3(p0, ob->size); + mul_v3_v3(p1, ob->size); + + if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + smd->domain->tex = NULL; + GPU_create_smoke(smd, 0); + draw_smoke_volume(sds, ob, sds->tex, + p0, p1, + sds->res, sds->dx, sds->scale * sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); + GPU_free_smoke(smd); + } + else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + sds->tex = NULL; + GPU_create_smoke(smd, 1); + draw_smoke_volume(sds, ob, sds->tex, + p0, p1, + sds->res_wt, sds->dx, sds->scale * sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); + GPU_free_smoke(smd); } - bglEnd(); - glPointSize(1.0); - - glMultMatrixf(ob->obmat); - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - if (col) cpack(col); + /* smoke debug render */ +#ifdef SMOKE_DEBUG_VELOCITY + draw_smoke_velocity(smd->domain, ob); +#endif +#ifdef SMOKE_DEBUG_HEAT + draw_smoke_heat(smd->domain, ob); #endif - } - else if (smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - smd->domain->tex = NULL; - GPU_create_smoke(smd, 1); - draw_volume(ar, smd->domain->tex, - smd->domain->p0, smd->domain->p1, - smd->domain->res_wt, smd->domain->dx_wt, - smd->domain->tex_shadow); - GPU_free_smoke(smd); } } } @@ -7368,7 +6989,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs); bglEnd(); glPointSize(1.0); -} +} static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index) { @@ -7388,7 +7009,7 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) { void *ptrs[2] = {(void *)(intptr_t) offset, em}; dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs); -} +} static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index) { @@ -7567,7 +7188,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* assumes all matrices/etc set OK */ /* helper function for drawing object instances - meshes */ -static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, +static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline) { Mesh *me = ob->data; diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 2c2d4039225..ebb48960b80 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -36,6 +36,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_smoke_types.h" #include "DNA_view3d_types.h" #include "BLI_utildefines.h" @@ -132,7 +133,7 @@ static int intersect_edges(float *points, float a, float b, float c, float d, fl int i; float t; int numpoints = 0; - + for (i = 0; i < 12; i++) { t = -(a * edges[i][0][0] + b * edges[i][0][1] + c * edges[i][0][2] + d) / (a * edges[i][1][0] + b * edges[i][1][1] + c * edges[i][1][2]); @@ -156,12 +157,12 @@ static int convex(const float p0[3], const float up[3], const float a[3], const return dot_v3v3(up, tmp) >= 0; } -void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, GPUTexture *tex_shadow) +void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, + GPUTexture *tex, float min[3], float max[3], + int res[3], float dx, float UNUSED(base_scale), float viewnormal[3], + GPUTexture *tex_shadow, GPUTexture *tex_flame) { - RegionView3D *rv3d = ar->regiondata; - - float viewnormal[3]; - int i, j, n, good_index; + int i, j, k, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; float *points = NULL; int numpoints = 0; @@ -193,25 +194,76 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; + unsigned char *spec_data; + float *spec_pixels; + GPUTexture *tex_spec; + /* Fragment program to calculate the view3d of smoke */ - /* using 2 textures, density and shadow */ - const char *text = "!!ARBfp1.0\n" - "PARAM dx = program.local[0];\n" - "PARAM darkness = program.local[1];\n" - "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" - "TEMP temp, shadow, value;\n" - "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" - "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" - "MUL value, temp, darkness;\n" - "MUL value, value, dx;\n" - "MUL value, value, f;\n" - "EX2 temp, -value.r;\n" - "SUB temp.a, 1.0, temp.r;\n" - "MUL temp.r, temp.r, shadow.r;\n" - "MUL temp.g, temp.g, shadow.r;\n" - "MUL temp.b, temp.b, shadow.r;\n" - "MOV result.color, temp;\n" - "END\n"; + /* using 4 textures, density, shadow, flame and flame spectrum */ + const char *shader_basic = + "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 temp, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, temp.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, darkness.r;\n" + "MUL temp.g, temp.g, darkness.g;\n" + "MUL temp.b, temp.b, darkness.b;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; + + /* color shader */ + const char *shader_color = + "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* unpremultiply volume texture */ + "RCP value.r, temp.a;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 value.r, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, value.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; + GLuint prog; @@ -223,6 +275,33 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r } tstart(); + /* generate flame spectrum texture */ + #define SPEC_WIDTH 256 + #define FIRE_THRESH 7 + #define MAX_FIRE_ALPHA 0.06f + #define FULL_ON_FIRE 100 + spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); + flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); + spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + for (k = 0; k < SPEC_WIDTH; k++) { + int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4; + if (k >= FIRE_THRESH) { + spec_pixels[index] = ((float)spec_data[k * 4]) / 255.0f; + spec_pixels[index + 1] = ((float)spec_data[k * 4 + 1]) / 255.0f; + spec_pixels[index + 2] = ((float)spec_data[k * 4 + 2]) / 255.0f; + spec_pixels[index + 3] = MAX_FIRE_ALPHA * ( + (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); + } + else { + spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f; + } + } + } + } + + tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); sub_v3_v3v3(size, max, min); @@ -296,32 +375,17 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); - glLoadMatrixf(rv3d->viewmat); - // glMultMatrixf(ob->obmat); - glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -#if 0 - printf("Viewinv:\n"); - printf("%f, %f, %f\n", rv3d->viewinv[0][0], rv3d->viewinv[0][1], rv3d->viewinv[0][2]); - printf("%f, %f, %f\n", rv3d->viewinv[1][0], rv3d->viewinv[1][1], rv3d->viewinv[1][2]); - printf("%f, %f, %f\n", rv3d->viewinv[2][0], rv3d->viewinv[2][1], rv3d->viewinv[2][2]); -#endif - - /* get view vector */ - copy_v3_v3(viewnormal, rv3d->viewinv[2]); - normalize_v3(viewnormal); /* find cube vertex that is closest to the viewer */ for (i = 0; i < 8; i++) { float x, y, z; - x = cv[i][0] - viewnormal[0]*size[0]*0.5f; - y = cv[i][1] - viewnormal[1]*size[1]*0.5f; - z = cv[i][2] - viewnormal[2]*size[2]*0.5f; + x = cv[i][0] - viewnormal[0] * size[0] * 0.5f; + y = cv[i][1] - viewnormal[1] * size[1] * 0.5f; + z = cv[i][2] - viewnormal[2] * size[2] * 0.5f; if ((x >= min[0]) && (x <= max[0]) && (y >= min[1]) && (y <= max[1]) && @@ -344,12 +408,19 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r glGenProgramsARB(1, &prog); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); - glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text); + /* set shader */ + if (sds->active_fields & SM_ACTIVE_COLORS) + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color); + else + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic); /* cell spacing */ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0); /* custom parameter for smoke style (higher = thicker) */ - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); + if (sds->active_fields & SM_ACTIVE_COLORS) + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0); + else + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0); } else printf("Your gfx card does not support 3D View smoke drawing.\n"); @@ -360,6 +431,11 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r else printf("No volume shadow\n"); + if (tex_flame) { + GPU_texture_bind(tex_flame, 2); + GPU_texture_bind(tex_spec, 3); + } + if (!GPU_non_power_of_two_support()) { cor[0] = (float)res[0] / (float)power_of_2_max_i(res[0]); cor[1] = (float)res[1] / (float)power_of_2_max_i(res[1]); @@ -373,7 +449,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]); - dd = ds / 96.f; + dd = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f; n = 0; good_index = i; @@ -416,14 +492,29 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r } } - // printf("numpoints: %d\n", numpoints); + /* render fire slice */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0); + glBegin(GL_POLYGON); + glColor3f(1.0, 1.0, 1.0); + for (i = 0; i < numpoints; i++) { + glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], + (points[i * 3 + 1] - min[1]) * cor[1] / size[1], + (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); + glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); + } + glEnd(); + + /* render smoke slice */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]); + glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); } glEnd(); } @@ -436,6 +527,14 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r if (tex_shadow) GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); + if (tex_flame) { + GPU_texture_unbind(tex_flame); + GPU_texture_unbind(tex_spec); + } + GPU_texture_free(tex_spec); + + free(spec_data); + free(spec_pixels); if (GLEW_ARB_fragment_program) { glDisable(GL_FRAGMENT_PROGRAM_ARB); @@ -451,6 +550,109 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r if (gl_depth) { glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glDepthMask(GL_TRUE); } } + +#ifdef SMOKE_DEBUG_VELOCITY +void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) +{ + float x, y, z; + float x0, y0, z0; + int *base_res = domain->base_res; + int *res = domain->res; + int *res_min = domain->res_min; + int *res_max = domain->res_max; + float *vel_x = smoke_get_velocity_x(domain->fluid); + float *vel_y = smoke_get_velocity_y(domain->fluid); + float *vel_z = smoke_get_velocity_z(domain->fluid); + + float min[3]; + float *cell_size = domain->cell_size; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f; + float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + + glLineWidth(1.0f); + + /* set first position so that it doesn't jump when domain moves */ + x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size); + y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size); + z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size); + if (x0 < res_min[0]) x0 += step_size; + if (y0 < res_min[1]) y0 += step_size; + if (z0 < res_min[2]) z0 += step_size; + add_v3_v3v3(min, domain->p0, domain->obj_shift_f); + + for (x = floor(x0); x < res_max[0]; x += step_size) + for (y = floor(y0); y < res_max[1]; y += step_size) + for (z = floor(z0); z < res_max[2]; z += step_size) { + int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1]; + + float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]}; + float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]); + + /* draw heat as scaled "arrows" */ + if (vel >= 0.01f) { + float col_g = 1.0f - vel; + CLAMP(col_g, 0.0f, 1.0f); + glColor3f(1.0f, col_g, 0.0f); + glPointSize(10.0f * vel); + + glBegin(GL_LINES); + glVertex3f(pos[0], pos[1], pos[2]); + glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); + glEnd(); + glBegin(GL_POINTS); + glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); + glEnd(); + } + } +} +#endif + +#ifdef SMOKE_DEBUG_HEAT +void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) +{ + float x, y, z; + float x0, y0, z0; + int *base_res = domain->base_res; + int *res = domain->res; + int *res_min = domain->res_min; + int *res_max = domain->res_max; + float *heat = smoke_get_heat(domain->fluid); + + float min[3]; + float *cell_size = domain->cell_size; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f; + float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + + /* set first position so that it doesn't jump when domain moves */ + x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size); + y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size); + z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size); + if (x0 < res_min[0]) x0 += step_size; + if (y0 < res_min[1]) y0 += step_size; + if (z0 < res_min[2]) z0 += step_size; + add_v3_v3v3(min, domain->p0, domain->obj_shift_f); + + for (x = floor(x0); x < res_max[0]; x += step_size) + for (y = floor(y0); y < res_max[1]; y += step_size) + for (z = floor(z0); z < res_max[2]; z += step_size) { + int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1]; + + float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]}; + + /* draw heat as different sized points */ + if (heat[index] >= 0.01f) { + float col_gb = 1.0f - heat[index]; + CLAMP(col_gb, 0.0f, 1.0f); + glColor3f(1.0f, col_gb, col_gb); + glPointSize(24.0f * heat[index]); + + glBegin(GL_POINTS); + glVertex3f(pos[0], pos[1], pos[2]); + glEnd(); + } + } +} +#endif diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index c8aca5674a4..9755c7d1b7c 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -86,13 +86,15 @@ #define B_REDR 2 #define B_OBJECTPANELMEDIAN 1008 +#define NBR_TRANSFORM_PROPERTIES 7 + /* temporary struct for storing transform properties */ typedef struct { float ob_eul[4]; /* used for quat too... */ float ob_scale[3]; /* need temp space due to linked values */ float ob_dims[3]; short link_scale; - float ve_median[9]; + float ve_median[NBR_TRANSFORM_PROPERTIES]; int curdef; float *defweightp; } TransformProperties; @@ -131,17 +133,38 @@ static float compute_scale_factor(const float ve_median, const float median) /* is used for both read and write... */ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { +/* Get rid of those ugly magic numbers, even in a single func they become confusing! */ +/* Location, common to all. */ +/* XXX Those two *must* remain contiguous (used as array)! */ +#define LOC_X 0 +#define LOC_Y 1 +#define LOC_Z 2 +/* Meshes... */ +#define M_CREASE 3 +#define M_WEIGHT 4 +/* XXX Those two *must* remain contiguous (used as array)! */ +#define M_SKIN_X 5 +#define M_SKIN_Y 6 +/* Curves... */ +#define C_BWEIGHT 3 +#define C_WEIGHT 4 +#define C_RADIUS 5 +#define C_TILT 6 +/*Lattice... */ +#define L_WEIGHT 4 + uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; MDeformVert *dvert = NULL; TransformProperties *tfp; - float median[9], ve_median[9]; - int tot, totw, totweight, totedge, totradius, totskinradius; + float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; + int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; + int meshdata = FALSE; char defstr[320]; - PointerRNA radius_ptr; + PointerRNA data_ptr; - median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = median[7] = median[8] = 0.0; - tot = totw = totweight = totedge = totradius = totskinradius = 0; - defstr[0] = 0; + fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f); + tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0; + defstr[0] = '\0'; /* make sure we got storage */ if (v3d->properties_storage == NULL) @@ -162,11 +185,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float evedef = eve; tot++; - add_v3_v3(median, eve->co); + add_v3_v3(&median[LOC_X], eve->co); vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); if (vs) { - add_v2_v2(median + 7, vs->radius); /* Third val not used currently. */ + add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ totskinradius++; } } @@ -176,12 +199,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float *f; - totedge++; + totedgedata++; f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - median[3] += f ? *f : 0.0f; + median[M_CREASE] += f ? *f : 0.0f; f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - median[6] += f ? *f : 0.0f; + median[M_WEIGHT] += f ? *f : 0.0f; } } @@ -211,6 +234,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float tfp->defweightp = &dvert->dw[0].weight; } } + + meshdata = totedgedata || totskinradius; } else if (ob->type == OB_CURVE || ob->type == OB_SURF) { Curve *cu = ob->data; @@ -229,22 +254,24 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu; while (a--) { if (bezt->f2 & SELECT) { - add_v3_v3(median, bezt->vec[1]); + add_v3_v3(&median[LOC_X], bezt->vec[1]); tot++; - median[4] += bezt->weight; - totweight++; - median[5] += bezt->radius; - totradius++; - selp = bezt; - seltype = &RNA_BezierSplinePoint; + median[C_WEIGHT] += bezt->weight; + median[C_RADIUS] += bezt->radius; + median[C_TILT] += bezt->alfa; + if (!totcurvedata) { /* I.e. first time... */ + selp = bezt; + seltype = &RNA_BezierSplinePoint; + } + totcurvedata++; } else { if (bezt->f1 & SELECT) { - add_v3_v3(median, bezt->vec[0]); + add_v3_v3(&median[LOC_X], bezt->vec[0]); tot++; } if (bezt->f3 & SELECT) { - add_v3_v3(median, bezt->vec[2]); + add_v3_v3(&median[LOC_X], bezt->vec[2]); tot++; } } @@ -256,16 +283,18 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(median, bp->vec); - median[3] += bp->vec[3]; - totw++; + add_v3_v3(&median[LOC_X], bp->vec); + median[C_BWEIGHT] += bp->vec[3]; + totcurvebweight++; tot++; - median[4] += bp->weight; - totweight++; - median[5] += bp->radius; - totradius++; - selp = bp; - seltype = &RNA_SplinePoint; + median[C_WEIGHT] += bp->weight; + median[C_RADIUS] += bp->radius; + median[C_TILT] += bp->alfa; + if (!totcurvedata) { /* I.e. first time... */ + selp = bp; + seltype = &RNA_SplinePoint; + } + totcurvedata++; } bp++; } @@ -273,84 +302,102 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float nu = nu->next; } - if (totradius == 1) - RNA_pointer_create(&cu->id, seltype, selp, &radius_ptr); + if (totcurvedata == 1) + RNA_pointer_create(&cu->id, seltype, selp, &data_ptr); } else if (ob->type == OB_LATTICE) { Lattice *lt = ob->data; BPoint *bp; int a; + StructRNA *seltype = NULL; + void *selp = NULL; a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(median, bp->vec); + add_v3_v3(&median[LOC_X], bp->vec); tot++; - median[4] += bp->weight; - totweight++; + median[L_WEIGHT] += bp->weight; + if (!totlattdata) { /* I.e. first time... */ + selp = bp; + seltype = &RNA_LatticePoint; + } + totlattdata++; } bp++; } + + if (totlattdata == 1) + RNA_pointer_create(<->id, seltype, selp, &data_ptr); } if (tot == 0) { uiDefBut(block, LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); return; } - median[0] /= (float)tot; - median[1] /= (float)tot; - median[2] /= (float)tot; - if (totedge) { - median[3] /= (float)totedge; - median[6] /= (float)totedge; - } - else if (totw) - median[3] /= (float)totw; - if (totweight) - median[4] /= (float)totweight; - if (totradius) - median[5] /= (float)totradius; - if (totskinradius) { - median[7] /= (float)totskinradius; - median[8] /= (float)totskinradius; - } + /* Location, X/Y/Z */ + mul_v3_fl(&median[LOC_X], 1.0f / (float)tot); if (v3d->flag & V3D_GLOBAL_STATS) - mul_m4_v3(ob->obmat, median); + mul_m4_v3(ob->obmat, &median[LOC_X]); + + if (meshdata) { + if (totedgedata) { + median[M_CREASE] /= (float)totedgedata; + median[M_WEIGHT] /= (float)totedgedata; + } + if (totskinradius) { + median[M_SKIN_X] /= (float)totskinradius; + median[M_SKIN_Y] /= (float)totskinradius; + } + } + else if (totcurvedata) { + median[C_WEIGHT] /= (float)totcurvedata; + median[C_RADIUS] /= (float)totcurvedata; + median[C_TILT] /= (float)totcurvedata; + if (totcurvebweight) + median[C_BWEIGHT] /= (float)totcurvebweight; + } + else if (totlattdata) + median[L_WEIGHT] /= (float)totlattdata; if (block) { /* buttons */ uiBut *but; int yi = 200; const int buth = 20 * UI_DPI_ICON_FAC; const int but_margin = 2; + const char *c; memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); if (tot == 1) { - uiDefBut(block, LABEL, 0, IFACE_("Vertex:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); - } - else { - uiDefBut(block, LABEL, 0, IFACE_("Median:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); + if (totcurvedata) /* Curve */ + c = IFACE_("Control Point:"); + else /* Mesh or lattice */ + c = IFACE_("Vertex:"); } + else + c = IFACE_("Median:"); + uiDefBut(block, LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); /* Should be no need to translate these. */ but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[0]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_X]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[1]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_Y]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[2]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_Z]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); - if (totw == tot) { + if (totcurvebweight == tot) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); + &(tfp->ve_median[C_BWEIGHT]), 0.01, 100.0, 1, 3, ""); } uiBlockBeginAlign(block); @@ -362,60 +409,60 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); - if (totweight == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); + /* Meshes... */ + if (meshdata) { + if (totedgedata) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + } + if (totskinradius) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totskinradius == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_SKIN_X]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totskinradius == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_SKIN_Y]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + } } - else if (totweight > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), - 0, yi -= buth, 200, buth, - &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); + /* Curve... */ + else if (totcurvedata == 1) { + uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); + uiDefButR(block, NUM, 0, "Radius", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL); + uiDefButR(block, NUM, 0, "Tilt", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "tilt", 0, -M_PI * 2.0f, M_PI * 2.0f, 1, 3, NULL); } - - if (totradius == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius:"), + else if (totcurvedata > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); - } - else if (totradius > 1) { + &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); + &(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); + but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[C_TILT]), -M_PI * 2.0f, M_PI * 2.0f, 1, 3, + TIP_("Tilt of curve control points")); + uiButSetUnitType(but, PROP_UNIT_ROTATION); } - - if (totskinradius == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius X:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius Y:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + /* Lattice... */ + else if (totlattdata == 1) { + uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); } - else if (totskinradius > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius X:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("Median X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius Y:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Median Y radius used by Skin modifier")); - } - - if (totedge == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); - } - else if (totedge > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Bevel Weight:"), + else if (totlattdata > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); } uiBlockEndAlign(block); @@ -423,42 +470,40 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } else { /* apply */ + int i; + memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median)); if (v3d->flag & V3D_GLOBAL_STATS) { invert_m4_m4(ob->imat, ob->obmat); - mul_m4_v3(ob->imat, median); - mul_m4_v3(ob->imat, ve_median); + mul_m4_v3(ob->imat, &median[LOC_X]); + mul_m4_v3(ob->imat, &ve_median[LOC_X]); } - sub_v3_v3v3(median, ve_median, median); - median[3] = ve_median[3] - median[3]; - median[4] = ve_median[4] - median[4]; - median[5] = ve_median[5] - median[5]; - median[6] = ve_median[6] - median[6]; - median[7] = ve_median[7] - median[7]; - median[8] = ve_median[8] - median[8]; + i = NBR_TRANSFORM_PROPERTIES; + while (i--) + median[i] = ve_median[i] - median[i]; if (ob->type == OB_MESH) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMVert *eve; BMIter iter; - if (len_v3(median) > 0.000001f) { + if (len_v3(&median[LOC_X]) > 0.000001f) { + BMVert *eve; BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - add_v3_v3(eve->co, median); + add_v3_v3(eve->co, &median[LOC_X]); } } EDBM_mesh_normals_update(em); } - if (median[3] != 0.0f) { + if (median[M_CREASE] != 0.0f) { BMEdge *eed; - const float sca = compute_scale_factor(ve_median[3], median[3]); + const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { @@ -494,9 +539,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - if (median[6] != 0.0f) { + if (median[M_WEIGHT] != 0.0f) { BMEdge *eed; - const float sca = compute_scale_factor(ve_median[6], median[6]); + const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { @@ -532,11 +577,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - if (median[7] != 0.0f) { + if (median[M_SKIN_X] != 0.0f) { BMVert *eve; /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[7]; - if (ve_median[7] - median[7] == 0.0f) { + float sca = ve_median[M_SKIN_X]; + if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -546,7 +591,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } else { - sca /= (ve_median[7] - median[7]); + sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -556,11 +601,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } } - if (median[8] != 0.0f) { + if (median[M_SKIN_Y] != 0.0f) { BMVert *eve; /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[8]; - if (ve_median[8] - median[8] == 0.0f) { + float sca = ve_median[M_SKIN_Y]; + if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -570,7 +615,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } else { - sca /= (ve_median[8] - median[8]); + sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -589,7 +634,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BezTriple *bezt; int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - const float scale_w = compute_scale_factor(ve_median[4], median[4]); + const float scale_w = compute_scale_factor(ve_median[C_WEIGHT], median[C_WEIGHT]); nu = nurbs->first; while (nu) { @@ -598,11 +643,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu; while (a--) { if (bezt->f2 & SELECT) { - add_v3_v3(bezt->vec[0], median); - add_v3_v3(bezt->vec[1], median); - add_v3_v3(bezt->vec[2], median); + add_v3_v3(bezt->vec[0], &median[LOC_X]); + add_v3_v3(bezt->vec[1], &median[LOC_X]); + add_v3_v3(bezt->vec[2], &median[LOC_X]); - if (median[4] != 0.0f) { + if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bezt->weight = scale_w; } @@ -613,14 +658,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - bezt->radius += median[5]; + bezt->radius += median[C_RADIUS]; + bezt->alfa += median[C_TILT]; } else { if (bezt->f1 & SELECT) { - add_v3_v3(bezt->vec[0], median); + add_v3_v3(bezt->vec[0], &median[LOC_X]); } if (bezt->f3 & SELECT) { - add_v3_v3(bezt->vec[2], median); + add_v3_v3(bezt->vec[2], &median[LOC_X]); } } bezt++; @@ -631,10 +677,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, median); - bp->vec[3] += median[3]; + add_v3_v3(bp->vec, &median[LOC_X]); + bp->vec[3] += median[C_BWEIGHT]; - if (median[4] != 0.0f) { + if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bp->weight = scale_w; } @@ -645,7 +691,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - bp->radius += median[5]; + bp->radius += median[C_RADIUS]; + bp->alfa += median[C_TILT]; } bp++; } @@ -660,15 +707,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Lattice *lt = ob->data; BPoint *bp; int a; - const float scale_w = compute_scale_factor(ve_median[4], median[4]); + const float scale_w = compute_scale_factor(ve_median[L_WEIGHT], median[L_WEIGHT]); a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, median); + add_v3_v3(bp->vec, &median[LOC_X]); - if (median[4] != 0.0f) { + if (median[L_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bp->weight = scale_w; } @@ -685,7 +732,28 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float /* ED_undo_push(C, "Transform properties"); */ } + +/* Clean up! */ +/* Location, common to all. */ +#undef LOC_X +#undef LOC_Y +#undef LOC_Z +/* Meshes (and lattice)... */ +#undef M_CREASE +#undef M_WEIGHT +#undef M_SKIN_X +#undef M_SKIN_Y +/* Curves... */ +#undef C_BWEIGHT +#undef C_WEIGHT +#undef C_RADIUS +#undef C_TILT +/* Lattice... */ +#undef L_WEIGHT } +#undef NBR_TRANSFORM_PROPERTIES + + #define B_VGRP_PNL_COPY 1 #define B_VGRP_PNL_NORMALIZE 2 #define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */ @@ -1161,7 +1229,6 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); col = uiLayoutColumn(pa->layout, FALSE); - /* row = uiLayoutRow(col, FALSE); */ /* UNUSED */ RNA_id_pointer_create(&ob->id, &obptr); if (ob == obedit) { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ca768f2ef17..8e1b0716136 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -355,7 +355,9 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** if (dx < GRID_MIN_PX_D) { rv3d->gridview *= sublines; dx *= sublines; - if (dx < GRID_MIN_PX_D) ; + if (dx < GRID_MIN_PX_D) { + /* pass */ + } else { UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, dx); @@ -556,7 +558,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) int co[2]; /* we don't want the clipping for cursor */ - if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { setlinestyle(0); cpack(0xFF); circ((float)co[0], (float)co[1], 10.0); @@ -1460,7 +1462,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, /* smart function to sample a rect spiralling outside, nice for backbuf selection */ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int size, - unsigned int min, unsigned int max, int *dist, short strict, + unsigned int min, unsigned int max, float *r_dist, short strict, void *handle, unsigned int (*indextest)(void *handle, unsigned int index)) { struct ImBuf *buf; @@ -1498,13 +1500,13 @@ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int if (strict) { indexok = indextest(handle, *tbuf - min + 1); if (indexok) { - *dist = (short) sqrt( (float)distance); + *r_dist = sqrtf((float)distance); index = *tbuf - min + 1; goto exit; } } else { - *dist = (short) sqrt( (float)distance); /* XXX, this distance is wrong - */ + *r_dist = sqrtf((float)distance); /* XXX, this distance is wrong - */ index = *tbuf - min + 1; /* messy yah, but indices start at 1 */ goto exit; } @@ -2854,6 +2856,12 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw engine->tile_x = ceil(ar->winx / (float)scene->r.xparts); engine->tile_y = ceil(ar->winy / (float)scene->r.yparts); + /* clamp small tile sizes to prevent inefficient threading utilization + * the same happens for final renders as well + */ + engine->tile_x = MAX2(engine->tile_x, 64); + engine->tile_y = MAX2(engine->tile_x, 64); + type->view_update(engine, C); rv3d->render_engine = engine; @@ -2870,12 +2878,20 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw rctf viewborder; rcti cliprct; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); - cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + } + else { + cliprct.xmin = v3d->render_border.xmin * ar->winx; + cliprct.xmax = v3d->render_border.xmax * ar->winx; + cliprct.ymin = v3d->render_border.ymin * ar->winy; + cliprct.ymax = v3d->render_border.ymax * ar->winy; + } cliprct.xmin += ar->winrct.xmin; cliprct.xmax += ar->winrct.xmin; @@ -3121,8 +3137,20 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha Object *ob; - if (rv3d->persp == RV3D_CAMOB) + if (rv3d->persp == RV3D_CAMOB) { drawviewborder(scene, ar, v3d); + } + else if (v3d->flag2 & V3D_RENDER_BORDER) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + setlinestyle(3); + cpack(0x4040FF); + + glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy, + v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy); + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ @@ -3172,7 +3200,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; - int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); + int draw_border = FALSE; + + if (rv3d->persp == RV3D_CAMOB) + draw_border = scene->r.mode & R_BORDER; + else + draw_border = v3d->flag2 & V3D_RENDER_BORDER; /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 735f7b5ea4a..96264081f10 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -929,18 +929,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } } -static int view3d_camera_active_poll(bContext *C) -{ - if (ED_operator_view3d_active(C)) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d && rv3d->persp == RV3D_CAMOB) { - return 1; - } - } - - return 0; -} - /* test for unlocked camera view in quad view */ static int view3d_camera_user_poll(bContext *C) { @@ -966,7 +954,6 @@ static int viewrotate_cancel(bContext *C, wmOperator *op) void VIEW3D_OT_rotate(wmOperatorType *ot) { - /* identifiers */ ot->name = "Rotate view"; ot->description = "Rotate the view"; @@ -1637,7 +1624,7 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom, if (use_cam_zoom) { float delta; delta = (x - vod->origx + y - vod->origy) / 10.0f; - vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? delta : -delta); + vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? -delta : delta); CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX); } @@ -1692,11 +1679,11 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom, if (use_cam_zoom) { /* zfac is ignored in this case, see below */ #if 0 - zfac = vod->camzoom0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->camzoom; + zfac = vod->camzoom0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->camzoom; #endif } else { - zfac = vod->dist0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->dist; + zfac = vod->dist0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->dist; } } @@ -1889,12 +1876,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); } ED_view3d_depth_tag_update(vod->rv3d); @@ -1972,7 +1959,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv if (zoom_invert) SWAP(float, len1, len2); - zfac = 1.0f + ((len2 - len1) * 0.01f * vod->rv3d->dist); + zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist); } if (zfac != 1.0f) @@ -2108,13 +2095,13 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewdolly_apply(vod, event->prevx, event->prevy, FALSE); + viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewdolly_apply(vod, event->prevx, event->prevy, FALSE); + viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0); } ED_view3d_depth_tag_update(vod->rv3d); @@ -2179,21 +2166,98 @@ void VIEW3D_OT_dolly(wmOperatorType *ot) RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX); } +static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, + const float min[3], const float max[3], + int ok_dist) +{ + RegionView3D *rv3d = ar->regiondata; + float afm[3]; + float size; + + /* SMOOTHVIEW */ + float new_ofs[3]; + float new_dist; + + sub_v3_v3v3(afm, max, min); + size = MAX3(afm[0], afm[1], afm[2]); + + if (ok_dist) { + /* fix up zoom distance if needed */ + + if (rv3d->is_persp) { + if (size <= v3d->near * 1.5f) { + /* do not zoom closer than the near clipping plane */ + size = v3d->near * 1.5f; + } + } + else { /* ortho */ + if (size < 0.0001f) { + /* bounding box was a single point so do not zoom */ + ok_dist = 0; + } + else { + /* adjust zoom so it looks nicer */ + size *= 0.7f; + } + } + } + + add_v3_v3v3(new_ofs, min, max); + mul_v3_fl(new_ofs, -0.5f); + new_dist = size; + + /* correction for window aspect ratio */ + if (ar->winy > 2 && ar->winx > 2) { + size = (float)ar->winx / (float)ar->winy; + if (size < 1.0f) size = 1.0f / size; + new_dist *= size; + } + + if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) { + rv3d->persp = RV3D_PERSP; + view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + } + else { + view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + } + + /* smooth view does viewlock RV3D_BOXVIEW copy */ +} + +/* same as view3d_from_minmax but for all regions (except cameras) */ +static void view3d_from_minmax_multi(bContext *C, View3D *v3d, + const float min[3], const float max[3], + const int ok_dist) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar->regiondata; + /* when using all regions, don't jump out of camera view, + * but _do_ allow locked cameras to be moved */ + if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { + view3d_from_minmax(C, v3d, ar, min, max, ok_dist); + } + } + } +} static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); Scene *scene = CTX_data_scene(C); Base *base; float *curs; - const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); - + const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || + /* any one of the regions may be locked */ + (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA)); int center = RNA_boolean_get(op->ptr, "center"); - float size, min[3], max[3], afm[3]; + float min[3], max[3]; int ok = 1, onedone = FALSE; if (center) { @@ -2230,37 +2294,16 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in return OPERATOR_FINISHED; } - sub_v3_v3v3(afm, max, min); - size = 0.7f * MAX3(afm[0], afm[1], afm[2]); - if (size == 0.0f) ok = 0; - - if (ok) { - float new_dist; - float new_ofs[3]; - - new_dist = size; - new_ofs[0] = -(min[0] + max[0]) / 2.0f; - new_ofs[1] = -(min[1] + max[1]) / 2.0f; - new_ofs[2] = -(min[2] + max[2]) / 2.0f; - - /* correction for window aspect ratio */ - if (ar->winy > 2 && ar->winx > 2) { - size = (float)ar->winx / (float)ar->winy; - if (size < 1.0f) size = 1.0f / size; - new_dist *= size; - } - - if ((rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->persp = RV3D_PERSP; - view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL); - } - else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, &new_dist, NULL); - } + if (ok == 0) { + return OPERATOR_FINISHED; } -// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); + if (use_all_regions) { + view3d_from_minmax_multi(C, v3d, min, max, TRUE); + } + else { + view3d_from_minmax(C, v3d, ar, min, max, TRUE); + } return OPERATOR_FINISHED; } @@ -2268,6 +2311,8 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in void VIEW3D_OT_view_all(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "View All"; ot->description = "View all objects in scene"; @@ -2280,25 +2325,25 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) /* flags */ ot->flag = 0; + prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); RNA_def_boolean(ot->srna, "center", 0, "Center", ""); } /* like a localview without local!, was centerview() in 2.4x */ -static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) +static int viewselected_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); Scene *scene = CTX_data_scene(C); Object *ob = OBACT; Object *obedit = CTX_data_edit_object(C); - float size, min[3], max[3], afm[3]; + float min[3], max[3]; int ok = 0, ok_dist = 1; - const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); - - /* SMOOTHVIEW */ - float new_ofs[3]; - float new_dist; + const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || + /* any one of the regions may be locked */ + (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA)); INIT_MINMAX(min, max); @@ -2369,54 +2414,17 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) } } - if (ok == 0) return OPERATOR_FINISHED; - - sub_v3_v3v3(afm, max, min); - size = MAX3(afm[0], afm[1], afm[2]); - - if (ok_dist) { - /* fix up zoom distance if needed */ - - if (rv3d->is_persp) { - if (size <= v3d->near * 1.5f) { - /* do not zoom closer than the near clipping plane */ - size = v3d->near * 1.5f; - } - } - else { /* ortho */ - if (size < 0.0001f) { - /* bounding box was a single point so do not zoom */ - ok_dist = 0; - } - else { - /* adjust zoom so it looks nicer */ - size *= 0.7f; - } - } - } - - add_v3_v3v3(new_ofs, min, max); - mul_v3_fl(new_ofs, -0.5f); - - new_dist = size; - - /* correction for window aspect ratio */ - if (ar->winy > 2 && ar->winx > 2) { - size = (float)ar->winx / (float)ar->winy; - if (size < 1.0f) size = 1.0f / size; - new_dist *= size; + if (ok == 0) { + return OPERATOR_FINISHED; } - if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->persp = RV3D_PERSP; - view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + if (use_all_regions) { + view3d_from_minmax_multi(C, v3d, min, max, ok_dist); } else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + view3d_from_minmax(C, v3d, ar, min, max, ok_dist); } - /* smooth view does viewlock RV3D_BOXVIEW copy */ - // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); return OPERATOR_FINISHED; @@ -2424,6 +2432,7 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_view_selected(wmOperatorType *ot) { + PropertyRNA *prop; /* identifiers */ ot->name = "View Selected"; @@ -2436,6 +2445,10 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot) /* flags */ ot->flag = 0; + + /* rna later */ + prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op)) @@ -2608,42 +2621,71 @@ static int render_border_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); + Scene *scene = CTX_data_scene(C); rcti rect; - rctf vb; + rctf vb, border; + + int camera_only = RNA_boolean_get(op->ptr, "camera_only"); + + if (camera_only && rv3d->persp != RV3D_CAMOB) + return OPERATOR_PASS_THROUGH; /* get border select values using rna */ WM_operator_properties_border_to_rcti(op, &rect); /* calculate range */ - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); - scene->r.border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); - scene->r.border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + } + else { + vb.xmin = 0; + vb.ymin = 0; + vb.xmax = ar->winx; + vb.ymax = ar->winy; + } + + border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); + border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); /* actually set border */ - CLAMP(scene->r.border.xmin, 0.0f, 1.0f); - CLAMP(scene->r.border.ymin, 0.0f, 1.0f); - CLAMP(scene->r.border.xmax, 0.0f, 1.0f); - CLAMP(scene->r.border.ymax, 0.0f, 1.0f); + CLAMP(border.xmin, 0.0f, 1.0f); + CLAMP(border.ymin, 0.0f, 1.0f); + CLAMP(border.xmax, 0.0f, 1.0f); + CLAMP(border.ymax, 0.0f, 1.0f); + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.border = border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->render_border = border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } /* drawing a border surrounding the entire camera view switches off border rendering * or the border covers no pixels */ - if ((scene->r.border.xmin <= 0.0f && scene->r.border.xmax >= 1.0f && - scene->r.border.ymin <= 0.0f && scene->r.border.ymax >= 1.0f) || - (scene->r.border.xmin == scene->r.border.xmax || - scene->r.border.ymin == scene->r.border.ymax)) + if ((border.xmin <= 0.0f && border.xmax >= 1.0f && + border.ymin <= 0.0f && border.ymax >= 1.0f) || + (border.xmin == border.xmax || border.ymin == border.ymax)) { - scene->r.mode &= ~R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode &= ~R_BORDER; + else + v3d->flag2 &= ~V3D_RENDER_BORDER; } else { - scene->r.mode |= R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode |= R_BORDER; + else + v3d->flag2 |= V3D_RENDER_BORDER; } - - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); return OPERATOR_FINISHED; @@ -2662,7 +2704,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) ot->modal = WM_border_select_modal; ot->cancel = WM_border_select_cancel; - ot->poll = view3d_camera_active_poll; + ot->poll = ED_operator_view3d_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2670,7 +2712,56 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) /* rna */ WM_operator_properties_border(ot); + RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only"); } + +/* ********************* Set render border operator ****************** */ + +static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op)) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + + Scene *scene = CTX_data_scene(C); + rctf *border = NULL; + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.mode &= ~R_BORDER; + border = &scene->r.border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->flag2 &= ~V3D_RENDER_BORDER; + border = &v3d->render_border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } + + border->xmin = 0.0f; + border->ymin = 0.0f; + border->xmax = 1.0f; + border->ymax = 1.0f; + + return OPERATOR_FINISHED; + +} + +void VIEW3D_OT_clear_render_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Render Border"; + ot->description = "Clear the boundaries of the border render and enables border render"; + ot->idname = "VIEW3D_OT_clear_render_border"; + + /* api callbacks */ + ot->exec = clear_render_border_exec; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ********************* Border Zoom operator ****************** */ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) @@ -2729,7 +2820,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) /* no depths to use, we cant do anything! */ if (depth_close == FLT_MAX) { - BKE_report(op->reports, RPT_ERROR, "Depth Too Large"); + BKE_report(op->reports, RPT_ERROR, "Depth too large"); return OPERATOR_CANCELLED; } /* convert border to 3d coordinates */ @@ -2901,7 +2992,7 @@ static EnumPropertyItem prop_view_items[] = { {RV3D_VIEW_RIGHT, "RIGHT", 0, "Right", "View From the Right"}, {RV3D_VIEW_TOP, "TOP", 0, "Top", "View From the Top"}, {RV3D_VIEW_BOTTOM, "BOTTOM", 0, "Bottom", "View From the Bottom"}, - {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the active camera"}, + {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the Active Camera"}, {0, NULL, 0, NULL, NULL} }; @@ -3125,7 +3216,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* identifiers */ ot->name = "View numpad"; - ot->description = "Set the view"; + ot->description = "Use a preset viewpoint"; ot->idname = "VIEW3D_OT_viewnumpad"; /* api callbacks */ @@ -3135,8 +3226,8 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* flags */ ot->flag = 0; - prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use"); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } @@ -3213,7 +3304,9 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); } static EnumPropertyItem prop_view_pan_items[] = { @@ -3262,7 +3355,9 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); + + /* Properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); } static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) @@ -3290,7 +3385,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) { /* identifiers */ ot->name = "View Persp/Ortho"; - ot->description = "Switch the current view from perspective/orthographic"; + ot->description = "Switch the current view from perspective/orthographic projection"; ot->idname = "VIEW3D_OT_view_persportho"; /* api callbacks */ @@ -3406,7 +3501,8 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot) /* flags */ ot->flag = 0; - + + /* properties */ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX); } @@ -3534,7 +3630,7 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent * /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]); } - if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { short depth_used = FALSE; if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */ diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index c743b88e889..cd358dea869 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -284,6 +284,11 @@ static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event puts("\n-- fly begin --"); #endif + /* sanity check: for rare but possible case (if lib-linking the camera fails) */ + if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) { + fly->rv3d->persp = RV3D_PERSP; + } + if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); return FALSE; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5bfabf4fc4a..3017891183e 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -40,6 +40,7 @@ struct ARegionType; struct BoundBox; struct DerivedMesh; struct Object; +struct SmokeDomainSettings; struct ViewContext; struct bAnimVizSettings; struct bContext; @@ -50,8 +51,6 @@ struct wmNDOFMotionData; struct wmOperatorType; struct wmWindowManager; -#define BL_NEAR_CLIP 0.001 - /* drawing flags: */ enum { DRAW_PICKING = (1 << 0), @@ -97,6 +96,7 @@ void VIEW3D_OT_cursor3d(struct wmOperatorType *ot); void VIEW3D_OT_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_render_border(struct wmOperatorType *ot); +void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot); void VIEW3D_OT_zoom_border(struct wmOperatorType *ot); void view3d_boxview_copy(ScrArea *sa, ARegion *ar); @@ -212,7 +212,20 @@ ARegion *view3d_has_tools_region(ScrArea *sa); extern const char *view3d_context_dir[]; /* doc access */ /* draw_volume.c */ -void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, struct GPUTexture *tex_shadow); +void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, + struct GPUTexture *tex, float min[3], float max[3], + int res[3], float dx, float base_scale, float viewnormal[3], + struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame); + +//#define SMOKE_DEBUG_VELOCITY +//#define SMOKE_DEBUG_HEAT + +#ifdef SMOKE_DEBUG_VELOCITY +void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob); +#endif +#ifdef SMOKE_DEBUG_HEAT +void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob); +#endif /* workaround for trivial but noticeable camera bug caused by imprecision * between view border calculation in 2D/3D space, workaround for bug [#28037]. diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c new file mode 100644 index 00000000000..0472f9f2c10 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -0,0 +1,415 @@ +/* + * ***** 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): Blender Foundation, full recode and added functions + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/object/view3d_iterators.c + * \ingroup spview3d + */ + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meta_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" + +#include "BKE_armature.h" +#include "BKE_curve.h" +#include "BKE_DerivedMesh.h" +#include "BKE_displist.h" + +#include "bmesh.h" + +#include "ED_mesh.h" +#include "ED_screen.h" +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_view3d.h" + + +typedef struct foreachScreenVert_userData { + void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + eV3DProjTest clip_flag; +} foreachScreenVert_userData; + +/* user data structures for derived mesh callbacks */ +typedef struct foreachScreenEdge_userData { + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ + eV3DProjTest clip_flag; +} foreachScreenEdge_userData; + +typedef struct foreachScreenFace_userData { + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + eV3DProjTest clip_flag; +} foreachScreenFace_userData; + + +/* Note! - foreach funcs should be called while drawing or directly after + * if not, ED_view3d_init_mats_rv3d() can be used for selection tools + * but would not give correct results with dupli's for eg. which don't + * use the object matrix in the usual way */ + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3], + const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) +{ + foreachScreenVert_userData *data = userData; + BMVert *eve = EDBM_vert_at_index(data->vc.em, index); + + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + float screen_co[2]; + + if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) { + return; + } + + data->func(data->userData, eve, screen_co, index); + } +} + +void mesh_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), + void *userData, eV3DProjTest clip_flag) +{ + foreachScreenVert_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + data.func = func; + data.userData = userData; + data.clip_flag = clip_flag; + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } + + EDBM_index_arrays_init(vc->em, 1, 0, 0); + dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) +{ + foreachScreenEdge_userData *data = userData; + BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); + + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float screen_co_a[2]; + float screen_co_b[2]; + + if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, data->clip_flag) != V3D_PROJ_RET_OK) { + return; + } + if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, data->clip_flag) != V3D_PROJ_RET_OK) { + return; + } + + if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) { + if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { + return; + } + } + + data->func(data->userData, eed, screen_co_a, screen_co_b, index); + } +} + +void mesh_foreachScreenEdge( + ViewContext *vc, + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), + void *userData, eV3DProjTest clip_flag) +{ + foreachScreenEdge_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + + data.win_rect.xmin = 0; + data.win_rect.ymin = 0; + data.win_rect.xmax = vc->ar->winx; + data.win_rect.ymax = vc->ar->winy; + + data.func = func; + data.userData = userData; + data.clip_flag = clip_flag; + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } + + EDBM_index_arrays_init(vc->em, 0, 1, 0); + dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) +{ + foreachScreenFace_userData *data = userData; + BMFace *efa = EDBM_face_at_index(data->vc.em, index); + + if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + float screen_co[2]; + if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) { + data->func(data->userData, efa, screen_co, index); + } + } +} + +void mesh_foreachScreenFace( + ViewContext *vc, + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), + void *userData, const eV3DProjTest clip_flag) +{ + foreachScreenFace_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + data.func = func; + data.userData = userData; + data.clip_flag = clip_flag; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + EDBM_index_arrays_init(vc->em, 0, 0, 1); + dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +void nurbs_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + Curve *cu = vc->obedit->data; + Nurb *nu; + int i; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } + + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + for (i = 0; i < nu->pntsu; i++) { + BezTriple *bezt = &nu->bezt[i]; + + if (bezt->hide == 0) { + float screen_co[2]; + + if (cu->drawflag & CU_HIDE_HANDLES) { + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 1, screen_co); + } + } + else { + if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 0, screen_co); + } + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 1, screen_co); + } + if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 2, screen_co); + } + } + } + } + } + else { + for (i = 0; i < nu->pntsu * nu->pntsv; i++) { + BPoint *bp = &nu->bp[i]; + + if (bp->hide == 0) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, bp, NULL, -1, screen_co); + } + } + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + MetaBall *mb = (MetaBall *)vc->obedit->data; + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) { + func(userData, ml, screen_co); + } + } +} + +/* ------------------------------------------------------------------------ */ + +void lattice_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, BPoint *bp, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag) +{ + Object *obedit = vc->obedit; + Lattice *lt = obedit->data; + BPoint *bp = lt->editlatt->latt->def; + DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); + float *co = dl ? dl->verts : NULL; + int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ + } + + for (i = 0; i < N; i++, bp++, co += 3) { + if (bp->hide == 0) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, clip_flag) == V3D_PROJ_RET_OK) { + func(userData, bp, screen_co); + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + bArmature *arm = vc->obedit->data; + EditBone *ebone; + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + float screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, ebone, screen_co_a, screen_co_b); + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +/* almost _exact_ copy of #armature_foreachScreenBone */ +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + bArmature *arm = vc->obact->data; + bPose *pose = vc->obact->pose; + bPoseChannel *pchan; + + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (PBONE_VISIBLE(arm, pchan->bone)) { + float screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, pchan, screen_co_a, screen_co_b); + } + } + } +} diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 14c02c2357e..73f1563417c 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -83,6 +83,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_select_circle); WM_operatortype_append(VIEW3D_OT_smoothview); WM_operatortype_append(VIEW3D_OT_render_border); + WM_operatortype_append(VIEW3D_OT_clear_render_border); WM_operatortype_append(VIEW3D_OT_zoom_border); WM_operatortype_append(VIEW3D_OT_manipulator); WM_operatortype_append(VIEW3D_OT_enable_manipulator); @@ -136,8 +137,10 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_dolly", MIDDLEMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center_cursor", PADPERIOD, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", FALSE); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_to_active", PADPERIOD, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_clear", PADPERIOD, KM_PRESS, KM_ALT, 0); @@ -169,6 +172,9 @@ void view3d_keymap(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE); + RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "center", TRUE); @@ -340,7 +346,13 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "camera_only", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "camera_only", FALSE); + + WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT | KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c new file mode 100644 index 00000000000..5362f0377c3 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -0,0 +1,493 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_project.c + * \ingroup spview3d + */ + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BLO_sys_types.h" /* int64_t */ + +#include "BIF_gl.h" /* bglMats */ +#include "BIF_glutil.h" /* bglMats */ + +#include "BLI_math_vector.h" + +#include "ED_view3d.h" /* own include */ + +#define BL_NEAR_CLIP 0.001 + +/* Non Clipping Projection Functions + * ********************************* */ + +/** + * \note use #ED_view3d_ob_project_mat_get to get the projection matrix + */ +void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4]) +{ + float vec4[4]; + + copy_v3_v3(vec4, co); + vec4[3] = 1.0; + /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ + + mul_m4_v4(mat, vec4); + + if (vec4[3] > FLT_EPSILON) { + r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; + r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; + } + else { + zero_v2(r_co); + } +} + +/** + * \note use #ED_view3d_ob_project_mat_get to get projecting mat + */ +void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) +{ + float vec4[4]; + + copy_v3_v3(vec4, vec); + vec4[3] = 1.0; + /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ + + mul_m4_v4(mat, vec4); + + if (vec4[3] > FLT_EPSILON) { + r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; + r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; + r_co[2] = vec4[2] / vec4[3]; + } + else { + zero_v3(r_co); + } +} + + +/* Clipping Projection Functions + * ***************************** */ + +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) +{ + eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT); + + if (ret != V3D_PROJ_RET_OK) { + base->sx = IS_CLIPPED; + base->sy = 0; + } + + return ret; +} + +/* perspmat is typically... + * - 'rv3d->perspmat', is_local == FALSE + * - 'rv3d->perspmatob', is_local == TRUE + */ +static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, + float perspmat[4][4], const int is_local, /* normally hidden */ + const float co[3], float r_co[2], const eV3DProjTest flag) +{ + float fx, fy, vec4[4]; + + /* check for bad flags */ + BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag); + + if (flag & V3D_PROJ_TEST_CLIP_BB) { + RegionView3D *rv3d = ar->regiondata; + if (rv3d->rflag & RV3D_CLIPPING) { + if (ED_view3d_clipping_test(rv3d, co, is_local)) { + return V3D_PROJ_RET_CLIP_BB; + } + } + } + + copy_v3_v3(vec4, co); + vec4[3] = 1.0; + mul_m4_v4(perspmat, vec4); + + if (vec4[3] > (float)BL_NEAR_CLIP) { + fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { + fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { + r_co[0] = (short)floor(fx); + r_co[1] = (short)floor(fy); + } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_NEAR; + } + + return V3D_PROJ_RET_OK; +} + +eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], short r_co[2], const eV3DProjTest flag) +{ + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_OK) { + if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && + (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) + { + r_co[0] = (short)floor(tvec[0]); + r_co[1] = (short)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], int r_co[2], const eV3DProjTest flag) +{ + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_OK) { + if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && + (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) + { + r_co[0] = (int)floor(tvec[0]); + r_co[1] = (int)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], float r_co[2], const eV3DProjTest flag) +{ + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_OK) { + if (finite(tvec[0]) && + finite(tvec[1])) + { + copy_v2_v2(r_co, tvec); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +/* --- short --- */ +eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + +/* --- int --- */ +eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + +/* --- float --- */ +eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + + + +/* More Generic Window/Ray/Vector projection functions + * *************************************************** */ + +/* odd function, need to document better */ +int initgrabz(RegionView3D *rv3d, float x, float y, float z) +{ + int flip = FALSE; + if (rv3d == NULL) return flip; + rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; + if (rv3d->zfac < 0.0f) + flip = TRUE; + /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that + * (accounting for near zero values) + */ + if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; + + /* Negative zfac means x, y, z was behind the camera (in perspective). + * This gives flipped directions, so revert back to ok default case. + */ + /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok + * Aligorith, 2009Aug31 */ + //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; + if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; + + return flip; +} + +/** + * Calculate a 3d viewpoint and direction vector from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. + * ray_start is clipped by the view near limit so points in front of it are always in view. + * In orthographic view the resulting ray_normal will match the view vector. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near clipping value). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param ray_start The world-space starting point of the segment. + * \param ray_normal The normalized world-space direction of towards mval. + */ +void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) +{ + float ray_end[3]; + + ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end); + sub_v3_v3v3(ray_normal, ray_end, ray_start); + normalize_v3(ray_normal); +} + +/** + * Calculate a normalized 3d direction vector from the viewpoint towards a global location. + * In orthographic view the resulting vector will match the view vector. + * \param rv3d The region (used for the window width and height). + * \param coord The world-space location. + * \param vec The resulting normalized vector. + */ +void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) +{ + if (rv3d->is_persp) { + float p1[4], p2[4]; + + copy_v3_v3(p1, coord); + p1[3] = 1.0f; + copy_v3_v3(p2, p1); + p2[3] = 1.0f; + mul_m4_v4(rv3d->viewmat, p2); + + mul_v3_fl(p2, 2.0f); + + mul_m4_v4(rv3d->viewinv, p2); + + sub_v3_v3v3(vec, p1, p2); + } + else { + copy_v3_v3(vec, rv3d->viewinv[2]); + } + normalize_v3(vec); +} + +/** + * Calculate a 3d location from 2d window coordinates. + * \param ar The region (used for the window width and height). + * \param depth_pt The reference location used to calculate the Z depth. + * \param mval The area relative location (such as event->mval converted to floats). + * \param out The resulting world-space location. + */ +void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + float line_sta[3]; + float line_end[3]; + + if (rv3d->is_persp) { + float mousevec[3]; + copy_v3_v3(line_sta, rv3d->viewinv[3]); + ED_view3d_win_to_vector(ar, mval, mousevec); + add_v3_v3v3(line_end, line_sta, mousevec); + + if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) { + /* highly unlikely to ever happen, mouse vec paralelle with view plane */ + zero_v3(out); + } + } + else { + const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; + const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f; + line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; + line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; + line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; + + add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); + closest_to_line_v3(out, depth_pt, line_sta, line_end); + } +} + +/** + * Calculate a 3d difference vector from 2d window offset. + * note that initgrabz() must be called first to determine + * the depth used to calculate the delta. + * \param ar The region (used for the window width and height). + * \param mval The area relative 2d difference (such as event->mval[0] - other_x). + * \param out The resulting world-space delta. + */ +void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + float dx, dy; + + dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; + dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; + + out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); + out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); + out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy); +} + +/** + * Calculate a 3d direction vector from 2d window coordinates. + * This direction vector starts and the view in the direction of the 2d window coordinates. + * In orthographic view all window coordinates yield the same vector. + * + * \note doesn't rely on initgrabz + * for perspective view, get the vector direction to + * the mouse cursor as a normalized vector. + * + * \param ar The region (used for the window width and height). + * \param mval The area relative 2d location (such as event->mval converted to floats). + * \param out The resulting normalized world-space direction vector. + */ +void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->is_persp) { + out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f; + out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f; + out[2] = -0.5f; + mul_project_m4_v3(rv3d->persinv, out); + sub_v3_v3(out, rv3d->viewinv[3]); + } + else { + copy_v3_v3(out, rv3d->viewinv[2]); + } + normalize_v3(out); +} + +/** + * Calculate a 3d segment from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_end is a far point. + * ray_start and ray_end are clipped by the view near and far limits + * so points along this line are always in view. + * In orthographic view all resulting segments will be parallel. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near and far clipping range). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param ray_start The world-space starting point of the segment. + * \param ray_end The world-space end point of the segment. + */ +void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->is_persp) { + float vec[3]; + ED_view3d_win_to_vector(ar, mval, vec); + + copy_v3_v3(ray_start, rv3d->viewinv[3]); + madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near); + madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far); + } + else { + float vec[4]; + vec[0] = 2.0f * mval[0] / ar->winx - 1; + vec[1] = 2.0f * mval[1] / ar->winy - 1; + vec[2] = 0.0f; + vec[3] = 1.0f; + + mul_m4_v4(rv3d->persinv, vec); + + madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f); + madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f); + } + + /* clipping */ + if (rv3d->rflag & RV3D_CLIPPING) { + int a; + for (a = 0; a < 4; a++) { + clip_line_plane(ray_start, ray_end, rv3d->clip[a]); + } + } +} + + +/* Utility functions for projection + * ******************************** */ + +void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) +{ + float vmat[4][4]; + + mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); + mult_m4_m4m4(pmat, rv3d->winmat, vmat); +} + +/** + * Uses window coordinates (x,y) and depth component z to find a point in + * modelspace */ +void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z) +{ + double ux, uy, uz; + + gluUnProject(x, y, z, mats->modelview, mats->projection, + (GLint *)mats->viewport, &ux, &uy, &uz); + + out[0] = ux; + out[1] = uy; + out[2] = uz; +} diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 53f2c2e9f5e..c30adf844a8 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -120,7 +120,7 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m initgrabz(vc->rv3d, fp[0], fp[1], fp[2]); - if (ret == V3D_PROJ_RET_SUCCESS) { + if (ret == V3D_PROJ_RET_OK) { const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])}; ED_view3d_win_to_delta(vc->ar, mval_f, dvec); @@ -258,6 +258,8 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) typedef struct LassoSelectUserData { ViewContext *vc; const rcti *rect; + const rctf *rect_fl; + rctf _rect_fl; const int (*mcords)[2]; int moves; int select; @@ -273,7 +275,11 @@ static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, const int moves, const int select) { r_data->vc = vc; + r_data->rect = rect; + r_data->rect_fl = &r_data->_rect_fl; + BLI_rctf_rcti_copy(&r_data->_rect_fl, rect); + r_data->mcords = mcords; r_data->moves = moves; r_data->select = select; @@ -314,29 +320,29 @@ static int view3d_selectable_data(bContext *C) /* helper also for borderselect */ -static int edge_fully_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) +static int edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { - return BLI_rcti_isect_pt(rect, x1, y1) && BLI_rcti_isect_pt(rect, x2, y2); + return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2); } -static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) +static int edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { int d1, d2, d3, d4; /* check points in rect */ - if (edge_fully_inside_rect(rect, x1, y1, x2, y2)) return 1; + if (edge_fully_inside_rect(rect, v1, v2)) return 1; /* check points completely out rect */ - if (x1 < rect->xmin && x2 < rect->xmin) return 0; - if (x1 > rect->xmax && x2 > rect->xmax) return 0; - if (y1 < rect->ymin && y2 < rect->ymin) return 0; - if (y1 > rect->ymax && y2 > rect->ymax) return 0; + if (v1[0] < rect->xmin && v2[0] < rect->xmin) return 0; + if (v1[0] > rect->xmax && v2[0] > rect->xmax) return 0; + if (v1[1] < rect->ymin && v2[1] < rect->ymin) return 0; + if (v1[1] > rect->ymax && v2[1] > rect->ymax) return 0; /* simple check lines intersecting. */ - d1 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymin); - d2 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymax); - d3 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymax); - d4 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymin); + d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin); + d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax); + d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax); + d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin); if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) return 0; if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) return 0; @@ -344,7 +350,7 @@ static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) return 1; } -static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]) { LassoSelectUserData *data = userData; bArmature *arm = data->vc->obact->data; @@ -353,6 +359,11 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann int is_point_done = FALSE; int points_proj_tot = 0; + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + /* project head location to screenspace */ if (x0 != IS_CLIPPED) { points_proj_tot++; @@ -387,6 +398,7 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann } static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, short select) { + ViewContext vc_tmp; LassoSelectUserData data; rcti rect; @@ -394,13 +406,16 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[] return; } + vc_tmp = *vc; + vc_tmp.obact = ob; + + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - - pose_foreachScreenBone(vc, do_lasso_select_pose__doSelectBone, &data); + pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = ob->data; @@ -445,23 +460,28 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons } } -static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { LassoSelectUserData *data = userData; if (EDBM_backbuf_check(bm_solidoffs + index)) { + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + if (data->pass == 0) { - if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1) && + if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) && BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, IS_CLIPPED) && BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, IS_CLIPPED)) { @@ -476,12 +496,12 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int } } } -static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { BM_face_select_set(data->vc->em->bm, efa, data->select); } @@ -494,11 +514,11 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m rcti rect; int bbsel; - BLI_lasso_boundbox(&rect, mcords, moves); - /* set editmesh */ vc->em = BMEdit_FromObject(vc->obedit); + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) @@ -515,17 +535,17 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -534,7 +554,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data); + mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -542,13 +562,13 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m EDBM_selectmode_flush(vc->em); } -static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { LassoSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { + if (BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; @@ -578,38 +598,45 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; + rcti rect; + + BLI_lasso_boundbox(&rect, mcords, moves); - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); + nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } -static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y) +static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2]) { LassoSelectUserData *data = userData; - if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; + rcti rect; - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + BLI_lasso_boundbox(&rect, mcords, moves); + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); + lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } -static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) +static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) { LassoSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; @@ -618,6 +645,11 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo int is_point_done = FALSE; int points_proj_tot = 0; + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + /* project head location to screenspace */ if (x0 != IS_CLIPPED) { points_proj_tot++; @@ -660,16 +692,16 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho LassoSelectUserData data; rcti rect; + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - if (extend == 0 && select) ED_armature_deselect_all_visible(vc->obedit); - armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data); + armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = vc->obedit->data; @@ -679,12 +711,12 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho } } -static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2]) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, INT_MAX)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], INT_MAX)) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; data->is_change = TRUE; @@ -700,13 +732,13 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m if (extend == 0 && select) BKE_mball_deselect_all(mb); + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - - mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data); + mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) @@ -856,9 +888,10 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, do_lasso_select_paintface(vc, mcords, moves, extend, select); else if (paint_vertsel_test(ob)) do_lasso_select_paintvert(vc, mcords, moves, extend, select); - else if (ob && ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) - ; - else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) + else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { + /* pass */ + } + else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) PE_lasso_select(C, mcords, moves, extend, select); else { do_lasso_select_objects(vc, mcords, moves, extend, select); @@ -911,7 +944,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); view3d_lasso_select(C, &vc, mcords, mcords_tot, extend, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } @@ -1387,9 +1420,12 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL; - int temp, a, dist = 100; + int a; + float dist = 100.0f; int retval = 0; short hits; + const float mval_fl[2] = {(float)mval[0], (float)mval[1]}; + /* setup view context for argument to callbacks */ view3d_set_viewcontext(C, &vc); @@ -1410,13 +1446,16 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese base = startbase; while (base) { if (BASE_SELECTABLE(v3d, base)) { - ED_view3d_project_base(ar, base); - temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]); - if (base == BASACT) temp += 10; - if (temp < dist) { - - dist = temp; - basact = base; + float screen_co[2]; + if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + float dist_temp = len_manhattan_v2v2(mval_fl, screen_co); + if (base == BASACT) dist_temp += 10.0f; + if (dist_temp < dist) { + dist = dist_temp; + basact = base; + } } } base = base->next; @@ -1506,7 +1545,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese } } } - else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { /* then bone is found */ + else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { + /* then bone is found */ /* we make the armature selected: * not-selected active object in posemode won't work well for tools */ @@ -1582,6 +1622,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese typedef struct BoxSelectUserData { ViewContext *vc; const rcti *rect; + const rctf *rect_fl; + rctf _rect_fl; int select; /* runtime */ @@ -1594,7 +1636,11 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, ViewContext *vc, const rcti *rect, const int select) { r_data->vc = vc; + r_data->rect = rect; + r_data->rect_fl = &r_data->_rect_fl; + BLI_rctf_rcti_copy(&r_data->_rect_fl, rect); + r_data->select = select; /* runtime */ @@ -1603,23 +1649,20 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, r_data->is_change = FALSE; } -int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, int y2) +int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]) { int radius_squared = radius * radius; /* check points in circle itself */ - if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radius_squared) { + if (len_squared_v2v2(cent, screen_co_a) <= radius_squared) { return TRUE; } - else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radius_squared) { + if (len_squared_v2v2(cent, screen_co_b) <= radius_squared) { return TRUE; } else { - const float cent[2] = {centx, centy}; - const float v1[2] = {x1, y1}; - const float v2[2] = {x2, y2}; /* pointdistline */ - if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radius_squared) { + if (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < (float)radius_squared) { return TRUE; } } @@ -1627,13 +1670,13 @@ int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, return FALSE; } -static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { BoxSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; @@ -1669,16 +1712,16 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte CU_deselect_all(vc->obedit); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data); + nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return OPERATOR_FINISHED; } -static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y) +static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, const float screen_co[2]) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -1692,42 +1735,42 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex ED_setflagsLatt(vc->obedit, 0); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data); + lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return OPERATOR_FINISHED; } -static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { BoxSelectUserData *data = userData; if (EDBM_backbuf_check(bm_solidoffs + index)) { if (data->pass == 0) { - if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) { + if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); data->is_done = TRUE; } } else { - if (edge_inside_rect(data->rect, x0, y0, x1, y1)) { + if (edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); } } } } -static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -1753,18 +1796,18 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -1773,7 +1816,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data); + mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -1972,12 +2015,10 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i } if (bone_selected) { - Object *ob = base->object; - - if (ob && (ob->type == OB_ARMATURE)) { - bArmature *arm = ob->data; + if (base->object && (base->object->type == OB_ARMATURE)) { + bArmature *arm = base->object->data; - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object); if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { /* mask modifier ('armature' mode), etc. */ @@ -2215,7 +2256,8 @@ void VIEW3D_OT_select(wmOperatorType *ot) typedef struct CircleSelectUserData { ViewContext *vc; short select; - int mval[2]; + int mval[2]; + float mval_fl[2]; float radius; float radius_squared; @@ -2229,6 +2271,9 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->vc = vc; r_data->select = select; copy_v2_v2_int(r_data->mval, mval); + r_data->mval_fl[0] = mval[0]; + r_data->mval_fl[1] = mval[1]; + r_data->radius = rad; r_data->radius_squared = rad * rad; @@ -2236,31 +2281,27 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->is_change = FALSE; } -static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void mesh_circle_doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) +static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - if (edge_inside_circle(data->mval[0], data->mval[1], (int)data->radius, x0, y0, x1, y1)) { + if (edge_inside_circle(data->mval_fl, (int)data->radius, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); } } -static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -2283,7 +2324,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_verts(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2292,7 +2333,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_edges(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -2301,7 +2342,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_faces(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data); + mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2344,16 +2385,13 @@ static void paint_vertsel_circle_select(ViewContext *vc, int select, const int m } -static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { CircleSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); @@ -2387,17 +2425,15 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); + nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } -static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y) +static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -2408,18 +2444,16 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data); + lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } /* NOTE: pose-bone case is copied from editbone case... */ -static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) +static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else @@ -2428,7 +2462,7 @@ static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int } return 0; } -static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]) { CircleSelectUserData *data = userData; bArmature *arm = data->vc->obact->data; @@ -2438,17 +2472,17 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan int points_proj_tot = 0; /* project head location to screenspace */ - if (x0 != IS_CLIPPED) { + if (screen_co_a[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, x0, y0)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { is_point_done = TRUE; } } /* project tail location to screenspace */ - if (x1 != IS_CLIPPED) { + if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, x1, y1)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { is_point_done = TRUE; } } @@ -2461,7 +2495,7 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan * It works nicer to only do this if the head or tail are not in the circle, * otherwise there is no way to circle select joints alone */ if ((is_point_done == FALSE) && (points_proj_tot == 2) && - edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else pchan->bone->flag &= ~BONE_SELECTED; @@ -2479,7 +2513,7 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ - pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data); + pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = vc->obact->data; @@ -2493,13 +2527,11 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f } } -static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) +static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, const float screen_co[2], short head) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - - if (len_squared_v2(delta) <= data->radius_squared) { + + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (head) { if (data->select) ebone->flag |= BONE_ROOTSEL; @@ -2516,7 +2548,7 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int } return 0; } -static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) +static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) { CircleSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; @@ -2526,17 +2558,17 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB int points_proj_tot = 0; /* project head location to screenspace */ - if (x0 != IS_CLIPPED) { + if (screen_co_a[0] != IS_CLIPPED) { points_proj_tot++; - if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) { + if (armature_circle_doSelectJoint(data, ebone, screen_co_a, TRUE)) { is_point_done = TRUE; } } /* project tail location to screenspace */ - if (x1 != IS_CLIPPED) { + if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (armature_circle_doSelectJoint(data, ebone, x1, y1, FALSE)) { + if (armature_circle_doSelectJoint(data, ebone, screen_co_b, FALSE)) { is_point_done = TRUE; } } @@ -2549,7 +2581,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB * It works nicer to only do this if the head or tail are not in the circle, * otherwise there is no way to circle select joints alone */ if ((is_point_done == FALSE) && (points_proj_tot == 2) && - edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); @@ -2568,7 +2600,7 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data); + armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { ED_armature_sync_selection(arm->edbo); @@ -2577,13 +2609,11 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 } } -static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; data->is_change = TRUE; @@ -2597,7 +2627,7 @@ static void mball_circle_select(ViewContext *vc, int select, const int mval[2], ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data); + mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } /** Callbacks for circle selection in Editmode */ @@ -2632,14 +2662,15 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2], const float radius_squared = rad * rad; const float mval_fl[2] = {mval[0], mval[1]}; int is_change = FALSE; + int select_flag = select ? SELECT : 0; Base *base; select = select ? BA_SELECT : BA_DESELECT; for (base = FIRSTBASE; base; base = base->next) { - if (((base->flag & SELECT) == 0) && BASE_SELECTABLE(vc->v3d, base)) { + if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) { float screen_co[2]; if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { ED_base_object_select(base, select); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index f138a95b0ef..de8cbd856e8 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -125,7 +125,7 @@ struct SmoothView3DStore { /* will start timer if appropriate */ /* the arguments are the desired situation */ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, - float *ofs, float *quat, float *dist, float *lens) + float *ofs, float *quat, float *dist, float *lens) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -140,7 +140,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera copy_qt_qt(sms.new_quat, rv3d->viewquat); sms.new_dist = rv3d->dist; sms.new_lens = v3d->lens; - sms.to_camera = 0; + sms.to_camera = FALSE; /* note on camera locking, this is a little confusing but works ok. * we may be changing the view 'as if' there is no active camera, but in fact @@ -162,22 +162,22 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera if (camera) { ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); - sms.to_camera = 1; /* restore view3d values in end */ + sms.to_camera = TRUE; /* restore view3d values in end */ } if (C && U.smooth_viewtx) { - int changed = 0; /* zero means no difference */ + int changed = FALSE; /* zero means no difference */ if (oldcamera != camera) - changed = 1; + changed = TRUE; else if (sms.new_dist != rv3d->dist) - changed = 1; + changed = TRUE; else if (sms.new_lens != v3d->lens) - changed = 1; + changed = TRUE; else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) - changed = 1; + changed = TRUE; else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) - changed = 1; + changed = TRUE; /* The new view is different from the old one * so animate the view */ @@ -241,13 +241,15 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera /* if we get here nothing happens */ if (ok == FALSE) { - if (sms.to_camera == 0) { + if (sms.to_camera == FALSE) { copy_v3_v3(rv3d->ofs, sms.new_ofs); copy_qt_qt(rv3d->viewquat, sms.new_quat); rv3d->dist = sms.new_dist; v3d->lens = sms.new_lens; } + ED_view3d_camera_lock_sync(v3d, rv3d); + if (rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_copy(sa, ar); @@ -569,328 +571,27 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co } } -/** - * Calculate a 3d segment from 2d window coordinates. - * This ray_start is located at the viewpoint, ray_end is a far point. - * ray_start and ray_end are clipped by the view near and far limits - * so points along this line are always in view. - * In orthographic view all resulting segments will be parallel. - * \param ar The region (used for the window width and height). - * \param v3d The 3d viewport (used for near and far clipping range). - * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param ray_start The world-space starting point of the segment. - * \param ray_end The world-space end point of the segment. - */ -void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - float vec[3]; - ED_view3d_win_to_vector(ar, mval, vec); - - copy_v3_v3(ray_start, rv3d->viewinv[3]); - madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near); - madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far); - } - else { - float vec[4]; - vec[0] = 2.0f * mval[0] / ar->winx - 1; - vec[1] = 2.0f * mval[1] / ar->winy - 1; - vec[2] = 0.0f; - vec[3] = 1.0f; - - mul_m4_v4(rv3d->persinv, vec); - - madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f); - madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f); - } - - /* clipping */ - if (rv3d->rflag & RV3D_CLIPPING) { - int a; - for (a = 0; a < 4; a++) { - clip_line_plane(ray_start, ray_end, rv3d->clip[a]); - } - } -} - -/** - * Calculate a 3d viewpoint and direction vector from 2d window coordinates. - * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. - * ray_start is clipped by the view near limit so points in front of it are always in view. - * In orthographic view the resulting ray_normal will match the view vector. - * \param ar The region (used for the window width and height). - * \param v3d The 3d viewport (used for near clipping value). - * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param ray_start The world-space starting point of the segment. - * \param ray_normal The normalized world-space direction of towards mval. - */ -void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) -{ - float ray_end[3]; - - ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end); - sub_v3_v3v3(ray_normal, ray_end, ray_start); - normalize_v3(ray_normal); -} - -/** - * Calculate a normalized 3d direction vector from the viewpoint towards a global location. - * In orthographic view the resulting vector will match the view vector. - * \param rv3d The region (used for the window width and height). - * \param coord The world-space location. - * \param vec The resulting normalized vector. - */ -void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) -{ - if (rv3d->is_persp) { - float p1[4], p2[4]; - - copy_v3_v3(p1, coord); - p1[3] = 1.0f; - copy_v3_v3(p2, p1); - p2[3] = 1.0f; - mul_m4_v4(rv3d->viewmat, p2); - - mul_v3_fl(p2, 2.0f); - - mul_m4_v4(rv3d->viewinv, p2); - - sub_v3_v3v3(vec, p1, p2); - } - else { - copy_v3_v3(vec, rv3d->viewinv[2]); - } - normalize_v3(vec); -} - -int initgrabz(RegionView3D *rv3d, float x, float y, float z) -{ - int flip = FALSE; - if (rv3d == NULL) return flip; - rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; - if (rv3d->zfac < 0.0f) - flip = TRUE; - /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that - * (accounting for near zero values) - */ - if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; - - /* Negative zfac means x, y, z was behind the camera (in perspective). - * This gives flipped directions, so revert back to ok default case. - */ - /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok - * Aligorith, 2009Aug31 */ - //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; - if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; - - return flip; -} - -/** - * Calculate a 3d location from 2d window coordinates. - * \param ar The region (used for the window width and height). - * \param depth_pt The reference location used to calculate the Z depth. - * \param mval The area relative location (such as event->mval converted to floats). - * \param out The resulting world-space location. - */ -void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - float line_sta[3]; - float line_end[3]; - - if (rv3d->is_persp) { - float mousevec[3]; - copy_v3_v3(line_sta, rv3d->viewinv[3]); - ED_view3d_win_to_vector(ar, mval, mousevec); - add_v3_v3v3(line_end, line_sta, mousevec); - - if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) { - /* highly unlikely to ever happen, mouse vec paralelle with view plane */ - zero_v3(out); - } - } - else { - const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; - const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f; - line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; - line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; - line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; - - add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); - closest_to_line_v3(out, depth_pt, line_sta, line_end); - } -} - -/** - * Calculate a 3d difference vector from 2d window offset. - * note that initgrabz() must be called first to determine - * the depth used to calculate the delta. - * \param ar The region (used for the window width and height). - * \param mval The area relative 2d difference (such as event->mval[0] - other_x). - * \param out The resulting world-space delta. - */ -void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - float dx, dy; - - dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; - dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; - - out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); - out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); - out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy); -} - -/** - * Calculate a 3d direction vector from 2d window coordinates. - * This direction vector starts and the view in the direction of the 2d window coordinates. - * In orthographic view all window coordinates yield the same vector. - * - * \note doesn't rely on initgrabz - * for perspective view, get the vector direction to - * the mouse cursor as a normalized vector. - * - * \param ar The region (used for the window width and height). - * \param mval The area relative 2d location (such as event->mval converted to floats). - * \param out The resulting normalized world-space direction vector. - */ -void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f; - out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f; - out[2] = -0.5f; - mul_project_m4_v3(rv3d->persinv, out); - sub_v3_v3(out, rv3d->viewinv[3]); - } - else { - copy_v3_v3(out, rv3d->viewinv[2]); - } - normalize_v3(out); -} - -float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) -{ - ViewDepths *vd = vc->rv3d->depths; - - x -= vc->ar->winrct.xmin; - y -= vc->ar->winrct.ymin; - - if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) - return vd->depths[y * vd->w + x]; - else - return 1; -} - -void ED_view3d_depth_tag_update(RegionView3D *rv3d) -{ - if (rv3d->depths) - rv3d->depths->damaged = 1; -} - -void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) -{ - float vmat[4][4]; - - mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); - mult_m4_m4m4(pmat, rv3d->winmat, vmat); -} - -/* Uses window coordinates (x,y) and depth component z to find a point in - * modelspace */ -void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z) -{ - double ux, uy, uz; - - gluUnProject(x, y, z, mats->modelview, mats->projection, - (GLint *)mats->viewport, &ux, &uy, &uz); - - out[0] = ux; - out[1] = uy; - out[2] = uz; -} - -/* use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4]) -{ - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ - - mul_m4_v4(mat, vec4); - - if (vec4[3] > FLT_EPSILON) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - } - else { - zero_v2(r_co); - } -} - -/* use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) -{ - float vec4[4]; - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ - - mul_m4_v4(mat, vec4); - - if (vec4[3] > FLT_EPSILON) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - r_co[2] = vec4[2] / vec4[3]; - } - else { - zero_v3(r_co); - } -} - -eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) -{ - eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN); - - if (ret != V3D_PROJ_RET_SUCCESS) { - base->sx = IS_CLIPPED; - base->sy = 0; - } - - return ret; -} int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) { /* return 1: draw */ - + float mat[4][4]; float vec[4], min, max; int a, flag = -1, fl; - + if (bb == NULL) return 1; if (bb->flag & OB_BB_DISABLED) return 1; - + mult_m4_m4m4(mat, rv3d->persmat, obmat); - + for (a = 0; a < 8; a++) { copy_v3_v3(vec, bb->vec[a]); vec[3] = 1.0; mul_m4_v4(mat, vec); max = vec[3]; min = -vec[3]; - + fl = 0; if (vec[0] < min) fl += 1; if (vec[0] > max) fl += 2; @@ -898,153 +599,31 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) if (vec[1] > max) fl += 8; if (vec[2] < min) fl += 16; if (vec[2] > max) fl += 32; - + flag &= fl; if (flag == 0) return 1; } - - return 0; -} - -/* perspmat is typically... - * - 'rv3d->perspmat', is_local == FALSE - * - 'rv3d->perspmatob', is_local == TRUE - */ -static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, - float perspmat[4][4], const int is_local, /* normally hidden */ - const float co[3], float r_co[2], eV3DProjTest flag) -{ - float fx, fy, vec4[4]; - if (flag & V3D_PROJ_TEST_CLIP_BB) { - RegionView3D *rv3d = ar->regiondata; - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, co, is_local)) { - return V3D_PROJ_RET_CLIP_BB; - } - } - } - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - mul_m4_v4(perspmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); - if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { - fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); - if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { - r_co[0] = (short)floor(fx); - r_co[1] = (short)floor(fy); - } - else { - return V3D_PROJ_RET_CLIP_WIN; - } - } - else { - return V3D_PROJ_RET_CLIP_WIN; - } - } - else { - return V3D_PROJ_RET_CLIP_NEAR; - } - - return V3D_PROJ_RET_SUCCESS; -} - -eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], eV3DProjTest flag) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { - if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && - (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) - { - r_co[0] = (short)floor(tvec[0]); - r_co[1] = (short)floor(tvec[1]); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], eV3DProjTest flag) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { - if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && - (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) - { - r_co[0] = (int)floor(tvec[0]); - r_co[1] = (int)floor(tvec[1]); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], eV3DProjTest flag) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { - if (finite(tvec[0]) && - finite(tvec[1])) - { - copy_v2_v2(r_co, tvec); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; + return 0; } -/* --- short --- */ -eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); -} -/* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) +float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) { - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); -} + ViewDepths *vd = vc->rv3d->depths; + + x -= vc->ar->winrct.xmin; + y -= vc->ar->winrct.ymin; -/* --- int --- */ -eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); -} -/* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); + if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) + return vd->depths[y * vd->w + x]; + else + return 1; } -/* --- float --- */ -eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); -} -/* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) +void ED_view3d_depth_tag_update(RegionView3D *rv3d) { - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); + if (rv3d->depths) + rv3d->depths->damaged = 1; } /* copies logic of get_view3d_viewplane(), keep in sync */ @@ -1458,7 +1037,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL locallay = free_localbit(bmain); if (locallay == 0) { - BKE_reportf(reports, RPT_ERROR, "No more than 8 localviews"); + BKE_reportf(reports, RPT_ERROR, "No more than 8 local views"); ok = FALSE; } else { @@ -1647,7 +1226,6 @@ static int localview_exec(bContext *C, wmOperator *op) void VIEW3D_OT_localview(wmOperatorType *ot) { - /* identifiers */ ot->name = "Local View"; ot->description = "Toggle display of selected object(s) separately and centered in view"; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d2354a4a7ad..4a61978cc80 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -90,15 +90,12 @@ #include "BLI_linklist.h" #include "BLI_smallhash.h" #include "BLI_array.h" -#include "PIL_time.h" #include "UI_interface_icons.h" #include "UI_resources.h" #include "transform.h" -#include <stdio.h> // XXX: duplicated??? - static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); @@ -230,7 +227,7 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { if (t->spacetype == SPACE_VIEW3D) { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */ adr[1] = (int)2140000000.0f; } @@ -355,7 +352,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) case SPACE_VIEW3D: { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { /* XXX, 2.64 and prior did this, weak! */ adr[0] = t->ar->winx / 2.0f; adr[1] = t->ar->winy / 2.0f; @@ -1273,7 +1270,6 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= t->handleEvent(t, event); if (handled || t->redraw) { - t->last_update = PIL_check_seconds_timer(); return 0; } else { @@ -1562,49 +1558,31 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi } /* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ -static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) +static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) { - int show_warning; - - /* red border around the viewport */ - UI_ThemeColor(TH_REDALERT); + const char printable[] = "Auto Keying On"; + float printable_size[2]; + int xco, yco; + + BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]); - glBegin(GL_LINE_LOOP); - glVertex2f(1, 1); - glVertex2f(1, ar->winy-1); - glVertex2f(ar->winx-1, ar->winy-1); - glVertex2f(ar->winx-1, 1); - glEnd(); + xco = ar->winx - (int)printable_size[0] - 10; + yco = ar->winy - (int)printable_size[1] - 10; - /* Entire warning should "blink" to catch periphery attention without being overly distracting - * much like how a traditional recording sign in the corner of a camcorder works - * - * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice). - * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle. - * - Always start with warning shown so that animators are more likely to notice when starting to transform + /* warning text (to clarify meaning of overlays) + * - original color was red to match the icon, but that clashes badly with a less nasty border */ - show_warning = (int)(t->last_update * 2.0) & 1; + UI_ThemeColorShade(TH_TEXT_HI, -50); + BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); - if ((show_warning) || (t->state == TRANS_STARTING)) { - const char printable[] = "Auto Keying On"; - int xco, yco; - - xco = ar->winx - BLF_width_default(printable) - 10; - yco = ar->winy - BLF_height_default(printable) - 10; - - /* red warning text */ - UI_ThemeColor(TH_REDALERT); - BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); - - /* autokey recording icon... */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - xco -= (ICON_DEFAULT_WIDTH + 2); - UI_icon_draw(xco, yco, ICON_REC); - - glDisable(GL_BLEND); - } + /* autokey recording icon... */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + xco -= (ICON_DEFAULT_WIDTH + 2); + UI_icon_draw(xco, yco, ICON_REC); + + glDisable(GL_BLEND); } static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) @@ -1613,10 +1591,18 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo Scene *scene = t->scene; Object *ob = OBACT; - /* draw autokeyframing hint in the corner */ - if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { - drawAutoKeyWarning(t, ar); - } + /* draw autokeyframing hint in the corner + * - only draw if enabled (advanced users may be distracted/annoyed), + * for objects that will be autokeyframed (no point ohterwise), + * AND only for the active region (as showing all is too overwhelming) + */ + if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) { + if (ar == t->ar) { + if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { + drawAutoKeyWarning(t, ar); + } + } + } } void saveTransform(bContext *C, TransInfo *t, wmOperator *op) @@ -4037,12 +4023,15 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); - sprintf(str, "Tilt: %s %s", &c[0], t->proptext); + sprintf(str, "Tilt: %s° %s", &c[0], t->proptext); final = DEG2RADF(final); + + /* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */ + t->values[0] = final; } else { - sprintf(str, "Tilt: %.2f %s", RAD2DEGF(final), t->proptext); + sprintf(str, "Tilt: %.2f° %s", RAD2DEGF(final), t->proptext); } for (i = 0; i < t->total; i++, td++) { @@ -4853,7 +4842,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo sv->edge_len = len_v3v3(dw_p, up_p); mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co); - if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { dist = len_squared_v2v2(mval, v_proj); if (dist < min_dist) { min_dist = dist; @@ -4871,10 +4860,9 @@ static int createSlideVerts(TransInfo *t) { BMEditMesh *em = BMEdit_FromObject(t->obedit); BMesh *bm = em->bm; - BMIter iter, iter2; + BMIter iter; BMEdge *e, *e1; BMVert *v, *v2, *first; - BMLoop *l, *l1, *l2; TransDataSlideVert *sv_array; BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); SmallHash table; @@ -4914,6 +4902,7 @@ static int createSlideVerts(TransInfo *t) /*ensure valid selection*/ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + BMIter iter2; numsel = 0; BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { @@ -4966,6 +4955,8 @@ static int createSlideVerts(TransInfo *t) j = 0; while (1) { + BMLoop *l, *l1, *l2; + v = NULL; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) @@ -5099,7 +5090,7 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { BMIter iter2; BMEdge *e2; - float vec1[3], mval[2] = {t->mval[0], t->mval[1]}, d; + float vec1[3], d; /* search cross edges for visible edge to the mouse cursor, * then use the shared vertex to calculate screen vector*/ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 40f53423d37..1f9775821d1 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -323,8 +323,6 @@ typedef struct TransInfo { float axis[3]; float axis_orig[3]; /* TransCon can change 'axis', store the original value here */ - double last_update; /* Time of last update (in seconds) */ - void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ struct ScrArea *sa; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 39a5da94798..2e9d1ee670f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -3986,13 +3986,13 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); if (t->frame_side == 'R') { - if (right <= cfra) *count = *flag = 0; /* ignore */ - else if (left > cfra) ; /* keep the selection */ + if (right <= cfra) { *count = *flag = 0; } /* ignore */ + else if (left > cfra) { } /* keep the selection */ else *flag |= SEQ_RIGHTSEL; } else { - if (left >= cfra) *count = *flag = 0; /* ignore */ - else if (right < cfra) ; /* keep the selection */ + if (left >= cfra) { *count = *flag = 0; } /* ignore */ + else if (right < cfra) { } /* keep the selection */ else *flag |= SEQ_LEFTSEL; } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 81a4c082dcc..fc0c174a525 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -605,8 +605,10 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ - ot->name = "Rotate"; + ot->name = "Rotate"; ot->description = "Rotate selected items"; ot->idname = OP_ROTATION; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; @@ -618,19 +620,22 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + RNA_def_property_subtype(prop, PROP_ANGLE); Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP); } static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ - ot->name = "Tilt"; + ot->name = "Tilt"; /* optionals - * "Tilt selected vertices" - * "Specify an extra axis rotation for selected vertices of 3d curve" */ - ot->description = "Tilt selected control vertices of 3d curve"; + * "Specify an extra axis rotation for selected vertices of 3D curve" */ + ot->description = "Tilt selected control vertices of 3D curve"; ot->idname = OP_TILT; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; @@ -641,9 +646,10 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_editcurve_3d; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + prop = RNA_def_float(ot->srna, "value", 0.0, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + RNA_def_property_subtype(prop, PROP_ANGLE); - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_warp(struct wmOperatorType *ot) diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 0e25739c34a..845d5b73f0c 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -631,7 +631,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], /* if there's an edge available, use that for the tangent */ if (em->bm->totedgesel >= 1) { BMEdge *eed = NULL; - BMIter iter; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { @@ -746,14 +745,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], MetaBall *mb = obedit->data; if (mb->lastelem) { - float mat[4][4]; + float qmat[3][3]; /* Rotation of MetaElem is stored in quat */ - quat_to_mat4(mat, mb->lastelem->quat); + quat_to_mat3(qmat, mb->lastelem->quat); - copy_v3_v3(normal, mat[2]); + copy_v3_v3(normal, qmat[2]); - negate_v3_v3(plane, mat[1]); + negate_v3_v3(plane, qmat[1]); result = ORIENTATION_FACE; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2f2b31de89d..94b8abb8850 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -317,7 +317,7 @@ void applyProject(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { // if (t->flag & (T_EDIT|T_POSE)) { // mul_m4_v3(imat, loc); @@ -603,7 +603,7 @@ int updateSelectedSnapPoint(TransInfo *t) int dx, dy; int dist; - if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { continue; } @@ -1236,7 +1236,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh new_depth = len_v3v3(location, ray_start); - if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); } else { @@ -1297,7 +1297,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], new_depth = len_v3v3(location, ray_start); - if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); } else { diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index d6794912043..7aaae404d15 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -453,8 +453,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) int drawfaces, interpedges; Image *ima = sima->image; - StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); - activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */ activef = BM_active_face_get(bm, FALSE, FALSE); ts = scene->toolsettings; @@ -823,51 +821,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) bglEnd(); } - /* finally draw stitch preview */ - if (stitch_preview) { - int i, index = 0; - glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - glEnableClientState(GL_VERTEX_ARRAY); - - glEnable(GL_BLEND); - - UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); - glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3); - - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys); - for (i = 0; i < stitch_preview->num_polys; i++) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); - glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); - glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); - - index += stitch_preview->uvs_per_polygon[i]; - } - glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); -#if 0 - UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); - glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3); -#endif - glDisable(GL_BLEND); - - /* draw vert preview */ - glPointSize(pointsize * 2.0f); - UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); - - UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); - - glPopClientAttrib(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - glPointSize(1.0); } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index f0ff79ae25e..3a89d6ce892 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -75,30 +75,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -/* smart stitch */ - -/* object that stores display data for previewing before accepting stitching */ -typedef struct StitchPreviewer { - /* here we'll store the preview triangle indices of the mesh */ - float *preview_polys; - /* uvs per polygon. */ - unsigned int *uvs_per_polygon; - /*number of preview polygons */ - unsigned int num_polys; - /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ - float *preview_stitchable; - float *preview_unstitchable; - /* here we'll store the number of elements to be drawn */ - unsigned int num_stitchable; - unsigned int num_unstitchable; - unsigned int preview_uvs; - /* ...and here we'll store the triangles*/ - float *static_tris; - unsigned int num_static_tris; -} StitchPreviewer; - -StitchPreviewer *uv_get_stitch_previewer(void); - /* operators */ void UV_OT_average_islands_scale(struct wmOperatorType *ot); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 6e655faf35f..acc69309a8c 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -170,7 +170,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma) { BMEditMesh *em; - BMFace *efa; BMIter iter; MTexPoly *tf; int update = 0; @@ -198,6 +197,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im ED_object_assign_active_image(bmain, obedit, efa->mat_nr + 1, ima); } else { + BMFace *efa; + /* old shading system, assign image to selected faces */ #ifdef USE_SWITCH_ASPECT float prev_aspect[2], fprev_aspect; @@ -771,13 +772,15 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if (i == id1) + if (i == id1) { uv1 = luv->uv; - else if (i == id) - ; /* uv2 = luv->uv; */ /* UNUSED */ - else if (i == id2) + } + else if (i == id) { + /* uv2 = luv->uv; */ /* UNUSED */ + } + else if (i == id2) { uv3 = luv->uv; - + } i++; } @@ -1310,9 +1313,7 @@ static void weld_align_uv(bContext *C, int tool) Object *obedit; Image *ima; BMEditMesh *em; - BMIter iter, liter; MTexPoly *tf; - MLoopUV *luv; float cent[2], min[2], max[2]; scene = CTX_data_scene(C); @@ -1324,6 +1325,7 @@ static void weld_align_uv(bContext *C, int tool) INIT_MINMAX2(min, max); if (tool == 'a') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1335,7 +1337,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); DO_MINMAX2(luv->uv, min, max); } } @@ -1347,6 +1349,7 @@ static void weld_align_uv(bContext *C, int tool) uvedit_center(scene, ima, obedit, cent, 0); if (tool == 'x' || tool == 'w') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1357,7 +1360,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); luv->uv[0] = cent[0]; } @@ -1366,6 +1369,7 @@ static void weld_align_uv(bContext *C, int tool) } if (tool == 'y' || tool == 'w') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1376,7 +1380,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); luv->uv[1] = cent[1]; } @@ -2131,7 +2135,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i NearestHit hit, *hit_p = NULL; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot select linked when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2238,7 +2242,7 @@ static int select_split_exec(bContext *C, wmOperator *op) short change = FALSE; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't split selection when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2279,6 +2283,7 @@ static int select_split_exec(bContext *C, wmOperator *op) } if (change) { + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL); return OPERATOR_FINISHED; } else { @@ -2316,7 +2321,7 @@ static int unlink_selection_exec(bContext *C, wmOperator *op) MLoopUV *luv; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot unlink selection when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2487,13 +2492,16 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s break; if (efa_index != vlist_iter->f) { + BMLoop *l_other; efa_vlist = EDBM_face_at_index(em, vlist_iter->f); /* tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY); */ /* UNUSED */ + l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex); + if (select) - uvedit_uv_select_enable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex), FALSE); + uvedit_uv_select_enable(em, scene, l_other, FALSE); else - uvedit_uv_select_disable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex)); + uvedit_uv_select_disable(em, scene, l_other); } vlist_iter = vlist_iter->next; } @@ -2827,7 +2835,7 @@ static int uv_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); change = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return change ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 4e0e7944e84..2b225118472 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -46,6 +46,8 @@ #include "BLI_math_vector.h" #include "BLI_string.h" +#include "BIF_gl.h" + #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" @@ -55,6 +57,7 @@ #include "ED_mesh.h" #include "ED_uvedit.h" #include "ED_screen.h" +#include "ED_space_api.h" #include "RNA_access.h" #include "RNA_define.h" @@ -63,11 +66,32 @@ #include "WM_types.h" #include "UI_view2d.h" +#include "UI_resources.h" #include "uvedit_intern.h" /* ********************** smart stitch operator *********************** */ +/* object that stores display data for previewing before accepting stitching */ +typedef struct StitchPreviewer { + /* here we'll store the preview triangle indices of the mesh */ + float *preview_polys; + /* uvs per polygon. */ + unsigned int *uvs_per_polygon; + /*number of preview polygons */ + unsigned int num_polys; + /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ + float *preview_stitchable; + float *preview_unstitchable; + /* here we'll store the number of elements to be drawn */ + unsigned int num_stitchable; + unsigned int num_unstitchable; + unsigned int preview_uvs; + /* ...and here we'll store the triangles*/ + float *static_tris; + unsigned int num_static_tris; +} StitchPreviewer; + struct IslandStitchData; @@ -143,6 +167,8 @@ typedef struct StitchState { int static_island; /* store number of primitives per face so that we can allocate the active island buffer later */ unsigned int *tris_per_island; + + void *draw_handle; } StitchState; typedef struct PreviewPosition { @@ -216,7 +242,7 @@ static void stitch_preview_delete(void) /* "getter method" */ -StitchPreviewer *uv_get_stitch_previewer(void) +static StitchPreviewer *uv_get_stitch_previewer(void) { return _stitch_preview; } @@ -981,6 +1007,55 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no normalize_v2(normal); } +static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) +{ + int i, index = 0; + float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); + StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); + + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + glEnableClientState(GL_VERTEX_ARRAY); + + glEnable(GL_BLEND); + + UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3); + + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys); + for (i = 0; i < stitch_preview->num_polys; i++) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); + glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); + glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); + + index += stitch_preview->uvs_per_polygon[i]; + } + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); +#if 0 + UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3); +#endif + glDisable(GL_BLEND); + + /* draw vert preview */ + glPointSize(pointsize * 2.0f); + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); + + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); + + glPopClientAttrib(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +} + static int stitch_init(bContext *C, wmOperator *op) { /* for fast edge lookup... */ @@ -1016,6 +1091,7 @@ static int stitch_init(bContext *C, wmOperator *op) state->static_island = RNA_int_get(op->ptr, "static_island"); state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); + state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { state->element_map = EDBM_uv_element_map_create(state->em, 0, 1); @@ -1282,6 +1358,8 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) if (sa) ED_area_headerprint(sa, NULL); + ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle); + DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 7c06fbd2a9d..19a1c4339ad 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -223,7 +223,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BMLoop *ls[3]; float *co[4]; float *uv[4]; - int i, lsel; + int lsel; if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) continue; @@ -245,6 +245,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, // tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); // UNUSED if (efa->len == 3 || efa->len == 4) { + int i; /* for quads let parametrize split, it can make better decisions * about which split is best for unwrapping than scanfill */ i = 0; @@ -291,6 +292,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { + int i; ls[0] = sf_tri->v1->tmp.p; ls[1] = sf_tri->v2->tmp.p; ls[2] = sf_tri->v3->tmp.p; @@ -727,12 +729,10 @@ static int pack_islands_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (RNA_struct_property_is_set(op->ptr, "margin")) { + if (RNA_struct_property_is_set(op->ptr, "margin")) scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); - } - else { + else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - } handle = construct_param_handle(scene, em, implicit, 0, 1, 1); param_pack(handle, scene->toolsettings->uvcalc_margin); @@ -759,7 +759,7 @@ void UV_OT_pack_islands(wmOperatorType *ot) ot->poll = ED_operator_uvedit; /* properties */ - RNA_def_float_factor(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); + RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /* ******************** Average Islands Scale operator **************** */ @@ -1184,7 +1184,8 @@ static int unwrap_exec(bContext *C, wmOperator *op) mat4_to_size(obsize, obedit->obmat); if (!compare_v3v3(obsize, unitsize, 1e-4f)) - BKE_report(op->reports, RPT_INFO, "Object scale is not 1.0. Unwrap will operate on a non-scaled version of the mesh."); + BKE_report(op->reports, RPT_INFO, + "Object scale is not 1.0, unwrap will operate on a non-scaled version of the mesh"); /* remember last method for live unwrap */ if (RNA_struct_property_is_set(op->ptr, "method")) @@ -1192,6 +1193,12 @@ static int unwrap_exec(bContext *C, wmOperator *op) else RNA_enum_set(op->ptr, "method", scene->toolsettings->unwrapper); + /* remember packing marging */ + if (RNA_struct_property_is_set(op->ptr, "margin")) + scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); + else + RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); + scene->toolsettings->uv_subsurf_level = subsurf_level; if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; @@ -1239,8 +1246,9 @@ void UV_OT_unwrap(wmOperatorType *ot) "Map UVs taking image aspect ratio into account"); RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data", "Map UVs taking vertex position after subsurf into account"); - RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "SubSurf Target", + RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target", "Number of times to subdivide before calculating UVs", 1, 6); + RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /**************** Project From View operator **************/ diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 198d002ff0d..f4bb5da0495 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -107,7 +107,7 @@ int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver); GPUTexture *GPU_texture_create_1D(int w, float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, char err_out[256]); -GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels); +GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels); GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]); GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]); GPUTexture *GPU_texture_from_blender(struct Image *ima, diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 201162262b2..2986ce85c88 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1562,7 +1562,7 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } - if (buffers->index_buf || !buffers->smooth) + if (gpu_vbo_enabled() && (buffers->index_buf || !buffers->smooth)) glGenBuffersARB(1, &buffers->vert_buf); buffers->tot_tri = tottri; @@ -1763,7 +1763,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to /* VBO is disabled; delete the previous buffer (if it exists) and * return an invalid handle */ - if (gpu_vbo_enabled()) { + if (!gpu_vbo_enabled()) { if (buffer) glDeleteBuffersARB(1, &buffer); return 0; diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 956c76aec20..ac05f1e8309 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1019,21 +1019,53 @@ void GPU_free_smoke(SmokeModifierData *smd) if (smd->domain->tex_shadow) GPU_texture_free(smd->domain->tex_shadow); smd->domain->tex_shadow = NULL; + + if (smd->domain->tex_flame) + GPU_texture_free(smd->domain->tex_flame); + smd->domain->tex_flame = NULL; } } void GPU_create_smoke(SmokeModifierData *smd, int highres) { #ifdef WITH_SMOKE - if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && !highres) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid)); - else if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && highres) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt)); + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + SmokeDomainSettings *sds = smd->domain; + if (!sds->tex && !highres) { + /* rgba texture for color + density */ + if (smoke_has_colors(sds->fluid)) { + float *data = MEM_callocN(sizeof(float)*sds->total_cells*4, "smokeColorTexture"); + smoke_get_rgba(sds->fluid, data, 0); + sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 4, data); + MEM_freeN(data); + } + /* density only */ + else { + sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_density(sds->fluid)); + } + sds->tex_flame = (smoke_has_fuel(sds->fluid)) ? GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_flame(sds->fluid)) : NULL; + } + else if (!sds->tex && highres) { + /* rgba texture for color + density */ + if (smoke_turbulence_has_colors(sds->wt)) { + float *data = MEM_callocN(sizeof(float)*smoke_turbulence_get_cells(sds->wt)*4, "smokeColorTexture"); + smoke_turbulence_get_rgba(sds->wt, data, 0); + sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 4, data); + MEM_freeN(data); + } + /* density only */ + else { + sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_density(sds->wt)); + } + sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ? GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_flame(sds->wt)) : NULL; + } - smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow); + sds->tex_shadow = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, sds->shadow); + } #else // WITH_SMOKE (void)highres; smd->domain->tex= NULL; + smd->domain->tex_flame= NULL; smd->domain->tex_shadow= NULL; #endif // WITH_SMOKE } diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index c5f427fbcab..798868a5efe 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -442,7 +442,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in } -GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) +GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels) { GPUTexture *tex; GLenum type, format, internalformat; @@ -480,9 +480,15 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) GPU_print_error("3D glBindTexture"); - type = GL_FLOAT; // GL_UNSIGNED_BYTE - format = GL_RED; - internalformat = GL_INTENSITY; + type = GL_FLOAT; + if (channels == 4) { + format = GL_RGBA; + internalformat = GL_RGBA; + } + else { + format = GL_RED; + internalformat = GL_INTENSITY; + } //if (fpixels) // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index e035f1c3f5a..e5f08d38ce8 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -780,7 +780,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la } } - if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS); + if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS) { + /* pass */ + } else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) { diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 81c3cab97d4..716ffc2b254 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1992,7 +1992,7 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result) result = vec4(L*color.rgb, 1.0); } -void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 result) +void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result) { /* ambient light */ vec3 L = vec3(0.2); @@ -2013,12 +2013,12 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 resu result = vec4(L*color.rgb, 1.0); } -void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 I, out vec4 result) +void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 T, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); } -void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, vec3 I, out vec4 result) +void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); } @@ -2195,7 +2195,8 @@ void node_light_path( out float is_glossy_ray, out float is_singular_ray, out float is_reflection_ray, - out float is_transmission_ray) + out float is_transmission_ray, + out float ray_length) { is_camera_ray = 1.0; is_shadow_ray = 0.0; @@ -2204,6 +2205,7 @@ void node_light_path( is_singular_ray = 0.0; is_reflection_ray = 0.0; is_transmission_ray = 0.0; + ray_length = 1.0; } void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant) @@ -2221,6 +2223,10 @@ void node_object_info(out vec3 location, out float object_index, out float mater random = 0.0; } +void node_bump(float strength, float height, vec3 N, out vec3 result) +{ + result = N; +} /* output */ diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h index e1d5f50edfb..4fc273bd435 100644 --- a/source/blender/ikplugin/BIK_api.h +++ b/source/blender/ikplugin/BIK_api.h @@ -92,5 +92,4 @@ void BIK_test_constraint(struct Object *ob, struct bConstraint *cons); } #endif -#endif // __BIK_API_H__ - +#endif /* __BIK_API_H__ */ diff --git a/source/blender/ikplugin/CMakeLists.txt b/source/blender/ikplugin/CMakeLists.txt index 903267c5618..0a0e0e664b4 100644 --- a/source/blender/ikplugin/CMakeLists.txt +++ b/source/blender/ikplugin/CMakeLists.txt @@ -56,9 +56,11 @@ endif() if(WITH_IK_ITASC) add_definitions(-DWITH_IK_ITASC) list(APPEND INC - ../../../extern/Eigen3 ../../../intern/itasc ) + list(APPEND INC_SYS + ../../../extern/Eigen3 + ) list(APPEND SRC intern/itasc_plugin.cpp intern/itasc_plugin.h diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h index 77c962269dc..53d9da8e614 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.h +++ b/source/blender/ikplugin/intern/ikplugin_api.h @@ -60,5 +60,4 @@ typedef struct IKPlugin IKPlugin; } #endif -#endif // __IKPLUGIN_API_H__ - +#endif /* __IKPLUGIN_API_H__ */ diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h index dd00c5f4add..c2ae4f937e7 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.h +++ b/source/blender/ikplugin/intern/iksolver_plugin.h @@ -47,5 +47,4 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose } #endif -#endif // __IKSOLVER_PLUGIN_H__ - +#endif /* __IKSOLVER_PLUGIN_H__ */ diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h index 0d5fde0bec0..0500125b4c7 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.h +++ b/source/blender/ikplugin/intern/itasc_plugin.h @@ -52,5 +52,4 @@ void itasc_test_constraint(struct Object *ob, struct bConstraint *cons); } #endif -#endif // __ITASC_PLUGIN_H__ - +#endif /* __ITASC_PLUGIN_H__ */ diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index bbe70a7d73f..344ae604ed4 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -25,7 +25,6 @@ set(INC . - ../avi ../blenkernel ../blenlib ../blenloader @@ -143,6 +142,13 @@ if(WITH_IMAGE_REDCODE) add_definitions(-DWITH_REDCODE) endif() +if(WITH_CODEC_AVI) + list(APPEND INC + ../avi + ) + add_definitions(-DWITH_AVI) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index e2604241caf..0653956e113 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -130,7 +130,8 @@ void IMB_colormanagement_colorspace_items_add(struct EnumPropertyItem **items, i void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_buffer, const unsigned char *buffer_byte, int stride, int offset_x, int offset_y, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, - int xmin, int ymin, int xmax, int ymax); + int xmin, int ymin, int xmax, int ymax, + int update_orig_byte_buffer); /* ** Pixel processor functions ** */ struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const struct ColorManagedViewSettings *view_settings, diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index f03f709f13f..76c247b2195 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -242,7 +242,7 @@ typedef struct ImBuf { ((unsigned long)(unsigned char)(ch1) << 8) | \ ((unsigned long)(unsigned char)(ch2) << 16) | \ ((unsigned long)(unsigned char)(ch3) << 24)) -#endif //MAKEFOURCC +#endif /* MAKEFOURCC */ /* * FOURCC codes for DX compressed-texture pixel formats @@ -255,7 +255,7 @@ typedef struct ImBuf { #define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4')) #define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5')) -#endif // DDS +#endif /* DDS */ extern const char *imb_ext_image[]; extern const char *imb_ext_image_qt[]; extern const char *imb_ext_movie[]; diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index d5cc4929aed..ed349e8f7eb 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -62,7 +62,9 @@ #include "imbuf.h" -#include "AVI_avi.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif #ifdef WITH_QUICKTIME # if defined(_WIN32) || defined(__APPLE__) diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 394f5169046..4aeba9af89d 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -78,7 +78,9 @@ #include "imbuf.h" -#include "AVI_avi.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined(__APPLE__) @@ -185,6 +187,7 @@ static void an_stringenc(char *string, const char *head, const char *tail, unsig BLI_stringenc(string, head, tail, numlen, pic); } +#ifdef WITH_AVI static void free_anim_avi(struct anim *anim) { #if defined(_WIN32) && !defined(FREE_WINDOWS) @@ -219,6 +222,7 @@ static void free_anim_avi(struct anim *anim) anim->duration = 0; } +#endif /* WITH_AVI */ #ifdef WITH_FFMPEG static void free_anim_ffmpeg(struct anim *anim); @@ -235,7 +239,10 @@ void IMB_free_anim(struct anim *anim) } free_anim_movie(anim); + +#ifdef WITH_AVI free_anim_avi(anim); +#endif #ifdef WITH_QUICKTIME free_anim_quicktime(anim); @@ -287,7 +294,7 @@ struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char return(anim); } - +#ifdef WITH_AVI static int startavi(struct anim *anim) { @@ -397,7 +404,9 @@ static int startavi(struct anim *anim) return 0; } +#endif /* WITH_AVI */ +#ifdef WITH_AVI static ImBuf *avi_fetchibuf(struct anim *anim, int position) { ImBuf *ibuf = NULL; @@ -447,6 +456,7 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position) return ibuf; } +#endif /* WITH_AVI */ #ifdef WITH_FFMPEG @@ -1206,7 +1216,11 @@ static ImBuf *anim_getnew(struct anim *anim) if (anim == NULL) return(NULL); free_anim_movie(anim); + +#ifdef WITH_AVI free_anim_avi(anim); +#endif + #ifdef WITH_QUICKTIME free_anim_quicktime(anim); #endif @@ -1233,6 +1247,7 @@ static ImBuf *anim_getnew(struct anim *anim) if (startmovie(anim)) return (NULL); ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); /* fake */ break; +#ifdef WITH_AVI case ANIM_AVI: if (startavi(anim)) { printf("couldnt start avi\n"); @@ -1240,6 +1255,7 @@ static ImBuf *anim_getnew(struct anim *anim) } ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); break; +#endif #ifdef WITH_QUICKTIME case ANIM_QTIME: if (startquicktime(anim)) return (0); @@ -1331,11 +1347,13 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim, int position, IMB_convert_rgba_to_abgr(ibuf); } break; +#ifdef WITH_AVI case ANIM_AVI: ibuf = avi_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; +#endif #ifdef WITH_QUICKTIME case ANIM_QTIME: ibuf = qtime_fetchibuf(anim, position); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 37510c10e9a..ff474d85a8c 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -99,6 +99,7 @@ static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; typedef struct ColormanageProcessor { OCIO_ConstProcessorRcPtr *processor; CurveMapping *curve_mapping; + int is_data_result; } ColormanageProcessor; /*********************** Color managed cache *************************/ @@ -1207,6 +1208,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) int predivide = handle->predivide; int is_data = handle->is_data; + int is_data_display = handle->cm_processor->is_data_result; linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color conversion linear buffer"); @@ -1228,7 +1230,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) *fp = (float)(*cp) / 255.0f; } - if (!is_data) { + if (!is_data && !is_data_display) { /* convert float buffer to scene linear space */ IMB_colormanagement_transform(linear_buffer, width, height, channels, from_colorspace, to_colorspace, predivide); @@ -1822,7 +1824,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet if (global_tot_display) ibuf->display_buffer_flags = MEM_callocN(sizeof(unsigned int) * global_tot_display, "imbuf display_buffer_flags"); } - else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { + else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { /* all display buffers were marked as invalid from other areas, * now propagate this flag to internal color management routines */ @@ -2347,7 +2349,6 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe } else if (byte_buffer) { rgba_uchar_to_float(pixel, byte_buffer + linear_index); - IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace); } @@ -2382,9 +2383,9 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer, const unsigned char *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, - int xmin, int ymin, int xmax, int ymax) + int xmin, int ymin, int xmax, int ymax, int update_orig_byte_buffer) { - if (ibuf->rect && ibuf->rect_float) { + if ((ibuf->rect && ibuf->rect_float) || update_orig_byte_buffer) { /* update byte buffer created by legacy color management */ unsigned char *rect = (unsigned char *) ibuf->rect; @@ -2449,28 +2450,29 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag const ColorManagedDisplaySettings *display_settings) { ColormanageProcessor *cm_processor; + ColorManagedViewSettings default_view_settings; + const ColorManagedViewSettings *applied_view_settings; + ColorSpace *display_space; cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor"); - { - ColorManagedViewSettings default_view_settings; - const ColorManagedViewSettings *applied_view_settings; + if (view_settings) { + applied_view_settings = view_settings; + } + else { + init_default_view_settings(display_settings, &default_view_settings); + applied_view_settings = &default_view_settings; + } - if (view_settings) { - applied_view_settings = view_settings; - } - else { - init_default_view_settings(display_settings, &default_view_settings); - applied_view_settings = &default_view_settings; - } + display_space = display_transform_get_colorspace(applied_view_settings, display_settings); + cm_processor->is_data_result = display_space->is_data; - cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, - applied_view_settings->exposure, applied_view_settings->gamma); + cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, + applied_view_settings->exposure, applied_view_settings->gamma); - if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { - cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping); - curvemapping_premultiply(cm_processor->curve_mapping, FALSE); - } + if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { + cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping); + curvemapping_premultiply(cm_processor->curve_mapping, FALSE); } return cm_processor; @@ -2479,9 +2481,13 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace) { ColormanageProcessor *cm_processor; + ColorSpace *color_space; cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor"); + color_space = colormanage_colorspace_get_named(to_colorspace); + cm_processor->is_data_result = color_space->is_data; + cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace); return cm_processor; diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h index c6712f4f058..9b90b744b67 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -271,4 +271,4 @@ void mem_read(Stream & mem, BlockATI1 & block); void mem_read(Stream & mem, BlockATI2 & block); void mem_read(Stream & mem, BlockCTX1 & block); -#endif // __BLOCKDXT_H__ +#endif /* __BLOCKDXT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h index 17de0a596c6..6676057d710 100644 --- a/source/blender/imbuf/intern/dds/Color.h +++ b/source/blender/imbuf/intern/dds/Color.h @@ -96,4 +96,4 @@ public: }; }; -#endif // __COLOR_H__ +#endif /* __COLOR_H__ */ diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index 2bf362f2780..f0864f06e6f 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -104,4 +104,4 @@ inline Color32 & ColorBlock::color(uint x, uint y) return m_color[y * 4 + x]; } -#endif // __COLORBLOCK_H__ +#endif /* __COLORBLOCK_H__ */ diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index a851533b1f3..ccac1c08b41 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -200,4 +200,4 @@ void mem_read(Stream & mem, DDSCaps & caps); void mem_read(Stream & mem, DDSHeader & header); void mem_read(Stream & mem, DDSHeader10 & header); -#endif // __DIRECTDRAWSURFACE_H__ +#endif /* __DIRECTDRAWSURFACE_H__ */ diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index 5dcf3011c76..81074fba6b7 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -101,4 +101,4 @@ inline Color32 & Image::pixel(uint x, uint y) return pixel(y * width() + x); } -#endif // __IMAGE_H__ +#endif /* __IMAGE_H__ */ diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h index 308ea810f03..ce36fb00b97 100644 --- a/source/blender/imbuf/intern/dds/PixelFormat.h +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -135,4 +135,4 @@ } // PixelFormat namespace -#endif // _DDS_IMAGE_PIXELFORMAT_H +#endif /* __PIXELFORMAT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h index 9f513ca8aba..7fed4ca89e7 100644 --- a/source/blender/imbuf/intern/dds/Stream.h +++ b/source/blender/imbuf/intern/dds/Stream.h @@ -45,5 +45,4 @@ unsigned int mem_read(Stream & mem, unsigned short & i); unsigned int mem_read(Stream & mem, unsigned char & i); unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt); -#endif // __STREAM_H__ - +#endif /* __STREAM_H__ */ diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index f35a4345366..593e08062fe 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -36,18 +36,19 @@ #include "IMB_indexer.h" #include "IMB_anim.h" -#include "AVI_avi.h" #include "imbuf.h" #include "MEM_guardedalloc.h" #include "DNA_userdef_types.h" #include "BKE_global.h" -#ifdef WITH_FFMPEG - -#include "ffmpeg_compat.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif -#endif //WITH_FFMPEG +#ifdef WITH_FFMPEG +# include "ffmpeg_compat.h" +#endif static char magic[] = "BlenMIdx"; @@ -989,6 +990,7 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, * - internal AVI (fallback) rebuilder * ---------------------------------------------------------------------- */ +#ifdef WITH_AVI typedef struct FallbackIndexBuilderContext { int anim_type; @@ -1149,6 +1151,8 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context, } } +#endif /* WITH_AVI */ + /* ---------------------------------------------------------------------- * - public API * ---------------------------------------------------------------------- */ @@ -1164,15 +1168,19 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecod context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); break; #endif +#ifdef WITH_AVI default: context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); break; +#endif } if (context) context->anim_type = anim->curtype; return context; + + (void)tcs_in_use, (void)proxy_sizes_in_use, (void)quality; } void IMB_anim_index_rebuild(struct IndexBuildContext *context, @@ -1184,10 +1192,14 @@ void IMB_anim_index_rebuild(struct IndexBuildContext *context, index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)context, stop, do_update, progress); break; #endif +#ifdef WITH_AVI default: index_rebuild_fallback((FallbackIndexBuilderContext *)context, stop, do_update, progress); break; +#endif } + + (void)stop, (void)do_update, (void)progress; } void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) @@ -1198,10 +1210,15 @@ void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)context, stop); break; #endif +#ifdef WITH_AVI default: index_rebuild_fallback_finish((FallbackIndexBuilderContext *)context, stop); break; +#endif } + + (void)stop; + (void)proxy_sizes; /* static defined at top of the file */ } diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 833671e3f2f..8dd791c8508 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -211,7 +211,12 @@ int IMB_ispic(const char *filename) static int isavi(const char *name) { +#ifdef WITH_AVI return AVI_is_avi(name); +#else + (void)name; + return FALSE; +#endif } #ifdef WITH_QUICKTIME @@ -223,6 +228,10 @@ static int isqtime(const char *name) #ifdef WITH_FFMPEG +/* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-format-attribute" + static char ffmpeg_last_error[1024]; static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg) @@ -240,6 +249,8 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_lis } } +#pragma GCC diagnostic pop + void IMB_ffmpeg_init(void) { av_register_all(); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 59874e0434b..a730bee4f79 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -564,6 +564,7 @@ typedef enum eDopeSheet_FilterFlag { /* general filtering 3 */ ADS_FILTER_INCL_HIDDEN = (1 << 26), /* include 'hidden' channels too (i.e. those from hidden Objects/Bones) */ ADS_FILTER_BY_FCU_NAME = (1 << 27), /* for F-Curves, filter by the displayed name (i.e. to isolate all Location curves only) */ + ADS_FILTER_ONLY_ERRORS = (1 << 28), /* show only F-Curves which are disabled/have errors - for debugging drivers */ /* combination filters (some only used at runtime) */ ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM | ADS_FILTER_NOMAT | ADS_FILTER_NOLAM | ADS_FILTER_NOCUR | ADS_FILTER_NOPART | ADS_FILTER_NOARM | ADS_FILTER_NOSPK) diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index bf388d8c018..5b25d1a072c 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -211,4 +211,4 @@ enum { MASK_ANIMF_EXPAND = (1 << 4) }; -#endif // __DNA_MASK_TYPES_H__ +#endif /* __DNA_MASK_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index f3c527b6531..09451754dee 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -295,6 +295,7 @@ typedef struct Material { #define MA_CUBIC 1 #define MA_OBCOLOR 2 #define MA_APPROX_OCCLUSION 4 +#define MA_GROUP_LOCAL 8 /* diff_shader */ #define MA_DIFF_LAMBERT 0 diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 1dd2aa6c59b..67d540db177 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -54,6 +54,7 @@ typedef enum PFieldType { PFIELD_BOID = 10, /* Defines predator / goal for boids */ PFIELD_TURBULENCE = 11, /* Force defined by BLI_gTurbulence */ PFIELD_DRAG = 12, /* Linear & quadratic drag */ + PFIELD_SMOKEFLOW = 13, /* Force based on smoke simulation air flow */ NUM_PFIELD_TYPES } PFieldType; @@ -110,14 +111,17 @@ typedef struct PartDeflect { struct RNG *rng; /* random noise generator for e.g. wind */ float f_noise; /* noise of force */ int seed; /* noise random seed */ + + struct Object *f_source; /* force source object */ } PartDeflect; typedef struct EffectorWeights { struct Group *group; /* only use effectors from this group of objects */ - float weight[13]; /* effector type specific weights */ + float weight[14]; /* effector type specific weights */ float global_gravity; short flag, rt[3]; + int pad; } EffectorWeights; /* EffectorWeights->flag */ @@ -365,6 +369,7 @@ typedef struct SoftBody { #define PFIELD_DO_LOCATION (1<<14) #define PFIELD_DO_ROTATION (1<<15) #define PFIELD_GUIDE_PATH_WEIGHT (1<<16) /* apply curve weights */ +#define PFIELD_SMOKE_DENSITY (1<<17) /* multiply smoke force by density */ /* pd->falloff */ #define PFIELD_FALL_SPHERE 0 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3a8620fdaba..2fc04c4a5db 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -378,6 +378,7 @@ typedef struct DupliObject { #define OB_DUPLIPARTS 2048 #define OB_RENDER_DUPLI 4096 #define OB_NO_CONSTRAINTS 8192 /* runtime constraints disable */ +#define OB_NO_PSYS_UPDATE 16384 /* hack to work around particle issue */ /* (short) ipoflag */ /* XXX: many old flags for features removed due to incompatibility diff --git a/source/blender/makesdna/DNA_packedFile_types.h b/source/blender/makesdna/DNA_packedFile_types.h index f01e89d18c9..4ec5866e8c3 100644 --- a/source/blender/makesdna/DNA_packedFile_types.h +++ b/source/blender/makesdna/DNA_packedFile_types.h @@ -45,7 +45,7 @@ enum PF_FileStatus PF_EQUAL = 0, PF_DIFFERS = 1, PF_NOFILE = 2, - + PF_WRITE_ORIGINAL = 3, PF_WRITE_LOCAL = 4, PF_USE_LOCAL = 5, @@ -53,7 +53,7 @@ enum PF_FileStatus PF_KEEP = 7, PF_REMOVE = 8, PF_NOOP = 9, - + PF_ASK = 10 }; diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index cceb7333478..76ba3fcf7f8 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -39,6 +39,7 @@ #define MOD_SMOKE_HIGH_SMOOTH (1<<5) /* smoothens high res emission*/ #define MOD_SMOKE_FILE_LOAD (1<<6) /* flag for file load */ +#define MOD_SMOKE_ADAPTIVE_DOMAIN (1<<7) /* noise */ #define MOD_SMOKE_NOISEWAVE (1<<0) @@ -61,6 +62,12 @@ #define SM_COLL_RIGID 1 #define SM_COLL_ANIMATED 2 +/* smoke data fileds (active_fields) */ +#define SM_ACTIVE_HEAT (1<<0) +#define SM_ACTIVE_FIRE (1<<1) +#define SM_ACTIVE_COLORS (1<<2) +#define SM_ACTIVE_COLOR_SET (1<<3) + typedef struct SmokeDomainSettings { struct SmokeModifierData *smd; /* for fast RNA access */ struct FLUID_3D *fluid; @@ -71,17 +78,37 @@ typedef struct SmokeDomainSettings { struct GPUTexture *tex; struct GPUTexture *tex_wt; struct GPUTexture *tex_shadow; + struct GPUTexture *tex_flame; float *shadow; - float p0[3]; /* start point of BB */ - float p1[3]; /* end point of BB */ - float dx; /* edge length of one cell */ - float omega; /* smoke color - from 0 to 1 */ - float temp; /* fluid temperature */ - float tempAmb; /* ambient temperature */ + + /* simulation data */ + float p0[3]; /* start point of BB in local space (includes sub-cell shift for adaptive domain)*/ + float p1[3]; /* end point of BB in local space */ + float dp0[3]; /* difference from object center to grid start point */ + float cell_size[3]; /* size of simulation cell in local space */ + float global_size[3]; /* global size of domain axises */ + float prev_loc[3]; + int shift[3]; /* current domain shift in simulation cells */ + float shift_f[3]; /* exact domain shift */ + float obj_shift_f[3]; /* how much object has shifted since previous smoke frame (used to "lock" domain while drawing) */ + float imat[4][4]; /* domain object imat */ + float obmat[4][4]; /* domain obmat */ + + int base_res[3]; /* initial "non-adapted" resolution */ + int res_min[3]; /* cell min */ + int res_max[3]; /* cell max */ + int res[3]; /* data resolution (res_max-res_min) */ + int total_cells; + float dx; /* 1.0f / res */ + float scale; /* largest domain size */ + + /* user settings */ + int adapt_margin; + int adapt_res; + float adapt_threshold; + float alpha; float beta; - float scale; /* largest domain size */ - int res[3]; /* domain resolution */ int amplify; /* wavelet amplification */ int maxres; /* longest axis on the BB gets this resolution assigned */ int flags; /* show up-res or low res, etc */ @@ -92,7 +119,6 @@ typedef struct SmokeDomainSettings { float strength; int res_wt[3]; float dx_wt; - int v3dnum; int cache_comp; int cache_high_comp; @@ -103,31 +129,67 @@ typedef struct SmokeDomainSettings { int border_collisions; /* How domain border collisions are handled */ float time_scale; float vorticity; - int pad2; + int active_fields; + float active_color[3]; /* monitor color situation of simulation */ + int pad; + + /* flame parameters */ + float burning_rate, flame_smoke, flame_vorticity; + float flame_ignition, flame_max_temp; + float flame_smoke_color[3]; } SmokeDomainSettings; /* inflow / outflow */ /* type */ -#define MOD_SMOKE_FLOW_TYPE_OUTFLOW (1<<1) +#define MOD_SMOKE_FLOW_TYPE_SMOKE 0 +#define MOD_SMOKE_FLOW_TYPE_FIRE 1 +#define MOD_SMOKE_FLOW_TYPE_OUTFLOW 2 +#define MOD_SMOKE_FLOW_TYPE_SMOKEFIRE 3 + +/* flow source */ +#define MOD_SMOKE_FLOW_SOURCE_PARTICLES 0 +#define MOD_SMOKE_FLOW_SOURCE_MESH 1 + +/* flow texture type */ +#define MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO 0 +#define MOD_SMOKE_FLOW_TEXTURE_MAP_UV 1 /* flags */ #define MOD_SMOKE_FLOW_ABSOLUTE (1<<1) /*old style emission*/ #define MOD_SMOKE_FLOW_INITVELOCITY (1<<2) /* passes particles speed to the smoke */ +#define MOD_SMOKE_FLOW_TEXTUREEMIT (1<<3) /* use texture to control emission speed */ typedef struct SmokeFlowSettings { struct SmokeModifierData *smd; /* for fast RNA access */ + struct DerivedMesh *dm; struct ParticleSystem *psys; + struct Tex *noise_texture; + + /* initial velocity */ + float *verts_old; /* previous vertex positions in domain space */ + int numverts; + float vel_multi; // Multiplier for inherited velocity + float vel_normal; + float vel_random; + /* emission */ float density; + float color[3]; + float fuel_amount; float temp; /* delta temperature (temp - ambient temp) */ - float velocity[2]; /* UNUSED, velocity taken from particles */ - float vel_multi; // Multiplier for particle velocity - float vgrp_heat_scale[2]; /* min and max scaling for vgroup_heat */ - short vgroup_flow; /* where inflow/outflow happens - red=1=action */ + float volume_density; /* density emitted within mesh volume */ + float surface_distance; /* maximum emission distance from mesh surface */ + /* texture control */ + float texture_size; + float texture_offset; + int pad; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ short vgroup_density; - short vgroup_heat; - short type; /* inflow =0 or outflow = 1 */ + + short type; /* smoke, flames, both, outflow */ + short source; + short texture_type; int flags; /* absolute emission etc*/ } SmokeFlowSettings; @@ -139,20 +201,11 @@ typedef struct SmokeFlowSettings { /* collision objects (filled with smoke) */ typedef struct SmokeCollSettings { struct SmokeModifierData *smd; /* for fast RNA access */ - struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ - float *points; - float *points_old; - float *vel; // UNUSED - int *tridivs; - float mat[4][4]; - float mat_old[4][4]; - int numpoints; - int numverts; // check if mesh changed - int numtris; - float dx; /* global domain cell length taken from (scale / resolution) */ + struct DerivedMesh *dm; + float *verts_old; + int numverts; short type; // static = 0, rigid = 1, dynamic = 2 short pad; - int pad2; } SmokeCollSettings; #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 4b8fc9c7ed6..2469656ecd7 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -618,7 +618,7 @@ enum FileSortTypeE { #define FILE_MAXFILE 256 #define FILE_MAX 1024 -#define FILE_MAX_LIBEXTRA (FILE_MAX + 32) +#define FILE_MAX_LIBEXTRA (FILE_MAX + MAX_ID_NAME) /* filesel types */ #define FILE_UNIX 8 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 9fdd9216549..ce94a229750 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -171,6 +171,9 @@ typedef struct VoxelData { short flag; short extend; short smoked_type; + short data_type; + short pad; + int _pad; struct Object *object; /* for rendering smoke sims */ float int_multiplier; @@ -470,6 +473,7 @@ typedef struct ColorMapping { #define MTEX_BUMP_TEXTURESPACE 2048 /* #define MTEX_BUMP_FLIPPED 4096 */ /* UNUSED */ #define MTEX_BICUBIC_BUMP 8192 +#define MTEX_MAPTO_BOUNDS 16384 /* blendtype */ #define MTEX_BLEND 0 @@ -577,6 +581,11 @@ typedef struct ColorMapping { #define TEX_VD_SMOKEDENSITY 0 #define TEX_VD_SMOKEHEAT 1 #define TEX_VD_SMOKEVEL 2 +#define TEX_VD_SMOKEFLAME 3 + +/* data_type */ +#define TEX_VD_INTENSITY 0 +#define TEX_VD_RGBA_PREMUL 1 /******************** Ocean *****************************/ /* output */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 1ab64ed1cc1..c6cefce2994 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -162,7 +162,10 @@ typedef struct MovieTrackingSettings { short speed; /* speed of tracking */ /* ** reconstruction settings ** */ - int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ + int keyframe1 DNA_DEPRECATED, + keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization + * were moved to per-tracking object settings + */ /* which camera intrinsics to refine. uses on the REFINE_* flags */ short refine_camera_intrinsics, pad2; @@ -220,6 +223,8 @@ typedef struct MovieTrackingObject { ListBase tracks; /* list of tracks use to tracking this object */ MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ + + int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ } MovieTrackingObject; typedef struct MovieTrackingStats { diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 96f0c0e7a9a..2c51a956e18 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -49,11 +49,14 @@ struct ColorBand; #define MAX_STYLE_NAME 64 /* default uifont_id offered by Blender */ -#define UIFONT_DEFAULT 0 -/*#define UIFONT_BITMAP 1*/ /*UNUSED*/ -/* free slots */ -#define UIFONT_CUSTOM1 2 -#define UIFONT_CUSTOM2 3 +typedef enum eUIFont_ID { + UIFONT_DEFAULT = 0, +/* UIFONT_BITMAP = 1 */ /* UNUSED */ + + /* free slots */ + UIFONT_CUSTOM1 = 2, + UIFONT_CUSTOM2 = 3 +} eUIFont_ID; /* default fonts to load/initalize */ /* first font is the default (index 0), others optional */ @@ -64,7 +67,6 @@ typedef struct uiFont { short uifont_id; /* own id */ short r_to_l; /* fonts that read from left to right */ short pad; - } uiFont; /* this state defines appearance of text */ @@ -79,13 +81,14 @@ typedef struct uiFontStyle { short align; /* text align hint */ float shadowalpha; /* total alpha */ float shadowcolor; /* 1 value, typically white or black anyway */ - } uiFontStyle; /* uiFontStyle->align */ -#define UI_STYLE_TEXT_LEFT 0 -#define UI_STYLE_TEXT_CENTER 1 -#define UI_STYLE_TEXT_RIGHT 2 +typedef enum eFontStyle_Align { + UI_STYLE_TEXT_LEFT = 0, + UI_STYLE_TEXT_CENTER = 1, + UI_STYLE_TEXT_RIGHT = 2 +} eFontStyle_Align; /* this is fed to the layout engine and widget code */ @@ -145,7 +148,6 @@ typedef struct uiPanelColors { } uiPanelColors; typedef struct ThemeUI { - /* Interface Elements (buttons, menus, icons) */ uiWidgetColors wcol_regular, wcol_tool, wcol_text; uiWidgetColors wcol_radio, wcol_option, wcol_toggle; @@ -209,8 +211,8 @@ typedef struct ThemeSpace { char vertex[4], vertex_select[4]; char edge[4], edge_select[4]; char edge_seam[4], edge_sharp[4], edge_facesel[4], edge_crease[4]; - char face[4], face_select[4]; // solid faces - char face_dot[4]; // selected color + char face[4], face_select[4]; /* solid faces */ + char face_dot[4]; /* selected color */ char extra_edge_len[4], extra_face_angle[4], extra_face_area[4], pad3[4]; char normal[4]; char vertex_normal[4]; @@ -225,7 +227,7 @@ typedef struct ThemeSpace { char handle_free[4], handle_auto[4], handle_vect[4], handle_align[4], handle_auto_clamped[4]; char handle_sel_free[4], handle_sel_auto[4], handle_sel_vect[4], handle_sel_align[4], handle_sel_auto_clamped[4]; - char ds_channel[4], ds_subchannel[4]; // dopesheet + char ds_channel[4], ds_subchannel[4]; /* dopesheet */ char console_output[4], console_input[4], console_info[4], console_error[4]; char console_cursor[4]; @@ -233,10 +235,10 @@ typedef struct ThemeSpace { char vertex_size, outline_width, facedot_size; char noodle_curving; - char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes + char syntaxl[4], syntaxn[4], syntaxb[4]; /* syntax for textwindow and nodes */ char syntaxv[4], syntaxc[4]; - char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; // for sequence editor + char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; /* for sequence editor */ char effect[4], hpad0[4], transition[4], meta[4]; char editmesh_active[4]; @@ -288,8 +290,10 @@ typedef struct ThemeWireColor { } ThemeWireColor; /* flags for ThemeWireColor */ -#define TH_WIRECOLOR_CONSTCOLS (1<<0) -#define TH_WIRECOLOR_TEXTCOLS (1<<1) +typedef enum eWireColor_Flags { + TH_WIRECOLOR_CONSTCOLS = (1 << 0), + TH_WIRECOLOR_TEXTCOLS = (1 << 1), +} eWireColor_Flags; /* A theme */ typedef struct bTheme { @@ -322,7 +326,6 @@ typedef struct bTheme { /*ThemeWireColor tobj[20];*/ int active_theme_area, pad; - } bTheme; /* for the moment only the name. may want to store options with this later */ @@ -346,8 +349,8 @@ typedef struct UserDef { char pythondir[768]; char sounddir[768]; char i18ndir[768]; - char image_editor[1024]; /* 1024 = FILE_MAX */ - char anim_player[1024]; /* 1024 = FILE_MAX */ + char image_editor[1024]; /* 1024 = FILE_MAX */ + char anim_player[1024]; /* 1024 = FILE_MAX */ int anim_player_preset; short v2d_min_gridsize; /* minimum spacing between gridlines in View2D grids */ @@ -394,7 +397,7 @@ typedef struct UserDef { int memcachelimit; int prefetchframes; short frameserverport; - short pad_rot_angle; /*control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use*/ + short pad_rot_angle; /* control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use */ short obcenter_dia; short rvisize; /* rotating view icon size */ short rvibright; /* rotating view icon brightness */ @@ -423,7 +426,7 @@ typedef struct UserDef { short autokey_mode; /* autokeying mode */ short autokey_flag; /* flags for autokeying */ - short text_render, pad9; /*options for text rendering*/ + short text_render, pad9; /* options for text rendering */ struct ColorBand coba_weight; /* from texture.h */ @@ -446,217 +449,258 @@ extern UserDef U; /* from blenkernel blender.c */ /* ***************** USERDEF ****************** */ /* userpref/section */ -#define USER_SECTION_INTERFACE 0 -#define USER_SECTION_EDIT 1 -#define USER_SECTION_FILE 2 -#define USER_SECTION_SYSTEM 3 -#define USER_SECTION_THEME 4 -#define USER_SECTION_INPUT 5 -#define USER_SECTION_ADDONS 6 +typedef enum eUserPref_Section { + USER_SECTION_INTERFACE = 0, + USER_SECTION_EDIT = 1, + USER_SECTION_FILE = 2, + USER_SECTION_SYSTEM = 3, + USER_SECTION_THEME = 4, + USER_SECTION_INPUT = 5, + USER_SECTION_ADDONS = 6, +} eUserPref_Section; /* flag */ -#define USER_AUTOSAVE (1 << 0) -/*#define USER_AUTOGRABGRID (1 << 1) deprecated */ -/*#define USER_AUTOROTGRID (1 << 2) deprecated */ -/*#define USER_AUTOSIZEGRID (1 << 3) deprecated */ -#define USER_SCENEGLOBAL (1 << 4) -#define USER_TRACKBALL (1 << 5) -/*#define USER_DUPLILINK (1 << 6) deprecated */ -/*#define USER_FSCOLLUM (1 << 7) deprecated */ -#define USER_MAT_ON_OB (1 << 8) -/*#define USER_NO_CAPSLOCK (1 << 9)*/ /* not used anywhere */ -/*#define USER_VIEWMOVE (1 << 10)*/ /* not used anywhere */ -#define USER_TOOLTIPS (1 << 11) -#define USER_TWOBUTTONMOUSE (1 << 12) -#define USER_NONUMPAD (1 << 13) -#define USER_LMOUSESELECT (1 << 14) -#define USER_FILECOMPRESS (1 << 15) -#define USER_SAVE_PREVIEWS (1 << 16) -#define USER_CUSTOM_RANGE (1 << 17) -#define USER_ADD_EDITMODE (1 << 18) -#define USER_ADD_VIEWALIGNED (1 << 19) -#define USER_RELPATHS (1 << 20) -#define USER_RELEASECONFIRM (1 << 21) -#define USER_SCRIPT_AUTOEXEC_DISABLE (1 << 22) -#define USER_FILENOUI (1 << 23) -#define USER_NONEGFRAMES (1 << 24) -#define USER_TXT_TABSTOSPACES_DISABLE (1 << 25) -#define USER_TOOLTIPS_PYTHON (1 << 26) - +typedef enum eUserPref_Flag { + USER_AUTOSAVE = (1 << 0), +/* USER_AUTOGRABGRID = (1 << 1), deprecated */ +/* USER_AUTOROTGRID = (1 << 2), deprecated */ +/* USER_AUTOSIZEGRID = (1 << 3), deprecated */ + USER_SCENEGLOBAL = (1 << 4), + USER_TRACKBALL = (1 << 5), +/* USER_DUPLILINK = (1 << 6), deprecated */ +/* USER_FSCOLLUM = (1 << 7), deprecated */ + USER_MAT_ON_OB = (1 << 8), +/* USER_NO_CAPSLOCK = (1 << 9), */ /* not used anywhere */ +/* USER_VIEWMOVE = (1 << 10), */ /* not used anywhere */ + USER_TOOLTIPS = (1 << 11), + USER_TWOBUTTONMOUSE = (1 << 12), + USER_NONUMPAD = (1 << 13), + USER_LMOUSESELECT = (1 << 14), + USER_FILECOMPRESS = (1 << 15), + USER_SAVE_PREVIEWS = (1 << 16), + USER_CUSTOM_RANGE = (1 << 17), + USER_ADD_EDITMODE = (1 << 18), + USER_ADD_VIEWALIGNED = (1 << 19), + USER_RELPATHS = (1 << 20), + USER_RELEASECONFIRM = (1 << 21), + USER_SCRIPT_AUTOEXEC_DISABLE = (1 << 22), + USER_FILENOUI = (1 << 23), + USER_NONEGFRAMES = (1 << 24), + USER_TXT_TABSTOSPACES_DISABLE = (1 << 25), + USER_TOOLTIPS_PYTHON = (1 << 26), +} eUserPref_Flag; + /* helper macro for checking frame clamping */ #define FRAMENUMBER_MIN_CLAMP(cfra) { \ if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \ cfra = 0; \ } (void)0 -/* viewzom */ -#define USER_ZOOM_CONT 0 -#define USER_ZOOM_SCALE 1 -#define USER_ZOOM_DOLLY 2 +/* viewzoom */ +typedef enum eViewZoom_Style { + USER_ZOOM_CONT = 0, + USER_ZOOM_SCALE = 1, + USER_ZOOM_DOLLY = 2 +} eViewZoom_Style; /* uiflag */ -// old flag for #define USER_KEYINSERTACT (1 << 0) -// old flag for #define USER_KEYINSERTOBJ (1 << 1) -#define USER_WHEELZOOMDIR (1 << 2) -#define USER_FILTERFILEEXTS (1 << 3) -#define USER_DRAWVIEWINFO (1 << 4) -#define USER_PLAINMENUS (1 << 5) // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase - // old flag for hide pulldown was here -/*#define USER_FLIPFULLSCREEN (1 << 7)*/ /* deprecated */ -#define USER_ALLWINCODECS (1 << 8) -#define USER_MENUOPENAUTO (1 << 9) -#define USER_ZBUF_CURSOR (1 << 10) -#define USER_AUTOPERSP (1 << 11) -#define USER_LOCKAROUND (1 << 12) -#define USER_GLOBALUNDO (1 << 13) -#define USER_ORBIT_SELECTION (1 << 14) -#define USER_ZBUF_ORBIT (1 << 15) -#define USER_HIDE_DOT (1 << 16) -#define USER_SHOW_ROTVIEWICON (1 << 17) -#define USER_SHOW_VIEWPORTNAME (1 << 18) -#define USER_CAM_LOCK_NO_PARENT (1 << 19) -#define USER_ZOOM_TO_MOUSEPOS (1 << 20) -#define USER_SHOW_FPS (1 << 21) -#define USER_MMB_PASTE (1 << 22) -#define USER_MENUFIXEDORDER (1 << 23) -#define USER_CONTINUOUS_MOUSE (1 << 24) -#define USER_ZOOM_INVERT (1 << 25) -#define USER_ZOOM_HORIZ (1 << 26) /* for CONTINUE and DOLLY zoom */ -#define USER_SPLASH_DISABLE (1 << 27) -#define USER_HIDE_RECENT (1 << 28) -#define USER_SHOW_THUMBNAILS (1 << 29) -#define USER_QUIT_PROMPT (1 << 30) +typedef enum eUserpref_UI_Flag { + /* flags 0 and 1 were old flags (for autokeying) that aren't used anymore */ + USER_WHEELZOOMDIR = (1 << 2), + USER_FILTERFILEEXTS = (1 << 3), + USER_DRAWVIEWINFO = (1 << 4), + USER_PLAINMENUS = (1 << 5), + /* flags 6 and 7 were old flags that are no-longer used */ + USER_ALLWINCODECS = (1 << 8), + USER_MENUOPENAUTO = (1 << 9), + USER_ZBUF_CURSOR = (1 << 10), + USER_AUTOPERSP = (1 << 11), + USER_LOCKAROUND = (1 << 12), + USER_GLOBALUNDO = (1 << 13), + USER_ORBIT_SELECTION = (1 << 14), + USER_ZBUF_ORBIT = (1 << 15), + USER_HIDE_DOT = (1 << 16), + USER_SHOW_ROTVIEWICON = (1 << 17), + USER_SHOW_VIEWPORTNAME = (1 << 18), + USER_CAM_LOCK_NO_PARENT = (1 << 19), + USER_ZOOM_TO_MOUSEPOS = (1 << 20), + USER_SHOW_FPS = (1 << 21), + USER_MMB_PASTE = (1 << 22), + USER_MENUFIXEDORDER = (1 << 23), + USER_CONTINUOUS_MOUSE = (1 << 24), + USER_ZOOM_INVERT = (1 << 25), + USER_ZOOM_HORIZ = (1 << 26), /* for CONTINUE and DOLLY zoom */ + USER_SPLASH_DISABLE = (1 << 27), + USER_HIDE_RECENT = (1 << 28), + USER_SHOW_THUMBNAILS = (1 << 29), + USER_QUIT_PROMPT = (1 << 30) +} eUserpref_UI_Flag; /* Auto-Keying mode */ +typedef enum eAutokey_Mode { /* AUTOKEY_ON is a bitflag */ -#define AUTOKEY_ON 1 + AUTOKEY_ON = 1, + /* AUTOKEY_ON + 2**n... (i.e. AUTOKEY_MODE_NORMAL = AUTOKEY_ON + 2) to preserve setting, even when autokey turned off */ -#define AUTOKEY_MODE_NORMAL 3 -#define AUTOKEY_MODE_EDITKEYS 5 + AUTOKEY_MODE_NORMAL = 3, + AUTOKEY_MODE_EDITKEYS = 5 +} eAutokey_Mode; /* Auto-Keying flag * U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days) * note: AUTOKEY_FLAG_* is used with a macro, search for lines like IS_AUTOKEY_FLAG(INSERTAVAIL) */ -#define AUTOKEY_FLAG_INSERTAVAIL (1<<0) -#define AUTOKEY_FLAG_INSERTNEEDED (1<<1) -#define AUTOKEY_FLAG_AUTOMATKEY (1<<2) -#define AUTOKEY_FLAG_XYZ2RGB (1<<3) - -/* toolsettings->autokey_flag */ -#define AUTOKEY_FLAG_ONLYKEYINGSET (1<<6) -#define ANIMRECORD_FLAG_WITHNLA (1<<10) +typedef enum eAutokey_Flag { + AUTOKEY_FLAG_INSERTAVAIL = (1 << 0), + AUTOKEY_FLAG_INSERTNEEDED = (1 << 1), + AUTOKEY_FLAG_AUTOMATKEY = (1 << 2), + AUTOKEY_FLAG_XYZ2RGB = (1 << 3), + + /* toolsettings->autokey_flag */ + AUTOKEY_FLAG_ONLYKEYINGSET = (1 << 6), + AUTOKEY_FLAG_NOWARNING = (1 << 7), + ANIMRECORD_FLAG_WITHNLA = (1 << 10), +} eAutokey_Flag; /* transopts */ -#define USER_TR_TOOLTIPS (1 << 0) -#define USER_TR_IFACE (1 << 1) -/*#define USER_TR_MENUS (1 << 2) deprecated*/ -/*#define USER_TR_FILESELECT (1 << 3) deprecated*/ -/*#define USER_TR_TEXTEDIT (1 << 4) deprecated*/ -#define USER_DOTRANSLATE (1 << 5) -#define USER_USETEXTUREFONT (1 << 6) -/*#define CONVERT_TO_UTF8 (1 << 7) deprecated*/ +typedef enum eUserpref_Translation_Flags { + USER_TR_TOOLTIPS = (1 << 0), + USER_TR_IFACE = (1 << 1), +/* USER_TR_MENUS = (1 << 2) deprecated */ +/* USER_TR_FILESELECT = (1 << 3) deprecated */ +/* USER_TR_TEXTEDIT = (1 << 4) deprecated */ + USER_DOTRANSLATE = (1 << 5), + USER_USETEXTUREFONT = (1 << 6), +/* CONVERT_TO_UTF8 = (1 << 7) deprecated */ +} eUserpref_Translation_Flags; /* dupflag */ -#define USER_DUP_MESH (1 << 0) -#define USER_DUP_CURVE (1 << 1) -#define USER_DUP_SURF (1 << 2) -#define USER_DUP_FONT (1 << 3) -#define USER_DUP_MBALL (1 << 4) -#define USER_DUP_LAMP (1 << 5) -#define USER_DUP_IPO (1 << 6) -#define USER_DUP_MAT (1 << 7) -#define USER_DUP_TEX (1 << 8) -#define USER_DUP_ARM (1 << 9) -#define USER_DUP_ACT (1 << 10) -#define USER_DUP_PSYS (1 << 11) +typedef enum eDupli_ID_Flags { + USER_DUP_MESH = (1 << 0), + USER_DUP_CURVE = (1 << 1), + USER_DUP_SURF = (1 << 2), + USER_DUP_FONT = (1 << 3), + USER_DUP_MBALL = (1 << 4), + USER_DUP_LAMP = (1 << 5), + USER_DUP_IPO = (1 << 6), + USER_DUP_MAT = (1 << 7), + USER_DUP_TEX = (1 << 8), + USER_DUP_ARM = (1 << 9), + USER_DUP_ACT = (1 << 10), + USER_DUP_PSYS = (1 << 11) +} eDupli_ID_Flags; /* gameflags */ -// #define USER_DEPRECATED_FLAG 1 -// #define USER_DISABLE_SOUND 2 deprecated, don't use without checking for -// backwards compatibilty in do_versions! -#define USER_DISABLE_MIPMAP 4 -#define USER_DISABLE_VBO 8 -#define USER_DISABLE_AA 16 +typedef enum eOpenGL_RenderingOptions { + /* USER_DEPRECATED_FLAG = (1 << 0), */ + /* USER_DISABLE_SOUND = (1 << 1), */ /* deprecated, don't use without checking for */ + /* backwards compatibilty in do_versions! */ + USER_DISABLE_MIPMAP = (1 << 2), + USER_DISABLE_VBO = (1 << 3), + USER_DISABLE_AA = (1 << 4), +} eOpenGL_RenderingOptions; /* wm draw method */ -#define USER_DRAW_TRIPLE 0 -#define USER_DRAW_OVERLAP 1 -#define USER_DRAW_FULL 2 -#define USER_DRAW_AUTOMATIC 3 -#define USER_DRAW_OVERLAP_FLIP 4 - -/* text draw options*/ -#define USER_TEXT_DISABLE_AA (1 << 0) +typedef enum eWM_DrawMethod { + USER_DRAW_TRIPLE = 0, + USER_DRAW_OVERLAP = 1, + USER_DRAW_FULL = 2, + USER_DRAW_AUTOMATIC = 3, + USER_DRAW_OVERLAP_FLIP = 4, +} eWM_DrawMethod; + +/* text draw options */ +typedef enum eText_Draw_Options { + USER_TEXT_DISABLE_AA = (1 << 0), +} eText_Draw_Options; /* tw_flag (transform widget) */ /* gp_settings (Grease Pencil Settings) */ -#define GP_PAINT_DOSMOOTH (1<<0) -#define GP_PAINT_DOSIMPLIFY (1<<1) +typedef enum eGP_UserdefSettings { + GP_PAINT_DOSMOOTH = (1 << 0), + GP_PAINT_DOSIMPLIFY = (1 << 1), +} eGP_UserdefSettings; /* color picker types */ -#define USER_CP_CIRCLE 0 -#define USER_CP_SQUARE_SV 1 -#define USER_CP_SQUARE_HS 2 -#define USER_CP_SQUARE_HV 3 +typedef enum eColorPicker_Types { + USER_CP_CIRCLE = 0, + USER_CP_SQUARE_SV = 1, + USER_CP_SQUARE_HS = 2, + USER_CP_SQUARE_HV = 3, +} eColorPicker_Types; /* timecode display styles */ +typedef enum eTimecodeStyles { /* as little info as is necessary to show relevant info * with '+' to denote the frames * i.e. HH:MM:SS+FF, MM:SS+FF, SS+FF, or MM:SS */ -#define USER_TIMECODE_MINIMAL 0 + USER_TIMECODE_MINIMAL = 0, + /* reduced SMPTE - (HH:)MM:SS:FF */ -#define USER_TIMECODE_SMPTE_MSF 1 + USER_TIMECODE_SMPTE_MSF = 1, + /* full SMPTE - HH:MM:SS:FF */ -#define USER_TIMECODE_SMPTE_FULL 2 + USER_TIMECODE_SMPTE_FULL = 2, + /* milliseconds for sub-frames - HH:MM:SS.sss */ -#define USER_TIMECODE_MILLISECONDS 3 + USER_TIMECODE_MILLISECONDS = 3, + /* seconds only */ -#define USER_TIMECODE_SECONDS_ONLY 4 + USER_TIMECODE_SECONDS_ONLY = 4, +} eTimecodeStyles; /* theme drawtypes */ -#define TH_MINIMAL 0 -#define TH_ROUNDSHADED 1 -#define TH_ROUNDED 2 -#define TH_OLDSKOOL 3 -#define TH_SHADED 4 +/* XXX: These are probably only for the old UI engine? */ +typedef enum eTheme_DrawTypes { + TH_MINIMAL = 0, + TH_ROUNDSHADED = 1, + TH_ROUNDED = 2, + TH_OLDSKOOL = 3, + TH_SHADED = 4 +} eTheme_DrawTypes; /* ndof_flag (3D mouse options) */ -#define NDOF_SHOW_GUIDE (1 << 0) -#define NDOF_FLY_HELICOPTER (1 << 1) -#define NDOF_LOCK_HORIZON (1 << 2) -/* the following might not need to be saved between sessions, - * but they do need to live somewhere accessible... */ -#define NDOF_SHOULD_PAN (1 << 3) -#define NDOF_SHOULD_ZOOM (1 << 4) -#define NDOF_SHOULD_ROTATE (1 << 5) -/* orbit navigation modes - * only two options, so it's sort of a hybrid bool/enum - * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ - -// #define NDOF_ORBIT_MODE (1 << 6) -// #define NDOF_OM_TARGETCAMERA 0 -// #define NDOF_OM_OBJECT NDOF_ORBIT_MODE - -/* actually... users probably don't care about what the mode - * is called, just that it feels right */ -/* zoom is up/down if this flag is set (otherwise forward/backward) */ -#define NDOF_ZOOM_UPDOWN (1 << 7) -#define NDOF_ZOOM_INVERT (1 << 8) -#define NDOF_ROTATE_INVERT_AXIS (1 << 9) -#define NDOF_TILT_INVERT_AXIS (1 << 10) -#define NDOF_ROLL_INVERT_AXIS (1 << 11) -#define NDOF_PANX_INVERT_AXIS (1 << 12) -#define NDOF_PANY_INVERT_AXIS (1 << 13) -#define NDOF_PANZ_INVERT_AXIS (1 << 14) -#define NDOF_TURNTABLE (1 << 15) +typedef enum eNdof_Flag { + NDOF_SHOW_GUIDE = (1 << 0), + NDOF_FLY_HELICOPTER = (1 << 1), + NDOF_LOCK_HORIZON = (1 << 2), + + /* the following might not need to be saved between sessions, + * but they do need to live somewhere accessible... */ + NDOF_SHOULD_PAN = (1 << 3), + NDOF_SHOULD_ZOOM = (1 << 4), + NDOF_SHOULD_ROTATE = (1 << 5), + + /* orbit navigation modes + * only two options, so it's sort of a hybrid bool/enum + * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ + + // NDOF_ORBIT_MODE = (1 << 6), + // #define NDOF_OM_TARGETCAMERA 0 + // #define NDOF_OM_OBJECT NDOF_ORBIT_MODE + + /* actually... users probably don't care about what the mode + * is called, just that it feels right */ + /* zoom is up/down if this flag is set (otherwise forward/backward) */ + NDOF_ZOOM_UPDOWN = (1 << 7), + NDOF_ZOOM_INVERT = (1 << 8), + NDOF_ROTATE_INVERT_AXIS = (1 << 9), + NDOF_TILT_INVERT_AXIS = (1 << 10), + NDOF_ROLL_INVERT_AXIS = (1 << 11), + NDOF_PANX_INVERT_AXIS = (1 << 12), + NDOF_PANY_INVERT_AXIS = (1 << 13), + NDOF_PANZ_INVERT_AXIS = (1 << 14), + NDOF_TURNTABLE = (1 << 15), +} eNdof_Flag; /* compute_device_type */ -#define USER_COMPUTE_DEVICE_NONE 0 -#define USER_COMPUTE_DEVICE_OPENCL 1 -#define USER_COMPUTE_DEVICE_CUDA 2 +typedef enum eCompute_Device_Type { + USER_COMPUTE_DEVICE_NONE = 0, + USER_COMPUTE_DEVICE_OPENCL = 1, + USER_COMPUTE_DEVICE_CUDA = 2, +} eCompute_Device_Type; #ifdef __cplusplus } diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 9da10381af0..c83b0bc366f 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -169,6 +169,7 @@ typedef struct View3D { short view DNA_DEPRECATED; struct Object *camera, *ob_centre; + rctf render_border; struct ListBase bgpicbase; struct BGpic *bgpic DNA_DEPRECATED; /* deprecated, use bgpicbase, only kept for do_versions(...) */ @@ -267,6 +268,7 @@ typedef struct View3D { #define V3D_SHOW_CAMERAPATH 256 #define V3D_SHOW_BUNDLENAME 512 #define V3D_BACKFACE_CULLING 1024 +#define V3D_RENDER_BORDER 2048 /* View3D->around */ #define V3D_CENTER 0 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 780ca0b5878..2294abc0735 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -334,7 +334,7 @@ typedef struct wmOperator { #define OPERATOR_FLAGS_ALL ((1<<5)-1) /* sanity checks for debug mode only */ -#define OPERATOR_RETVAL_CHECK(ret) BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) +#define OPERATOR_RETVAL_CHECK(ret) (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) /* wmOperator flag */ #define OP_GRAB_POINTER 1 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 2041ee01d6e..24457f557b0 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -487,11 +487,15 @@ static int preprocess_include(char *maindata, int len) } /* do not copy when: */ - if (comment) ; - else if (cp[0] == ' ' && cp[1] == ' ') ; - else if (cp[-1] == '*' && cp[0] == ' ') ; /* pointers with a space */ - - /* skip special keywords */ + if (comment) { + /* pass */ + } + else if (cp[0] == ' ' && cp[1] == ' ') { + /* pass */ + } + else if (cp[-1] == '*' && cp[0] == ' ') { + /* pointers with a space */ + } /* skip special keywords */ else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) { /* single values are skipped already, so decrement 1 less */ a -= 13; @@ -1030,7 +1034,9 @@ static int make_structDNA(char *baseDirectory, FILE *file) if (debugSDNA > -1) printf("Writing file ... "); - if (nr_names == 0 || nr_structs == 0) ; + if (nr_names == 0 || nr_structs == 0) { + /* pass */ + } else { strcpy(str, "SDNA"); dna_write(file, str, 4); @@ -1090,7 +1096,9 @@ static int make_structDNA(char *baseDirectory, FILE *file) int a; fp = fopen("padding.c", "w"); - if (fp == NULL) ; + if (fp == NULL) { + /* pass */ + } else { /* add all include files defined in the global array */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index f6142f37248..89be5761fac 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1102,8 +1102,8 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property return NULL; /* only supported in case of standard next functions */ - if (strcmp(nextfunc, "rna_iterator_array_next") == 0) ; - else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) ; + if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {} + else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {} else return NULL; } @@ -1372,9 +1372,12 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; const char *nextfunc = (const char *)cprop->next; - if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) ; - else if (dp->dnalengthname || dp->dnalengthfixed) + if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) { + /* pass */ + } + else if (dp->dnalengthname || dp->dnalengthfixed) { cprop->length = (void *)rna_def_property_length_func(f, srna, prop, dp, (const char *)cprop->length); + } /* test if we can allow raw array access, if it is using our standard * array get/next function, we can be sure it is an actual array */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index c88944b4584..610895002aa 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -996,7 +996,7 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin IDProperty *item; item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE); - *hardmin = item ? (float)IDP_Double(item) : FLT_MIN; + *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX; item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE); *hardmax = item ? (float)IDP_Double(item) : FLT_MAX; @@ -3169,7 +3169,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro itemtype = RNA_property_type(iprop); } else { - BKE_reportf(reports, RPT_ERROR, "Property named %s not found", propname); + BKE_reportf(reports, RPT_ERROR, "Property named '%s' not found", propname); err = 1; break; } @@ -3606,7 +3606,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int /* copy string, taking into account escaped ] */ if (bracket) { for (p = *path, i = 0, j = 0; i < len; i++, p++) { - if (*p == '\\' && *(p + 1) == quote) ; + if (*p == '\\' && *(p + 1) == quote) {} else buf[j++] = *p; } diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index b3ef977a5c0..54e213c1ac6 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -287,6 +287,13 @@ static void rna_def_dopesheet(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + /* Debug Filtering Settings */ + prop = RNA_def_property(srna, "show_only_errors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLY_ERRORS); + RNA_def_property_ui_text(prop, "Show Errors", "Only include F-Curves and Drivers that are disabled or have errors"); + RNA_def_property_ui_icon(prop, ICON_HELP, 0); // XXX: this doesn't quite fit? + RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + /* Object Group Filtering Settings */ prop = RNA_def_property(srna, "show_only_group_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLYOBGROUP); diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c index 39128b48cd8..b93fd9daa36 100644 --- a/source/blender/makesrna/intern/rna_animation_api.c +++ b/source/blender/makesrna/intern/rna_animation_api.c @@ -60,7 +60,7 @@ static void rna_KeyingSet_context_refresh(KeyingSet *ks, bContext *C, ReportList break; case MODIFYKEY_MISSING_TYPEINFO: - BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set. Appears to be missing type info"); + BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set, appears to be missing type info"); break; } } diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index ceadaa036f1..fa43bf39319 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -103,7 +103,7 @@ static void rna_Armature_act_edit_bone_set(PointerRNA *ptr, PointerRNA value) static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, const char *name) { if (arm->edbo == NULL) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in editmode, cant add an editbone", arm->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot add an editbone", arm->id.name + 2); return NULL; } return ED_armature_edit_bone_add(arm, name); @@ -112,12 +112,12 @@ static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, static void rna_Armature_edit_bone_remove(bArmature *arm, ReportList *reports, EditBone *ebone) { if (arm->edbo == NULL) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in editmode, cant remove an editbone", arm->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot remove an editbone", arm->id.name + 2); return; } if (BLI_findindex(arm->edbo, ebone) == -1) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' doesn't contain bone '%s'", arm->id.name + 2, ebone->name); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' does not contain bone '%s'", arm->id.name + 2, ebone->name); return; } diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 4d33dc2f1e9..4de034b6407 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -505,13 +505,17 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain) Image *ima = (Image *) id; BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD); + WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); + WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id); } else if (GS(id->name) == ID_MC) { MovieClip *clip = (MovieClip *) id; BKE_movieclip_reload(clip); + WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, &clip->id); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, &clip->id); } } diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index c47cb8ef2af..ad05eff9568 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -62,9 +62,9 @@ EnumPropertyItem keyframe_handle_type_items[] = { }; EnumPropertyItem beztriple_interpolation_mode_items[] = { - {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", ""}, - {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""}, - {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""}, + {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", "No interpolation. Value of A gets held until B is encountered"}, + {BEZT_IPO_LIN, "LINEAR", 0, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"}, + {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"}, {0, NULL, 0, NULL, NULL} }; @@ -511,7 +511,7 @@ static void rna_Nurb_update_knot_v(Main *bmain, Scene *scene, PointerRNA *ptr) static void rna_Curve_spline_points_add(ID *id, Nurb *nu, ReportList *reports, int number) { if (nu->type == CU_BEZIER) { - BKE_report(reports, RPT_ERROR, "Bezier spline can't have points added"); + BKE_report(reports, RPT_ERROR, "Bezier spline cannot have points added"); } else if (number == 0) { /* do nothing */ @@ -581,7 +581,7 @@ static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, Nurb *nu) found = BLI_remlink_safe(nurbs, nu); if (!found) { - BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" does not contain spline given", cu->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Curve '%s' does not contain spline given", cu->id.name + 2); return; } @@ -721,7 +721,7 @@ static void rna_def_bpoint(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); /* Number values */ - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); @@ -808,13 +808,14 @@ static void rna_def_beztriple(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_points"); /* Number values */ - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "weight_softbody", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight"); RNA_def_property_range(prop, 0.01f, 100.0f); RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); @@ -1163,7 +1164,7 @@ static void rna_def_curve_spline_points(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_Curve_spline_points_add"); RNA_def_function_ui_description(func, "Add a number of points to this spline"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the spline", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); #if 0 func= RNA_def_function(srna, "remove", "rna_Curve_spline_remove"); @@ -1190,7 +1191,7 @@ static void rna_def_curve_spline_bezpoints(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_Curve_spline_bezpoints_add"); RNA_def_function_ui_description(func, "Add a number of points to this spline"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); - RNA_def_int(func, "count", 1, INT_MIN, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); #if 0 func = RNA_def_function(srna, "remove", "rna_Curve_spline_remove"); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 45092d09ce1..d4e0ba68d9d 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -46,6 +46,17 @@ #include "rna_internal.h" + +#ifdef DEBUG +# define ASSERT_SOFT_HARD_LIMITS \ + if (softmin < hardmin || softmax > hardmax) { \ + fprintf(stderr, "Error with soft/hard limits: %s.%s\n", CONTAINER_RNA_ID(cont), identifier); \ + BLI_assert(!"invalid soft/hard limits"); \ + } (void)0 +#else +# define ASSERT_SOFT_HARD_LIMITS (void)0 +#endif + /* Global used during defining */ BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1}; @@ -2248,12 +2259,15 @@ PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *iden return prop; } -PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, - int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax) +PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, + int hardmin, int hardmax, const char *ui_name, const char *ui_description, + int softmin, int softmax) { ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); RNA_def_property_int_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2270,6 +2284,8 @@ PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */ if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_int_array_default(prop, default_value); @@ -2287,6 +2303,8 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifie ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_int_array_default(prop, default_value); @@ -2426,6 +2444,8 @@ PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, f ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2442,6 +2462,8 @@ PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2472,6 +2494,8 @@ PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identif ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2489,10 +2513,9 @@ PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identi { ContainerRNA *cont = cont_; PropertyRNA *prop; - int length[2]; + const int length[2] = {rows, columns}; - length[0] = rows; - length[1] = columns; + ASSERT_SOFT_HARD_LIMITS; prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX); RNA_def_property_multi_array(prop, 2, length); @@ -2510,7 +2533,9 @@ PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *iden { ContainerRNA *cont = cont_; PropertyRNA *prop; - + + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len != 0) ? PROP_EULER : PROP_ANGLE); if (len != 0) { RNA_def_property_array(prop, len); @@ -2534,6 +2559,8 @@ PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identif ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2551,6 +2578,8 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *id ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2567,6 +2596,8 @@ PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 24b14fdb884..d899b5833bb 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -1497,7 +1497,7 @@ static void rna_def_fcurve_keyframe_points(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_FKeyframe_points_add"); RNA_def_function_ui_description(func, "Add a keyframe point to a F-Curve"); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the spline", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); func = RNA_def_function(srna, "remove", "rna_FKeyframe_points_remove"); RNA_def_function_ui_description(func, "Remove keyframe from an F-Curve"); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index bf7f4984ea1..b0fcfb9b540 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -111,6 +111,112 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); } +static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count) +{ + if (count > 0) { + if (stroke->points == NULL) + stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points"); + else + stroke->points = MEM_reallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count)); + + stroke->totpoints += count; + } +} + +static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports, int index) +{ + bGPDspoint *pt_tmp = stroke->points; + + /* python style negative indexing */ + if (index < 0) { + index += stroke->totpoints; + } + + if (stroke->totpoints <= index || index < 0) { + BKE_report(reports, RPT_ERROR, "GPencilStrokePoints.pop: index out of range"); + return; + } + + stroke->totpoints--; + + stroke->points = MEM_callocN(sizeof(bGPDspoint) * stroke->totpoints, "gp_stroke_points"); + + if (index > 0) + memcpy(stroke->points, pt_tmp, sizeof(bGPDspoint) * index); + + if (index < stroke->totpoints) + memcpy(&stroke->points[index], &pt_tmp[index + 1], sizeof(bGPDspoint) * (stroke->totpoints - index)); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame) +{ + bGPDstroke *stroke = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + + BLI_addtail(&frame->strokes, stroke); + + return stroke; +} + +static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, bGPDstroke *stroke) +{ + if (BLI_findindex(&frame->strokes, stroke) == -1) { + BKE_reportf(reports, RPT_ERROR, "Stroke not found in grease pencil frame"); + return; + } + + BLI_freelinkN(&frame->strokes, stroke); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, int frame_number) +{ + bGPDframe *frame; + + if (BKE_gpencil_layer_find_frame(layer, frame_number)) { + BKE_reportf(reports, RPT_ERROR, "Frame already exists on this frame number"); + return NULL; + } + + frame = gpencil_frame_addnew(layer, frame_number); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); + + return frame; +} + +static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, bGPDframe *frame) +{ + if (BLI_findindex(&layer->frames, frame) == -1) { + BKE_reportf(reports, RPT_ERROR, "Frame not found in grease pencil layer"); + return; + } + + gpencil_layer_delframe(layer, frame); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src) +{ + bGPDframe *frame = gpencil_frame_duplicate(src); + + while (BKE_gpencil_layer_find_frame(layer, frame->framenum)) { + frame->framenum++; + } + + BLI_addtail(&layer->frames, frame); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); + + return frame; +} + static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int setactive) { bGPDlayer *gl = gpencil_layer_addnew(gpd, name, setactive); @@ -122,14 +228,7 @@ static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int seta static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlayer *layer) { - bGPDlayer *gl; - - for (gl = gpd->layers.first; gl; gl = gl->next) { - if (gl == layer) - break; - } - - if (gl == NULL) { + if (BLI_findindex(&gpd->layers, layer) == -1) { BKE_reportf(reports, RPT_ERROR, "Layer not found in grease pencil data"); return; } @@ -139,6 +238,27 @@ static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlaye WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } +static void rna_GPencil_frame_clear(bGPDframe *frame) +{ + free_gpencil_strokes(frame); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + +static void rna_GPencil_layer_clear(bGPDlayer *layer) +{ + free_gpencil_frames(layer); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + +static void rna_GPencil_clear(bGPdata *gpd) +{ + free_gpencil_layers(&gpd->layers); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + #else static void rna_def_gpencil_stroke_point(BlenderRNA *brna) @@ -154,19 +274,49 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "x"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Coordinates", ""); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "pressure"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); +} + +static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + /* PropertyRNA *parm; */ + + RNA_def_property_srna(cprop, "GPencilStrokePoints"); + srna = RNA_def_struct(brna, "GPencilStrokePoints", NULL); + RNA_def_struct_sdna(srna, "bGPDstroke"); + RNA_def_struct_ui_text(srna, "Grease Pencil Stroke Points", "Collection of grease pencil stroke points"); + + func = RNA_def_function(srna, "add", "rna_GPencil_stroke_point_add"); + RNA_def_function_ui_description(func, "Add a new grease pencil stroke point"); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the stroke", 0, INT_MAX); + + func = RNA_def_function(srna, "pop", "rna_GPencil_stroke_point_pop"); + RNA_def_function_ui_description(func, "Remove a grease pencil stroke point"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "Index", "point index", INT_MIN, INT_MAX); } static void rna_def_gpencil_stroke(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + static EnumPropertyItem stroke_draw_mode_items[] = { + {0, "SCREEN", 0, "Screen", "Stroke is in screen-space"}, + {GP_STROKE_3DSPACE, "3DSPACE", 0, "3D Space", "Stroke is in 3D-space"}, + {GP_STROKE_2DSPACE, "2DSPACE", 0, "2D Space", "Stroke is in 2D-space"}, + {GP_STROKE_2DIMAGE, "2DIMAGE", 0, "2D Image", "Stroke is in 2D-space (but with special 'image' scaling)"}, + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "GPencilStroke", NULL); RNA_def_struct_sdna(srna, "bGPDstroke"); @@ -177,15 +327,45 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "points", "totpoints"); RNA_def_property_struct_type(prop, "GPencilStrokePoint"); RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points"); - - /* Flags - Readonly type-info really... */ - /* TODO... */ + rna_def_gpencil_stroke_points_api(brna, prop); + + prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, stroke_draw_mode_items); + RNA_def_property_ui_text(prop, "Draw Mode", ""); + RNA_def_property_update(prop, 0, "rna_GPencil_update"); +} + +static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "GPencilStrokes"); + srna = RNA_def_struct(brna, "GPencilStrokes", NULL); + RNA_def_struct_sdna(srna, "bGPDframe"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames"); + + func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new"); + RNA_def_function_ui_description(func, "Add a new grease pencil frame"); + parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_GPencil_stroke_remove"); + RNA_def_function_ui_description(func, "Remove a grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); } static void rna_def_gpencil_frame(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + FunctionRNA *func; srna = RNA_def_struct(brna, "GPencilFrame", NULL); RNA_def_struct_sdna(srna, "bGPDframe"); @@ -196,7 +376,8 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "strokes", NULL); RNA_def_property_struct_type(prop, "GPencilStroke"); RNA_def_property_ui_text(prop, "Strokes", "Freehand curves defining the sketch on this frame"); - + rna_def_gpencil_strokes_api(brna, prop); + /* Frame Number */ prop = RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "framenum"); @@ -211,12 +392,51 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT); RNA_def_property_ui_text(prop, "Select", "Frame is selected for editing in the DopeSheet"); + + func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil frame data"); +} + +static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "GPencilFrames"); + srna = RNA_def_struct(brna, "GPencilFrames", NULL); + RNA_def_struct_sdna(srna, "bGPDlayer"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames"); + + func = RNA_def_function(srna, "new", "rna_GPencil_frame_new"); + RNA_def_function_ui_description(func, "Add a new grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_int(func, "frame_number", 1, MINFRAME, MAXFRAME, "Frame Number", "The frame on which this sketch appears", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_pointer(func, "frame", "GPencilFrame", "", "The newly created frame"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_GPencil_frame_remove"); + RNA_def_function_ui_description(func, "Remove a grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "frame", "GPencilFrame", "Frame", "The frame to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + + func = RNA_def_function(srna, "copy", "rna_GPencil_frame_copy"); + RNA_def_function_ui_description(func, "Copy a grease pencil frame"); + parm = RNA_def_pointer(func, "source", "GPencilFrame", "Source", "The source frame"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_pointer(func, "copy", "GPencilFrame", "", "The newly copied frame"); + RNA_def_function_return(func, parm); } static void rna_def_gpencil_layer(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + FunctionRNA *func; srna = RNA_def_struct(brna, "GPencilLayer", NULL); RNA_def_struct_sdna(srna, "bGPDlayer"); @@ -234,7 +454,8 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "frames", NULL); RNA_def_property_struct_type(prop, "GPencilFrame"); RNA_def_property_ui_text(prop, "Frames", "Sketches for this layer on different frames"); - + rna_def_gpencil_frames_api(brna, prop); + /* Active Frame */ prop = RNA_def_property(srna, "active_frame", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "actframe"); @@ -317,9 +538,12 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY); RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil layer data"); } -static void rna_def_gpencil_layers(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; PropertyRNA *prop; @@ -357,7 +581,8 @@ static void rna_def_gpencil_data(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + FunctionRNA *func; + static EnumPropertyItem draw_mode_items[] = { {GP_DATA_VIEWALIGN, "CURSOR", 0, "Cursor", "Draw stroke at the 3D cursor"}, {0, "VIEW", 0, "View", "Stick stroke to the view "}, /* weird, GP_DATA_VIEWALIGN is inverted */ @@ -376,7 +601,7 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); RNA_def_property_struct_type(prop, "GPencilLayer"); RNA_def_property_ui_text(prop, "Layers", ""); - rna_def_gpencil_layers(brna, prop); + rna_def_gpencil_layers_api(brna, prop); /* Flags */ prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); @@ -390,6 +615,8 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + func = RNA_def_function(srna, "clear", "rna_GPencil_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil data"); } /* --- */ diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index 586b71aa2da..4baf46fd0b5 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -54,7 +54,7 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter) static void rna_Group_objects_link(Group *group, bContext *C, ReportList *reports, Object *object) { if (!add_to_group(group, object, CTX_data_scene(C), NULL)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" already in group \"%s\"", object->id.name + 2, group->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' already in group '%s'", object->id.name + 2, group->id.name + 2); return; } @@ -64,7 +64,7 @@ static void rna_Group_objects_link(Group *group, bContext *C, ReportList *report static void rna_Group_objects_unlink(Group *group, bContext *C, ReportList *reports, Object *object) { if (!rem_from_group(group, object, CTX_data_scene(C), NULL)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" not in group \"%s\"", object->id.name + 2, group->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in group '%s'", object->id.name + 2, group->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 7766dff4273..d8ae579cd6b 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -184,7 +184,10 @@ static void rna_Image_update(Image *image, ReportList *reports) return; } - IMB_rect_from_float(ibuf); + if (ibuf->rect) + IMB_rect_from_float(ibuf); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } static void rna_Image_scale(Image *image, ReportList *reports, int width, int height) @@ -297,9 +300,9 @@ void RNA_api_image(StructRNA *srna) func = RNA_def_function(srna, "scale", "rna_Image_scale"); RNA_def_function_ui_description(func, "Scale the image in pixels"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_int(func, "width", 0, 1, 10000, "", "Width", 1, 10000); + parm = RNA_def_int(func, "width", 1, 1, 10000, "", "Width", 1, 10000); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "height", 0, 1, 10000, "", "Height", 1, 10000); + parm = RNA_def_int(func, "height", 1, 1, 10000, "", "Height", 1, 10000); RNA_def_property_flag(parm, PROP_REQUIRED); func = RNA_def_function(srna, "gl_touch", "rna_Image_gl_touch"); diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c index d4082cf3d9f..e4a29d9c674 100644 --- a/source/blender/makesrna/intern/rna_lattice.c +++ b/source/blender/makesrna/intern/rna_lattice.c @@ -240,6 +240,12 @@ static void rna_def_latticepoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Deformed Location", ""); RNA_def_property_update(prop, 0, "rna_Lattice_update_data"); + prop = RNA_def_property(srna, "weight_softbody", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight"); + RNA_def_property_range(prop, 0.01f, 100.0f); + RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); + RNA_def_property_update(prop, 0, "rna_Lattice_update_data"); + prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_LatticePoint_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", @@ -320,7 +326,7 @@ static void rna_def_lattice(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, "rna_Lattice_points_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Points", "Points of the lattice"); - + /* pointers */ rna_def_animdata_common(srna); } diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 3485f6b2528..b77af6988ec 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -71,6 +71,7 @@ #include "BKE_speaker.h" #include "BKE_movieclip.h" #include "BKE_mask.h" +#include "BKE_gpencil.h" #include "BKE_linestyle.h" #include "DNA_armature_types.h" @@ -93,9 +94,12 @@ #include "DNA_node_types.h" #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" +#include "DNA_gpencil_types.h" #include "ED_screen.h" +#include "BLF_translation.h" + static Camera *rna_Main_cameras_new(Main *UNUSED(bmain), const char *name) { ID *id = BKE_camera_add(name); @@ -107,7 +111,7 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, struct Cam if (ID_REAL_USERS(camera) <= 0) BKE_libblock_free(&bmain->camera, camera); else - BKE_reportf(reports, RPT_ERROR, "Camera \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Camera '%s' must have zero users to be removed, found %d", camera->id.name + 2, ID_REAL_USERS(camera)); /* XXX python now has invalid pointer? */ @@ -127,7 +131,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports else if (scene->id.next) newscene = scene->id.next; else { - BKE_reportf(reports, RPT_ERROR, "Scene \"%s\" is the last, cant ve removed", scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2); return; } @@ -174,7 +178,7 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co if (RNA_enum_id_from_value(id_type_items, GS(data->name), &idname) == 0) idname = "UNKNOWN"; - BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for a object", idname); + BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for an object", idname); return NULL; } } @@ -198,7 +202,7 @@ static void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Obj BKE_libblock_free(&bmain->object, object); } else { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Object '%s' must have zero users to be removed, found %d", object->id.name + 2, ID_REAL_USERS(object)); } } @@ -214,7 +218,7 @@ static void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct M if (ID_REAL_USERS(material) <= 0) BKE_libblock_free(&bmain->mat, material); else - BKE_reportf(reports, RPT_ERROR, "Material \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Material '%s' must have zero users to be removed, found %d", material->id.name + 2, ID_REAL_USERS(material)); /* XXX python now has invalid pointer? */ @@ -232,7 +236,7 @@ static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, struct bN if (ID_REAL_USERS(tree) <= 0) BKE_libblock_free(&bmain->nodetree, tree); else - BKE_reportf(reports, RPT_ERROR, "Node Tree \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d", tree->id.name + 2, ID_REAL_USERS(tree)); /* XXX python now has invalid pointer? */ @@ -249,7 +253,7 @@ void rna_Main_meshes_remove(Main *bmain, ReportList *reports, Mesh *mesh) if (ID_REAL_USERS(mesh) <= 0) BKE_libblock_free(&bmain->mesh, mesh); else - BKE_reportf(reports, RPT_ERROR, "Mesh \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d", mesh->id.name + 2, ID_REAL_USERS(mesh)); /* XXX python now has invalid pointer? */ @@ -267,7 +271,7 @@ static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, Lamp *lamp) if (ID_REAL_USERS(lamp) <= 0) BKE_libblock_free(&bmain->lamp, lamp); else - BKE_reportf(reports, RPT_ERROR, "Lamp \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Lamp '%s' must have zero users to be removed, found %d", lamp->id.name + 2, ID_REAL_USERS(lamp)); /* XXX python now has invalid pointer? */ @@ -288,8 +292,8 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con ima = BKE_image_load(filepath); if (!ima) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unsupported image format"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unsupported image format")); return ima; } @@ -298,7 +302,7 @@ static void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *imag if (ID_REAL_USERS(image) <= 0) BKE_libblock_free(&bmain->image, image); else - BKE_reportf(reports, RPT_ERROR, "Image \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d", image->id.name + 2, ID_REAL_USERS(image)); /* XXX python now has invalid pointer? */ @@ -315,7 +319,7 @@ static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, struct La if (ID_REAL_USERS(lt) <= 0) BKE_libblock_free(&bmain->latt, lt); else - BKE_reportf(reports, RPT_ERROR, "Lattice \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Lattice '%s' must have zero users to be removed, found %d", lt->id.name + 2, ID_REAL_USERS(lt)); } @@ -330,7 +334,7 @@ static void rna_Main_curves_remove(Main *bmain, ReportList *reports, struct Curv if (ID_REAL_USERS(cu) <= 0) BKE_libblock_free(&bmain->curve, cu); else - BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Curve '%s' must have zero users to be removed, found %d", cu->id.name + 2, ID_REAL_USERS(cu)); } @@ -345,7 +349,7 @@ static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, struct M if (ID_REAL_USERS(mb) <= 0) BKE_libblock_free(&bmain->mball, mb); else - BKE_reportf(reports, RPT_ERROR, "Metaball \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Metaball '%s' must have zero users to be removed, found %d", mb->id.name + 2, ID_REAL_USERS(mb)); } @@ -357,8 +361,8 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char * font = BKE_vfont_load(bmain, filepath); if (!font) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unsupported font format"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unsupported font format")); return font; @@ -368,7 +372,7 @@ static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, VFont *vfont if (ID_REAL_USERS(vfont) <= 0) BKE_libblock_free(&bmain->vfont, vfont); else - BKE_reportf(reports, RPT_ERROR, "Font \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Font '%s' must have zero users to be removed, found %d", vfont->id.name + 2, ID_REAL_USERS(vfont)); /* XXX python now has invalid pointer? */ @@ -386,7 +390,7 @@ static void rna_Main_textures_remove(Main *bmain, ReportList *reports, struct Te if (ID_REAL_USERS(tex) <= 0) BKE_libblock_free(&bmain->tex, tex); else - BKE_reportf(reports, RPT_ERROR, "Texture \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Texture '%s' must have zero users to be removed, found %d", tex->id.name + 2, ID_REAL_USERS(tex)); } @@ -401,7 +405,7 @@ static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, struct Bru if (ID_REAL_USERS(brush) <= 0) BKE_libblock_free(&bmain->brush, brush); else - BKE_reportf(reports, RPT_ERROR, "Brush \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Brush '%s' must have zero users to be removed, found %d", brush->id.name + 2, ID_REAL_USERS(brush)); } @@ -416,7 +420,7 @@ static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, struct Worl if (ID_REAL_USERS(world) <= 0) BKE_libblock_free(&bmain->world, world); else - BKE_reportf(reports, RPT_ERROR, "World \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "World '%s' must have zero users to be removed, found %d", world->id.name + 2, ID_REAL_USERS(world)); } @@ -442,7 +446,7 @@ static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, Speaker * if (ID_REAL_USERS(speaker) <= 0) BKE_libblock_free(&bmain->speaker, speaker); else - BKE_reportf(reports, RPT_ERROR, "Speaker \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Speaker '%s' must have zero users to be removed, found %d", speaker->id.name + 2, ID_REAL_USERS(speaker)); /* XXX python now has invalid pointer? */ @@ -467,8 +471,8 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f txt = BKE_text_load(filepath, bmain->name); if (!txt) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unable to load text"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to load text")); return txt; } @@ -484,7 +488,7 @@ static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, bArmatur if (ID_REAL_USERS(arm) <= 0) BKE_libblock_free(&bmain->armature, arm); else - BKE_reportf(reports, RPT_ERROR, "Armature \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Armature '%s' must have zero users to be removed, found %d", arm->id.name + 2, ID_REAL_USERS(arm)); /* XXX python now has invalid pointer? */ @@ -502,7 +506,7 @@ static void rna_Main_actions_remove(Main *bmain, ReportList *reports, bAction *a if (ID_REAL_USERS(act) <= 0) BKE_libblock_free(&bmain->action, act); else - BKE_reportf(reports, RPT_ERROR, "Action \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Action '%s' must have zero users to be removed, found %d", act->id.name + 2, ID_REAL_USERS(act)); /* XXX python now has invalid pointer? */ @@ -519,7 +523,7 @@ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, Particle if (ID_REAL_USERS(part) <= 0) BKE_libblock_free(&bmain->particle, part); else - BKE_reportf(reports, RPT_ERROR, "Particle Settings \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Particle settings '%s' must have zero users to be removed, found %d", part->id.name + 2, ID_REAL_USERS(part)); /* XXX python now has invalid pointer? */ @@ -533,8 +537,8 @@ static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *repor clip = BKE_movieclip_file_add(filepath); if (!clip) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s.", filepath, - errno ? strerror(errno) : "Unable to load movie clip"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to load movie clip")); return clip; } @@ -562,6 +566,19 @@ static void rna_Main_masks_remove(Main *bmain, Mask *mask) /* XXX python now has invalid pointer? */ } +static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, bGPdata *gpd) +{ + if (ID_REAL_USERS(gpd) <= 0) { + BKE_gpencil_free(gpd); + BKE_libblock_free(&bmain->gpencil, gpd); + } + else + BKE_reportf(reports, RPT_ERROR, "Grease Pencil '%s' must have zero users to be removed, found %d", + gpd->id.name + 2, ID_REAL_USERS(gpd)); + + /* XXX python now has invalid pointer? */ +} + FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char* name) { FreestyleLineStyle *linestyle = FRS_new_linestyle(name, bmain); @@ -994,9 +1011,9 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Add a new image to the main database"); parm = RNA_def_string(func, "name", "Image", 0, "", "New name for the datablock"); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "width", 1024, 1, INT_MAX, "", "Width of the image", 0, INT_MAX); + parm = RNA_def_int(func, "width", 1024, 1, INT_MAX, "", "Width of the image", 1, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "height", 1024, 1, INT_MAX, "", "Height of the image", 0, INT_MAX); + parm = RNA_def_int(func, "height", 1024, 1, INT_MAX, "", "Height of the image", 1, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "alpha", 0, "Alpha", "Use alpha channel"); RNA_def_boolean(func, "float_buffer", 0, "Float Buffer", "Create an image with floating point color"); @@ -1528,6 +1545,20 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + func = RNA_def_function(srna, "new", "gpencil_data_addnew"); + RNA_def_function_flag(func, FUNC_NO_SELF); + parm = RNA_def_string(func, "name", "GreasePencil", 0, "", "New name for the datablock"); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "New grease pencil datablock"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Main_grease_pencil_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove a grease pencil instance from the current blendfile"); + parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "Grease Pencil to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Main_gpencil_is_updated_get", NULL); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 96529de074b..a2fbada3cc1 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -319,7 +319,7 @@ MTex *rna_mtex_texture_slots_add(ID *self_id, struct bContext *C, ReportList *re { MTex *mtex = add_mtex_id(self_id, -1); if (mtex == NULL) { - BKE_reportf(reports, RPT_ERROR, "maximum number of textures added %d", MAX_MTEX); + BKE_reportf(reports, RPT_ERROR, "Maximum number of textures added %d", MAX_MTEX); return NULL; } @@ -334,7 +334,7 @@ MTex *rna_mtex_texture_slots_create(ID *self_id, struct bContext *C, ReportList MTex *mtex; if (index < 0 || index >= MAX_MTEX) { - BKE_reportf(reports, RPT_ERROR, "index %d is invalid", index); + BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index); return NULL; } @@ -354,12 +354,12 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r give_active_mtex(self_id, &mtex_ar, &act); if (mtex_ar == NULL) { - BKE_report(reports, RPT_ERROR, "mtex not found for this type"); + BKE_report(reports, RPT_ERROR, "Mtex not found for this type"); return; } if (index < 0 || index >= MAX_MTEX) { - BKE_reportf(reports, RPT_ERROR, "index %d is invalid", index); + BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index); return; } @@ -468,6 +468,12 @@ static void rna_def_material_mtex(BlenderRNA *brna) "from their parent"); RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_map_to_bounds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_MAPTO_BOUNDS); + RNA_def_property_ui_text(prop, "Map to Bounds", + "Map coordinates in object bounds"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_from_original", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_OB_DUPLI_ORIG); RNA_def_property_ui_text(prop, "From Original", @@ -1817,7 +1823,12 @@ void RNA_def_material(BlenderRNA *brna) "Material uses the light group exclusively - these lamps are excluded " "from other scene lighting"); RNA_def_property_update(prop, 0, "rna_Material_update"); - + + prop= RNA_def_property(srna, "use_light_group_local", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_GROUP_LOCAL); + RNA_def_property_ui_text(prop, "Light Group Local", "When linked in, Material uses local light group with the same name"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRACEBLE); RNA_def_property_ui_text(prop, "Traceable", diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index df73fcd96dd..5ddf2073f19 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1275,12 +1275,12 @@ static PointerRNA rna_Mesh_tessface_vertex_color_new(struct Mesh *me, struct bCo int index; if (me->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessface colors's in editmode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface colors in edit mode"); return PointerRNA_NULL; } if (me->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessface colors's when MPoly's exist"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface colors when MPoly's exist"); return PointerRNA_NULL; } @@ -1368,12 +1368,12 @@ static PointerRNA rna_Mesh_tessface_uv_texture_new(struct Mesh *me, struct bCont int index; if (me->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessface uv's in editmode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's in edit mode"); return PointerRNA_NULL; } if (me->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessface uv's when MPoly's exist"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's when MPoly's exist"); return PointerRNA_NULL; } diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index c8b52b45604..fe2c29632f2 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -133,7 +133,7 @@ static void rna_MetaBall_elements_remove(MetaBall *mb, ReportList *reports, Meta found = BLI_remlink_safe(&mb->elems, ml); if (!found) { - BKE_reportf(reports, RPT_ERROR, "Metaball \"%s\" does not contain spline given", mb->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Metaball '%s' does not contain spline given", mb->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 1b26c0447ff..8a8bb2a2384 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -257,9 +257,6 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) { SmokeModifierData *smd = (SmokeModifierData *)ptr->data; Object *ob = (Object *)ptr->id.data; - ParticleSystemModifierData *psmd = NULL; - ParticleSystem *psys = NULL; - ParticleSettings *part = NULL; /* nothing changed */ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) @@ -273,28 +270,6 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) ob->dt = OB_WIRE; break; case MOD_SMOKE_TYPE_FLOW: - for (psys = ob->particlesystem.first; psys; psys = psys->next) - if (psys->part->type == PART_EMITTER) - break; - if (ob->type == OB_MESH && !psys) { - /* add particle system */ - psmd = (ParticleSystemModifierData *)object_add_particle_system(scene, ob, NULL); - if (psmd) { - psys = psmd->psys; - part = psys->part; - part->lifetime = 1.0f; - part->sta = 1.0f; - part->end = 250.0f; - part->ren_as = PART_DRAW_NOT; - part->flag |= PART_UNBORN; - part->draw_as = PART_DRAW_DOT; - BLI_strncpy(psys->name, "SmokeParticles", sizeof(psys->name)); - psys->recalc |= (PSYS_RECALC_RESET | PSYS_RECALC_PHYS); - DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); - } - } - if (smd->flow) - smd->flow->psys = psys; case MOD_SMOKE_TYPE_COLL: case 0: default: diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 4ff1365427e..8378cb92e20 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -302,7 +302,7 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo NlaStrip *strip = add_nlastrip(action); if (strip == NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to create new strip"); + BKE_report(reports, RPT_ERROR, "Unable to create new strip"); return NULL; } @@ -310,8 +310,8 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo strip->start = start; if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) { - BKE_reportf(reports, RPT_ERROR, - "Unable to add strip. Track doesn't have any space to accommodate this new strip"); + BKE_report(reports, RPT_ERROR, + "Unable to add strip (the track does not have any space to accommodate this new strip)"); free_nlastrip(NULL, strip); return NULL; } @@ -348,7 +348,7 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *reports, NlaStrip *strip) { if (BLI_findindex(&track->strips, strip) == -1) { - BKE_reportf(reports, RPT_ERROR, "NLA's Strip '%s' not found in track '%s'", strip->name, track->name); + BKE_reportf(reports, RPT_ERROR, "NLA strip '%s' not found in track '%s'", strip->name, track->name); return; } else { diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d650c8dbf69..0d7d20d04ae 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -689,7 +689,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r bNodeTemplate ntemp; if (type == NODE_GROUP && group == NULL) { - BKE_reportf(reports, RPT_ERROR, "node type \'GROUP\' missing group argument"); + BKE_report(reports, RPT_ERROR, "Node type 'GROUP' missing group argument"); return NULL; } @@ -700,7 +700,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r node = nodeAddNode(ntree, &ntemp); if (node == NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to create node"); + BKE_report(reports, RPT_ERROR, "Unable to create node"); } else { ntreeUpdateTree(ntree); /* update group node socket links*/ @@ -756,7 +756,7 @@ static bNode *rna_NodeTree_node_texture_new(bNodeTree *ntree, bContext *C, Repor static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, bNode *node) { if (BLI_findindex(&ntree->nodes, node) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in nodetree", node->name); + BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name); } else { if (node->id) @@ -800,7 +800,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, nodeFindNode(ntree, tosock, &tonode, NULL, &to_in_out); if (&from_in_out == &to_in_out) { - BKE_reportf(reports, RPT_ERROR, "Same input/output direction of sockets"); + BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets"); return NULL; } @@ -827,7 +827,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNodeLink *link) { if (BLI_findindex(&ntree->links, link) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate link in nodetree"); + BKE_report(reports, RPT_ERROR, "Unable to locate link in node tree"); } else { nodeRemLink(ntree, link); @@ -882,9 +882,9 @@ static bNodeSocket *rna_NodeTree_input_expose(bNodeTree *ntree, ReportList *repo int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_IN) - BKE_reportf(reports, RPT_ERROR, "Socket is not an input"); + BKE_report(reports, RPT_ERROR, "Socket is not an input"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_IN); @@ -906,9 +906,9 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_OUT) - BKE_reportf(reports, RPT_ERROR, "Socket is not an output"); + BKE_report(reports, RPT_ERROR, "Socket is not an output"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_OUT); @@ -1462,7 +1462,8 @@ static void def_sh_tex_sky(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE); - RNA_def_property_ui_text(prop, "Turbidity", ""); + RNA_def_property_range(prop, 1.0f, 30.0f); + RNA_def_property_ui_text(prop, "Turbidity", "Atmospheric turbidity"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index db1e1e16adf..6d97e959112 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -67,6 +67,7 @@ DefNode( ShaderNode, SH_NODE_ADD_SHADER, 0, "AD DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATTRIBUTE", Attribute, "Attribute", "" ) DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" ) DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" ) +DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass Bsdf", "" ) @@ -81,6 +82,7 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" ) DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" ) DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" ) +DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" ) DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" ) DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" ) @@ -91,7 +93,7 @@ DefNode( ShaderNode, SH_NODE_TEX_WAVE, def_sh_tex_wave, "TE DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TEX_MUSGRAVE", TexMusgrave, "Musgrave Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) -DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) +DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 879a77527cd..3204dc8e6bc 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -158,7 +158,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { BKE_libblock_free_us(&(G.main->object), tmpobj); - BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); + BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)"); return NULL; } @@ -351,7 +351,7 @@ void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, in /* free duplilist if a user forgets to */ if (ob->duplilist) { - BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed"); + BKE_report(reports, RPT_WARNING, "Object.dupli_list has not been freed"); free_object_duplilist(ob->duplilist); ob->duplilist = NULL; @@ -387,7 +387,7 @@ static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList * return keyptr; } else { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\"does not support shapes", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' does not support shapes", ob->id.name + 2); return PointerRNA_NULL; } } @@ -402,14 +402,14 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int float weight, int assignmode) { if (ob->type != OB_MESH) { - BKE_report(reports, RPT_ERROR, "Object should be of MESH type"); + BKE_report(reports, RPT_ERROR, "Object should be of mesh type"); return; } Mesh *me = (Mesh *)ob->data; int group_index = BLI_findlink(&ob->defbase, group); if (group_index == -1) { - BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh"); + BKE_report(reports, RPT_ERROR, "No vertex groups assigned to mesh"); return; } @@ -441,7 +441,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start BVHTreeFromMesh treeData = {NULL}; if (ob->derivedFinal == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for ray casting", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for ray casting", ob->id.name + 2); return; } @@ -449,7 +449,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6); if (treeData.tree == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for ray casting", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' could not create internal data for ray casting", ob->id.name + 2); return; } else { @@ -483,7 +483,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl BVHTreeFromMesh treeData = {NULL}; if (ob->derivedFinal == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for finding nearest point", + BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for finding nearest point", ob->id.name + 2); return; } @@ -492,7 +492,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6); if (treeData.tree == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for finding nearest point", + BKE_reportf(reports, RPT_ERROR, "Object '%s' could not create internal data for finding nearest point", ob->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 1c896133408..940d59ec9b3 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -1056,6 +1056,13 @@ static void rna_def_effector_weight(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Drag", "Drag effector weight"); RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop = RNA_def_property(srna, "smokeflow", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[13]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Smoke Flow", "Smoke Flow effector weight"); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); } static void rna_def_field(BlenderRNA *brna) @@ -1082,6 +1089,7 @@ static void rna_def_field(BlenderRNA *brna) {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", "Create turbulence with a noise field"}, {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", "Create a force that dampens motion"}, + {PFIELD_SMOKEFLOW, "SMOKE_FLOW", ICON_FORCE_SMOKEFLOW, "Smoke Flow", "Create a force based on smoke simulation air flow"}, {0, NULL, 0, NULL, NULL} }; @@ -1307,7 +1315,7 @@ static void rna_def_field(BlenderRNA *brna) prop = RNA_def_property(srna, "use_2d_force", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_2D); - RNA_def_property_ui_text(prop, "2D", "Apply force only in 2d"); + RNA_def_property_ui_text(prop, "2D", "Apply force only in 2D"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); prop = RNA_def_property(srna, "use_root_coords", PROP_BOOLEAN, PROP_NONE); @@ -1334,6 +1342,11 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_MULTIPLE_SPRINGS); RNA_def_property_ui_text(prop, "Multiple Springs", "Every point is effected by multiple springs"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop = RNA_def_property(srna, "use_smoke_density", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_SMOKE_DENSITY); + RNA_def_property_ui_text(prop, "Apply Density", "Adjust force strength based on smoke density"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /* Pointer */ @@ -1342,6 +1355,12 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Texture", "Texture to use as force"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop = RNA_def_property(srna, "source_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "f_source"); + RNA_def_property_ui_text(prop, "Domain Object", "Select domain object of the smoke simulation"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /********** Curve Guide Field Settings **********/ diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index d2e4e8edbfb..736753894d1 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -160,7 +160,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo return NULL; if (strlen(identifier) >= sizeof(dummyet.idname)) { - BKE_reportf(reports, RPT_ERROR, "registering render engine class: '%s' is too long, maximum length is %d", + BKE_reportf(reports, RPT_ERROR, "Registering render engine class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyet.idname)); return NULL; } @@ -329,7 +329,6 @@ static void rna_def_render_engine(BlenderRNA *brna) prop = RNA_def_pointer(func, "result", "RenderResult", "Result", ""); RNA_def_property_flag(prop, PROP_REQUIRED); prop = RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results"); - RNA_def_property_flag(prop, PROP_REQUIRED); func = RNA_def_function(srna, "test_break", "RE_engine_test_break"); prop = RNA_def_boolean(func, "do_break", 0, "Break", ""); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 62ba3a7e663..24f17034ea1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -360,7 +360,7 @@ static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *report Base *base; if (BKE_scene_base_find(scene, ob)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\"", ob->id.name + 2, scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in scene '%s'", ob->id.name + 2, scene->id.name + 2); return NULL; } @@ -392,7 +392,7 @@ static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *o return; } if (base == scene->basact && ob->mode != OB_MODE_OBJECT) { - BKE_reportf(reports, RPT_ERROR, "Object '%s' must be in 'Object Mode' to unlink", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' must be in object mode to unlink", ob->id.name + 2); return; } if (scene->basact == base) { @@ -1329,7 +1329,7 @@ static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[]) static void rna_TimeLine_remove(Scene *scene, ReportList *reports, TimeMarker *marker) { if (!BLI_remlink_safe(&scene->markers, marker)) { - BKE_reportf(reports, RPT_ERROR, "TimelineMarker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); return; } @@ -1360,7 +1360,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons return ks; } else { - BKE_report(reports, RPT_ERROR, "Keying Set could not be added"); + BKE_report(reports, RPT_ERROR, "Keying set could not be added"); return NULL; } } @@ -4042,14 +4042,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR); RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "mblur_samples"); RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text(prop, "Motion Samples", "Number of scene samples to take with motion blur"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "blurfac"); @@ -4057,7 +4057,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.01, 2.0f, 1, 0); RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); /* border */ prop = RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index f63ef6c8d76..067589ca543 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -234,9 +234,10 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor } #else /* WITH_AUDASPACE */ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports, - const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), int UNUSED(start_frame)) + const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), + int UNUSED(start_frame)) { - BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support."); + BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support"); return NULL; } #endif /* WITH_AUDASPACE */ @@ -249,39 +250,37 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor Scene *scene = (Scene *)id; Sequence *seq; struct SeqEffectHandle sh; + int num_inputs = BKE_sequence_effect_get_num_inputs(type); - switch (BKE_sequence_effect_get_num_inputs(type)) { + switch (num_inputs) { case 0: if (end_frame <= start_frame) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: End frame not set"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set"); return NULL; } break; case 1: if (seq1 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 1 input sequence"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 1 input sequence"); return NULL; } break; case 2: if (seq1 == NULL || seq2 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 2 input sequences"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 2 input sequences"); return NULL; } break; case 3: if (seq1 == NULL || seq2 == NULL || seq3 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 3 input sequences"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 3 input sequences"); return NULL; } break; default: - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: BKE_sequence_effect_get_num_inputs() > 3 (should never happen)"); + BKE_reportf(reports, RPT_ERROR, + "Sequences.new_effect: effect expects more than 3 inputs (%d, should never happen!)", + num_inputs); return NULL; } @@ -456,7 +455,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_clip", "rna_Sequences_new_clip"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -472,8 +471,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_mask", "rna_Sequences_new_mask"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_function_ui_description(func, "Add a new mask sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -490,7 +489,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_scene", "rna_Sequences_new_scene"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new scene sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -507,7 +506,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_image", "rna_Sequences_new_image"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new image sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to image"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -524,7 +523,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_movie", "rna_Sequences_new_movie"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new movie sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -540,8 +539,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_sound", "rna_Sequences_new_sound"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID | FUNC_USE_MAIN); - RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_function_ui_description(func, "Add a new sound sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -558,7 +557,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_effect", "rna_Sequences_new_effect"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new effect sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_enum(func, "type", seq_effect_items, 0, "Type", "type for the new sequence"); diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index e8818248609..faad2407516 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -65,14 +65,20 @@ static void rna_Smoke_dependency_update(Main *bmain, Scene *scene, PointerRNA *p DAG_scene_sort(bmain, scene); } +static void rna_Smoke_resetCache(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; + if (settings->smd && settings->smd->domain) + settings->point_cache[0]->flag |= PTCACHE_OUTDATED; + DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); +} + static void rna_Smoke_reset(Main *bmain, Scene *scene, PointerRNA *ptr) { SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; smokeModifier_reset(settings->smd); - - if (settings->smd && settings->smd->domain) - settings->point_cache[0]->flag |= PTCACHE_OUTDATED; + rna_Smoke_resetCache(bmain, scene, ptr); rna_Smoke_update(bmain, scene, ptr); } @@ -142,6 +148,30 @@ static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values) memcpy(values, density, size * sizeof(float)); } +static void rna_SmokeFlow_density_vgroup_get(PointerRNA *ptr, char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_vgroup_name_index_get(ptr, value, flow->vgroup_density); +} + +static int rna_SmokeFlow_density_vgroup_length(PointerRNA *ptr) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + return rna_object_vgroup_name_index_length(ptr, flow->vgroup_density); +} + +static void rna_SmokeFlow_density_vgroup_set(PointerRNA *ptr, const char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_vgroup_name_index_set(ptr, value, &flow->vgroup_density); +} + +static void rna_SmokeFlow_uvlayer_set(PointerRNA *ptr, const char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_uvlayer_name_set(ptr, value, flow->uvlayer_name, sizeof(flow->uvlayer_name)); +} + #else static void rna_def_smoke_domain_settings(BlenderRNA *brna) @@ -217,7 +247,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5); RNA_def_property_ui_text(prop, "Density", "How much density affects smoke motion (higher value results in faster rising smoke)"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "beta", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "beta"); @@ -225,7 +255,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5); RNA_def_property_ui_text(prop, "Heat", "How much heat affects smoke motion (higher value results in faster rising smoke)"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "collision_group", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "coll_group"); @@ -253,24 +283,24 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_range(prop, 0.0, 10.0, 1, 2); RNA_def_property_ui_text(prop, "Strength", "Strength of noise"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "diss_speed"); RNA_def_property_range(prop, 1.0, 10000.0); RNA_def_property_ui_range(prop, 1.0, 10000.0, 1, 0); RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "use_dissolve_smoke", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE); RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "use_dissolve_smoke_log", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG); RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x "); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); @@ -297,21 +327,21 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "smooth_emitter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGH_SMOOTH); RNA_def_property_ui_text(prop, "Smooth Emitter", "Smooth emitted smoke to avoid blockiness"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "time_scale"); RNA_def_property_range(prop, 0.2, 1.5); RNA_def_property_ui_range(prop, 0.2, 1.5, 0.02, 5); RNA_def_property_ui_text(prop, "Time Scale", "Adjust simulation speed"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "vorticity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vorticity"); RNA_def_property_range(prop, 0.01, 4.0); RNA_def_property_ui_range(prop, 0.01, 4.0, 0.02, 5); RNA_def_property_ui_text(prop, "Vorticity", "Amount of turbulence/rotation in fluid"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); RNA_def_property_array(prop, 32); @@ -321,25 +351,80 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_float_funcs(prop, "rna_SmokeModifier_density_get", NULL, NULL); RNA_def_property_ui_text(prop, "Density", "Smoke density"); - prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "dx"); + prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "dx", "Cell Size"); + RNA_def_property_ui_text(prop, "cell_size", "Cell Size"); - prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); + prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_float_sdna(prop, NULL, "p0"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "p0", "Start point"); - prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "scale"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "scale", "Domain scale factor"); - - prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); + prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_int_sdna(prop, NULL, "res"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "res", "Smoke Grid Resolution"); + + prop = RNA_def_property(srna, "burning_rate", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 4.0); + RNA_def_property_ui_range(prop, 0.01, 2.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Speed", "Speed of the burning reaction. Use larger values for smaller flame"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_smoke", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 8.0); + RNA_def_property_ui_range(prop, 0.0, 4.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Smoke", "Amount of smoke created by burning fuel"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_vorticity", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Vorticity", "Additional vorticity for the flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_ignition", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.5, 5.0); + RNA_def_property_ui_range(prop, 0.5, 2.5, 1.0, 5); + RNA_def_property_ui_text(prop, "Ignition", "Minimum temperature of flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_max_temp", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 1.0, 10.0); + RNA_def_property_ui_range(prop, 1.0, 5.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Maximum", "Maximum temperature of flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_smoke_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Smoke Color", "Color of smoke emitted from burning fuel"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "use_adaptive_domain", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_ADAPTIVE_DOMAIN); + RNA_def_property_ui_text(prop, "Adaptive Domain", "Adapt simulation resolution and size to fluid"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "additional_res", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "adapt_res"); + RNA_def_property_range(prop, 0, 512); + RNA_def_property_ui_range(prop, 0, 512, 2, 0); + RNA_def_property_ui_text(prop, "Additional", "Maximum number of additional cells"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "adapt_margin", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "adapt_margin"); + RNA_def_property_range(prop, 2, 24); + RNA_def_property_ui_range(prop, 2, 24, 2, 0); + RNA_def_property_ui_text(prop, "Margin", "Margin added around fluid to minimize boundary interference"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "adapt_threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 0.5); + RNA_def_property_ui_range(prop, 0.01, 0.5, 1.0, 5); + RNA_def_property_ui_text(prop, "Threshold", "Maximum amount of fluid cell can contain before it's considered empty"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) @@ -347,6 +432,26 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem smoke_flow_types[] = { + {MOD_SMOKE_FLOW_TYPE_OUTFLOW, "OUTFLOW", 0, "Outflow", "Delete smoke from simulation"}, + {MOD_SMOKE_FLOW_TYPE_SMOKE, "SMOKE", 0, "Smoke", "Add smoke"}, + {MOD_SMOKE_FLOW_TYPE_SMOKEFIRE, "BOTH", 0, "Fire + Smoke", "Add fire and smoke"}, + {MOD_SMOKE_FLOW_TYPE_FIRE, "FIRE", 0, "Fire", "Add fire"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem smoke_flow_sources[] = { + {MOD_SMOKE_FLOW_SOURCE_PARTICLES, "PARTICLES", ICON_PARTICLES, "Particle System", "Emit smoke from particles"}, + {MOD_SMOKE_FLOW_SOURCE_MESH, "MESH", ICON_META_CUBE, "Mesh", "Emit smoke from mesh surface or volume"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem smoke_flow_texture_types[] = { + {MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO, "AUTO", 0, "Generated", "Generated coordinates centered to flow object"}, + {MOD_SMOKE_FLOW_TEXTURE_MAP_UV, "UV", 0, "UV", "Use UV layer for texture coordinates"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SmokeFlowSettings", NULL); RNA_def_struct_ui_text(srna, "Flow Settings", "Smoke flow settings"); RNA_def_struct_sdna(srna, "SmokeFlowSettings"); @@ -354,11 +459,23 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "density"); - RNA_def_property_range(prop, 0.001, 1); - RNA_def_property_ui_range(prop, 0.001, 1.0, 1.0, 4); + RNA_def_property_range(prop, 0.0, 1); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1.0, 4); RNA_def_property_ui_text(prop, "Density", ""); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "smoke_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "color"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Smoke Color", "Color of smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "fuel_amount", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 10); + RNA_def_property_ui_range(prop, 0.0, 5.0, 1.0, 4); + RNA_def_property_ui_text(prop, "Flame Rate", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "temperature", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "temp"); RNA_def_property_range(prop, -10, 10); @@ -373,9 +490,16 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object"); RNA_def_property_update(prop, 0, "rna_Smoke_reset_dependancy"); - prop = RNA_def_property(srna, "use_outflow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "type", MOD_SMOKE_FLOW_TYPE_OUTFLOW); - RNA_def_property_ui_text(prop, "Outflow", "Delete smoke from simulation"); + prop = RNA_def_property(srna, "smoke_flow_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, smoke_flow_types); + RNA_def_property_ui_text(prop, "Flow Type", "Change how flow affects the simulation"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "smoke_flow_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "source"); + RNA_def_property_enum_items(prop, smoke_flow_sources); + RNA_def_property_ui_text(prop, "Source", "Change how smoke is emitted"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "use_absolute", PROP_BOOLEAN, PROP_NONE); @@ -385,14 +509,82 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "initial_velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_INITVELOCITY); - RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke inherits its velocity from the emitter particle"); + RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke has some initial velocity when it is emitted"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "velocity_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vel_multi"); RNA_def_property_range(prop, -2.0, 2.0); RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); - RNA_def_property_ui_text(prop, "Multiplier", "Multiplier to adjust velocity passed to smoke"); + RNA_def_property_ui_text(prop, "Source", "Multiplier of source velocity passed to smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "velocity_normal", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_normal"); + RNA_def_property_range(prop, -2.0, 2.0); + RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Normal", "Amount of normal directional velocity"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "velocity_random", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_random"); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 2.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Random", "Amount of random velocity"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "volume_density", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Volume", "Factor for smoke emitted from inside the mesh volume"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "surface_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.5, 10.0); + RNA_def_property_ui_range(prop, 0.5, 5.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Surface", "Maximum distance from mesh surface to emit smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "density_vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_SmokeFlow_density_vgroup_get", + "rna_SmokeFlow_density_vgroup_length", + "rna_SmokeFlow_density_vgroup_set"); + RNA_def_property_ui_text(prop, "Vertex Group", + "Name of Vertex Group which determines surface emission rate"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_TEXTUREEMIT); + RNA_def_property_ui_text(prop, "Use Texture", "Use a texture to control emission strength"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_map_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "texture_type"); + RNA_def_property_enum_items(prop, smoke_flow_texture_types); + RNA_def_property_ui_text(prop, "Mapping", "Texture mapping type"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); + RNA_def_property_ui_text(prop, "UV Map", "UV map name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmokeFlow_uvlayer_set"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "noise_texture", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Texture", "Texture that controls emission strength"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 10.0); + RNA_def_property_ui_range(prop, 0.1, 5.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Size", "Size of texture mapping"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_offset", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 200.0); + RNA_def_property_ui_range(prop, 0.0, 100.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Offset", "Z-offset of texture mapping"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ff5f4988cc1..51fb9d413da 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -336,6 +336,15 @@ static void rna_View3D_CursorLocation_set(PointerRNA *ptr, const float *values) copy_v3_v3(cursor, values); } +static float rna_View3D_GridScaleUnit_get(PointerRNA *ptr) +{ + View3D *v3d = (View3D *)(ptr->data); + bScreen *sc = (bScreen *)ptr->id.data; + Scene *scene = (Scene *)sc->scene; + + return ED_view3d_grid_scale(scene, v3d, NULL); +} + static void rna_SpaceView3D_layer_set(PointerRNA *ptr, const int *values) { View3D *v3d = (View3D *)(ptr->data); @@ -1324,7 +1333,7 @@ static void rna_def_background_image(BlenderRNA *brna) srna = RNA_def_struct(brna, "BackgroundImage", NULL); RNA_def_struct_sdna(srna, "BGpic"); - RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3d View background"); + RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3D View background"); prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "source"); @@ -1494,7 +1503,39 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera", "Active camera used in this view (when unlocked from the scene's active camera)"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + /* render border */ + prop = RNA_def_property(srna, "use_render_border", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_RENDER_BORDER); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Render Border", + "use a user-defined border region within the frame size for rendered viewport"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum X", "Minimum X value to for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum Y", "Minimum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum X", "Maximum X value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum Y", "Maximum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "lock_object", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_sdna(prop, NULL, "ob_centre"); @@ -1571,7 +1612,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_range(prop, 1, 1024); RNA_def_property_int_default(prop, 10); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + prop = RNA_def_property(srna, "grid_scale_unit", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_View3D_GridScaleUnit_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Grid Scale Unit", "Grid cell size scaled by scene unit system settings"); + prop = RNA_def_property(srna, "show_floor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_FLOOR); RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid in perspective view"); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 45e3d15b9be..e77c5d13a6b 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -71,7 +71,7 @@ EnumPropertyItem texture_type_items[] = { {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""}, {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"}, {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"}, - {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3d texture based on volumetric data"}, + {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"}, {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {0, NULL, 0, NULL, NULL} @@ -1800,7 +1800,8 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) }; static EnumPropertyItem smoked_type_items[] = { - {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Density", "Use smoke density as texture data"}, + {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Smoke", "Use smoke density and color as texture data"}, + {TEX_VD_SMOKEFLAME, "SMOKEFLAME", 0, "Flame", "Use flame temperature as texture data"}, {TEX_VD_SMOKEHEAT, "SMOKEHEAT", 0, "Heat", "Use smoke heat as texture data. Values from -2.0 to 2.0 are used"}, {TEX_VD_SMOKEVEL, "SMOKEVEL", 0, "Velocity", "Use smoke velocity as texture data"}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index a2880510958..5be9d3a0dec 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -120,10 +120,10 @@ void RNA_api_environment_map(StructRNA *srna) RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken"); - RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", + RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 1000.0f, "File layout", "Flat array describing the X,Y position of each cube face in the " "output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 0.0f); + "(use -1 to skip a face)", 0.0f, 1000.0f); } #endif diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 0c62a280935..4b744b160fc 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -567,18 +567,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna) "Limit speed of tracking to make visual feedback easier " "(this does not affect the tracking quality)"); - /* keyframe_a */ - prop = RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "keyframe1"); - RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); - - /* keyframe_b */ - prop = RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "keyframe2"); - RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); - /* intrinsics refinement during bundle adjustment */ prop = RNA_def_property(srna, "refine_intrinsics", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "refine_camera_intrinsics"); @@ -1393,6 +1381,18 @@ static void rna_def_trackingObject(BlenderRNA *brna) RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingObject_flushUpdate"); + + /* keyframe_a */ + prop = RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe1"); + RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); + + /* keyframe_b */ + prop = RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe2"); + RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); } static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 70d94bfc7ed..7bfa7ccc3c2 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -85,7 +85,7 @@ static ARegionType *region_type_find(ReportList *reports, int space_type, int re /* region type not found? abort */ if (art == NULL) { - BKE_report(reports, RPT_ERROR, "Region not found in spacetype"); + BKE_report(reports, RPT_ERROR, "Region not found in space type"); return NULL; } diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 006e1ad3903..2e1c62cce53 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -439,7 +439,8 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "compact", 0, "", "Use more compact layout"); func = RNA_def_function(srna, "template_list", "uiTemplateList"); - RNA_def_function_ui_description(func, "Item. A list widget to display data. e.g. vertexgroups"); + RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups " + "(WARNING: only one per panel allowed!)."); RNA_def_function_flag(func, FUNC_USE_CONTEXT); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 3eadc4468ba..307e2ff4f82 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2520,7 +2520,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sub Level Menu Open Delay", "Time delay in 1/10 seconds before automatically opening sub level menus"); - prop = RNA_def_property(srna, "quit_dialog", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_quit_dialog", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_QUIT_PROMPT); RNA_def_property_ui_text(prop, "Prompt Quit", "Asks for confirmation when quitting through the window close button"); @@ -2755,6 +2755,11 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTAVAIL); RNA_def_property_ui_text(prop, "Auto Keyframe Insert Available", "Automatic keyframe insertion in available F-Curves"); + + prop = RNA_def_property(srna, "use_auto_keying_warning", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_NOWARNING); + RNA_def_property_ui_text(prop, "Show Auto Keying Warning", + "Show warning indicators when transforming Object and Bones if Auto Keying is enabled"); /* keyframing settings */ prop = RNA_def_property(srna, "use_keyframe_insert_needed", PROP_BOOLEAN, PROP_NONE); @@ -2788,7 +2793,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_NONEGFRAMES); RNA_def_property_ui_text(prop, "Allow Negative Frames", "Current frame number can be manually set to a negative value"); - + /* fcurve opacity */ prop = RNA_def_property(srna, "fcurve_unselected_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "fcu_inactive_alpha"); @@ -2992,7 +2997,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */ /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */ /* Note: As this list is in alphabetical order, and not defined order, - * here is the highest define currently in use: 33 (Hebrew). */ + * here is the highest define currently in use: 35 (Esperanto). */ static EnumPropertyItem language_items[] = { { 0, "", 0, N_("Nearly Done"), ""}, { 0, "DEFAULT", 0, "Default (Default)", ""}, @@ -3010,25 +3015,27 @@ static void rna_def_userdef_system(BlenderRNA *brna) {14, "TRADITIONAL_CHINESE", 0, "Traditional Chinese (繁體中文)", "zh_TW"}, {18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"}, { 0, "", 0, N_("In Progress"), ""}, - {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"}, - {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"}, +/* {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"},*/ /* XXX Not active nor enough translated. */ +/* {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"},*/ /* XXX Not active nor enough translated. */ {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, - { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, + {35, "ESPERANTO", 0, "Esperanto (Esperanto)", "eo"}, + {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"}, +/* { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"},*/ /* XXX Not active nor enough translated. */ { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, - {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"}, +/* {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"},*/ /* XXX Not active nor enough translated. */ /* using the utf8 flipped form of Hebrew (עִבְרִית)) */ {33, "HEBREW", 0, "Hebrew (תירִבְעִ)", "he_IL"}, {31, "HUNGARIAN", 0, "Hungarian (Magyar)", "hu_HU"}, {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"}, {29, "KYRGYZ", 0, "Kyrgyz (Кыргыз тили)", "ky_KG"}, -/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX No po's yet. */ - {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"}, +/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX Not active nor enough translated. */ +/* {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"},*/ /* XXX Not active nor enough translated. */ /* using the utf8 flipped form of Persian (فارسی) */ {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"}, - {19, "POLISH", 0, "Polish (Polski)", "pl_PL"}, -/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX No po's yet. */ +/* {19, "POLISH", 0, "Polish (Polski)", "pl_PL"},*/ /* XXX Not active nor enough translated. */ +/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX Not active nor enough translated. */ {17, "SERBIAN", 0, "Serbian (Српски)", "sr_RS"}, {28, "SERBIAN_LATIN", 0, "Serbian Latin (Srpski latinica)", "sr_RS@latin"}, { 7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"}, diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index d8753f4ff43..30bdc717f50 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1062,7 +1062,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * } else { BKE_reportf(reports, RPT_ERROR, - "registering operator class: '%s', invalid bl_idname '%s', at position %d", + "Registering operator class: '%s', invalid bl_idname '%s', at position %d", identifier, _operator_idname, i); return NULL; } @@ -1071,7 +1071,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * } if (i > ((int)sizeof(dummyop.idname)) - 3) { - BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s', invalid bl_idname '%s', " + BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', " "is too long, maximum length is %d", identifier, _operator_idname, (int)sizeof(dummyop.idname) - 3); return NULL; @@ -1079,7 +1079,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * if (dot != 1) { BKE_reportf(reports, RPT_ERROR, - "registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", + "Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", identifier, _operator_idname); return NULL; } diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index bf411c3b2fc..51e574e276d 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -79,4 +79,4 @@ extern ModifierTypeInfo modifierType_Skin; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); -#endif //__MOD_MODIFIERTYPES_H__ +#endif /* __MOD_MODIFIERTYPES_H__ */ diff --git a/source/blender/modifiers/intern/MOD_boolean_util.h b/source/blender/modifiers/intern/MOD_boolean_util.h index b996dc6d6ba..209db60f0c9 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.h +++ b/source/blender/modifiers/intern/MOD_boolean_util.h @@ -51,4 +51,4 @@ int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_sel struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select, int int_op_type); -#endif // MOD_BOOLEAN_UTILS +#endif /* MOD_BOOLEAN_UTILS */ diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index cb6681bfa68..171d601ea6d 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -47,6 +47,10 @@ #include "BKE_particle.h" #include "BKE_cdderivedmesh.h" +#include "BKE_tessmesh.h" + +/* testing only! - Campbell */ +// #define USE_DECIMATE_BMESH #ifdef WITH_MOD_DECIMATE #include "LOD_decimation.h" @@ -70,6 +74,33 @@ static void copyData(ModifierData *md, ModifierData *target) } #ifdef WITH_MOD_DECIMATE +#ifdef USE_DECIMATE_BMESH + +#include "bmesh.h" + +static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), + DerivedMesh *derivedData, + ModifierApplyFlag UNUSED(flag)) +{ + DecimateModifierData *dmd = (DecimateModifierData *) md; + DerivedMesh *dm = derivedData, *result = NULL; + BMEditMesh *em; + BMesh *bm; + + em = DM_to_editbmesh(dm, NULL, FALSE); + bm = em->bm; + + BM_mesh_decimate(bm, dmd->percent); + + BLI_assert(em->looptris == NULL); + result = CDDM_from_BMEditMesh(em, NULL, TRUE, FALSE); + BMEdit_Free(em); + MEM_freeN(em); + + return result; +} + +#else static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) @@ -192,6 +223,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), return dm; } } +#endif // USE_DECIMATE_BMESH #else // WITH_MOD_DECIMATE static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), DerivedMesh *derivedData, diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index e64e80efde3..20b02c63605 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -81,6 +81,44 @@ static int dependsOnTime(ModifierData *UNUSED(md)) { return 0; } + +static int isDisabled(ModifierData *md, int useRenderParams) +{ + ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; + ParticleSystem *psys; + ModifierData *ob_md; + + if (!pimd->ob) + return TRUE; + + psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); + if (psys == NULL) + return TRUE; + + /* If the psys modifier is disabled we cannot use its data. + * First look up the psys modifier from the object, then check if it is enabled. + */ + for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) { + if (ob_md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md; + if (psmd->psys == psys) { + int required_mode; + + if (useRenderParams) required_mode = eModifierMode_Render; + else required_mode = eModifierMode_Realtime; + + if (!modifier_isEnabled(md->scene, ob_md, required_mode)) + return TRUE; + + break; + } + } + } + + return FALSE; +} + + static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), Object *UNUSED(ob), @@ -384,7 +422,7 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* initData */ initData, /* requiredDataMask */ NULL, /* freeData */ NULL, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepgraph */ updateDepgraph, /* dependsOnTime */ dependsOnTime, /* dependsOnNormals */ NULL, diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 254c02b7672..cd2ef5957cd 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -44,6 +44,7 @@ #include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_particle.h" +#include "BKE_scene.h" #include "MOD_util.h" @@ -130,6 +131,7 @@ static void deformVerts(ModifierData *md, Object *ob, ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; int needsFree = 0; + /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ob->particlesystem.first) psys = psmd->psys; @@ -188,9 +190,11 @@ static void deformVerts(ModifierData *md, Object *ob, psmd->totdmface = psmd->dm->getNumTessFaces(psmd->dm); } - psmd->flag &= ~eParticleSystemFlag_psys_updated; - particle_system_update(md->scene, ob, psys); - psmd->flag |= eParticleSystemFlag_psys_updated; + if (!(ob->transflag & OB_NO_PSYS_UPDATE)) { + psmd->flag &= ~eParticleSystemFlag_psys_updated; + particle_system_update(md->scene, ob, psys); + psmd->flag |= eParticleSystemFlag_psys_updated; + } } /* disabled particles in editmode for now, until support for proper derivedmesh diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index b9b3b89e06d..4b2ce47b8d9 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -81,19 +81,31 @@ static void freeData(ModifierData *md) smokeModifier_free(smd); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, - float (*vertexCos)[3], - int UNUSED(numVerts), - ModifierApplyFlag UNUSED(flag)) +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) { - SmokeModifierData *smd = (SmokeModifierData *) md; - DerivedMesh *dm = get_cddm(ob, NULL, derivedData, vertexCos); + SmokeModifierData *smd = (SmokeModifierData *)md; + CustomDataMask dataMask = 0; + + if (smd && (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (smd->flow->source == MOD_SMOKE_FLOW_SOURCE_MESH) { + /* vertex groups */ + if (smd->flow->vgroup_density) + dataMask |= CD_MASK_MDEFORMVERT; + /* uv layer */ + if (smd->flow->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_UV) + dataMask |= CD_MASK_MTFACE; + } + } + return dataMask; +} - smokeModifier_do(smd, md->scene, ob, dm); +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag UNUSED(flag)) +{ + SmokeModifierData *smd = (SmokeModifierData *) md; - if (dm != derivedData) - dm->release(dm); + return smokeModifier_do(smd, md->scene, ob, dm); } static int dependsOnTime(ModifierData *UNUSED(md)) @@ -102,11 +114,11 @@ static int dependsOnTime(ModifierData *UNUSED(md)) } static void updateDepgraph(ModifierData *md, DagForest *forest, - struct Scene *scene, - Object *UNUSED(ob), + struct Scene *scene, struct Object *ob, DagNode *obNode) { SmokeModifierData *smd = (SmokeModifierData *) md; + Base *base; if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { if (smd->domain->fluid_group || smd->domain->coll_group) { @@ -139,8 +151,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } else { - Base *base = scene->base.first; - + base = scene->base.first; for (; base; base = base->next) { SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); @@ -150,6 +161,14 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } } + /* add relation to all "smoke flow" force fields */ + base = scene->base.first; + for (; base; base = base->next) { + if (base->object->pd && base->object->pd->forcefield == PFIELD_SMOKEFLOW && base->object->pd->f_source == ob) { + DagNode *node2 = dag_get_node(forest, base->object); + dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object"); + } + } } } @@ -167,26 +186,30 @@ static void foreachIDLink(ModifierData *md, Object *ob, walk(userData, ob, (ID **)&smd->domain->effector_weights->group); } } + + if (smd->type == MOD_SMOKE_TYPE_FLOW && smd->flow) { + walk(userData, ob, (ID **)&smd->flow->noise_texture); + } } ModifierTypeInfo modifierType_Smoke = { /* name */ "Smoke", /* structName */ "SmokeModifierData", /* structSize */ sizeof(SmokeModifierData), - /* type */ eModifierTypeType_OnlyDeform, + /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single, /* copyData */ copyData, - /* deformVerts */ deformVerts, + /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, /* isDisabled */ NULL, /* updateDepgraph */ updateDepgraph, diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 1df7d535c35..cc77d73a736 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -223,7 +223,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, const int numEdges = dm->getNumEdges(dm); const int numFaces = dm->getNumPolys(dm); int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; - int j; /* only use material offsets if we have 2 or more materials */ const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0; @@ -292,9 +291,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } for (i = 0, mp = orig_mpoly; i < numFaces; i++, mp++) { - MLoop *ml = orig_mloop + mp->loopstart; unsigned int ml_v1; unsigned int ml_v2; + int j; + + ml = orig_mloop + mp->loopstart; for (j = 0, ml_v1 = ml->v, ml_v2 = ml[mp->totloop - 1].v; j < mp->totloop; @@ -376,6 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < dm->numPolyData; i++, mp++) { MLoop *ml2; int e; + int j; ml2 = mloop + mp->loopstart + dm->numLoopData; for (j = 0; j < mp->totloop; j++) { @@ -591,6 +593,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int *origindex_edge; int *orig_ed; + int j; /* add faces & edges */ origindex_edge = result->getEdgeDataArray(result, CD_ORIGINDEX); @@ -715,13 +718,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < newEdges; i++, ed++) { float nor_cpy[3]; short *nor_short; - int j; + int k; /* note, only the first vertex (lower half of the index) is calculated */ normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); - for (j = 0; j < 2; j++) { /* loop over both verts of the edge */ - nor_short = mvert[*(&ed->v1 + j)].no; + for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ + nor_short = mvert[*(&ed->v1 + k)].no; normal_short_to_float_v3(nor, nor_short); add_v3_v3(nor, nor_cpy); normalize_v3(nor); diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 440d2c157fe..b713f56a4c2 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -186,7 +186,7 @@ static void waveModifier_do(WaveModifierData *md, const float falloff = wmd->falloff; float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */ - if (wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH) + if ((wmd->flag & MOD_WAVE_NORM) && (ob->type == OB_MESH)) mvert = dm->getVertArray(dm); if (wmd->objectcenter) { diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 08e0e7b0f93..3fd9bfecedf 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -25,6 +25,10 @@ set(INC . + composite + intern + shader + texture ../blenfont ../blenkernel ../blenlib @@ -39,10 +43,6 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_PATH} - intern - composite - shader - texture ) set(SRC @@ -146,13 +146,14 @@ set(SRC shader/nodes/node_shader_vectMath.c shader/nodes/node_shader_attribute.c shader/nodes/node_shader_background.c - # shader/nodes/node_shader_bsdf_anisotropic.c # XXX, why not included? + shader/nodes/node_shader_bsdf_anisotropic.c shader/nodes/node_shader_bsdf_diffuse.c shader/nodes/node_shader_bsdf_glossy.c shader/nodes/node_shader_bsdf_glass.c shader/nodes/node_shader_bsdf_translucent.c shader/nodes/node_shader_bsdf_transparent.c shader/nodes/node_shader_bsdf_velvet.c + shader/nodes/node_shader_bump.c shader/nodes/node_shader_emission.c shader/nodes/node_shader_fresnel.c shader/nodes/node_shader_layer_weight.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 49428c06e5f..7585ed0d61c 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -88,6 +88,7 @@ void register_node_type_sh_bsdf_glass(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_translucent(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_transparent(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_velvet(struct bNodeTreeType *ttype); +void register_node_type_sh_bsdf_anisotropic(struct bNodeTreeType *ttype); void register_node_type_sh_emission(struct bNodeTreeType *ttype); void register_node_type_sh_holdout(struct bNodeTreeType *ttype); void register_node_type_sh_volume_transparent(struct bNodeTreeType *ttype); @@ -109,6 +110,7 @@ void register_node_type_sh_tex_wave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_musgrave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_noise(struct bNodeTreeType *ttype); void register_node_type_sh_tex_checker(struct bNodeTreeType *ttype); +void register_node_type_sh_bump(struct bNodeTreeType *ttype); #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index 9157728b546..4a7643f5771 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -33,6 +33,8 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness U"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness V"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -43,7 +45,10 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_out[]= { static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[3].link) + in[3].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out); } /* node type definition */ @@ -51,7 +56,7 @@ void register_node_type_sh_bsdf_anisotropic(bNodeTreeType *ttype) { static bNodeType ntype; - node_type_base(ttype, &ntype, SH_NODE_BSDF_ANISOTROPIC, "Glossy Anisotropic BSDF", NODE_CLASS_SHADER, 0); + node_type_base(ttype, &ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER, 0); node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_bsdf_anisotropic_in, sh_node_bsdf_anisotropic_out); node_type_size(&ntype, 150, 60, 200); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index d2e2db3e78a..63ce637fd72 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -42,7 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_out[]= { static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_diffuse", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_diffuse", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 8ff0ad57742..7b8b80ae8e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -33,6 +33,7 @@ static bNodeSocketTemplate sh_node_bsdf_glass_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -43,7 +44,10 @@ static bNodeSocketTemplate sh_node_bsdf_glass_out[]= { static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_glass", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[3].link) + in[3].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_glass", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index d28b3454f02..9f42e23ebb6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -42,8 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_out[]= { static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - /* todo: is incoming vector normalized? */ - return GPU_stack_link(mat, "node_bsdf_glossy", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_glossy", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index a3ba3ac7ff3..b3290411aee 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -41,7 +42,10 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_out[]= { static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_translucent", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[1].link) + in[1].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_translucent", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index 04a1c1b32df..97bc37a84c9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Sigma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -42,7 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_out[]= { static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_velvet", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_velvet", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c new file mode 100644 index 00000000000..315565e619b --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -0,0 +1,68 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_bump.c + * \ingroup shdnodes + */ + + + +#include "node_shader_util.h" + + +/* **************** BUMP ******************** */ +static bNodeSocketTemplate sh_node_bump_in[]= { + { SOCK_FLOAT, 1, "Strength", 0.1f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + { SOCK_FLOAT, 1, "Height", 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_bump_out[]= { + { SOCK_VECTOR, 0, "Normal"}, + { -1, 0, "" } +}; + +static int gpu_shader_bump(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "node_bump", in, out, GPU_builtin(GPU_VIEW_NORMAL)); +} + +/* node type definition */ +void register_node_type_sh_bump(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_bump_in, sh_node_bump_out); + node_type_size(&ntype, 150, 60, 200); + node_type_storage(&ntype, "BumpNode", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, NULL); + node_type_gpu(&ntype, gpu_shader_bump); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 9656d93f1b0..1bfd88d3af7 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -4,7 +4,7 @@ * 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. + * 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 @@ -240,19 +240,19 @@ void ntreeTexEndExecTree(bNodeTreeExec *exec, int use_tree_data) } int ntreeTexExecTree( - bNodeTree *nodes, - TexResult *texres, - float *co, - float *dxt, float *dyt, - int osatex, - short thread, - Tex *UNUSED(tex), - short which_output, - int cfra, - int preview, - ShadeInput *shi, - MTex *mtex -) { + bNodeTree *nodes, + TexResult *texres, + float co[3], + float dxt[3], float dyt[3], + int osatex, + const short thread, + Tex *UNUSED(tex), + short which_output, + int cfra, + int preview, + ShadeInput *shi, + MTex *mtex) +{ TexCallData data; float *nor = texres->nor; int retval = TEX_INT; diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c index 5e58b74ac3a..06473d800d0 100644 --- a/source/blender/nodes/texture/node_texture_util.c +++ b/source/blender/nodes/texture/node_texture_util.c @@ -4,7 +4,7 @@ * 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. + * 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 @@ -29,7 +29,7 @@ * \ingroup nodes */ - + /* * HOW TEXTURE NODES WORK * @@ -112,13 +112,13 @@ void params_from_cdata(TexParams *out, TexCallData *in) out->mtex = in->mtex; } -void tex_do_preview(bNode *node, float *co, float *col) +void tex_do_preview(bNode *node, const float coord[2], const float col[4]) { - bNodePreview *preview= node->preview; + bNodePreview *preview = node->preview; if (preview) { - int xs= ((co[0] + 1.0f)*0.5f)*preview->xsize; - int ys= ((co[1] + 1.0f)*0.5f)*preview->ysize; + int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize; + int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize; nodeAddToPreview(node, col, xs, ys, 0); /* 0 = no color management */ } @@ -132,19 +132,19 @@ void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexC dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); else dg = out->data; - - dg->cdata= cdata; + + dg->cdata = cdata; dg->fn = texfn; dg->node = node; - memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*)); + memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *)); dg->type = out->sockettype; } void ntreeTexCheckCyclics(struct bNodeTree *ntree) { bNode *node; - for (node= ntree->nodes.first; node; node= node->next) { - + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == TEX_NODE_TEXTURE && node->id) { /* custom2 stops the node from rendering */ if (node->custom1) { diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h index e938e6fc419..16dbc2f7bfb 100644 --- a/source/blender/nodes/texture/node_texture_util.h +++ b/source/blender/nodes/texture/node_texture_util.h @@ -79,8 +79,10 @@ typedef struct TexCallData { TexResult *target; + /* all float[3] */ float *co; float *dxt, *dyt; + int osatex; char do_preview; short thread; @@ -94,7 +96,7 @@ typedef struct TexCallData { typedef struct TexParams { float *co; float *dxt, *dyt; - float *previewco; + const float *previewco; int cfra; int osatex; @@ -119,7 +121,7 @@ void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread); float tex_input_value(bNodeStack *in, TexParams *params, short thread); void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data); -void tex_do_preview(bNode *node, float *coord, float *col); +void tex_do_preview(bNode *node, const float coord[2], const float col[4]); void params_from_cdata(TexParams *out, TexCallData *in); diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c index f6259962529..c575547b3ce 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.c +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c @@ -66,7 +66,7 @@ static float noise(int n) /* fast integer noise */ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread) { - float *co = p->co; + const float *co = p->co; float x = co[0]; float y = co[1]; diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c index ce22bc00a55..fdd3b97ad59 100644 --- a/source/blender/nodes/texture/nodes/node_texture_output.c +++ b/source/blender/nodes/texture/nodes/node_texture_output.c @@ -65,7 +65,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(o tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread); target->tin = (target->tr + target->tg + target->tb) / 3.0f; - target->talpha = 1; + target->talpha = TRUE; if (target->nor) { if (in[1] && in[1]->hasinput) diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c index 102f6e1c428..1f724292661 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -57,7 +57,7 @@ static bNodeSocketTemplate outputs_color_only[]= { { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f } /* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */ -static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread) +static void do_proc(float *result, TexParams *p, const float col1[4], const float col2[4], char is_normal, Tex *tex, const short thread) { TexResult texres; int textype; @@ -69,7 +69,7 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char texres.nor = NULL; textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex); + &texres, thread, 0, p->shi, p->mtex); if (is_normal) return; @@ -83,7 +83,7 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char } } -typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, short thread); +typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, const short thread); static void texfn( float *result, diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c index a7832c8c180..2f997d36e71 100644 --- a/source/blender/nodes/texture/nodes/node_texture_rotate.c +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c @@ -47,7 +47,7 @@ static bNodeSocketTemplate outputs[]= { { -1, 0, "" } }; -static void rotate(float new_co[3], float a, float ax[3], float co[3]) +static void rotate(float new_co[3], float a, float ax[3], const float co[3]) { float para[3]; float perp[3]; diff --git a/source/blender/nodes/texture/nodes/node_texture_valToNor.c b/source/blender/nodes/texture/nodes/node_texture_valToNor.c index 2d107b87578..73dcc72eb40 100644 --- a/source/blender/nodes/texture/nodes/node_texture_valToNor.c +++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.c @@ -47,7 +47,7 @@ static bNodeSocketTemplate outputs[]= { static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) { float new_co[3]; - float *co = p->co; + const float *co = p->co; float nabla = tex_input_value(in[1], p, thread); float val; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index fd5fa63647b..2cae10101d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -645,7 +645,7 @@ static PyGetSetDef bpy_bmface_getseters[] = { static PyGetSetDef bpy_bmloop_getseters[] = { /* generic */ - // flags are available but not used for loops. + /* flags are available but not used for loops. */ // {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT}, // {(char *)"hide", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc, (void *)BM_ELEM_HIDDEN}, {(char *)"tag", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc, (void *)BM_ELEM_TAG}, diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 85095596a4e..2ff731559d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -387,7 +387,7 @@ void BPy_BM_init_types_select(void) BPy_BMEditSelSeq_Type.tp_name = "BMEditSelSeq"; BPy_BMEditSelIter_Type.tp_name = "BMEditSelIter"; - BPy_BMEditSelSeq_Type.tp_doc = NULL; // todo + BPy_BMEditSelSeq_Type.tp_doc = NULL; /* todo */ BPy_BMEditSelIter_Type.tp_doc = NULL; BPy_BMEditSelSeq_Type.tp_repr = (reprfunc)NULL; diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 06b6192a091..d4ec8137399 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -300,40 +300,34 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) } /* returns NULL on success, error string on failure */ -static int idp_sequence_type(PyObject *seq) +static int idp_sequence_type(PyObject *seq_fast) { PyObject *item; int type = IDP_INT; - Py_ssize_t i, len = PySequence_Size(seq); + Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast); for (i = 0; i < len; i++) { - item = PySequence_GetItem(seq, i); + item = PySequence_Fast_GET_ITEM(seq_fast, i); if (PyFloat_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ - Py_DECREF(item); return -1; } type = IDP_DOUBLE; } else if (PyLong_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ - Py_DECREF(item); return -1; } } else if (PyMapping_Check(item)) { if (i != 0 && (type != IDP_IDPARRAY)) { /* mixed dict/int */ - Py_DECREF(item); return -1; } type = IDP_IDPARRAY; } else { - Py_XDECREF(item); return -1; } - - Py_DECREF(item); } return type; @@ -386,48 +380,61 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty //prop->subtype = IDP_STRING_SUB_BYTE; } else if (PySequence_Check(ob)) { + PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop"); PyObject *item; int i; - if ((val.array.type = idp_sequence_type(ob)) == -1) + if (ob_seq_fast == NULL) { + PyErr_Print(); + PyErr_Clear(); + return "error converting the sequence"; + } + + if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { + Py_DECREF(ob_seq_fast); return "only floats, ints and dicts are allowed in ID property arrays"; + } /* validate sequence and derive type. * we assume IDP_INT unless we hit a float * number; then we assume it's */ - val.array.len = PySequence_Size(ob); + val.array.len = PySequence_Fast_GET_SIZE(ob_seq_fast); switch (val.array.type) { case IDP_DOUBLE: prop = IDP_New(IDP_ARRAY, &val, name); for (i = 0; i < val.array.len; i++) { - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); ((double *)IDP_Array(prop))[i] = (float)PyFloat_AsDouble(item); - Py_DECREF(item); } break; case IDP_INT: prop = IDP_New(IDP_ARRAY, &val, name); for (i = 0; i < val.array.len; i++) { - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); ((int *)IDP_Array(prop))[i] = (int)PyLong_AsSsize_t(item); - Py_DECREF(item); } break; case IDP_IDPARRAY: prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { const char *error; - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); error = BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item); - Py_DECREF(item); - if (error) + if (error) { + Py_DECREF(ob_seq_fast); return error; + } } break; + default: + Py_DECREF(ob_seq_fast); + return "internal error with idp array.type"; } + + Py_DECREF(ob_seq_fast); } else if (PyMapping_Check(ob)) { PyObject *keys, *vals, *key, *pval; @@ -471,7 +478,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty if (group->type == IDP_IDPARRAY) { IDP_AppendArray(group, prop); - // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory + // IDP_FreeProperty(item); /* IDP_AppendArray does a shallow copy (memcpy), only free memory */ MEM_freeN(prop); } else { diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 481cfb17c7a..935a5f9030b 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -69,4 +69,4 @@ int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix); PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag); -#endif // __PY_CAPI_UTILS_H__ +#endif /* __PY_CAPI_UTILS_H__ */ diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 15aa5164c86..bd660b94321 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -30,13 +30,13 @@ set(INC ../../blenlib ../../blenloader ../../editors/include + ../../gpu ../../makesdna ../../makesrna ../../windowmanager - ../../gpu + ../../../../intern/cycles/blender ../../freestyle/intern/python ../../../../intern/guardedalloc - ../../../../intern/cycles/blender ) set(INC_SYS diff --git a/source/blender/python/intern/bpy_app.h b/source/blender/python/intern/bpy_app.h index 5bf36f04ba0..226bf44a493 100644 --- a/source/blender/python/intern/bpy_app.h +++ b/source/blender/python/intern/bpy_app.h @@ -29,4 +29,4 @@ PyObject *BPY_app_struct(void); -#endif // __BPY_APP_H__ +#endif /* __BPY_APP_H__ */ diff --git a/source/blender/python/intern/bpy_app_ffmpeg.h b/source/blender/python/intern/bpy_app_ffmpeg.h index cadbb021d31..26d6e13f8f4 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.h +++ b/source/blender/python/intern/bpy_app_ffmpeg.h @@ -29,4 +29,4 @@ PyObject *BPY_app_ffmpeg_struct(void); -#endif // __BPY_APP_FFMPEG_H__ +#endif /* __BPY_APP_FFMPEG_H__ */ diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 4d7f2080bbc..90a0444ceae 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -284,7 +284,7 @@ void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *ar if (PyList_GET_SIZE(cb_list) > 0) { PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject *args = PyTuple_New(1); // save python creating each call + PyObject *args = PyTuple_New(1); /* save python creating each call */ PyObject *func; PyObject *ret; Py_ssize_t pos; diff --git a/source/blender/python/intern/bpy_app_handlers.h b/source/blender/python/intern/bpy_app_handlers.h index 1f1eaf04a8b..40ca43909ed 100644 --- a/source/blender/python/intern/bpy_app_handlers.h +++ b/source/blender/python/intern/bpy_app_handlers.h @@ -29,4 +29,4 @@ PyObject *BPY_app_handlers_struct(void); -#endif // __BPY_APP_HANDLERS_H__ +#endif /* __BPY_APP_HANDLERS_H__ */ diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index de23b3bf109..9a79616c23b 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -280,7 +280,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) } -#if 0 // slow, with this can avoid all Py_CompileString above. +#if 0 /* slow, with this can avoid all Py_CompileString above. */ /* execute expression to get a value */ retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); #else diff --git a/source/blender/python/intern/bpy_driver.h b/source/blender/python/intern/bpy_driver.h index 6d1696d6cdc..1fccec7e1b2 100644 --- a/source/blender/python/intern/bpy_driver.h +++ b/source/blender/python/intern/bpy_driver.h @@ -36,4 +36,4 @@ extern PyObject *bpy_pydriver_Dict; float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime); void BPY_driver_reset(void); -#endif // __BPY_DRIVER_H__ +#endif /* __BPY_DRIVER_H__ */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index b628f42e759..f6ab100ca1a 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -69,7 +69,7 @@ #include "BPY_extern.h" -#include "../generic/bpy_internal_import.h" // our own imports +#include "../generic/bpy_internal_import.h" /* our own imports */ #include "../generic/py_capi_utils.h" /* inittab initialization functions */ @@ -180,10 +180,10 @@ void BPY_text_free_code(Text *text) void BPY_modules_update(bContext *C) { -#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec. +#if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */ PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject(mod, "data", BPY_rna_module()); - PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating + PyModule_AddObject(mod, "types", BPY_rna_types()); /* atm this does not need updating */ #endif /* refreshes the main struct */ @@ -268,7 +268,7 @@ void BPY_python_start(int argc, const char **argv) Py_Initialize(); - // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal + // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ /* sigh, why do python guys not have a (char **) version anymore? */ { int i; diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h index 575f9824379..9ac49c370e4 100644 --- a/source/blender/python/intern/bpy_traceback.h +++ b/source/blender/python/intern/bpy_traceback.h @@ -28,4 +28,4 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset); -#endif // __BPY_TRACEBACK_H__ +#endif /* __BPY_TRACEBACK_H__ */ diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 53d0e10a01e..30b6806a796 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -35,6 +35,8 @@ #include "BKE_report.h" #include "BKE_context.h" +#include "BLF_translation.h" + #include "../generic/py_capi_utils.h" static bContext *__py_context = NULL; @@ -79,7 +81,7 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short short BPy_errors_to_report(ReportList *reports) { PyObject *pystring; - PyObject *pystring_format = NULL; // workaround, see below + PyObject *pystring_format = NULL; /* workaround, see below */ char *cstring; const char *filename; @@ -98,7 +100,7 @@ short BPy_errors_to_report(ReportList *reports) pystring = PyC_ExceptionBuffer(); if (pystring == NULL) { - BKE_report(reports, RPT_ERROR, "unknown py-exception, couldn't convert"); + BKE_report(reports, RPT_ERROR, "Unknown py-exception, couldn't convert"); return 0; } @@ -108,17 +110,18 @@ short BPy_errors_to_report(ReportList *reports) cstring = _PyUnicode_AsString(pystring); -#if 0 // ARG!. workaround for a bug in blenders use of vsnprintf +#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */ BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno); #else - pystring_format = PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno); + pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); cstring = _PyUnicode_AsString(pystring_format); BKE_report(reports, RPT_ERROR, cstring); #endif - - fprintf(stderr, "%s\nlocation:%s:%d\n", cstring, filename, lineno); // not exactly needed. just for testing - + + /* not exactly needed. just for testing */ + fprintf(stderr, TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); + Py_DECREF(pystring); - Py_DECREF(pystring_format); // workaround + Py_DECREF(pystring_format); /* workaround */ return 1; } diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index 8b5e39fbd27..c14b4a0686b 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -858,7 +858,7 @@ PyTypeObject color_Type = { * (i.e. it was allocated elsewhere by MEM_mallocN()) * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type) +PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type) { ColorObject *self; diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h index eff09c25a99..d753b60d195 100644 --- a/source/blender/python/mathutils/mathutils_Color.h +++ b/source/blender/python/mathutils/mathutils_Color.h @@ -47,7 +47,7 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type); +PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type); PyObject *Color_CreatePyObject_cb(PyObject *cb_user, unsigned char cb_type, unsigned char cb_subtype); diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index da32e36dc02..4977663038d 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_noise.h" #include "BLI_utildefines.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/python/mathutils/mathutils_noise.h b/source/blender/python/mathutils/mathutils_noise.h index f4bec88e59a..2ed3e32f4f1 100644 --- a/source/blender/python/mathutils/mathutils_noise.h +++ b/source/blender/python/mathutils/mathutils_noise.h @@ -33,4 +33,4 @@ PyMODINIT_FUNC PyInit_mathutils_noise(void); PyMODINIT_FUNC PyInit_mathutils_noise_types(void); PyMODINIT_FUNC PyInit_mathutils_noise_metrics(void); -#endif // __MATHUTILS_NOISE_H__ +#endif /* __MATHUTILS_NOISE_H__ */ diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py index 489f011e693..15cc60d997e 100644 --- a/source/blender/python/rna_dump.py +++ b/source/blender/python/rna_dump.py @@ -95,7 +95,7 @@ def seek(r, txt, recurs): if GEN_PATH: newtxt = txt + '.' + item - if item == 'rna_type' and VERBOSE_TYPE == False: # just avoid because it spits out loads of data + if item == 'rna_type' and VERBOSE_TYPE is False: # just avoid because it spits out loads of data continue value = getattr(r, item, None) @@ -114,7 +114,7 @@ def seek(r, txt, recurs): except: length = 0 - if VERBOSE == False and length >= 4: + if VERBOSE is False and length >= 4: for i in (0, length - 1): if i > 0: if PRINT_DATA: diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c index 659fd997c1f..1d5838e9905 100644 --- a/source/blender/quicktime/apple/quicktime_export.c +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -218,7 +218,7 @@ static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) /* retreive codecdata from quicktime in a atomcontainer */ myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent, &myContainer); if (myErr != noErr) { - BKE_reportf(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed"); goto bail; } @@ -238,7 +238,7 @@ static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) GetCodecInfo(&ci, qtdata->gSpatialSettings.codecType, 0); } else { - BKE_reportf(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed"); } QTUnlockContainer(myContainer); @@ -268,7 +268,7 @@ static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) if (qcd->cdParms && qcd->cdSize) { myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle); if (myErr != noErr) { - BKE_reportf(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed"); goto bail; } @@ -295,7 +295,7 @@ static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) } else { - BKE_reportf(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed"); } bail: if (myHandle != NULL) @@ -414,7 +414,7 @@ static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, in gTemporalSettings = qtdata->gTemporalSettings; if (qtdata->gSpatialSettings.codecType == kH264CodecType) { if (gTemporalSettings.temporalQuality != codecMinQuality) { - BKE_reportf(reports, RPT_WARNING, "Only minimum quality compression supported for QuickTime H.264.\n"); + BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for Quicktime H.264"); gTemporalSettings.temporalQuality = codecMinQuality; } } @@ -564,7 +564,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R /* hack: create an empty file to make FSPathMakeRef() happy */ myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR); if (myFile < 0) { - BKE_reportf(reports, RPT_ERROR, "error while creating movie file!\n"); + BKE_report(reports, RPT_ERROR, "Error while creating movie file!"); /* do something? */ } close(myFile); @@ -599,7 +599,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R #endif } else { - //printf("Created QuickTime movie: %s\n", name); + /* printf("Created QuickTime movie: %s\n", name); */ QT_CreateMyVideoTrack(rectx, recty, reports); } @@ -636,7 +636,7 @@ void end_qt(void) DisposeMovie(qtexport->theMovie); - //printf("Finished QuickTime movie.\n"); + /* printf("Finished QuickTime movie.\n"); */ } #ifdef __APPLE__ diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index ed896357c90..cef4cb8c2a6 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -164,6 +164,6 @@ enum { }; #endif -#endif //(_WIN32) || (__APPLE__) +#endif /* (_WIN32) || (__APPLE__) */ -#endif // __QUICKTIME_IMP_H__ +#endif /* __QUICKTIME_IMP_H__ */ diff --git a/source/blender/quicktime/quicktime_import.h b/source/blender/quicktime/quicktime_import.h index 19bdbb4814c..fb068fc2533 100644 --- a/source/blender/quicktime/quicktime_import.h +++ b/source/blender/quicktime/quicktime_import.h @@ -51,8 +51,8 @@ #import <Carbon/Carbon.h> #include <QuickTime/Movies.h> #endif -#endif //__MOVIES__ -#endif //USE_QTKIT +#endif /* __MOVIES__ */ +#endif /* USE_QTKIT */ #ifdef _WIN32 #ifndef __FIXMATH__ @@ -76,4 +76,4 @@ ImBuf *qtime_fetchibuf (struct anim *anim, int position); int imb_is_a_quicktime (char *name); ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags); -#endif // __QUICKTIME_IMPORT_H__ +#endif /* __QUICKTIME_IMPORT_H__ */ diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 57fb80f11c0..10045a8f7e1 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -191,12 +191,12 @@ struct MTex; struct ImBuf; /* this one uses nodes */ -int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); /* nodes disabled */ -int multitex_ext_safe(struct Tex *tex, float *texvec, struct TexResult *texres); +int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres); /* only for internal node usage */ -int multitex_nodes(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, - short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); +int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, + const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); /* shaded view and bake */ struct Render; diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h index 24138884cd2..d0f346f7402 100644 --- a/source/blender/render/intern/include/envmap.h +++ b/source/blender/render/intern/include/envmap.h @@ -46,7 +46,7 @@ struct Render; struct TexResult; void make_envmaps(struct Render *re); -int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); #endif /* __ENVMAP_H__ */ diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h index cc8fabda49c..e0c293e2473 100644 --- a/source/blender/render/intern/include/pointdensity.h +++ b/source/blender/render/intern/include/pointdensity.h @@ -43,7 +43,7 @@ struct TexResult; void cache_pointdensity(struct Render *re, struct Tex *tex); void make_pointdensities(struct Render *re); void free_pointdensities(struct Render *re); -int pointdensitytex(struct Tex *tex, float *texvec, struct TexResult *texres); +int pointdensitytex(struct Tex *tex, const float texvec[3], struct TexResult *texres); #endif /* __POINTDENSITY_H__ */ diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 7752baadff4..07fc7d7a6ed 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -104,7 +104,7 @@ RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstance void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max); /* initializes an hint for optimizing raycast where it is know that a ray will pass by the given BB often the origin point */ -void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float *min, float *max); +void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float min[3], float max[3]); /* initializes an hint for optimizing raycast where it is know that a ray will be contained inside the given cone*/ /* void RE_rayobject_hint_cone(RayObject *r, struct RayHint *hint, float *); */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 60f3ced5652..dab89e1d1c0 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -120,6 +120,9 @@ struct Render /* state settings */ short flag, osa, ok, result_ok; + /* due to performance issues, getting initialized from color management settings once on Render initialization */ + short scene_color_manage; + /* result of rendering */ RenderResult *result; /* if render with single-layer option, other rendered layers are stored here */ diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 0fbbf52e613..30712250440 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -62,7 +62,7 @@ typedef struct PixStrMain { /* ------------------------------------------------------------------------- */ -void calc_view_vector(float *view, float x, float y); +void calc_view_vector(float view[3], float x, float y); float mistfactor(float zcor, const float co[3]); /* dist and height, return alpha */ void renderspothalo(struct ShadeInput *shi, float col[4], float alpha); @@ -95,5 +95,4 @@ extern void init_ao_sphere(struct World *wrld); extern void init_render_qmcsampler(Render *re); extern void free_render_qmcsampler(Render *re); -#endif /* RENDER_EXT_H */ - +#endif /* __RENDERCORE_H__ */ diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index d116dfe7b17..5213f14d773 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -88,7 +88,7 @@ void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); -int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]); +int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]); /* functions are not exported... so wrong names */ diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index a8519d8a7fb..4f6e005d742 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -60,7 +60,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip); void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from); -void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float *dxyview, float *co, float *dxco, float *dyco); +void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]); void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z); void shade_input_set_uv(struct ShadeInput *shi); void shade_input_set_normals(struct ShadeInput *shi); diff --git a/source/blender/render/intern/include/sunsky.h b/source/blender/render/intern/include/sunsky.h index 74e42109be5..04aff810bbb 100644 --- a/source/blender/render/intern/include/sunsky.h +++ b/source/blender/render/intern/include/sunsky.h @@ -69,7 +69,7 @@ typedef struct SunSky { float atm_BetaRM[3]; } SunSky; -void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness, +void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, float spread, float sun_brightness, float sun_size, float back_scatter, float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace); diff --git a/source/blender/render/intern/include/texture_ocean.h b/source/blender/render/intern/include/texture_ocean.h index 7d4110aadf3..121142aa0b0 100644 --- a/source/blender/render/intern/include/texture_ocean.h +++ b/source/blender/render/intern/include/texture_ocean.h @@ -23,4 +23,9 @@ * ***** END GPL LICENSE BLOCK ***** */ -int ocean_texture(struct Tex *tex, float *texvec, struct TexResult *texres); +#ifndef __TEXTURE_OCEAN_H__ +#define __TEXTURE_OCEAN_H__ + +int ocean_texture(struct Tex *tex, const float texvec[2], struct TexResult *texres); + +#endif /* __TEXTURE_OCEAN_H__ */ diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index 8e402bc5418..9aa280d8276 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -30,8 +30,8 @@ */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax); -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co); +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]); +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]); void volume_precache(Render *re); void free_volume_precache(Render *re); diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 6f14c6153f9..c3babf99d51 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -467,7 +467,7 @@ float RE_rayobject_cost(RayObject *r) /* Bounding Boxes */ -void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) +void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3]) { if (RE_rayobject_isRayFace(r)) { RayFace *face = (RayFace *) RE_rayobject_align(r); diff --git a/source/blender/render/intern/raytrace/rayobject_internal.h b/source/blender/render/intern/raytrace/rayobject_internal.h index 3f768e5adcb..07672f7bfb2 100644 --- a/source/blender/render/intern/raytrace/rayobject_internal.h +++ b/source/blender/render/intern/raytrace/rayobject_internal.h @@ -124,9 +124,9 @@ typedef int (*RE_rayobject_raycast_callback)(RayObject *, struct Isect *); typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); typedef void (*RE_rayobject_done_callback)(RayObject *); typedef void (*RE_rayobject_free_callback)(RayObject *); -typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); +typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float min[3], float max[3]); typedef float (*RE_rayobject_cost_callback)(RayObject *); -typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float *, float *); +typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float min[3], float max[3]); typedef struct RayObjectAPI { RE_rayobject_raycast_callback raycast; @@ -154,5 +154,4 @@ int RE_rayobject_intersect(RayObject *r, struct Isect *i); } #endif -#endif - +#endif /* __RAYOBJECT_INTERNAL_H__ */ diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 5ae716ac942..77e9dc9d8fd 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -382,8 +382,12 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa while (TRUE) { - if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) ; - else ocface[oc->ocres * x + y] = 1; + if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) { + /* pass*/ + } + else { + ocface[oc->ocres * x + y] = 1; + } labdao = labda; if (labdax == labday) { diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 3926e8b8e51..678aa8e5634 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -193,7 +193,7 @@ static void rtbuild_calc_bb(RTBuilder *b) } } -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) +void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]) { rtbuild_calc_bb(b); DO_MIN(b->bb, min); @@ -457,26 +457,26 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) /* * Bounding Box utils */ -float bb_volume(float *min, float *max) +float bb_volume(const float min[3], const float max[3]) { return (max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2]); } -float bb_area(float *min, float *max) +float bb_area(const float min[3], const float max[3]) { float sub[3], a; sub[0] = max[0] - min[0]; sub[1] = max[1] - min[1]; sub[2] = max[2] - min[2]; - a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2; + a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2.0f; /* used to have an assert() here on negative results * however, in this case its likely some overflow or ffast math error. * so just return 0.0f instead. */ return a < 0.0f ? 0.0f : a; } -int bb_largest_axis(float *min, float *max) +int bb_largest_axis(const float min[3], const float max[3]) { float sub[3]; @@ -497,7 +497,9 @@ int bb_largest_axis(float *min, float *max) } } -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max) +/* only returns 0 if merging inner and outerbox would create a box larger than outer box */ +int bb_fits_inside(const float outer_min[3], const float outer_max[3], + const float inner_min[3], const float inner_max[3]) { int i; for (i = 0; i < 3; i++) diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h index 22e3d009c07..9e296da144b 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -86,7 +86,7 @@ RTBuilder *rtbuild_create(int size); void rtbuild_free(RTBuilder *b); void rtbuild_add(RTBuilder *b, RayObject *o); void rtbuild_done(RTBuilder *b, RayObjectControl *c); -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); +void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]); int rtbuild_size(RTBuilder *b); RayObject *rtbuild_get_primitive(RTBuilder *b, int offset); @@ -109,13 +109,14 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); /* bb utils */ -float bb_area(float *min, float *max); -float bb_volume(float *min, float *max); -int bb_largest_axis(float *min, float *max); -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max); /* only returns 0 if merging inner and outerbox would create a box larger than outer box */ +float bb_area(const float min[3], const float max[3]); +float bb_volume(const float min[3], const float max[3]); +int bb_largest_axis(const float min[3], const float max[3]); +int bb_fits_inside(const float outer_min[3], const float outer_max[3], + const float inner_min[3], const float inner_max[3]); #ifdef __cplusplus } #endif -#endif +#endif /* __RAYOBJECT_RTBUILD_H__ */ diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index a58094e5021..4fdf3ac23e8 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -29,12 +29,11 @@ * \ingroup render */ - -#ifdef __SSE__ - #ifndef __SVBVH_H__ #define __SVBVH_H__ +#ifdef __SSE__ + #include "bvh.h" #include "BLI_memarena.h" #include "BKE_global.h" @@ -231,7 +230,7 @@ struct Reorganize_SVBVH { return node; } - void copy_bb(float *bb, const float *old_bb) + void copy_bb(float bb[6], const float old_bb[6]) { std::copy(old_bb, old_bb + 6, bb); } @@ -282,7 +281,7 @@ struct Reorganize_SVBVH { useless_bb += alloc_childs - nchilds; while (alloc_childs > nchilds) { - const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN }; + const static float def_bb[6] = {FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX}; alloc_childs--; node->child[alloc_childs] = NULL; copy_bb(node->child_bb + alloc_childs * 6, def_bb); @@ -311,7 +310,6 @@ struct Reorganize_SVBVH { } }; -#endif - -#endif //__SSE__ +#endif /* __SSE__ */ +#endif /* __SVBVH_H__ */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index e3db4b7c266..e399951bd15 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4149,8 +4149,12 @@ static void set_fullsample_trace_flag(Render *re, ObjectRen *obr) vlr->flag |= R_FULL_OSA; } else if (trace) { - if (mode & MA_SHLESS); - else if (vlr->mat->material_type == MA_TYPE_VOLUME); + if (mode & MA_SHLESS) { + /* pass */ + } + else if (vlr->mat->material_type == MA_TYPE_VOLUME) { + /* pass */ + } else if ((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP))) { /* for blurry reflect/refract, better to take more samples * inside the raytrace than as OSA samples */ @@ -4768,10 +4772,12 @@ void RE_Database_Free(Render *re) static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob) { /* override not showing object when duplis are used with particles */ - if (ob->transflag & OB_DUPLIPARTS) - ; /* let particle system(s) handle showing vs. not showing */ - else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) + if (ob->transflag & OB_DUPLIPARTS) { + /* pass */ /* let particle system(s) handle showing vs. not showing */ + } + else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) { return 0; + } /* don't add non-basic meta objects, ends up having renderobjects with no geometry */ if (ob->type == OB_MBALL && ob!=BKE_mball_basis_find(re->scene, ob)) diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 03eb21dfa23..910307f370b 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -154,6 +154,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); envre->scene = re->scene; /* unsure about this... */ + envre->scene_color_manage = re->scene_color_manage; envre->lay = re->lay; /* view stuff in env render */ @@ -642,31 +643,31 @@ static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) /* ------------------------------------------------------------------------- */ -static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int face) +static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const float dyt[3], int face) { if (face == 2 || face == 4) { - dxts[0] = dxt[0]; - dyts[0] = dyt[0]; - dxts[1] = dxt[2]; - dyts[1] = dyt[2]; + r_dxt[0] = dxt[0]; + r_dyt[0] = dyt[0]; + r_dxt[1] = dxt[2]; + r_dyt[1] = dyt[2]; } else if (face == 3 || face == 5) { - dxts[0] = dxt[1]; - dxts[1] = dxt[2]; - dyts[0] = dyt[1]; - dyts[1] = dyt[2]; + r_dxt[0] = dxt[1]; + r_dxt[1] = dxt[2]; + r_dyt[0] = dyt[1]; + r_dyt[1] = dyt[2]; } else { - dxts[0] = dxt[0]; - dyts[0] = dyt[0]; - dxts[1] = dxt[1]; - dyts[1] = dyt[1]; + r_dxt[0] = dxt[0]; + r_dyt[0] = dyt[0]; + r_dxt[1] = dxt[1]; + r_dyt[1] = dyt[1]; } } /* ------------------------------------------------------------------------- */ -int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) { extern Render R; /* only in this call */ /* texvec should be the already reflected normal */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 6c86f2a2999..154292a3065 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -150,8 +150,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul fx-= xs; fy-= ys; - if ( (tex->flag & TEX_CHECKER_ODD)==0) { - if ((xs+ys) & 1);else return retval; + if ( (tex->flag & TEX_CHECKER_ODD) == 0) { + if ((xs + ys) & 1) { + /* pass */ + } + else { + return retval; + } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { if ((xs+ys) & 1) return retval; @@ -474,7 +479,9 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) muly= 1.0; - if (starty==endy); + if (starty==endy) { + /* pass */ + } else { if (y==starty) muly= 1.0f-(rf->ymin - y); if (y==endy) muly= (rf->ymax - y); @@ -1453,8 +1460,12 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const image_mipmap_test(tex, ibuf); if (tex->imaflag & TEX_USEALPHA) { - if (tex->imaflag & TEX_CALCALPHA); - else texres->talpha= 1; + if (tex->imaflag & TEX_CALCALPHA) { + /* pass */ + } + else { + texres->talpha = TRUE; + } } texr.talpha= texres->talpha; @@ -1550,11 +1561,17 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const if (boundary==0) { if ( (tex->flag & TEX_CHECKER_ODD)==0) { - if ((xs+ys) & 1); - else return retval; + if ((xs + ys) & 1) { + /* pass */ + } + else { + return retval; + } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { - if ((xs+ys) & 1) return retval; + if ((xs + ys) & 1) { + return retval; + } } fx-= xs; fy-= ys; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 88c64b44b64..2b564a09024 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -558,20 +558,19 @@ void initparts(Render *re, int do_crop) xparts = re->r.xparts; yparts = re->r.yparts; - /* mininum part size, but for exr tile saving it was checked already */ - if (!(re->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE))) { - if (re->r.mode & R_PANORAMA) { - if (ceil(re->rectx / (float)xparts) < 8) - xparts = 1 + re->rectx / 8; - } - else + /* minimum part size */ + if (re->r.mode & R_PANORAMA) { + if (ceil(re->rectx / (float)xparts) < 8) + xparts = 1 + re->rectx / 8; + } + else { if (ceil(re->rectx / (float)xparts) < 64) xparts = 1 + re->rectx / 64; - - if (ceil(re->recty / (float)yparts) < 64) - yparts = 1 + re->recty / 64; } + if (ceil(re->recty / (float)yparts) < 64) + yparts = 1 + re->recty / 64; + /* part size */ partx = ceil(re->rectx / (float)xparts); party = ceil(re->recty / (float)yparts); diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index af774c5be73..895c5d6c8fb 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -625,9 +625,12 @@ static void occ_build_sh_normalize(OccNode *node) sh_mul(node->sh, 1.0f / node->area); for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) ; - else if (node->child[b].node) + if (node->childflag & (1 << b)) { + /* pass */ + } + else if (node->child[b].node) { occ_build_sh_normalize(node->child[b].node); + } } } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 981f705e07c..648c27e0d2f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -508,7 +508,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (re->r.scemode & R_PREVIEWBUTS) { - if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) ; + if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) { + /* pass */ + } else { render_result_free(re->result); re->result = NULL; @@ -657,8 +659,12 @@ static void *do_part_thread(void *pa_v) } else if (render_display_draw_enabled(&R)) { /* on break, don't merge in result for preview renders, looks nicer */ - if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) ; - else render_result_merge(R.result, pa->result); + if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) { + /* pass */ + } + else { + render_result_merge(R.result, pa->result); + } } } @@ -1592,6 +1598,7 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) re->main = bmain; re->scene = sce; + re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */ @@ -1974,7 +1981,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r if (scene->r.scemode & R_DOCOMP) { if (scene->use_nodes) { if (!scene->nodetree) { - BKE_report(reports, RPT_ERROR, "No Nodetree in Scene"); + BKE_report(reports, RPT_ERROR, "No node tree in Scene"); return 0; } @@ -2089,6 +2096,7 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc re->main = bmain; re->scene = scene; + re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); re->camera_override = camera_override; re->lay = lay; @@ -2201,6 +2209,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie /* note; the way it gets 32 bits rects is weak... */ if (ibuf->rect == NULL) { ibuf->rect = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect"); + ibuf->mall |= IB_rect; RE_ResultGet32(re, ibuf->rect); do_free = TRUE; } @@ -2214,6 +2223,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie if (do_free) { MEM_freeN(ibuf->rect); ibuf->rect = NULL; + ibuf->mall &= ~IB_rect; } /* imbuf knows which rects are not part of ibuf */ @@ -2434,6 +2444,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) re->main = bmain; re->scene = sce; + re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); re->lay = sce->lay; camera = RE_GetCamera(re); @@ -2478,6 +2489,7 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) re = RE_NewRender(scene->id.name); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene = scene; + re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); success = render_result_exr_file_read(re, 0); diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 49c2bf1d053..f8462dcd888 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" @@ -405,7 +406,7 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData * } -int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) +int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) { int retval = TEX_INT; PointDensity *pd = tex->pd; @@ -481,7 +482,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) case TEX_PD_COLOR_PARTAGE: if (pd->coba) { if (do_colorband(pd->coba, age, col)) { - texres->talpha= 1; + texres->talpha = TRUE; copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; @@ -494,7 +495,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) if (pd->coba) { if (do_colorband(pd->coba, speed, col)) { - texres->talpha= 1; + texres->talpha = TRUE; copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; @@ -503,7 +504,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) break; } case TEX_PD_COLOR_PARTVEL: - texres->talpha= 1; + texres->talpha = TRUE; mul_v3_fl(vec, pd->speed_scale); copy_v3_v3(&texres->tr, vec); texres->ta = texres->tin; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index aa35d73f3b5..260a80d70e9 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -2532,7 +2532,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]) #if 0 /* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */ -static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co) +static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float co[3]) { Isect isec; float lampco[3]; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 982f7e7d824..167e91272e2 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -35,6 +35,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_noise.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -184,7 +185,7 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres) -static int blend(Tex *tex, float *texvec, TexResult *texres) +static int blend(Tex *tex, const float texvec[3], TexResult *texres) { float x, y, t; @@ -236,7 +237,7 @@ static int blend(Tex *tex, float *texvec, TexResult *texres) /* newnoise: all noisebased types now have different noisebases to choose from */ -static int clouds(Tex *tex, float *texvec, TexResult *texres) +static int clouds(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -331,7 +332,7 @@ static float wood_int(Tex *tex, float x, float y, float z) return wi; } -static int wood(Tex *tex, float *texvec, TexResult *texres) +static int wood(Tex *tex, const float texvec[3], TexResult *texres) { int rv=TEX_INT; @@ -382,7 +383,7 @@ static float marble_int(Tex *tex, float x, float y, float z) return mi; } -static int marble(Tex *tex, float *texvec, TexResult *texres) +static int marble(Tex *tex, const float texvec[3], TexResult *texres) { int rv=TEX_INT; @@ -406,7 +407,7 @@ static int marble(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ -static int magic(Tex *tex, float *texvec, TexResult *texres) +static int magic(Tex *tex, const float texvec[3], TexResult *texres) { float x, y, z, turb=1.0; int n; @@ -482,7 +483,7 @@ static int magic(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: stucci also modified to use different noisebasis */ -static int stucci(Tex *tex, float *texvec, TexResult *texres) +static int stucci(Tex *tex, const float texvec[3], TexResult *texres) { float nor[3], b2, ofs; int retval= TEX_INT; @@ -524,7 +525,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: musgrave terrain noise types */ -static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_mFractalOrfBmTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, int); @@ -554,7 +555,7 @@ static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_ridgedOrHybridMFTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, float, float, int); @@ -585,7 +586,7 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_HTerrainTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -610,7 +611,7 @@ static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_distNoiseTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -639,7 +640,7 @@ static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */ -static float voronoiTex(Tex *tex, float *texvec, TexResult *texres) +static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */ @@ -868,7 +869,7 @@ static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, f /* ------------------------------------------------------------------------- */ -static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], float *dxt, float *dyt) +static void do_2d_mapping(MTex *mtex, float texvec[3], VlakRen *vlr, const float n[3], float dxt[3], float dyt[3]) { Tex *tex; Object *ob= NULL; @@ -884,15 +885,15 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], if (R.osa==0) { if (wrap==MTEX_FLAT) { - fx = (t[0] + 1.0f) / 2.0f; - fy = (t[1] + 1.0f) / 2.0f; + fx = (texvec[0] + 1.0f) / 2.0f; + fy = (texvec[1] + 1.0f) / 2.0f; } - else if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else if (wrap==MTEX_SPHERE) map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); + else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); else { - if (texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else if (texco == TEXCO_GLOB) cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); } /* repeat */ @@ -932,14 +933,14 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], fy= tex->cropymin+ fy*fac1; } - t[0]= fx; - t[1]= fy; + texvec[0]= fx; + texvec[1]= fy; } else { if (wrap==MTEX_FLAT) { - fx= (t[0] + 1.0f) / 2.0f; - fy= (t[1] + 1.0f) / 2.0f; + fx= (texvec[0] + 1.0f) / 2.0f; + fy= (texvec[1] + 1.0f) / 2.0f; dxt[0]/= 2.0f; dxt[1]/= 2.0f; dxt[2]/= 2.0f; @@ -950,29 +951,36 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], else if (ELEM(wrap, MTEX_TUBE, MTEX_SPHERE)) { /* exception: the seam behind (y<0.0) */ ok= 1; - if (t[1]<=0.0f) { - fx= t[0]+dxt[0]; - fy= t[0]+dyt[0]; - if (fx>=0.0f && fy>=0.0f && t[0]>=0.0f); - else if (fx<=0.0f && fy<=0.0f && t[0]<=0.0f); - else ok= 0; + if (texvec[1]<=0.0f) { + fx= texvec[0]+dxt[0]; + fy= texvec[0]+dyt[0]; + if (fx>=0.0f && fy>=0.0f && texvec[0]>=0.0f) { + /* pass */ + } + else if (fx<=0.0f && fy<=0.0f && texvec[0]<=0.0f) { + /* pass */ + } + else { + ok = 0; + } } + if (ok) { if (wrap==MTEX_TUBE) { - map_to_tube(area, area+1, t[0], t[1], t[2]); - map_to_tube(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]); - map_to_tube(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]); + map_to_tube(area, area+1, texvec[0], texvec[1], texvec[2]); + map_to_tube(area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]); + map_to_tube(area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]); } else { - map_to_sphere(area, area+1, t[0], t[1], t[2]); - map_to_sphere(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]); - map_to_sphere(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]); + map_to_sphere(area, area+1, texvec[0], texvec[1], texvec[2]); + map_to_sphere(area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]); + map_to_sphere(area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]); } areaflag= 1; } else { - if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); + else map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); dxt[0]/= 2.0f; dxt[1]/= 2.0f; dyt[0]/= 2.0f; @@ -981,9 +989,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], } else { - if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else proj = cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); if (proj==1) { SWAP(float, dxt[1], dxt[2]); @@ -1083,117 +1091,117 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], dyt[1]*= fac1; } - t[0]= fx; - t[1]= fy; + texvec[0]= fx; + texvec[1]= fy; } } /* ************************************** */ -static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output) +static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output) { float tmpvec[3]; - int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ + int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */ - texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */ + texres->talpha = FALSE; /* is set when image texture returns alpha (considered premul) */ if (tex->use_nodes && tex->nodetree) { retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, - tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); + tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); } - else - switch (tex->type) { - - case 0: - texres->tin= 0.0f; - return 0; - case TEX_CLOUDS: - retval= clouds(tex, texvec, texres); - break; - case TEX_WOOD: - retval= wood(tex, texvec, texres); - break; - case TEX_MARBLE: - retval= marble(tex, texvec, texres); - break; - case TEX_MAGIC: - retval= magic(tex, texvec, texres); - break; - case TEX_BLEND: - retval= blend(tex, texvec, texres); - break; - case TEX_STUCCI: - retval= stucci(tex, texvec, texres); - break; - case TEX_NOISE: - retval= texnoise(tex, texres); - break; - case TEX_IMAGE: - if (osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); - else retval= imagewrap(tex, tex->ima, NULL, texvec, texres); - BKE_image_tag_time(tex->ima); /* tag image as having being used */ - break; - case TEX_ENVMAP: - retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres); - break; - case TEX_MUSGRAVE: - /* newnoise: musgrave types */ - - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - switch (tex->stype) { - case TEX_MFRACTAL: - case TEX_FBM: - retval= mg_mFractalOrfBmTex(tex, tmpvec, texres); - break; - case TEX_RIDGEDMF: - case TEX_HYBRIDMF: - retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres); - break; - case TEX_HTERRAIN: - retval= mg_HTerrainTex(tex, tmpvec, texres); - break; + else { + switch (tex->type) { + case 0: + texres->tin= 0.0f; + return 0; + case TEX_CLOUDS: + retval = clouds(tex, texvec, texres); + break; + case TEX_WOOD: + retval = wood(tex, texvec, texres); + break; + case TEX_MARBLE: + retval = marble(tex, texvec, texres); + break; + case TEX_MAGIC: + retval = magic(tex, texvec, texres); + break; + case TEX_BLEND: + retval = blend(tex, texvec, texres); + break; + case TEX_STUCCI: + retval = stucci(tex, texvec, texres); + break; + case TEX_NOISE: + retval = texnoise(tex, texres); + break; + case TEX_IMAGE: + if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); + else retval = imagewrap(tex, tex->ima, NULL, texvec, texres); + BKE_image_tag_time(tex->ima); /* tag image as having being used */ + break; + case TEX_ENVMAP: + retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres); + break; + case TEX_MUSGRAVE: + /* newnoise: musgrave types */ + + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + switch (tex->stype) { + case TEX_MFRACTAL: + case TEX_FBM: + retval = mg_mFractalOrfBmTex(tex, tmpvec, texres); + break; + case TEX_RIDGEDMF: + case TEX_HYBRIDMF: + retval = mg_ridgedOrHybridMFTex(tex, tmpvec, texres); + break; + case TEX_HTERRAIN: + retval = mg_HTerrainTex(tex, tmpvec, texres); + break; + } + break; + /* newnoise: voronoi type */ + case TEX_VORONOI: + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + retval = voronoiTex(tex, tmpvec, texres); + break; + case TEX_DISTNOISE: + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + retval = mg_distNoiseTex(tex, tmpvec, texres); + break; + case TEX_POINTDENSITY: + retval = pointdensitytex(tex, texvec, texres); + break; + case TEX_VOXELDATA: + retval = voxeldatatex(tex, texvec, texres); + break; + case TEX_OCEAN: + retval = ocean_texture(tex, texvec, texres); + break; } - break; - /* newnoise: voronoi type */ - case TEX_VORONOI: - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - retval= voronoiTex(tex, tmpvec, texres); - break; - case TEX_DISTNOISE: - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - retval= mg_distNoiseTex(tex, tmpvec, texres); - break; - case TEX_POINTDENSITY: - retval= pointdensitytex(tex, texvec, texres); - break; - case TEX_VOXELDATA: - retval= voxeldatatex(tex, texvec, texres); - break; - case TEX_OCEAN: - retval= ocean_texture(tex, texvec, texres); - break; } if (tex->flag & TEX_COLORBAND) { float col[4]; if (do_colorband(tex->coba, texres->tin, col)) { - texres->talpha= 1; + texres->talpha = TRUE; texres->tr= col[0]; texres->tg= col[1]; texres->tb= col[2]; @@ -1205,7 +1213,8 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, } /* this is called from the shader and texture nodes */ -int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output, ShadeInput *shi, MTex *mtex) +int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, + const short thread, short which_output, ShadeInput *shi, MTex *mtex) { if (tex==NULL) { memset(texres, 0, sizeof(TexResult)); @@ -1221,13 +1230,13 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, if (mtex) { /* we have mtex, use it for 2d mapping images only */ do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); - rgbnor= multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); } } @@ -1257,12 +1266,13 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, return rgbnor; } - else + else { return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + } } /* this is called for surface shading */ -static int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, float *dyt, TexResult *texres) +static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres) { Tex *tex = mtex->tex; @@ -1279,13 +1289,13 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, /* Warning, if the texres's values are not declared zero, check the return value to be sure * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */ -int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) { return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL); } /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */ -int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres) +int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres) { int use_nodes= tex->use_nodes, retval; @@ -1510,7 +1520,8 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen return in; } -static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt) +static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, + const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) { /* new: first swap coords, then map, then trans/scale */ if (tex->type == TEX_IMAGE) { @@ -1542,10 +1553,10 @@ static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, floa texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f; texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f; if (shi->osatex) { - dxt[0] = mtex->size[0]*dxt[0]; - dxt[1] = mtex->size[1]*dxt[1]; - dyt[0] = mtex->size[0]*dyt[0]; - dyt[1] = mtex->size[1]*dyt[1]; + dxt[0] = mtex->size[0] * dxt[0]; + dxt[1] = mtex->size[1] * dxt[1]; + dyt[0] = mtex->size[0] * dyt[0]; + dyt[1] = mtex->size[1] * dyt[1]; } /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */ @@ -1675,7 +1686,8 @@ static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *s } } -static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) +static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, + float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; @@ -1831,7 +1843,9 @@ static void ntap_bump_init(NTapBump *ntap_bump) memset(ntap_bump, 0, sizeof(*ntap_bump)); } -static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) +static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, + float Tnor, const float co[3], const float dx[3], const float dy[3], + float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ @@ -2257,11 +2271,11 @@ void do_material_tex(ShadeInput *shi, Render *re) if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { if (use_compat_bump) { rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); } else if (use_ntap_bump) { rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); } else { texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); @@ -2377,7 +2391,7 @@ void do_material_tex(ShadeInput *shi, Render *re) ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } @@ -2445,7 +2459,9 @@ void do_material_tex(ShadeInput *shi, Render *re) copy_v3_v3(nor, texres.nor); - if (mtex->normapspace == MTEX_NSPACE_CAMERA); + if (mtex->normapspace == MTEX_NSPACE_CAMERA) { + /* pass */ + } else if (mtex->normapspace == MTEX_NSPACE_WORLD) { mul_mat3_m4_v3(re->viewmat, nor); } @@ -2651,6 +2667,13 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ mul_m4_v3(shi->obi->duplitexmat, co); } mul_m4_v3(ob->imat_ren, co); + + if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { + /* use bb vec[0] as min and bb vec[6] as max */ + co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; + co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; + co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; + } } } /* not really orco, but 'local' */ @@ -2663,6 +2686,13 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ Object *ob= shi->obi->ob; copy_v3_v3(co, xyz); mul_m4_v3(ob->imat_ren, co); + + if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { + /* use bb vec[0] as min and bb vec[6] as max */ + co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; + co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; + co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; + } } } else if (mtex->texco==TEXCO_GLOB) { @@ -2729,6 +2759,12 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ if ((rgbnor & TEX_RGB) == 0) { copy_v3_v3(tcol, &mtex->r); } + else if (mtex->mapto & MAP_DENSITY) { + copy_v3_v3(tcol, &texres.tr); + if (texres.talpha) { + texres.tin = stencilTin; + } + } else { copy_v3_v3(tcol, &texres.tr); if (texres.talpha) { @@ -2887,7 +2923,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } @@ -2922,10 +2958,14 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) } if (mtex->mapto & MAP_ALPHA) { if (rgb) { - if (texres.talpha) texres.tin= texres.ta; - else texres.tin = rgb_to_bw(&texres.tr); + if (texres.talpha) { + texres.tin = texres.ta; + } + else { + texres.tin = rgb_to_bw(&texres.tr); + } } - + col_r[3]*= texres.tin; } } @@ -3102,7 +3142,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } @@ -3316,7 +3356,7 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 0d894073cee..0bfbed8e58c 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -59,6 +59,7 @@ #include "BKE_main.h" #include "BKE_node.h" #include "BKE_texture.h" +#include "BKE_scene.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -93,7 +94,7 @@ extern struct Render R; /* x and y are current pixels in rect to be rendered */ /* do not normalize! */ -void calc_view_vector(float *view, float x, float y) +void calc_view_vector(float view[3], float x, float y) { view[2]= -ABS(R.clipsta); @@ -271,16 +272,26 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl) har= R.sortedhalos[a]; /* layer test, clip halo with y */ - if ((har->lay & lay)==0); - else if (testrect.ymin > har->maxy); - else if (testrect.ymax < har->miny); + if ((har->lay & lay) == 0) { + /* pass */ + } + else if (testrect.ymin > har->maxy) { + /* pass */ + } + else if (testrect.ymax < har->miny) { + /* pass */ + } else { minx= floor(har->xs-har->rad); maxx= ceil(har->xs+har->rad); - if (testrect.xmin > maxx); - else if (testrect.xmax < minx); + if (testrect.xmin > maxx) { + /* pass */ + } + else if (testrect.xmax < minx) { + /* pass */ + } else { minx= MAX2(minx, testrect.xmin); @@ -980,7 +991,9 @@ static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl) float *rectf= rlpp[sample]->rectf; for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) { - if (rectf[3] >= 1.0f); + if (rectf[3] >= 1.0f) { + /* pass */ + } else if (rectf[3] > 0.0f) { rectf[0] /= rectf[3]; rectf[1] /= rectf[3]; @@ -1833,16 +1846,23 @@ static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* pos har->miny= miny= haloys - har->rad/R.ycor; har->maxy= maxy= haloys + har->rad/R.ycor; - if (maxy<0); - else if (rr->recty<miny); + if (maxy < 0) { + /* pass */ + } + else if (rr->recty < miny) { + /* pass */ + } else { - minx= floor(haloxs-har->rad); - maxx= ceil(haloxs+har->rad); + minx = floor(haloxs - har->rad); + maxx = ceil(haloxs + har->rad); - if (maxx<0); - else if (rr->rectx<minx); + if (maxx < 0) { + /* pass */ + } + else if (rr->rectx < minx) { + /* pass */ + } else { - if (minx<0) minx= 0; if (maxx>=rr->rectx) maxx= rr->rectx-1; if (miny<0) miny= 0; @@ -2099,7 +2119,9 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua copy_v3_v3(nor, shi->vn); - if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA); + if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) { + /* pass */ + } else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { float mat[3][3], imat[3][3]; @@ -2202,7 +2224,8 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua float rgb[3]; copy_v3_v3(rgb, shr.combined); - IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); + if (R.scene_color_manage) + IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); rgb_float_to_uchar(col, rgb); } else { @@ -2492,7 +2515,9 @@ static int get_next_bake_face(BakeShade *bs) /* clear image */ if (R.r.bake_flag & R_BAKE_CLEAR) IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); - + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + /* might be read by UI to set active image for display */ R.bakebuf= ima; } @@ -2630,6 +2655,8 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up Image *ima; int a, vdone = FALSE, use_mask = FALSE, result = BAKE_RESULT_OK; + re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene); + /* initialize render global */ R= *re; R.bakebuf= NULL; @@ -2712,7 +2739,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter); ibuf->userflags |= IB_BITMAPDIRTY; - if (ibuf->rect_float) IMB_rect_from_float(ibuf); } } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 6395a04b534..1721741d64d 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -976,10 +976,13 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, if (ma->mtex[0]) { - if ( (ma->mode & MA_HALOTEX) ) har->tex= 1; - else if (har->mat->septex & (1<<0)); /* only 1 level textures */ + if (ma->mode & MA_HALOTEX) { + har->tex = 1; + } + else if (har->mat->septex & (1 << 0)) { + /* only 1 level textures */ + } else { - mtex= ma->mtex[0]; copy_v3_v3(texvec, vec); @@ -1353,40 +1356,42 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } -int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4]) +int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4]) { float mat[4][4], vec[4]; - int a, fl, flag= -1; + int a, fl, flag = -1; copy_m4_m4(mat, winmat); - for (a=0; a<8; a++) { + for (a=0; a < 8; a++) { vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0]; vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1]; vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2]; vec[3]= 1.0; mul_m4_v4(mat, vec); - fl= 0; + fl = 0; if (bounds) { - if (vec[0] < bounds[0]*vec[3]) fl |= 1; - else if (vec[0] > bounds[1]*vec[3]) fl |= 2; + if (vec[0] < bounds[0] * vec[3]) fl |= 1; + else if (vec[0] > bounds[1] * vec[3]) fl |= 2; - if (vec[1] > bounds[3]*vec[3]) fl |= 4; - else if (vec[1]< bounds[2]*vec[3]) fl |= 8; + if (vec[1] > bounds[3] * vec[3]) fl |= 4; + else if (vec[1] < bounds[2] * vec[3]) fl |= 8; } else { - if (vec[0] < -vec[3]) fl |= 1; - else if (vec[0] > vec[3]) fl |= 2; + if (vec[0] < -vec[3]) fl |= 1; + else if (vec[0] > vec[3]) fl |= 2; - if (vec[1] > vec[3]) fl |= 4; + if (vec[1] > vec[3]) fl |= 4; else if (vec[1] < -vec[3]) fl |= 8; } - if (vec[2] < -vec[3]) fl |= 16; - else if (vec[2] > vec[3]) fl |= 32; + if (vec[2] < -vec[3]) fl |= 16; + else if (vec[2] > vec[3]) fl |= 32; flag &= fl; - if (flag==0) return 0; + if (flag == 0) { + return 0; + } } return flag; diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index ff543b8ce06..36e9f4cb785 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -87,12 +87,6 @@ extern struct Render R; * */ -#define VECADDISFAC(v1,v3,fac) { \ - *(v1 + 0) += *(v3 + 0) * (fac); \ - *(v1 + 1) += *(v3 + 1) * (fac); \ - *(v1 + 2) += *(v3 + 2) * (fac); \ -} (void)0 - /* initialize material variables in shadeinput, * doing inverse gamma correction where applicable */ void shade_input_init_material(ShadeInput *shi) @@ -121,13 +115,13 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) shi->depth--; /* a couple of passes */ - VECADDISFAC(shr->combined, shr_t.combined, fac); + madd_v3_v3fl(shr->combined, shr_t.combined, fac); if (shi->passflag & SCE_PASS_SPEC) - VECADDISFAC(shr->spec, shr_t.spec, fac); + madd_v3_v3fl(shr->spec, shr_t.spec, fac); if (shi->passflag & SCE_PASS_DIFFUSE) - VECADDISFAC(shr->diff, shr_t.diff, fac); + madd_v3_v3fl(shr->diff, shr_t.diff, fac); if (shi->passflag & SCE_PASS_SHADOW) - VECADDISFAC(shr->shad, shr_t.shad, fac); + madd_v3_v3fl(shr->shad, shr_t.shad, fac); negate_v3(shi->vn); negate_v3(shi->facenor); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 6742244ea61..100cbd416e0 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -123,30 +123,45 @@ float mistfactor(float zcor, float const co[3]) { float fac, hi; - fac= zcor - R.wrld.miststa; /* zcor is calculated per pixel */ + fac = zcor - R.wrld.miststa; /* zcor is calculated per pixel */ /* fac= -co[2]-R.wrld.miststa; */ - if (fac>0.0f) { - if (fac< R.wrld.mistdist) { + if (fac > 0.0f) { + if (fac < R.wrld.mistdist) { - fac= (fac/(R.wrld.mistdist)); + fac = (fac / R.wrld.mistdist); - if (R.wrld.mistype==0) fac*= fac; - else if (R.wrld.mistype==1); - else fac= sqrt(fac); + if (R.wrld.mistype == 0) { + fac *= fac; + } + else if (R.wrld.mistype == 1) { + /* pass */ + } + else { + fac = sqrt(fac); + } + } + else { + fac = 1.0f; } - else fac= 1.0f; } - else fac= 0.0f; + else { + fac = 0.0f; + } /* height switched off mist */ if (R.wrld.misthi!=0.0f && fac!=0.0f) { /* at height misthi the mist is completely gone */ - hi= R.viewinv[0][2]*co[0]+R.viewinv[1][2]*co[1]+R.viewinv[2][2]*co[2]+R.viewinv[3][2]; + hi = R.viewinv[0][2] * co[0] + + R.viewinv[1][2] * co[1] + + R.viewinv[2][2] * co[2] + + R.viewinv[3][2]; - if (hi>R.wrld.misthi) fac= 0.0f; + if (hi > R.wrld.misthi) { + fac = 0.0f; + } else if (hi>0.0f) { hi= (R.wrld.misthi-hi)/R.wrld.misthi; fac*= hi*hi; @@ -453,9 +468,10 @@ static float area_lamp_energy(float (*area)[3], const float co[3], const float v /* cross product */ #define CROSS(dest, a, b) \ - { dest[0]= a[1] * b[2] - a[2] * b[1]; \ - dest[1]= a[2] * b[0] - a[0] * b[2]; \ - dest[2]= a[0] * b[1] - a[1] * b[0]; \ + { \ + dest[0]= a[1] * b[2] - a[2] * b[1]; \ + dest[1]= a[2] * b[0] - a[0] * b[2]; \ + dest[2]= a[0] * b[1] - a[1] * b[0]; \ } (void)0 CROSS(cross[0], vec[0], vec[1]); @@ -1351,7 +1367,9 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int /* this complex construction screams for a nicer implementation! (ton) */ if (R.r.mode & R_SHADOW) { if (ma->mode & MA_SHADOW) { - if (lar->type==LA_HEMI || lar->type==LA_AREA); + if (lar->type == LA_HEMI || lar->type == LA_AREA) { + /* pass */ + } else if ((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) { float thresh= shi->obr->ob->smoothresh; if (inp>thresh) @@ -1466,8 +1484,10 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int if (shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) { - if (!(passflag & (SCE_PASS_COMBINED|SCE_PASS_SPEC))); - else if (lar->type==LA_HEMI) { + if (!(passflag & (SCE_PASS_COMBINED | SCE_PASS_SPEC))) { + /* pass */ + } + else if (lar->type == LA_HEMI) { float t; /* hemi uses no spec shaders (yet) */ diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 69e738e840d..77d68e6c85a 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -238,7 +238,9 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd) float indexf, t, idxf; int index; - if (rr > (RD_TABLE_RANGE_2*RD_TABLE_RANGE_2)); + if (rr > (RD_TABLE_RANGE_2 * RD_TABLE_RANGE_2)) { + /* pass */ + } else if (rr > RD_TABLE_RANGE) { rr= sqrt(rr); indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2); @@ -379,7 +381,7 @@ static void add_radiance(ScatterTree *tree, float *frontrad, float *backrad, flo } } -static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int self, ScatterResult *result) +static void traverse_octree(ScatterTree *tree, ScatterNode *node, const float co[3], int self, ScatterResult *result) { float sub[3], dist; int i, index = 0; @@ -430,7 +432,7 @@ static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int } } -static void compute_radiance(ScatterTree *tree, float *co, float *rad) +static void compute_radiance(ScatterTree *tree, const float co[3], float *rad) { ScatterResult result; float rdsum[3], backrad[3], backrdsum[3]; diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index 94e94b98d26..1288b0305b1 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -146,7 +146,7 @@ static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, * sun_size, controls sun's size * back_scatter, controls back scatter light * */ -void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness, +void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, float spread, float sun_brightness, float sun_size, float back_scatter, float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace) { diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c index b2bc635cba7..a7547479093 100644 --- a/source/blender/render/intern/source/texture_ocean.c +++ b/source/blender/render/intern/source/texture_ocean.c @@ -55,7 +55,7 @@ extern struct Render R; /* ***** actual texture sampling ***** */ -int ocean_texture(Tex *tex, float *texvec, TexResult *texres) +int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres) { OceanTex *ot = tex->ot; ModifierData *md; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 8a92695a15e..fb7ea38ef68 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -92,7 +92,7 @@ static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset } /* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */ -static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), float *co) +static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), const float co[3]) { Isect isect= {{0}}; float dir[3] = {0.0f, 0.0f, 1.0f}; @@ -118,7 +118,7 @@ static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), flo } /* find the bounding box of an objectinstance in global space */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax) +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]) { ObjectRen *obr = obi->obr; VolumePrecache *vp = obi->volume_precache; @@ -826,7 +826,7 @@ void free_volume_precache(Render *re) BLI_freelistN(&re->volumes); } -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co) +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]) { RayObject *tree; int inside=0; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index d73171648fb..7eccacb816d 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -227,69 +227,102 @@ static void init_frame_smoke(VoxelData *vd, float cfra) /* draw code for smoke */ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { SmokeModifierData *smd = (SmokeModifierData *)md; - + SmokeDomainSettings *sds = smd->domain; - if (smd->domain && smd->domain->fluid) { - if (cfra < smd->domain->point_cache[0]->startframe) + if (sds && sds->fluid) { + if (cfra < sds->point_cache[0]->startframe) ; /* don't show smoke before simulation starts, this could be made an option in the future */ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { size_t totRes; size_t i; float *heat; - copy_v3_v3_int(vd->resol, smd->domain->res); - totRes = vd_resol_size(vd); + if (!smoke_has_heat(sds->fluid)) return; - /* scaling heat values from -2.0-2.0 to 0.0-1.0 */ + copy_v3_v3_int(vd->resol, sds->res); + totRes = vd_resol_size(vd); vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + /* get heat data */ + heat = smoke_get_heat(sds->fluid); - - heat = smoke_get_heat(smd->domain->fluid); - + /* scale heat values from -2.0-2.0 to 0.0-1.0 */ for (i = 0; i < totRes; i++) { vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; } - - /* vd->dataset = smoke_get_heat(smd->domain->fluid); */ } else if (vd->smoked_type == TEX_VD_SMOKEVEL) { size_t totRes; size_t i; float *xvel, *yvel, *zvel; - copy_v3_v3_int(vd->resol, smd->domain->res); + copy_v3_v3_int(vd->resol, sds->res); totRes = vd_resol_size(vd); - - /* scaling heat values from -2.0-2.0 to 0.0-1.0 */ vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + /* get velocity data */ + xvel = smoke_get_velocity_x(sds->fluid); + yvel = smoke_get_velocity_y(sds->fluid); + zvel = smoke_get_velocity_z(sds->fluid); - xvel = smoke_get_velocity_x(smd->domain->fluid); - yvel = smoke_get_velocity_y(smd->domain->fluid); - zvel = smoke_get_velocity_z(smd->domain->fluid); - + /* map velocities between 0 and 0.3f */ for (i = 0; i < totRes; i++) { vd->dataset[i] = sqrt(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; } } - else { + else if (vd->smoked_type == TEX_VD_SMOKEFLAME) { size_t totRes; - float *density; + float *flame; - if (smd->domain->flags & MOD_SMOKE_HIGHRES) { - smoke_turbulence_get_res(smd->domain->wt, vd->resol); - density = smoke_turbulence_get_density(smd->domain->wt); + if (sds->flags & MOD_SMOKE_HIGHRES) { + if (!smoke_turbulence_has_fuel(sds->wt)) return; + smoke_turbulence_get_res(sds->wt, vd->resol); + flame = smoke_turbulence_get_flame(sds->wt); } else { - copy_v3_v3_int(vd->resol, smd->domain->res); - density = smoke_get_density(smd->domain->fluid); + if (!smoke_has_fuel(sds->fluid)) return; + copy_v3_v3_int(vd->resol, sds->res); + flame = smoke_get_flame(sds->fluid); + } + + /* always store copy, as smoke internal data can change */ + totRes= vd_resol_size(vd); + vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); + memcpy(vd->dataset, flame, sizeof(float)*totRes); + } + else { + size_t totCells; + int depth = 4; + vd->data_type = TEX_VD_RGBA_PREMUL; + + /* data resolution */ + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_get_res(sds->wt, vd->resol); + } + else { + copy_v3_v3_int(vd->resol, sds->res); } /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ - totRes = vd_resol_size(vd); + totCells = vd_resol_size(vd) * depth; /* always store copy, as smoke internal data can change */ - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - memcpy(vd->dataset, density, sizeof(float) * totRes); + vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data"); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + if (smoke_turbulence_has_colors(sds->wt)) { + smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1); + } + else { + smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1); + } + } + else { + if (smoke_has_colors(sds->fluid)) { + smoke_get_rgba(sds->fluid, vd->dataset, 1); + } + else { + smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1); + } + } } /* end of fluid condition */ } } @@ -320,6 +353,8 @@ void cache_voxeldata(Tex *tex, int scene_frame) MEM_freeN(vd->dataset); vd->dataset = NULL; } + /* reset data_type */ + vd->data_type = TEX_VD_INTENSITY; if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; @@ -379,9 +414,11 @@ void make_voxeldata(struct Render *re) int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres) { - int retval = TEX_INT; VoxelData *vd = tex->vd; - float co[3], offset[3] = {0.5, 0.5, 0.5}; + float co[3], offset[3] = {0.5, 0.5, 0.5}, a; + int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT; + int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1; + int ch; if (vd->dataset == NULL) { texres->tin = 0.0f; @@ -420,29 +457,61 @@ int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texre break; } } - - switch (vd->interp_type) { - case TEX_VD_NEARESTNEIGHBOR: - texres->tin = BLI_voxel_sample_nearest(vd->dataset, vd->resol, co); - break; - case TEX_VD_LINEAR: - texres->tin = BLI_voxel_sample_trilinear(vd->dataset, vd->resol, co); - break; - case TEX_VD_QUADRATIC: - texres->tin = BLI_voxel_sample_triquadratic(vd->dataset, vd->resol, co); - break; - case TEX_VD_TRICUBIC_CATROM: - case TEX_VD_TRICUBIC_BSPLINE: - texres->tin = BLI_voxel_sample_tricubic(vd->dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); - break; + + for (ch = 0; ch < depth; ch++) { + float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2]; + float *result = &texres->tin; + + if (vd->data_type == TEX_VD_RGBA_PREMUL) { + switch (ch) { + case 0: + result = &texres->tr; + break; + case 1: + result = &texres->tg; + break; + case 2: + result = &texres->tb; + break; + } + } + + switch (vd->interp_type) { + case TEX_VD_NEARESTNEIGHBOR: + *result = BLI_voxel_sample_nearest(dataset, vd->resol, co); + break; + case TEX_VD_LINEAR: + *result = BLI_voxel_sample_trilinear(dataset, vd->resol, co); + break; + case TEX_VD_QUADRATIC: + *result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co); + break; + case TEX_VD_TRICUBIC_CATROM: + case TEX_VD_TRICUBIC_BSPLINE: + *result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); + break; + } } - + + a = texres->tin; texres->tin *= vd->int_multiplier; BRICONT; - texres->tr = texres->tin; - texres->tg = texres->tin; - texres->tb = texres->tin; + if (vd->data_type == TEX_VD_RGBA_PREMUL) { + /* unmultiply */ + if (a>0.001f) { + texres->tr /= a; + texres->tg /= a; + texres->tb /= a; + } + texres->talpha = 1; + } + else { + texres->tr = texres->tin; + texres->tg = texres->tin; + texres->tb = texres->tin; + } + texres->ta = texres->tin; BRICONTRGB; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index bf6962d0087..ba62baae897 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2038,7 +2038,9 @@ static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg) MEM_freeN(temprectp); - if (neg); /* z values for negative are already correct */ + if (neg) { + /* z values for negative are already correct */ + } else { /* clear not filled z values */ for (len= xs*ys -1; len>=0; len--) { diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index dae0e9193c2..ffeb7aff6fa 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../blenkernel ../blenlib ../blenloader + ../compositor ../editors/include ../editors/io ../gpu @@ -37,7 +38,6 @@ set(INC ../makesdna ../makesrna ../nodes - ../compositor ../render/extern/include ../../gameengine/BlenderRoutines ../../../intern/elbeem/extern diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 82bd37eb6cc..99d1c14059a 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -540,7 +540,11 @@ typedef struct wmOperatorType { /* verify if the operator can be executed in the current context, note * that the operator might still fail to execute even if this return true */ - int (*poll)(struct bContext *); + int (*poll)(struct bContext *) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* optional panel for redo and repeat, autogenerated if not set */ void (*ui)(struct bContext *, struct wmOperator *); @@ -564,7 +568,11 @@ typedef struct wmOperatorType { /* only used for operators defined with python * use to store pointers to python functions */ void *pyop_data; - int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot); + int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* RNA integration */ ExtensionRNA ext; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2f238cd22e7..73950bdfa19 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -255,8 +255,12 @@ void wm_event_do_notifiers(bContext *C) for (win = wm->windows.first; win; win = win->next) { /* filter out notifiers */ - if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) ; - else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) ; + if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) { + /* pass */ + } + else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) { + /* pass */ + } else { ScrArea *sa; ARegion *ar; @@ -883,8 +887,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, wm_operator_reports(C, op, retval, (reports != NULL)); } - if (retval & OPERATOR_HANDLED) - ; /* do nothing, wm_operator_exec() has been called somewhere */ + if (retval & OPERATOR_HANDLED) { + /* do nothing, wm_operator_exec() has been called somewhere */ + } else if (retval & OPERATOR_FINISHED) { if (!is_nested_call) { /* not called by py script */ WM_operator_last_properties_store(op); @@ -2919,7 +2924,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U event.keymodifier = 0; /* if test_break set, it catches this. XXX Keep global for now? */ - if (event.type == ESCKEY) + if (event.type == ESCKEY && event.val == KM_PRESS) G.is_break = TRUE; wm_event_add(win, &event); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index aab20e5849b..433c447bfd4 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -192,9 +192,12 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* cases 1 and 2 */ if (oldwmlist->first == NULL) { - if (G.main->wm.first) ; /* nothing todo */ - else + if (G.main->wm.first) { + /* nothing todo */ + } + else { wm_add_default(C); + } } else { /* cases 3 and 4 */ @@ -450,9 +453,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) if (sce->r.engine[0] && BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) { - BKE_reportf(reports, RPT_WARNING, - "Engine not available: '%s' for scene: %s, " - "an addon may need to be installed or enabled", + BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' " + "(an addon may need to be installed or enabled)", sce->r.engine, sce->id.name + 2); } } @@ -465,17 +467,17 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) else if (retval == BKE_READ_EXOTIC_OK_OTHER) BKE_write_undo(C, "Import file"); else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) { - BKE_reportf(reports, RPT_ERROR, IFACE_("Can't read file: \"%s\", %s."), filepath, - errno ? strerror(errno) : IFACE_("Unable to open the file")); + BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to open the file")); } else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) { - BKE_reportf(reports, RPT_ERROR, IFACE_("File format is not supported in file: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath); } else if (retval == BKE_READ_EXOTIC_FAIL_PATH) { - BKE_reportf(reports, RPT_ERROR, IFACE_("File path invalid: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath); } else { - BKE_reportf(reports, RPT_ERROR, IFACE_("Unknown error loading: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath); BLI_assert(!"invalid 'retval'"); } @@ -791,7 +793,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { - BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.240s'", filepath); + BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); return -1; } } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 9bb3b2a0e69..658a13a8918 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -302,7 +302,7 @@ int WM_init_game(bContext *C) else { ReportTimerInfo *rti; - BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found. Game auto start is not possible."); + BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index e4d6b3dd465..8c9d4861a9e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -79,6 +79,7 @@ #include "BIF_glutil.h" /* for paint cursor */ #include "BLF_api.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -1161,7 +1162,7 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) if ((op->type->flag & OPTYPE_REGISTER) == 0) { BKE_reportf(op->reports, RPT_ERROR, - "Operator '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + "Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } @@ -1192,11 +1193,12 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op) { /* CTX_wm_reports(C) because operator is on stack, not active in event system */ if ((op->type->flag & OPTYPE_REGISTER) == 0) { - BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + BKE_reportf(CTX_wm_reports(C), RPT_ERROR, + "Operator redo '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } if (op->type->poll && op->type->poll(C) == 0) { - BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context.", op->type->idname); + BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context", op->type->idname); return OPERATOR_CANCELLED; } @@ -1232,7 +1234,7 @@ static void WM_OT_debug_menu(wmOperatorType *ot) ot->exec = wm_debug_menu_exec; ot->poll = WM_operator_winactive; - RNA_def_int(ot->srna, "debug_value", 0, -10000, 10000, "Debug Value", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000); } @@ -1838,6 +1840,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) /* mark all library linked objects to be updated */ recalc_all_library_objects(bmain); + IMB_colormanagement_check_file_config(bmain); /* append, rather than linking */ if ((flag & FILE_LINK) == 0) { @@ -3127,7 +3130,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, /* check flags */ if ((flags & RC_PROP_REQUIRE_BOOL) && (flags & RC_PROP_REQUIRE_FLOAT)) { - BKE_reportf(op->reports, RPT_ERROR, "Property can't be both boolean and float"); + BKE_report(op->reports, RPT_ERROR, "Property cannot be both boolean and float"); return 0; } @@ -3150,7 +3153,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, if (flags & RC_PROP_ALLOW_MISSING) return 1; else { - BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name); + BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name); return 0; } } @@ -3163,8 +3166,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, ((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT)) { MEM_freeN(str); - BKE_reportf(op->reports, RPT_ERROR, - "Property from path %s is not a float", name); + BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' is not a float", name); return 0; } } @@ -3172,8 +3174,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, /* check property's array length */ if (*r_prop && (len = RNA_property_array_length(r_ptr, *r_prop)) != req_length) { MEM_freeN(str); - BKE_reportf(op->reports, RPT_ERROR, - "Property from path %s has length %d instead of %d", + BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' has length %d instead of %d", name, len, req_length); return 0; } @@ -3241,8 +3242,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op) else if (rc->image_id_ptr.data) { /* extra check, pointer must be to an ID */ if (!RNA_struct_is_ID(rc->image_id_ptr.type)) { - BKE_report(op->reports, RPT_ERROR, - "Pointer from path image_id is not an ID"); + BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID"); return 0; } } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 35cc1545c40..cf5bce568d5 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -89,6 +89,8 @@ typedef struct PlayState { short stopped; short go; + int fstep; + /* current picture */ struct PlayAnimPict *picture; @@ -213,7 +215,6 @@ typedef struct PlayAnimPict { static struct ListBase picsbase = {NULL, NULL}; static int fromdisk = FALSE; -static int fstep = 1; static float zoomx = 1.0, zoomy = 1.0; static double ptottime = 0.0, swaptime = 0.04; @@ -229,7 +230,7 @@ static int pupdate_time(void) return (ptottime < 0); } -static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid) +static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) { if (ibuf == NULL) { @@ -287,7 +288,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) int pic; ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); if (ibuf) { - playanim_toscreen(NULL, ibuf, fontid); + playanim_toscreen(NULL, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } @@ -390,7 +391,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL); } if (ibuf) { - playanim_toscreen(picture, ibuf, fontid); + playanim_toscreen(picture, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } pupdate_time(); @@ -446,34 +447,34 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) ps->pingpong = !ps->pingpong; break; case GHOST_kKeyNumpad1: - if (val) swaptime = fstep / 60.0; + if (val) swaptime = ps->fstep / 60.0; break; case GHOST_kKeyNumpad2: - if (val) swaptime = fstep / 50.0; + if (val) swaptime = ps->fstep / 50.0; break; case GHOST_kKeyNumpad3: - if (val) swaptime = fstep / 30.0; + if (val) swaptime = ps->fstep / 30.0; break; case GHOST_kKeyNumpad4: if (g_WS.qual & WS_QUAL_SHIFT) - swaptime = fstep / 24.0; + swaptime = ps->fstep / 24.0; else - swaptime = fstep / 25.0; + swaptime = ps->fstep / 25.0; break; case GHOST_kKeyNumpad5: - if (val) swaptime = fstep / 20.0; + if (val) swaptime = ps->fstep / 20.0; break; case GHOST_kKeyNumpad6: - if (val) swaptime = fstep / 15.0; + if (val) swaptime = ps->fstep / 15.0; break; case GHOST_kKeyNumpad7: - if (val) swaptime = fstep / 12.0; + if (val) swaptime = ps->fstep / 12.0; break; case GHOST_kKeyNumpad8: - if (val) swaptime = fstep / 10.0; + if (val) swaptime = ps->fstep / 10.0; break; case GHOST_kKeyNumpad9: - if (val) swaptime = fstep / 6.0; + if (val) swaptime = ps->fstep / 6.0; break; case GHOST_kKeyLeftArrow: if (val) { @@ -531,10 +532,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) { if (g_WS.qual & WS_QUAL_SHIFT) { if (ps->curframe_ibuf) - printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, fstep / swaptime); + printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, ps->fstep / swaptime); } else { - swaptime = fstep / 5.0; + swaptime = ps->fstep / 5.0; } } break; @@ -675,7 +676,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) glPixelZoom(zoomx, zoomy); glEnable(GL_DITHER); ptottime = 0.0; - playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid); + playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); break; } @@ -747,6 +748,8 @@ void WM_main_playanim(int argc, const char **argv) ps.picture = NULL; /* resetmap = FALSE */ + ps.fstep = 1; + ps.fontid = -1; while (argc > 1) { @@ -794,8 +797,8 @@ void WM_main_playanim(int argc, const char **argv) argv++; break; case 'j': - fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); - swaptime *= fstep; + ps.fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); + swaptime *= ps.fstep; argc--; argv++; break; @@ -894,11 +897,11 @@ void WM_main_playanim(int argc, const char **argv) efra = MAXFRAME; } - build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); for (i = 2; i < argc; i++) { BLI_strncpy(filepath, argv[i], sizeof(filepath)); - build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); } IMB_freeImBuf(ibuf); @@ -970,7 +973,7 @@ void WM_main_playanim(int argc, const char **argv) while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid); + playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); } /* else deleten */ else { printf("error: can't play this image type\n"); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index d0bed4e5965..44827302d7d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -300,11 +300,9 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) void wm_window_title(wmWindowManager *wm, wmWindow *win) { - /* handle the 'temp' window, only set title when not set before */ if (win->screen && win->screen->temp) { - char *title = GHOST_GetTitle(win->ghostwin); - if (title == NULL || title[0] == 0) - GHOST_SetTitle(win->ghostwin, "Blender"); + /* nothing to do for 'temp' windows, + * because WM_window_open_temp always sets window title */ } else { diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index a9522e3618d..39ed89638b2 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -300,6 +300,7 @@ struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) {return (struct void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) {} void ED_view3D_background_image_clear(struct View3D *v3d) {} void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]) {} +float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {return 0.0f;} void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist) {} int text_file_modified(struct Text *text) {return 0;} void ED_node_shader_default(struct Material *ma) {} diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 5cfa97e2e7e..6807f531f0a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -35,9 +35,9 @@ #include <stdlib.h> #include <stdio.h> -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show stl-warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show stl-warnings */ +# pragma warning (disable:4786) #endif #include "GL/glew.h" @@ -69,37 +69,33 @@ #include "Value.h" - -#ifdef __cplusplus extern "C" { -#endif - /***/ -#include "DNA_view3d_types.h" -#include "DNA_screen_types.h" -#include "DNA_userdef_types.h" -#include "DNA_windowmanager_types.h" -#include "BKE_global.h" -#include "BKE_report.h" - -#include "MEM_guardedalloc.h" - -/* #include "BKE_screen.h" */ /* cant include this because of 'new' function name */ -extern float BKE_screen_view3d_zoom_to_fac(float camzoom); - -#include "BKE_main.h" -#include "BLI_blenlib.h" -#include "BLO_readfile.h" -#include "DNA_scene_types.h" -#include "BKE_ipo.h" - /***/ - -#include "BKE_context.h" -#include "../../blender/windowmanager/WM_types.h" -#include "../../blender/windowmanager/wm_window.h" -#include "../../blender/windowmanager/wm_event_system.h" -#ifdef __cplusplus + #include "DNA_view3d_types.h" + #include "DNA_screen_types.h" + #include "DNA_userdef_types.h" + #include "DNA_scene_types.h" + #include "DNA_windowmanager_types.h" + + #include "BKE_global.h" + #include "BKE_report.h" + #include "BKE_ipo.h" + #include "BKE_main.h" + #include "BKE_context.h" + + /* avoid c++ conflict with 'new' */ + #define new _new + #include "BKE_screen.h" + #undef new + + #include "MEM_guardedalloc.h" + + #include "BLI_blenlib.h" + #include "BLO_readfile.h" + + #include "../../blender/windowmanager/WM_types.h" + #include "../../blender/windowmanager/wm_window.h" + #include "../../blender/windowmanager/wm_event_system.h" } -#endif #ifdef WITH_AUDASPACE # include "AUD_C-API.h" diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index fa0994d788a..a053e069153 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -23,7 +23,6 @@ set(INC ../../blender/makesdna ../../blender/makesrna ../../blender/windowmanager - ../../../extern/bullet2/src ../../../intern/container ../../../intern/guardedalloc ../../../intern/moto/include @@ -31,6 +30,7 @@ set(INC ) set(INC_SYS + ../../../extern/bullet2/src ${PTHREADS_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH} ) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index 4f450bcd668..1afa5d3d07b 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -33,6 +33,7 @@ #include "KX_BlenderCanvas.h" #include "DNA_screen_types.h" #include <stdio.h> +#include <assert.h> KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect, struct ARegion *ar) : @@ -44,6 +45,8 @@ m_frame_rect(rect) // area boundaries needed for mouse coordinates in Letterbox framing mode m_area_left = ar->winrct.xmin; m_area_top = ar->winrct.ymax; + + glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport); } KX_BlenderCanvas::~KX_BlenderCanvas() @@ -116,14 +119,14 @@ int KX_BlenderCanvas::GetHeight( int KX_BlenderCanvas::GetMouseX(int x) { - float left = GetWindowArea().GetLeft(); - return float(x - (left - m_area_left)); + int left = GetWindowArea().GetLeft(); + return x - (left - m_area_left); } int KX_BlenderCanvas::GetMouseY(int y) { - float top = GetWindowArea().GetTop(); - return float(y - (m_area_top - top)); + int top = GetWindowArea().GetTop(); + return y - (m_area_top - top); } float KX_BlenderCanvas::GetMouseNormalizedX(int x) @@ -166,10 +169,31 @@ SetViewPort( m_area_rect.SetRight(minx + x2); m_area_rect.SetTop(miny + y2); + m_viewport[0] = minx+x1; + m_viewport[1] = miny+y1; + m_viewport[2] = vp_width; + m_viewport[3] = vp_height; + glViewport(minx + x1, miny + y1, vp_width, vp_height); glScissor(minx + x1, miny + y1, vp_width, vp_height); } + const int* +KX_BlenderCanvas:: +GetViewPort() { +#ifdef DEBUG + // If we're in a debug build, we might as well make sure our values don't differ + // from what the gpu thinks we have. This could lead to nasty, hard to find bugs. + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + assert(viewport[0] == m_viewport[0]); + assert(viewport[1] == m_viewport[1]); + assert(viewport[2] == m_viewport[2]); + assert(viewport[3] == m_viewport[3]); +#endif + + return m_viewport; +} void KX_BlenderCanvas::SetMouseState(RAS_MouseState mousestate) { diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index ee7997abb39..244394a115d 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -61,6 +61,7 @@ private: /** Rect that defines the area used for rendering, relative to the context */ RAS_Rect m_displayarea; + int m_viewport[4]; public: /* Construct a new canvas. @@ -150,6 +151,8 @@ public: int x1, int y1, int x2, int y2 ); + const int* + GetViewPort(); void SetMouseState( @@ -189,8 +192,8 @@ private: struct wmWindow* m_win; RAS_Rect m_frame_rect; RAS_Rect m_area_rect; - short m_area_left; - short m_area_top; + int m_area_left; + int m_area_top; #ifdef WITH_CXX_GUARDEDALLOC @@ -198,5 +201,4 @@ private: #endif }; -#endif // __KX_BLENDERCANVAS_H__ - +#endif /* __KX_BLENDERCANVAS_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h index 3b89538df47..7ba612b19cf 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h @@ -34,7 +34,7 @@ #ifdef __cplusplus extern "C" { -#endif //__cplusplus +#endif /* __cplusplus */ struct wmWindow; struct ARegion; @@ -58,7 +58,6 @@ void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int widt #ifdef __cplusplus } -#endif //__cplusplus - -#endif //__KX_BLENDERGL_H__ +#endif /* __cplusplus */ +#endif /* __KX_BLENDERGL_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h index 43870d9030d..a183d4059f8 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h @@ -32,8 +32,8 @@ #ifndef __KX_BLENDERINPUTDEVICE_H__ #define __KX_BLENDERINPUTDEVICE_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning(disable : 4786) // shut off 255 char limit debug template warning +#ifdef _MSC_VER +# pragma warning(disable:4786) // shut off 255 char limit debug template warning #endif #include <map> @@ -75,5 +75,5 @@ public: MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_BlenderInputDevice") #endif }; -#endif //__KX_BLENDERINPUTDEVICE_H__ +#endif /* __KX_BLENDERINPUTDEVICE_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp index 54c60096812..f4e325eabb8 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp @@ -30,9 +30,9 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// annoying warnings about truncated STL debug info -#pragma warning (disable :4786) +#ifdef _MSC_VER + /* annoying warnings about truncated STL debug info */ +# pragma warning (disable:4786) #endif #include "KX_BlenderKeyboardDevice.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h index e9140efce01..dec70203ecb 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h @@ -59,5 +59,4 @@ private: #endif }; -#endif //__KX_BLENDERKEYBOARDDEVICE_H__ - +#endif /* __KX_BLENDERKEYBOARDDEVICE_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp index 5cd2038163c..aa2392ded08 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp @@ -29,10 +29,9 @@ * \ingroup blroutines */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// annoying warnings about truncated STL debug info -#pragma warning (disable :4786) +#ifdef _MSC_VER + /* annoying warnings about truncated STL debug info */ +# pragma warning (disable:4786) #endif #include "KX_BlenderMouseDevice.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h index 0571cafd7a1..8746da83a81 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h @@ -55,5 +55,4 @@ public: #endif }; -#endif //__KX_BLENDERMOUSEDEVICE_H__ - +#endif /* __KX_BLENDERMOUSEDEVICE_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index 54ff4dde947..7195524ceae 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -32,9 +32,9 @@ #ifndef __KX_BLENDERRENDERTOOLS_H__ #define __KX_BLENDERRENDERTOOLS_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show stl-warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show stl-warnings */ +# pragma warning (disable:4786) #endif #include "RAS_IRenderTools.h" @@ -72,26 +72,26 @@ public: void ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat); void RenderText3D(int fontid, - const char* text, - int size, - int dpi, - float* color, - double* mat, - float aspect); + const char* text, + int size, + int dpi, + float* color, + double* mat, + float aspect); void RenderText2D(RAS_TEXT_RENDER_MODE mode, - const char* text, - int xco, - int yco, - int width, - int height); + const char* text, + int xco, + int yco, + int width, + int height); void RenderText(int mode, - class RAS_IPolyMaterial* polymat, - float v1[3], - float v2[3], - float v3[3], - float v4[3], - int glattrib); + class RAS_IPolyMaterial* polymat, + float v1[3], + float v2[3], + float v3[3], + float v4[3], + int glattrib); void applyTransform(RAS_IRasterizer* rasty, double* oglmatrix, int objectdrawmode); int applyLights(int objectlayer, const MT_Transform& viewmat); @@ -112,7 +112,4 @@ public: #endif }; -#endif //__KX_BLENDERRENDERTOOLS_H__ - - - +#endif /* __KX_BLENDERRENDERTOOLS_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp b/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp index d7d8c5121a2..0582e79d269 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp @@ -32,9 +32,9 @@ #include "KX_ISystem.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable :4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #ifdef WIN32 #include <windows.h> diff --git a/source/gameengine/BlenderRoutines/KX_BlenderSystem.h b/source/gameengine/BlenderRoutines/KX_BlenderSystem.h index a8e033ed47b..0867ef2421f 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderSystem.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderSystem.h @@ -53,5 +53,4 @@ public: #endif }; -#endif //__KX_BLENDERSYSTEM_H__ - +#endif /* __KX_BLENDERSYSTEM_H__ */ diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 640a9a9ccb7..46075ea933d 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -108,7 +108,7 @@ public: return 1; } } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ protected: MT_Point3 m_lastpos; diff --git a/source/gameengine/Converter/BL_ArmatureActuator.h b/source/gameengine/Converter/BL_ArmatureActuator.h index 0c88dccb6f3..ba02c5aa362 100644 --- a/source/gameengine/Converter/BL_ArmatureActuator.h +++ b/source/gameengine/Converter/BL_ArmatureActuator.h @@ -49,13 +49,13 @@ class BL_ArmatureActuator : public SCA_IActuator Py_Header public: BL_ArmatureActuator(SCA_IObject* gameobj, - int type, - const char *posechannel, - const char *constraintname, - KX_GameObject* targetobj, - KX_GameObject* subtargetobj, - float weight, - float influence); + int type, + const char *posechannel, + const char *constraintname, + KX_GameObject* targetobj, + KX_GameObject* subtargetobj, + float weight, + float influence); virtual ~BL_ArmatureActuator(); @@ -77,7 +77,7 @@ public: static PyObject *pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: // identify the constraint that this actuator controls @@ -93,6 +93,4 @@ private: int m_type; }; -#endif //__BL_ARMATUREACTUATOR_H__ - - +#endif /* __BL_ARMATUREACTUATOR_H__ */ diff --git a/source/gameengine/Converter/BL_ArmatureChannel.cpp b/source/gameengine/Converter/BL_ArmatureChannel.cpp index e588d1d310c..8f5547c337c 100644 --- a/source/gameengine/Converter/BL_ArmatureChannel.cpp +++ b/source/gameengine/Converter/BL_ArmatureChannel.cpp @@ -455,12 +455,12 @@ PyObject *BL_ArmatureBone::py_bone_get_children(void *self, const struct KX_PYAT Bone* bone = reinterpret_cast<Bone*>(self); Bone* child; int count = 0; - for (child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next) + for (child = (Bone *)bone->childbase.first; child; child = child->next) count++; PyObject *childrenlist = PyList_New(count); - for (count = 0, child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next, ++count) + for (count = 0, child = (Bone *)bone->childbase.first; child; child = child->next, ++count) PyList_SET_ITEM(childrenlist,count,NewProxyPlus_Ext(NULL,&Type,child,false)); return childrenlist; diff --git a/source/gameengine/Converter/BL_ArmatureChannel.h b/source/gameengine/Converter/BL_ArmatureChannel.h index b764d32e8a7..51114c5df30 100644 --- a/source/gameengine/Converter/BL_ArmatureChannel.h +++ b/source/gameengine/Converter/BL_ArmatureChannel.h @@ -68,7 +68,7 @@ public: static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject *py_attr_get_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int py_attr_set_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* this is a factory class to access bBone data field in the GE. @@ -93,6 +93,4 @@ public: }; - -#endif //__BL_ARMATURECHANNEL_H__ - +#endif /* __BL_ARMATURECHANNEL_H__ */ diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.h b/source/gameengine/Converter/BL_ArmatureConstraint.h index 579153a2e79..98c2954baf4 100644 --- a/source/gameengine/Converter/BL_ArmatureConstraint.h +++ b/source/gameengine/Converter/BL_ArmatureConstraint.h @@ -119,8 +119,7 @@ public: static PyObject *py_attr_getattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__BL_ARMATURECONSTRAINT_H__ - +#endif /* __BL_ARMATURECONSTRAINT_H__ */ diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index da73d7a762a..ed97b9ff73f 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -105,7 +105,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) for (; pchan; pchan=pchan->next, outpchan=outpchan->next) BLI_ghash_insert(ghash, pchan, outpchan); - for (pchan=(bPoseChannel*)out->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) { + for (pchan = (bPoseChannel*)out->chanbase.first; pchan; pchan = pchan->next) { pchan->parent= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->parent); pchan->child= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->child); @@ -186,7 +186,10 @@ void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/) if (schan->rotmode) dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight); } - for (dcon= (bConstraint*)dchan->constraints.first, scon= (bConstraint*)schan->constraints.first; dcon && scon; dcon= (bConstraint*)dcon->next, scon= (bConstraint*)scon->next) { + for (dcon= (bConstraint *)dchan->constraints.first, scon= (bConstraint *)schan->constraints.first; + dcon && scon; + dcon = dcon->next, scon = scon->next) + { /* no 'add' option for constraint blending */ dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight; } @@ -282,8 +285,8 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter) KX_GameObject* gamesubtarget; // and locate the constraint - for (pchan = (bPoseChannel*)m_pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) { - for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) { + for (pchan = (bPoseChannel *)m_pose->chanbase.first; pchan; pchan = pchan->next) { + for (pcon = (bConstraint *)pchan->constraints.first; pcon; pcon = pcon->next) { if (pcon->flag & CONSTRAINT_DISABLE) continue; // which constraint should we support? @@ -315,7 +318,7 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter) } if (target->next != NULL) { // secondary target - target = (bConstraintTarget*)target->next; + target = target->next; if (target->tar && target->tar != m_objArma) { // only track external object blendtarget = target->tar; diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index 4e7dc3df2f3..445b9af1b10 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -120,7 +120,7 @@ public: static PyObject *pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); KX_PYMETHOD_DOC_NOARGS(BL_ArmatureObject, update); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ protected: /* list element: BL_ArmatureConstraint. Use SG_DListHead to have automatic list replication */ @@ -152,6 +152,4 @@ void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, s void game_copy_pose(struct bPose **dst, struct bPose *src, int copy_con); void game_free_pose(struct bPose *pose); - -#endif - +#endif /* __BL_ARMATUREOBJECT_H__ */ diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 6ffdea9f90e..912e2126874 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -30,8 +30,8 @@ * \ingroup bgeconv */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include <math.h> diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h index e6c35c20f4c..2a7efaac898 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.h +++ b/source/gameengine/Converter/BL_BlenderDataConversion.h @@ -52,5 +52,4 @@ void BL_ConvertBlenderObjects(struct Main* maggie, SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code); -#endif // __BL_BLENDERDATACONVERSION_H__ - +#endif /* __BL_BLENDERDATACONVERSION_H__ */ diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index d14160d39a3..95e3b7c517d 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -32,9 +32,9 @@ #ifndef __BL_DEFORMABLEGAMEOBJECT_H__ #define __BL_DEFORMABLEGAMEOBJECT_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif #include "DNA_mesh_types.h" #include "KX_GameObject.h" @@ -104,5 +104,4 @@ protected: #endif }; -#endif - +#endif /* __BL_DEFORMABLEGAMEOBJECT_H__ */ diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index b8002d05f18..0d3c0d269fc 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -30,11 +30,10 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include "RAS_IPolygonMaterial.h" diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index c84d31c72cd..6e84cdf03f8 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -38,9 +38,9 @@ #include "MT_Point3.h" #include <stdlib.h> -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif class BL_DeformableGameObject; @@ -70,7 +70,7 @@ public: virtual RAS_Deformer* GetReplica() {return NULL;} virtual void ProcessReplica(); struct Mesh* GetMesh() { return m_bmesh; } - virtual class RAS_MeshObject* GetRasMesh() { return (RAS_MeshObject*)m_pMeshObject; } + virtual class RAS_MeshObject* GetRasMesh() { return m_pMeshObject; } virtual float (* GetTransVerts(int *tot))[3] { *tot= m_tvtot; return m_transverts; } // virtual void InitDeform(double time) {} diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index eafed8497ba..53755deefe1 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "MEM_guardedalloc.h" #include "BL_ModifierDeformer.h" @@ -42,7 +41,6 @@ #include "RAS_MeshObject.h" #include "PHY_IGraphicController.h" -//#include "BL_ArmatureController.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" #include "DNA_key_types.h" @@ -65,7 +63,6 @@ extern "C"{ #include "BKE_lattice.h" #include "BKE_modifier.h" } - #include "BLI_blenlib.h" #include "BLI_math.h" @@ -113,7 +110,7 @@ bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob) if ((ob->gameflag & OB_SOFT_BODY) != 0) return false; ModifierData* md; - for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) { + for (md = (ModifierData *)ob->modifiers.first; md; md = md->next) { if (modifier_dependsOnTime(md)) continue; if (!(md->mode & eModifierMode_Realtime)) diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h index 5d0c3bc1317..4efe4ca5bfc 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.h +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -32,9 +32,9 @@ #ifndef __BL_MODIFIERDEFORMER_H__ #define __BL_MODIFIERDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" @@ -51,33 +51,34 @@ public: BL_ModifierDeformer(BL_DeformableGameObject *gameobj, - Scene *scene, - Object *bmeshobj, - RAS_MeshObject *mesh) - : - BL_ShapeDeformer(gameobj,bmeshobj, mesh), - m_lastModifierUpdate(-1), - m_scene(scene), - m_dm(NULL) + Scene *scene, + Object *bmeshobj, + RAS_MeshObject *mesh) + : + BL_ShapeDeformer(gameobj,bmeshobj, mesh), + m_lastModifierUpdate(-1), + m_scene(scene), + m_dm(NULL) { m_recalcNormal = false; - }; + } /* this second constructor is needed for making a mesh deformable on the fly. */ BL_ModifierDeformer(BL_DeformableGameObject *gameobj, - struct Scene *scene, - struct Object *bmeshobj_old, - struct Object *bmeshobj_new, - class RAS_MeshObject *mesh, - bool release_object, - BL_ArmatureObject* arma = NULL) - : - BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma), - m_lastModifierUpdate(-1), - m_scene(scene), - m_dm(NULL) + struct Scene *scene, + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class RAS_MeshObject *mesh, + bool release_object, + BL_ArmatureObject* arma = NULL) + : + BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma), + m_lastModifierUpdate(-1), + m_scene(scene), + m_dm(NULL) { - }; + /* pass */ + } virtual void ProcessReplica(); virtual RAS_Deformer *GetReplica(); @@ -111,5 +112,4 @@ protected: #endif }; -#endif - +#endif /* __BL_MODIFIERDEFORMER_H__ */ diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index b88631c89d6..f72275b79cf 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -108,7 +108,7 @@ public: } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ protected: @@ -141,5 +141,4 @@ protected: struct PointerRNA *m_idptr; }; -#endif - +#endif /* __BL_SHAPEACTIONACTUATOR_H__ */ diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index f8941e16ed2..f262532e7e2 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "MEM_guardedalloc.h" #include "BL_ShapeDeformer.h" @@ -41,7 +40,6 @@ #include "RAS_IPolygonMaterial.h" #include "RAS_MeshObject.h" -//#include "BL_ArmatureController.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" @@ -60,7 +58,6 @@ extern "C"{ #include "BKE_lattice.h" #include "BKE_animsys.h" } - #include "BLI_blenlib.h" #include "BLI_math.h" diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index ecf501d9a91..60f27c85e4f 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -32,9 +32,9 @@ #ifndef __BL_SHAPEDEFORMER_H__ #define __BL_SHAPEDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include "BL_SkinDeformer.h" #include "BL_DeformableGameObject.h" diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index c175c1e3b7b..e068a91bf7e 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif // Eigen3 stuff used for BGEDeformVerts #include <Eigen/Core> @@ -72,7 +71,7 @@ static short get_deformflags(struct Object *bmeshobj) short flags = ARM_DEF_VGROUP; ModifierData *md; - for (md = (ModifierData*)bmeshobj->modifiers.first; md; md = (ModifierData*)md->next) + for (md = (ModifierData *)bmeshobj->modifiers.first; md; md = md->next) { if (md->type == eModifierType_Armature) { @@ -249,7 +248,7 @@ void BL_SkinDeformer::BGEDeformVerts() int i; for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first; dg; - ++i, dg=(bDeformGroup*)dg->next) + ++i, dg = dg->next) { m_dfnrToPC[i] = BKE_pose_channel_find_name(par_arma->pose, dg->name); diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index 48c3c3e6186..7495deb2257 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -32,9 +32,9 @@ #ifndef __BL_SKINDEFORMER_H__ #define __BL_SKINDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif /* WIN32 */ #include "CTR_HashedPtr.h" #include "BL_MeshDeformer.h" @@ -56,18 +56,18 @@ public: void SetArmature (class BL_ArmatureObject *armobj); BL_SkinDeformer(BL_DeformableGameObject *gameobj, - struct Object *bmeshobj, - class RAS_MeshObject *mesh, - BL_ArmatureObject* arma = NULL); + struct Object *bmeshobj, + class RAS_MeshObject *mesh, + BL_ArmatureObject* arma = NULL); /* this second constructor is needed for making a mesh deformable on the fly. */ BL_SkinDeformer(BL_DeformableGameObject *gameobj, - struct Object *bmeshobj_old, - struct Object *bmeshobj_new, - class RAS_MeshObject *mesh, - bool release_object, - bool recalc_normal, - BL_ArmatureObject* arma = NULL); + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class RAS_MeshObject *mesh, + bool release_object, + bool recalc_normal, + BL_ArmatureObject* arma = NULL); virtual RAS_Deformer *GetReplica(); virtual void ProcessReplica(); @@ -120,5 +120,4 @@ protected: #endif }; -#endif - +#endif /* __BL_SKINDEFORMER_H__ */ diff --git a/source/gameengine/Converter/BlenderWorldInfo.h b/source/gameengine/Converter/BlenderWorldInfo.h index 2cf706a3089..30de5e89269 100644 --- a/source/gameengine/Converter/BlenderWorldInfo.h +++ b/source/gameengine/Converter/BlenderWorldInfo.h @@ -104,5 +104,4 @@ public: #endif }; -#endif //__BLENDERWORLDINFO_H__ - +#endif /* __BLENDERWORLDINFO_H__ */ diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index 1826f1ad25b..7b801fd4ffb 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -49,16 +49,15 @@ set(INC ../../blender/makesdna ../../blender/makesrna ../../blender/windowmanager - ../../../extern/bullet2/src - ../../../extern/Eigen3 ../../../intern/container ../../../intern/guardedalloc ../../../intern/moto/include ../../../intern/string - ../../../extern/recastnavigation/Detour/Include ) set(INC_SYS + ../../../extern/recastnavigation/Detour/Include + ../../../extern/Eigen3 ${PTHREADS_INCLUDE_DIRS} ) @@ -110,6 +109,9 @@ set(SRC ) if(WITH_BULLET) + list(APPEND INC_SYS + ../../../extern/bullet2/src + ) add_definitions(-DUSE_BULLET) endif() diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp index 72212581d4b..1e1bc738301 100644 --- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp +++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp @@ -52,7 +52,7 @@ BL_InterpolatorList::BL_InterpolatorList(bAction *action) if (action==NULL) return; - for (FCurve *fcu= (FCurve *)action->curves.first; fcu; fcu= (FCurve *)fcu->next) { + for (FCurve *fcu = (FCurve *)action->curves.first; fcu; fcu = fcu->next) { if (fcu->rna_path) { BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu); //assert(new_ipo); diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h index 980aeef7e60..d828910233f 100644 --- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h +++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h @@ -73,5 +73,4 @@ public: #endif }; -#endif //__KX_BLENDERSCALARINTERPOLATOR_H__ - +#endif /* __KX_BLENDERSCALARINTERPOLATOR_H__ */ diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 9020720eaeb..34af4038c4e 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -29,9 +29,8 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* suppress stl-MSVC debug info warning */ #endif #include "KX_Scene.h" diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index b51c2f21ca7..34a1117a0eb 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -165,11 +165,11 @@ public: printf("\t m_materials: %d\n", (int)m_materials.size()); printf("\nMappings...\n"); - printf("\t m_map_blender_to_gameobject: %d\n", (int)m_map_blender_to_gameobject.size()); - printf("\t m_map_mesh_to_gamemesh: %d\n", (int)m_map_mesh_to_gamemesh.size()); - printf("\t m_map_blender_to_gameactuator: %d\n", (int)m_map_blender_to_gameactuator.size()); - printf("\t m_map_blender_to_gamecontroller: %d\n", (int)m_map_blender_to_gamecontroller.size()); - printf("\t m_map_blender_to_gameAdtList: %d\n", (int)m_map_blender_to_gameAdtList.size()); + printf("\t m_map_blender_to_gameobject: %d\n", m_map_blender_to_gameobject.size()); + printf("\t m_map_mesh_to_gamemesh: %d\n", m_map_mesh_to_gamemesh.size()); + printf("\t m_map_blender_to_gameactuator: %d\n", m_map_blender_to_gameactuator.size()); + printf("\t m_map_blender_to_gamecontroller: %d\n", m_map_blender_to_gamecontroller.size()); + printf("\t m_map_blender_to_gameAdtList: %d\n", m_map_blender_to_gameAdtList.size()); #ifdef WITH_CXX_GUARDEDALLOC MEM_printmemlist_pydict(); @@ -196,5 +196,4 @@ public: #endif }; -#endif //__KX_BLENDERSCENECONVERTER_H__ - +#endif /* __KX_BLENDERSCENECONVERTER_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 287be3b8359..ea2b85f8c5e 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -30,10 +30,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include <math.h> @@ -105,22 +104,25 @@ #include "BL_BlenderDataConversion.h" /** - * KX_BLENDERTRUNC needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set + * KX_flt_trunc needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set */ -#define KX_BLENDERTRUNC(x) (( x < 0.0001f && x > -0.0001f ) ? 0.0f : x) +BLI_INLINE float KX_flt_trunc(const float x) +{ + return ( x < 0.0001f && x > -0.0001f ) ? 0.0f : x; +} void BL_ConvertActuators(const char* maggiename, - struct Object* blenderobject, - KX_GameObject* gameobj, - SCA_LogicManager* logicmgr, - KX_Scene* scene, - KX_KetsjiEngine* ketsjiEngine, - int activeLayerBitInfo, - bool isInActiveLayer, - RAS_IRenderTools* rendertools, - KX_BlenderSceneConverter* converter - ) + struct Object* blenderobject, + KX_GameObject* gameobj, + SCA_LogicManager* logicmgr, + KX_Scene* scene, + KX_KetsjiEngine* ketsjiEngine, + int activeLayerBitInfo, + bool isInActiveLayer, + RAS_IRenderTools* rendertools, + KX_BlenderSceneConverter* converter + ) { int uniqueint = 0; @@ -146,20 +148,23 @@ void BL_ConvertActuators(const char* maggiename, { bObjectActuator* obact = (bObjectActuator*) bact->data; KX_GameObject* obref = NULL; - MT_Vector3 forcevec(KX_BLENDERTRUNC(obact->forceloc[0]), - KX_BLENDERTRUNC(obact->forceloc[1]), - KX_BLENDERTRUNC(obact->forceloc[2])); - MT_Vector3 torquevec(obact->forcerot[0],obact->forcerot[1],obact->forcerot[2]); - MT_Vector3 dlocvec ( KX_BLENDERTRUNC(obact->dloc[0]), - KX_BLENDERTRUNC(obact->dloc[1]), - KX_BLENDERTRUNC(obact->dloc[2])); - MT_Vector3 drotvec ( KX_BLENDERTRUNC(obact->drot[0]),obact->drot[1],obact->drot[2]); - MT_Vector3 linvelvec ( KX_BLENDERTRUNC(obact->linearvelocity[0]), - KX_BLENDERTRUNC(obact->linearvelocity[1]), - KX_BLENDERTRUNC(obact->linearvelocity[2])); - MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]), - KX_BLENDERTRUNC(obact->angularvelocity[1]), - KX_BLENDERTRUNC(obact->angularvelocity[2])); + MT_Vector3 forcevec(KX_flt_trunc(obact->forceloc[0]), + KX_flt_trunc(obact->forceloc[1]), + KX_flt_trunc(obact->forceloc[2])); + MT_Vector3 torquevec(obact->forcerot[0], + obact->forcerot[1], + obact->forcerot[2]); + MT_Vector3 dlocvec(KX_flt_trunc(obact->dloc[0]), + KX_flt_trunc(obact->dloc[1]), + KX_flt_trunc(obact->dloc[2])); + MT_Vector3 drotvec(KX_flt_trunc(obact->drot[0]), + obact->drot[1],obact->drot[2]); + MT_Vector3 linvelvec(KX_flt_trunc(obact->linearvelocity[0]), + KX_flt_trunc(obact->linearvelocity[1]), + KX_flt_trunc(obact->linearvelocity[2])); + MT_Vector3 angvelvec(KX_flt_trunc(obact->angularvelocity[0]), + KX_flt_trunc(obact->angularvelocity[1]), + KX_flt_trunc(obact->angularvelocity[2])); short damping = obact->damping; /* Blender uses a bit vector internally for the local-flags. In */ @@ -181,17 +186,17 @@ void BL_ConvertActuators(const char* maggiename, obref = converter->FindGameObject(obact->reference); } - KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(gameobj, - obref, - forcevec.getValue(), - torquevec.getValue(), - dlocvec.getValue(), - drotvec.getValue(), - linvelvec.getValue(), - angvelvec.getValue(), - damping, - bitLocalFlag - ); + KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator( + gameobj, + obref, + forcevec.getValue(), + torquevec.getValue(), + dlocvec.getValue(), + drotvec.getValue(), + linvelvec.getValue(), + angvelvec.getValue(), + damping, + bitLocalFlag); baseact = tmpbaseact; break; } @@ -210,22 +215,22 @@ void BL_ConvertActuators(const char* maggiename, if (actact->flag & ACT_IPOCHILD) ipo_flags |= BL_Action::ACT_IPOFLAG_CHILD; BL_ActionActuator* tmpbaseact = new BL_ActionActuator( - gameobj, - propname, - propframe, - actact->sta, - actact->end, - actact->act, - actact->type, // + 1, because Blender starts to count at zero, - actact->blendin, - actact->priority, - actact->layer, - actact->layer_weight, - ipo_flags, - actact->end_reset, - actact->stridelength - // Ketsji at 1, because zero is reserved for "NoDef" - ); + gameobj, + propname, + propframe, + actact->sta, + actact->end, + actact->act, + actact->type, // + 1, because Blender starts to count at zero, + actact->blendin, + actact->priority, + actact->layer, + actact->layer_weight, + ipo_flags, + actact->end_reset, + actact->stridelength + // Ketsji at 1, because zero is reserved for "NoDef" + ); baseact= tmpbaseact; break; } @@ -237,18 +242,17 @@ void BL_ConvertActuators(const char* maggiename, STR_String propframe = (actact->frameProp ? actact->frameProp : ""); BL_ShapeActionActuator* tmpbaseact = new BL_ShapeActionActuator( - gameobj, - propname, - propframe, - actact->sta, - actact->end, - actact->act, - actact->type, // + 1, because Blender starts to count at zero, - actact->blendin, - actact->priority, - actact->stridelength - // Ketsji at 1, because zero is reserved for "NoDef" - ); + gameobj, + propname, + propframe, + actact->sta, + actact->end, + actact->act, + actact->type, // + 1, because Blender starts to count at zero, + actact->blendin, + actact->priority, + actact->stridelength); + // Ketsji at 1, because zero is reserved for "NoDef" baseact= tmpbaseact; break; } @@ -267,17 +271,17 @@ void BL_ConvertActuators(const char* maggiename, bool ipo_add = (ipoact->flag & ACT_IPOADD); KX_IpoActuator* tmpbaseact = new KX_IpoActuator( - gameobj, - propname , - frameProp, - ipoact->sta, - ipoact->end, - ipochild, - ipoact->type + 1, // + 1, because Blender starts to count at zero, - // Ketsji at 1, because zero is reserved for "NoDef" - ipo_as_force, - ipo_add, - local); + gameobj, + propname , + frameProp, + ipoact->sta, + ipoact->end, + ipochild, + ipoact->type + 1, // + 1, because Blender starts to count at zero, + // Ketsji at 1, because zero is reserved for "NoDef" + ipo_as_force, + ipo_add, + local); baseact = tmpbaseact; break; } @@ -293,14 +297,14 @@ void BL_ConvertActuators(const char* maggiename, /* visifac, fac and axis are not copied from the struct... */ /* that's some internal state... */ - KX_CameraActuator *tmpcamact - = new KX_CameraActuator(gameobj, - tmpgob, - camact->height, - camact->min, - camact->max, - camact->axis, - camact->damping); + KX_CameraActuator *tmpcamact = new KX_CameraActuator( + gameobj, + tmpgob, + camact->height, + camact->min, + camact->max, + camact->axis, + camact->damping); baseact = tmpcamact; } break; @@ -333,14 +337,13 @@ void BL_ConvertActuators(const char* maggiename, ? (char*) msgAct->body : ""); - KX_NetworkMessageActuator *tmpmsgact = - new KX_NetworkMessageActuator( - gameobj, // actuator controlling object - scene->GetNetworkScene(), // needed for replication - toPropName, - subject, - bodyType, - body); + KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator( + gameobj, // actuator controlling object + scene->GetNetworkScene(), // needed for replication + toPropName, + subject, + bodyType, + body); baseact = tmpmsgact; break; } @@ -457,11 +460,11 @@ void BL_ConvertActuators(const char* maggiename, destinationObj = converter->FindGameObject(propact->ob); SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator( - gameobj, - destinationObj, - propact->name, - propact->value, - propact->type+1); // + 1 because Ketsji Logic starts + gameobj, + destinationObj, + propact->name, + propact->value, + propact->type + 1); // + 1 because Ketsji Logic starts // with 0 for KX_ACT_PROP_NODEF baseact = tmppropact; break; @@ -491,18 +494,16 @@ void BL_ConvertActuators(const char* maggiename, } } - KX_SCA_AddObjectActuator* tmpaddact = - new KX_SCA_AddObjectActuator( - gameobj, - originalval, - editobact->time, - scene, - editobact->linVelocity, - (editobact->localflag & ACT_EDOB_LOCAL_LINV)!=0, - editobact->angVelocity, - (editobact->localflag & ACT_EDOB_LOCAL_ANGV)!=0 - ); - + KX_SCA_AddObjectActuator* tmpaddact = new KX_SCA_AddObjectActuator( + gameobj, + originalval, + editobact->time, + scene, + editobact->linVelocity, + (editobact->localflag & ACT_EDOB_LOCAL_LINV) != 0, + editobact->angVelocity, + (editobact->localflag & ACT_EDOB_LOCAL_ANGV) != 0); + //editobact->ob to gameobj baseact = tmpaddact; } @@ -519,23 +520,20 @@ void BL_ConvertActuators(const char* maggiename, RAS_MeshObject *tmpmesh = NULL; if (editobact->me) tmpmesh = BL_ConvertMesh( - editobact->me, - blenderobject, - scene, - converter - ); + editobact->me, + blenderobject, + scene, + converter + ); - KX_SCA_ReplaceMeshActuator* tmpreplaceact - = new KX_SCA_ReplaceMeshActuator( - gameobj, - tmpmesh, - scene, - (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX)==0, - (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS)!=0 - - ); - - baseact = tmpreplaceact; + KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator( + gameobj, + tmpmesh, + scene, + (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX) == 0, + (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS) != 0); + + baseact = tmpreplaceact; } break; case ACT_EDOB_TRACK_TO: @@ -544,25 +542,23 @@ void BL_ConvertActuators(const char* maggiename, if (editobact->ob) originalval = converter->FindGameObject(editobact->ob); - KX_TrackToActuator* tmptrackact - = new KX_TrackToActuator(gameobj, - originalval, - editobact->time, - editobact->flag, - blenderobject->trackflag, - blenderobject->upflag - ); - baseact = tmptrackact; + KX_TrackToActuator* tmptrackact = new KX_TrackToActuator( + gameobj, + originalval, + editobact->time, + editobact->flag, + blenderobject->trackflag, + blenderobject->upflag); + baseact = tmptrackact; break; } case ACT_EDOB_DYNAMICS: { - KX_SCA_DynamicActuator* tmpdynact - = new KX_SCA_DynamicActuator(gameobj, - editobact->dyn_operation, - editobact->mass - ); - baseact = tmpdynact; + KX_SCA_DynamicActuator* tmpdynact = new KX_SCA_DynamicActuator( + gameobj, + editobact->dyn_operation, + editobact->mass); + baseact = tmpdynact; } } break; @@ -694,17 +690,17 @@ void BL_ConvertActuators(const char* maggiename, ; /* error */ } } - KX_ConstraintActuator *tmpconact - = new KX_ConstraintActuator(gameobj, - conact->damp, - conact->rotdamp, - min, - max, - conact->maxrot, - locrot, - conact->time, - conact->flag, - prop); + KX_ConstraintActuator *tmpconact = new KX_ConstraintActuator( + gameobj, + conact->damp, + conact->rotdamp, + min, + max, + conact->maxrot, + locrot, + conact->time, + conact->flag, + prop); baseact = tmpconact; break; } @@ -777,13 +773,14 @@ void BL_ConvertActuators(const char* maggiename, default: ; /* flag error */ } - tmpsceneact = new KX_SceneActuator(gameobj, - mode, - scene, - ketsjiEngine, - nextSceneName, - cam); - baseact = tmpsceneact; + tmpsceneact = new KX_SceneActuator( + gameobj, + mode, + scene, + ketsjiEngine, + nextSceneName, + cam); + baseact = tmpsceneact; break; } case ACT_GAME: @@ -832,13 +829,14 @@ void BL_ConvertActuators(const char* maggiename, default: ; /* flag error */ } - tmpgameact = new KX_GameActuator(gameobj, - mode, - filename, - loadinganimationname, - scene, - ketsjiEngine); - baseact = tmpgameact; + tmpgameact = new KX_GameActuator( + gameobj, + mode, + filename, + loadinganimationname, + scene, + ketsjiEngine); + baseact = tmpgameact; break; } @@ -905,12 +903,13 @@ void BL_ConvertActuators(const char* maggiename, default: ; /* error */ } - tmprandomact = new SCA_RandomActuator(gameobj, - seedArg, - modeArg, - paraArg1, - paraArg2, - randAct->propname); + tmprandomact = new SCA_RandomActuator( + gameobj, + seedArg, + modeArg, + paraArg1, + paraArg2, + randAct->propname); baseact = tmprandomact; } break; @@ -999,8 +998,9 @@ void BL_ConvertActuators(const char* maggiename, break; } - tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag, - _2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),scene); + tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag, + _2dfilter->float_arg, _2dfilter->int_arg, + ketsjiEngine->GetRasterizer(), scene); if (_2dfilter->text) { @@ -1055,7 +1055,15 @@ void BL_ConvertActuators(const char* maggiename, bArmatureActuator* armAct = (bArmatureActuator*) bact->data; KX_GameObject *tmpgob = converter->FindGameObject(armAct->target); KX_GameObject *subgob = converter->FindGameObject(armAct->subtarget); - BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator(gameobj, armAct->type, armAct->posechannel, armAct->constraint, tmpgob, subgob, armAct->weight, armAct->influence); + BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator( + gameobj, + armAct->type, + armAct->posechannel, + armAct->constraint, + tmpgob, + subgob, + armAct->weight, + armAct->influence); baseact = tmparmact; break; } diff --git a/source/gameengine/Converter/KX_ConvertActuators.h b/source/gameengine/Converter/KX_ConvertActuators.h index b7c890458cc..385d274bf89 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.h +++ b/source/gameengine/Converter/KX_ConvertActuators.h @@ -33,16 +33,14 @@ #define __KX_CONVERTACTUATORS_H__ void BL_ConvertActuators(const char* maggiename, - struct Object* blenderobject, - class KX_GameObject* gameobj, - class SCA_LogicManager* logicmgr, - class KX_Scene* scene, - class KX_KetsjiEngine* ketsjiEngine, - int activeLayerBitInfo, - bool isInActiveLayer, - class RAS_IRenderTools* rendertools, - class KX_BlenderSceneConverter* converter); - - -#endif //__KX_CONVERTACTUATORS_H__ + struct Object* blenderobject, + class KX_GameObject* gameobj, + class SCA_LogicManager* logicmgr, + class KX_Scene* scene, + class KX_KetsjiEngine* ketsjiEngine, + int activeLayerBitInfo, + bool isInActiveLayer, + class RAS_IRenderTools* rendertools, + class KX_BlenderSceneConverter* converter); +#endif /* __KX_CONVERTACTUATORS_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h index d1d52f866ec..817a49e1b2f 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.h +++ b/source/gameengine/Converter/KX_ConvertControllers.h @@ -43,6 +43,4 @@ void BL_ConvertControllers( class KX_BlenderSceneConverter* converter ); - -#endif //__KX_CONVERTCONTROLLERS_H__ - +#endif /* __KX_CONVERTCONTROLLERS_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertProperties.h b/source/gameengine/Converter/KX_ConvertProperties.h index 345af3bfa74..8f96cc21af6 100644 --- a/source/gameengine/Converter/KX_ConvertProperties.h +++ b/source/gameengine/Converter/KX_ConvertProperties.h @@ -38,5 +38,4 @@ void BL_ConvertProperties(struct Object* object, class SCA_IScene* scene, bool isInActiveLayer); -#endif //__KX_CONVERTPROPERTIES_H__ - +#endif /* __KX_CONVERTPROPERTIES_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 3d4f3ae08f2..859257e192d 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -33,17 +33,17 @@ #include <stdio.h> -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "wm_event_types.h" #include "KX_BlenderSceneConverter.h" #include "KX_ConvertSensors.h" /* This little block needed for linking to Blender... */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#include "BLI_winstuff.h" +#ifdef _MSC_VER +# include "BLI_winstuff.h" #endif #include "DNA_object_types.h" diff --git a/source/gameengine/Converter/KX_ConvertSensors.h b/source/gameengine/Converter/KX_ConvertSensors.h index 0694815c77e..56248721a37 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.h +++ b/source/gameengine/Converter/KX_ConvertSensors.h @@ -42,5 +42,4 @@ void BL_ConvertSensors(struct Object* blenderobject, class RAS_ICanvas* canvas, class KX_BlenderSceneConverter* converter); -#endif //__KX_CONVERTSENSORS_H__ - +#endif /* __KX_CONVERTSENSORS_H__ */ diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp index 12f88251805..4fc0b0ad3ec 100644 --- a/source/gameengine/Converter/KX_IpoConvert.cpp +++ b/source/gameengine/Converter/KX_IpoConvert.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show stl-warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show stl-warnings */ +# pragma warning (disable:4786) #endif #include "BKE_material.h" /* give_current_material */ diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h index 7bb2df978f6..861a2ba66f2 100644 --- a/source/gameengine/Converter/KX_IpoConvert.h +++ b/source/gameengine/Converter/KX_IpoConvert.h @@ -66,5 +66,4 @@ void BL_ConvertMaterialIpos(struct Object* blenderobject, class KX_BlenderSceneConverter *converter); -#endif //__KX_IPOCONVERT_H__ - +#endif /* __KX_IPOCONVERT_H__ */ diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp index e3c12c2b966..72d0c8733f2 100644 --- a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp +++ b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp @@ -30,8 +30,8 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif //WIN32 #include "MT_assert.h" diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.h b/source/gameengine/Converter/KX_SoftBodyDeformer.h index d692d45eb18..d7bc088e1c0 100644 --- a/source/gameengine/Converter/KX_SoftBodyDeformer.h +++ b/source/gameengine/Converter/KX_SoftBodyDeformer.h @@ -32,9 +32,9 @@ #ifndef __KX_SOFTBODYDEFORMER_H__ #define __KX_SOFTBODYDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include "RAS_Deformer.h" #include "BL_DeformableGameObject.h" diff --git a/source/gameengine/Expressions/BoolValue.h b/source/gameengine/Expressions/BoolValue.h index 64ac0266baf..b88c839a58e 100644 --- a/source/gameengine/Expressions/BoolValue.h +++ b/source/gameengine/Expressions/BoolValue.h @@ -61,5 +61,4 @@ private: #endif }; -#endif // !defined __BOOLVALUE_H__ - +#endif /* __BOOLVALUE_H__ */ diff --git a/source/gameengine/Expressions/ConstExpr.h b/source/gameengine/Expressions/ConstExpr.h index 86d411cef26..768f2bbd10e 100644 --- a/source/gameengine/Expressions/ConstExpr.h +++ b/source/gameengine/Expressions/ConstExpr.h @@ -51,5 +51,4 @@ private: #endif }; -#endif // !defined(AFX_CONSTEXPR_H__061ECFC3_BE87_11D1_A51C_00A02472FC58__INCLUDED_) - +#endif /* __CONSTEXPR_H__ */ diff --git a/source/gameengine/Expressions/EXP_C-Api.h b/source/gameengine/Expressions/EXP_C-Api.h index 4d43695f9b9..d73b0a209d4 100644 --- a/source/gameengine/Expressions/EXP_C-Api.h +++ b/source/gameengine/Expressions/EXP_C-Api.h @@ -64,5 +64,4 @@ const char* EXP_GetText(EXP_ValueHandle); } #endif -#endif //__EXP_C_API_H__ - +#endif /* __EXP_C_API_H__ */ diff --git a/source/gameengine/Expressions/EmptyValue.h b/source/gameengine/Expressions/EmptyValue.h index 54920359f3f..8eccb97e0f5 100644 --- a/source/gameengine/Expressions/EmptyValue.h +++ b/source/gameengine/Expressions/EmptyValue.h @@ -45,5 +45,4 @@ public: #endif }; -#endif // !defined __EMPTYVALUE_H__ - +#endif /* __EMPTYVALUE_H__ */ diff --git a/source/gameengine/Expressions/ErrorValue.h b/source/gameengine/Expressions/ErrorValue.h index 12bc7c7ffcb..0095528254e 100644 --- a/source/gameengine/Expressions/ErrorValue.h +++ b/source/gameengine/Expressions/ErrorValue.h @@ -43,5 +43,4 @@ private: #endif }; -#endif // !defined __ERRORVALUE_H__ - +#endif /* __ERRORVALUE_H__ */ diff --git a/source/gameengine/Expressions/Expression.h b/source/gameengine/Expressions/Expression.h index 5f5db505331..d1b7eda43f0 100644 --- a/source/gameengine/Expressions/Expression.h +++ b/source/gameengine/Expressions/Expression.h @@ -146,5 +146,4 @@ protected: #endif }; -#endif // !defined __EXPRESSION_H__ - +#endif /* __EXPRESSION_H__ */ diff --git a/source/gameengine/Expressions/FloatValue.h b/source/gameengine/Expressions/FloatValue.h index 59311e5d373..bc6a2d052d4 100644 --- a/source/gameengine/Expressions/FloatValue.h +++ b/source/gameengine/Expressions/FloatValue.h @@ -54,5 +54,4 @@ protected: #endif }; -#endif // !defined __FLOATVALUE_H__ - +#endif /* __FLOATVALUE_H__ */ diff --git a/source/gameengine/Expressions/IdentifierExpr.h b/source/gameengine/Expressions/IdentifierExpr.h index 58e75c4b02e..26eb3691378 100644 --- a/source/gameengine/Expressions/IdentifierExpr.h +++ b/source/gameengine/Expressions/IdentifierExpr.h @@ -56,5 +56,4 @@ public: #endif }; -#endif //__IDENTIFIEREXPR_H__ - +#endif /* __IDENTIFIEREXPR_H__ */ diff --git a/source/gameengine/Expressions/IfExpr.h b/source/gameengine/Expressions/IfExpr.h index f8ed81168d0..80e35471d82 100644 --- a/source/gameengine/Expressions/IfExpr.h +++ b/source/gameengine/Expressions/IfExpr.h @@ -16,12 +16,8 @@ * \ingroup expressions */ -#if !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_) -#define AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_ - -#if defined(_MSC_VER) && _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 +#ifndef __IFEXPR_H__ +#define __IFEXPR_H__ #include "Expression.h" @@ -55,5 +51,4 @@ public: #endif }; -#endif // !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_) - +#endif /* __IFEXPR_H__ */ diff --git a/source/gameengine/Expressions/IntValue.h b/source/gameengine/Expressions/IntValue.h index e728467cc4e..8411b09693c 100644 --- a/source/gameengine/Expressions/IntValue.h +++ b/source/gameengine/Expressions/IntValue.h @@ -69,5 +69,4 @@ private: #endif }; -#endif // !defined __INTVALUE_H__ - +#endif /* __INTVALUE_H__ */ diff --git a/source/gameengine/Expressions/KX_HashedPtr.h b/source/gameengine/Expressions/KX_HashedPtr.h index 866689ed203..d822af38c44 100644 --- a/source/gameengine/Expressions/KX_HashedPtr.h +++ b/source/gameengine/Expressions/KX_HashedPtr.h @@ -58,5 +58,4 @@ public: #endif }; -#endif //__KX_HASHEDPTR_H__ - +#endif /* __KX_HASHEDPTR_H__ */ diff --git a/source/gameengine/Expressions/KX_Python.h b/source/gameengine/Expressions/KX_Python.h index 4a7ce4d3fb7..62dd9a13dd4 100644 --- a/source/gameengine/Expressions/KX_Python.h +++ b/source/gameengine/Expressions/KX_Python.h @@ -79,5 +79,4 @@ #undef toupper #endif -#endif // __KX_PYTHON_H__ - +#endif /* __KX_PYTHON_H__ */ diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 20005088310..5240c54ae4e 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -87,5 +87,5 @@ private: bool m_bReleaseContents; }; -#endif // !defined __LISTVALUE_H__ +#endif /* __LISTVALUE_H__ */ diff --git a/source/gameengine/Expressions/Operator1Expr.h b/source/gameengine/Expressions/Operator1Expr.h index 13a1b16500a..3dd76f773f2 100644 --- a/source/gameengine/Expressions/Operator1Expr.h +++ b/source/gameengine/Expressions/Operator1Expr.h @@ -16,8 +16,8 @@ * \ingroup expressions */ -#if !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_) -#define AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_ +#ifndef __OPERATOR1EXPR_H__ +#define __OPERATOR1EXPR_H__ #include "Expression.h" @@ -56,5 +56,4 @@ private: #endif }; -#endif // !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_) - +#endif /* __OPERATOR1EXPR_H__ */ diff --git a/source/gameengine/Expressions/Operator2Expr.h b/source/gameengine/Expressions/Operator2Expr.h index 23272930131..8c30b7cd634 100644 --- a/source/gameengine/Expressions/Operator2Expr.h +++ b/source/gameengine/Expressions/Operator2Expr.h @@ -62,5 +62,5 @@ private: #endif }; -#endif // !defined __OPERATOR2EXPR_H__ +#endif /* __OPERATOR2EXPR_H__ */ diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 005bf2f6cb2..83b7c8c8771 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -548,7 +548,7 @@ public: \ #define Py_HeaderPtr \ public: \ -#endif // WITH_CXX_GUARDEDALLOC +#endif /* WITH_CXX_GUARDEDALLOC */ #endif @@ -633,4 +633,4 @@ public: PyObject *PyUnicode_From_STR_String(const STR_String& str); #endif -#endif // __PYOBJECTPLUS_H__ +#endif /* __PYOBJECTPLUS_H__ */ diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h index bc102c6e203..22d433455ec 100644 --- a/source/gameengine/Expressions/StringValue.h +++ b/source/gameengine/Expressions/StringValue.h @@ -45,7 +45,7 @@ public: virtual PyObject* ConvertValueToPython() { return PyUnicode_From_STR_String(m_strString); } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: // data member @@ -57,5 +57,4 @@ private: #endif }; -#endif - +#endif /* __STRINGVALUE_H__ */ diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index e0c4daeccd0..c4af3255f4a 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -16,13 +16,13 @@ * \ingroup expressions */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) -#endif //WIN32 - #ifndef __VALUE_H__ #define __VALUE_H__ +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif + #include <map> // array functionality for the propertylist #include "STR_String.h" // STR_String class @@ -53,14 +53,6 @@ using namespace std; #define assertd(exp) ((void)NULL) #endif - -#ifndef USE_PRAGMA_ONCE -#ifdef WIN32 - #pragma once - -#endif //WIN32 -#endif - enum VALUE_OPERATOR { VALUE_MOD_OPERATOR, // % @@ -233,7 +225,7 @@ public: static PyObject *pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef); virtual PyObject *ConvertKeysToPython( void ); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ @@ -439,5 +431,4 @@ protected: #endif }; -#endif // !defined _VALUEBASECLASS_H - +#endif /* __VALUE_H__ */ diff --git a/source/gameengine/Expressions/VectorValue.cpp b/source/gameengine/Expressions/VectorValue.cpp index 65f5d7d3d22..ed13b0c8639 100644 --- a/source/gameengine/Expressions/VectorValue.cpp +++ b/source/gameengine/Expressions/VectorValue.cpp @@ -15,8 +15,8 @@ * */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "Value.h" diff --git a/source/gameengine/Expressions/VectorValue.h b/source/gameengine/Expressions/VectorValue.h index b7afa61d4dd..9b9f9612810 100644 --- a/source/gameengine/Expressions/VectorValue.h +++ b/source/gameengine/Expressions/VectorValue.h @@ -90,5 +90,4 @@ protected: #endif }; -#endif // !defined __VECTORVALUE_H__ - +#endif /* __VECTORVALUE_H__ */ diff --git a/source/gameengine/Expressions/VoidValue.h b/source/gameengine/Expressions/VoidValue.h index a1a82f8aa65..e97278b3142 100644 --- a/source/gameengine/Expressions/VoidValue.h +++ b/source/gameengine/Expressions/VoidValue.h @@ -78,4 +78,3 @@ public: }; #endif /* __VOIDVALUE_H__ */ - diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index ccc3f9be3af..ff152d6d2fb 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -48,5 +48,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_ANDCONTROLLER_H__ - +#endif /* __SCA_ANDCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h index dee9ea4e8ba..997be1145db 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h +++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h @@ -53,5 +53,4 @@ public: #endif }; -#endif //__SCA_ACTUATOREVENTMANAGER_H__ - +#endif /* __SCA_ACTUATOREVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 894dc2162cf..6005bd3ac6c 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -64,7 +64,7 @@ public: static int CheckActuator(void *self, const PyAttributeDef*); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif +#endif /* __SCA_ACTUATORSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h index cf4063fba1f..47293c75726 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h +++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h @@ -47,5 +47,4 @@ public: #endif }; -#endif //__SCA_ALWAYSEVENTMANAGER_H__ - +#endif /* __SCA_ALWAYSEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index 6b697f4f15b..1a6a82a33eb 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -32,11 +32,10 @@ * \ingroup gamelogic */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include "SCA_AlwaysSensor.h" diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index d0963fd0ea1..e0ab4279b1c 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -50,5 +50,4 @@ public: virtual void Init(); }; -#endif //__SCA_ALWAYSSENSOR_H__ - +#endif /* __SCA_ALWAYSSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_BasicEventManager.h b/source/gameengine/GameLogic/SCA_BasicEventManager.h index 24206e46a61..a015233454b 100644 --- a/source/gameengine/GameLogic/SCA_BasicEventManager.h +++ b/source/gameengine/GameLogic/SCA_BasicEventManager.h @@ -54,5 +54,4 @@ public: #endif }; -#endif //__SCA_BASICEVENTMANAGER_H__ - +#endif /* __SCA_BASICEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index f2bcd67e652..af751cffc2e 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -32,11 +32,10 @@ * \ingroup gamelogic */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include <stddef.h> diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index 2c408921f27..b516cd8360e 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -65,5 +65,4 @@ public: }; -#endif //__KX_ALWAYSSENSOR - +#endif /* __SCA_DELAYSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 06edc83ab96..c16944ccde1 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -63,5 +63,4 @@ public: #endif }; -#endif //__SCA_EXPRESSIONCONTROLLER_H__ - +#endif /* __SCA_EXPRESSIONCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 801483bb882..090df1e75e2 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -164,5 +164,4 @@ public: #endif }; -#endif //__SCA_IACTUATOR_H__ - +#endif /* __SCA_IACTUATOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 656c4299dff..1bc6b60bf1e 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -106,8 +106,7 @@ public: static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif - +#endif /* __SCA_ICONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h index 66a1209751d..bc4d22eaaaf 100644 --- a/source/gameengine/GameLogic/SCA_IInputDevice.h +++ b/source/gameengine/GameLogic/SCA_IInputDevice.h @@ -320,5 +320,5 @@ public: #endif }; -#endif //__SCA_IINPUTDEVICE_H__ +#endif /* __SCA_IINPUTDEVICE_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index c5fa9399ab7..dc0aa4ce331 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -159,9 +159,8 @@ protected: /** Convert a a c++ value to KX_TRUE, KX_FALSE in Python. */ PyObject *BoolToPyArg(bool); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif - +#endif /* __SCA_ILOGICBRICK_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index a850d23babf..0189af00322 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -225,5 +225,4 @@ public: }; -#endif //__SCA_IOBJECT_H__ - +#endif /* __SCA_IOBJECT_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h index a399e313082..997266976ad 100644 --- a/source/gameengine/GameLogic/SCA_IScene.h +++ b/source/gameengine/GameLogic/SCA_IScene.h @@ -78,5 +78,4 @@ public: #endif }; -#endif //__SCA_ISCENE_H__ - +#endif /* __SCA_ISCENE_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 3bb29f3f0a2..091aa675741 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -212,8 +212,7 @@ public: KX_SENSOR_JUST_DEACTIVATED }; -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__SCA_ISENSOR_H__ - +#endif /* __SCA_ISENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index 5dc35faf244..6c6dc019a5e 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -30,11 +30,11 @@ */ -#ifndef __JOYSENSOR_H_ -#define __JOYSENSOR_H +#ifndef __JOYSENSOR_H__ +#define __JOYSENSOR_H__ #include "SCA_ISensor.h" -#include "./Joystick/SCA_JoystickDefines.h" +#include "Joystick/SCA_JoystickDefines.h" class SCA_JoystickSensor :public SCA_ISensor { @@ -161,8 +161,8 @@ public: return 0; } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif +#endif /* __JOYSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h index fd3c0706fa7..cd1cbf4adee 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardManager.h +++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h @@ -63,5 +63,4 @@ public: #endif }; -#endif //__SCA_KEYBOARDMANAGER_H__ - +#endif /* __SCA_KEYBOARDMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index caa141e48f2..c6610d0284e 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -138,7 +138,4 @@ bool IsPrintable(int keyIndex); bool IsDelete(int keyIndex); -#endif //__SCA_KEYBOARDSENSOR_H__ - - - +#endif /* __SCA_KEYBOARDSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index 817f3a1c22a..690930196b3 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -31,8 +31,8 @@ #ifndef __SCA_LOGICMANAGER_H__ #define __SCA_LOGICMANAGER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include <vector> @@ -151,5 +151,4 @@ public: #endif }; -#endif //__SCA_LOGICMANAGER_H__ - +#endif /* __SCA_LOGICMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp index a067b9c4d5b..6d05b862c2d 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.cpp +++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp @@ -34,10 +34,10 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include "BoolValue.h" diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h index 02c28807566..a57e52070a7 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.h +++ b/source/gameengine/GameLogic/SCA_MouseManager.h @@ -72,5 +72,4 @@ public: #endif }; -#endif //__SCA_MOUSEMANAGER_H__ - +#endif /* __SCA_MOUSEMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index d4eff371d4a..8d05a548681 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -117,5 +117,4 @@ class SCA_MouseSensor : public SCA_ISensor #endif }; -#endif //__SCA_MOUSESENSOR_H__ - +#endif /* __SCA_MOUSESENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 040df7f0ade..a3f02908dd2 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -49,5 +49,4 @@ public: /* --------------------------------------------------------------------- */ }; -#endif //__SCA_NANDCONTROLLER_H__ - +#endif /* __SCA_NANDCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index 1630f8055ec..ec8159de8d1 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -45,5 +45,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_NORCONTROLLER_H__ - +#endif /* __SCA_NORCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index 9a4e4c7398d..9499c893c72 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -46,5 +46,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_ORCONTROLLER_H__ - +#endif /* __SCA_ORCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index e465098131e..83a6d05df1b 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -86,5 +86,4 @@ public: }; -#endif //__KX_PROPERTYACTUATOR_DOC - +#endif /* __KX_PROPERTYACTUATOR_DOC */ diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h index 7a4ec750484..554fe686df2 100644 --- a/source/gameengine/GameLogic/SCA_PropertyEventManager.h +++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h @@ -52,5 +52,4 @@ public: #endif }; -#endif //__SCA_PROPERTYEVENTMANAGER_H__ - +#endif /* __SCA_PROPERTYEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 8a72ce6bad9..f1f10d22711 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -115,5 +115,4 @@ class SCA_PythonController : public SCA_IController #endif }; -#endif //__SCA_PYTHONCONTROLLER_H__ - +#endif /* __SCA_PYTHONCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PythonKeyboard.h b/source/gameengine/GameLogic/SCA_PythonKeyboard.h index aab49bcb83b..53068f38e6a 100644 --- a/source/gameengine/GameLogic/SCA_PythonKeyboard.h +++ b/source/gameengine/GameLogic/SCA_PythonKeyboard.h @@ -47,5 +47,4 @@ public: #endif }; -#endif //__SCA_PYTHONKEYBOARD_H__ - +#endif /* __SCA_PYTHONKEYBOARD_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PythonMouse.h b/source/gameengine/GameLogic/SCA_PythonMouse.h index f770a54d6e6..bc6e65f07a8 100644 --- a/source/gameengine/GameLogic/SCA_PythonMouse.h +++ b/source/gameengine/GameLogic/SCA_PythonMouse.h @@ -56,5 +56,4 @@ public: #endif }; -#endif //__SCA_PYTHONMOUSE_H__ - +#endif /* __SCA_PYTHONMOUSE_H__ */ diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index f61de24c0cc..32b29fc4f43 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -112,7 +112,7 @@ class SCA_RandomActuator : public SCA_IActuator KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatNormal); KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatNegativeExponential); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h index b46899b1355..2d83c5fcdca 100644 --- a/source/gameengine/GameLogic/SCA_RandomEventManager.h +++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h @@ -51,5 +51,4 @@ public: #endif }; -#endif //__SCA_RANDOMEVENTMANAGER_H__ - +#endif /* __SCA_RANDOMEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 008445ef878..628562b77e6 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -68,5 +68,4 @@ public: #endif }; -#endif //__SCA_RANDOMSENSOR_H__ - +#endif /* __SCA_RANDOMSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp index e8a6289a98e..5aa6fdc8625 100644 --- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp @@ -29,11 +29,10 @@ * \ingroup gamelogic */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning(disable:4786) #endif #include "SCA_TimeEventManager.h" diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.h b/source/gameengine/GameLogic/SCA_TimeEventManager.h index 092cf016370..4c929dca23c 100644 --- a/source/gameengine/GameLogic/SCA_TimeEventManager.h +++ b/source/gameengine/GameLogic/SCA_TimeEventManager.h @@ -59,5 +59,4 @@ public: #endif }; -#endif //__SCA_TIMEEVENTMANAGER_H__ - +#endif /* __SCA_TIMEEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index 5ef4dc67cf2..c257b71273e 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -50,5 +50,4 @@ public: }; -#endif //__SCA_XNORCONTROLLER_H__ - +#endif /* __SCA_XNORCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index 56cd2440863..c64a3380ede 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -45,5 +45,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_XORCONTROLLER_H__ - +#endif /* __SCA_XORCONTROLLER_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp index 7581484a41f..b5c1c29238a 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp @@ -57,6 +57,8 @@ GPC_Canvas::GPC_Canvas( m_displayarea.m_y1 = 0; m_displayarea.m_x2 = width; m_displayarea.m_y2 = height; + + glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport); } @@ -121,11 +123,31 @@ void GPC_Canvas::SetViewPort(int x1, int y1, int x2, int y2) * whole canvas/rendertools mess. */ glEnable(GL_SCISSOR_TEST); + + m_viewport[0] = x1; + m_viewport[1] = y1; + m_viewport[2] = x2-x1 + 1; + m_viewport[3] = y2-y1 + 1; glViewport(x1,y1,x2-x1 + 1,y2-y1 + 1); glScissor(x1,y1,x2-x1 + 1,y2-y1 + 1); }; +const int *GPC_Canvas::GetViewPort() +{ +#ifdef DEBUG + // If we're in a debug build, we might as well make sure our values don't differ + // from what the gpu thinks we have. This could lead to nasty, hard to find bugs. + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + assert(viewport[0] == m_viewport[0]); + assert(viewport[1] == m_viewport[1]); + assert(viewport[2] == m_viewport[2]); + assert(viewport[3] == m_viewport[3]); +#endif + + return m_viewport; +} void GPC_Canvas::ClearBuffer( int type diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h index 453b9505183..ec5375c0e13 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.h +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h @@ -38,7 +38,7 @@ #ifdef WIN32 #pragma warning (disable:4786) // suppress stl-MSVC debug info warning #include <windows.h> -#endif // WIN32 +#endif /* WIN32 */ #include "GL/glew.h" @@ -90,6 +90,8 @@ protected: * relative to the context */ RAS_Rect m_displayarea; + int m_viewport[4]; + /** Storage for the banners to display. */ TBannerMap m_banners; /** State of banner display. */ @@ -153,6 +155,7 @@ public: ); void SetViewPort(int x1, int y1, int x2, int y2); + const int *GetViewPort(); void ClearColor(float r, float g, float b, float a); @@ -270,5 +273,4 @@ protected: static TBannerId s_bannerId; }; -#endif // __GPC_CANVAS_H__ - +#endif /* __GPC_CANVAS_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.h b/source/gameengine/GamePlayer/common/GPC_Engine.h index 60f0d2af199..6247bd630bb 100644 --- a/source/gameengine/GamePlayer/common/GPC_Engine.h +++ b/source/gameengine/GamePlayer/common/GPC_Engine.h @@ -121,5 +121,4 @@ private: }; -#endif // __GPC_ENGINE_H__ - +#endif /* __GPC_ENGINE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h index 63e051dd1d4..c082bc1b82f 100644 --- a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h @@ -33,8 +33,8 @@ #define __GPC_KEYBOARDDEVICE_H__ #ifdef WIN32 -#pragma warning (disable : 4786) -#endif // WIN32 +#pragma warning (disable:4786) +#endif /* WIN32 */ #include "SCA_IInputDevice.h" @@ -87,5 +87,4 @@ public: virtual void HookEscape(); }; -#endif // _GPC_KEYBOARDDEVICE_H - +#endif /* __GPC_KEYBOARDDEVICE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h index 2db1b1ec34c..b092fbd21dd 100644 --- a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h @@ -33,8 +33,8 @@ #define __GPC_MOUSEDEVICE_H__ #ifdef WIN32 -#pragma warning (disable : 4786) -#endif // WIN32 +#pragma warning (disable:4786) +#endif /* WIN32 */ #include "SCA_IInputDevice.h" @@ -102,5 +102,4 @@ protected: virtual bool ConvertEvent(KX_EnumInputs kxevent, int eventval); }; -#endif // __GPC_MOUSEDEVICE_H__ - +#endif /* __GPC_MOUSEDEVICE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RawImage.h b/source/gameengine/GamePlayer/common/GPC_RawImage.h index 4d3f45597f8..afff59484b9 100644 --- a/source/gameengine/GamePlayer/common/GPC_RawImage.h +++ b/source/gameengine/GamePlayer/common/GPC_RawImage.h @@ -117,5 +117,4 @@ protected: int m_height; }; -#endif // __GPC_RAWIMAGE_H__ - +#endif /* __GPC_RAWIMAGE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h index 6f15276ab83..d5c1b210454 100644 --- a/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h +++ b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h @@ -34,5 +34,4 @@ void GetRawLoadingAnimation(unsigned char **data, int *dataSize); -#endif // __GPC_RAWLOADDOTBLENDARRAY_H__ - +#endif /* __GPC_RAWLOADDOTBLENDARRAY_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h index ade00020353..bb5c5e220a3 100644 --- a/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h +++ b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h @@ -38,5 +38,4 @@ void GetRawBlender3DLogo(unsigned char **data, int *width, int *height); void GetRawNaNLogo(unsigned char **data, int *width, int *height); #endif -#endif // __GPC_RAWLOGOARRAYS_H__ - +#endif /* __GPC_RAWLOGOARRAYS_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 9cd6715f3d2..4bf81bf543e 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -359,7 +359,8 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode, glGetIntegerv(GL_LIGHTING, (GLint*)&light); glDisable(GL_LIGHTING); - + glDisable(GL_DEPTH_TEST); + // Set up viewing settings glMatrixMode(GL_PROJECTION); glPushMatrix(); diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index 166a931beab..1030c09548a 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -36,7 +36,7 @@ // don't show stl-warnings #pragma warning (disable:4786) #include <windows.h> -#endif // WIN32 +#endif /* WIN32 */ #include "RAS_IRenderTools.h" @@ -106,7 +106,4 @@ public: virtual void SetClientObject(RAS_IRasterizer *rasty, void* obj); }; -#endif // __GPC_RENDERTOOLS_H__ - - - +#endif /* __GPC_RENDERTOOLS_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_System.h b/source/gameengine/GamePlayer/common/GPC_System.h index 03bb7743637..4169064179e 100644 --- a/source/gameengine/GamePlayer/common/GPC_System.h +++ b/source/gameengine/GamePlayer/common/GPC_System.h @@ -59,5 +59,4 @@ public: // NG_NetworkDeviceInterface* m_ndi; }; -#endif // __GPC_SYSTEM_H__ - +#endif /* __GPC_SYSTEM_H__ */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h index d931f605a64..440fd2bba27 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h @@ -33,8 +33,8 @@ #define __GPG_CANVAS_H__ #ifdef WIN32 -#pragma warning (disable : 4786) -#endif // WIN32 +#pragma warning (disable:4786) +#endif /* WIN32 */ #include "GPC_Canvas.h" @@ -66,5 +66,4 @@ public: void EndDraw() {}; }; -#endif // __GPG_CANVAS_H__ - +#endif /* __GPG_CANVAS_H__ */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h index 8d72a621b6a..ff8d56db40a 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h @@ -34,8 +34,8 @@ #define __GPG_KEYBOARDDEVICE_H__ #ifdef WIN32 -#pragma warning (disable : 4786) -#endif // WIN32 +#pragma warning (disable:4786) +#endif /* WIN32 */ #include "GHOST_Types.h" #include "GPC_KeyboardDevice.h" @@ -53,5 +53,4 @@ public: virtual ~GPG_KeyboardDevice(void); }; -#endif //__GPG_KEYBOARDDEVICE_H__ - +#endif /* __GPG_KEYBOARDDEVICE_H__ */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_System.h b/source/gameengine/GamePlayer/ghost/GPG_System.h index 796ad0c2b8c..d68fc812dd3 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_System.h +++ b/source/gameengine/GamePlayer/ghost/GPG_System.h @@ -35,7 +35,7 @@ #ifdef WIN32 #pragma warning (disable:4786) // suppress stl-MSVC debug info warning -#endif // WIN32 +#endif /* WIN32 */ #include "GPC_System.h" @@ -51,5 +51,4 @@ public: virtual double GetTimeInSeconds(); }; -#endif // __GPG_SYSTEM_H__ - +#endif /* __GPG_SYSTEM_H__ */ diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h index ab2adf7fe34..370bbf51d72 100644 --- a/source/gameengine/Ketsji/BL_Action.h +++ b/source/gameengine/Ketsji/BL_Action.h @@ -136,5 +136,4 @@ public: #endif }; -#endif //BL_ACTION - +#endif /* BL_ACTION */ diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h index dbdaa6652ad..600e7b6621e 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.h +++ b/source/gameengine/Ketsji/BL_ActionManager.h @@ -98,5 +98,4 @@ public: #endif }; -#endif //BL_ACTIONMANAGER - +#endif /* BL_ACTIONMANAGER */ diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index f23dbfdf3a5..626c65baadd 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -101,4 +101,4 @@ public: #endif }; -#endif//__BL_BLENDERSHADER_H__ +#endif /* __BL_BLENDERSHADER_H__ */ diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index b577a1849a0..82476873b85 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -252,4 +252,4 @@ public: #endif }; -#endif//__BL_SHADER_H__ +#endif /* __BL_SHADER_H__ */ diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h index a6bd354d260..cd18ef93822 100644 --- a/source/gameengine/Ketsji/BL_Texture.h +++ b/source/gameengine/Ketsji/BL_Texture.h @@ -79,4 +79,4 @@ public: #endif }; -#endif//__BL_TEXTURE_H__ +#endif /* __BL_TEXTURE_H__ */ diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index 269311b7e00..b42c2c27075 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -248,9 +248,11 @@ endif() if(WITH_BULLET) list(APPEND INC - ../../../extern/bullet2/src ../Physics/Bullet ) + list(APPEND INC + ../../../extern/bullet2/src + ) add_definitions(-DUSE_BULLET) endif() diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h index 3202785ee81..9a13b6d53e2 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h @@ -52,5 +52,4 @@ public: return m_ndi; } }; -#endif //__KX_NETWORKEVENTMANAGER_H__ - +#endif /* __KX_NETWORKEVENTMANAGER_H__ */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index 980e1cda6dc..325a7be9bd7 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -69,5 +69,4 @@ public: }; -#endif //__KX_NETWORKMESSAGEACTUATOR_H__ - +#endif /* __KX_NETWORKMESSAGEACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 6b9779de6e3..a1f0692b7b3 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -83,9 +83,8 @@ public: static PyObject* pyattr_get_bodies(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_subjects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_NETWORKMESSAGESENSOR_H__ - +#endif /* __KX_NETWORKMESSAGESENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ArmatureSensor.h b/source/gameengine/Ketsji/KX_ArmatureSensor.h index 74603b3ff01..b3ea905d198 100644 --- a/source/gameengine/Ketsji/KX_ArmatureSensor.h +++ b/source/gameengine/Ketsji/KX_ArmatureSensor.h @@ -74,7 +74,7 @@ public: /* --------------------------------------------------------------------- */ static PyObject *pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: struct bConstraint* m_constraint; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index a69f5c92d19..1653669ebcc 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -119,7 +119,7 @@ public: KX_PYMETHOD_DOC(KX_BlenderMaterial, setTexture); KX_PYMETHOD_DOC(KX_BlenderMaterial, setBlending); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ // -------------------------------- // pre calculate to avoid pops/lag at startup diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 71e806686ca..4813b39a34e 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -96,5 +96,4 @@ public: #endif }; -#endif //__KX_BULLETPHYSICSCONTROLLER_H__ - +#endif /* __KX_BULLETPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index c0071ab22f6..90912409af1 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -956,7 +956,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition, } } - GLint viewport[4]; + const GLint *viewport; GLdouble win[3]; GLdouble modelmatrix[16]; GLdouble projmatrix[16]; @@ -967,7 +967,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition, m_modelmatrix.getValue(modelmatrix); m_projmatrix.getValue(projmatrix); - glGetIntegerv(GL_VIEWPORT, viewport); + viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort(); gluProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]); @@ -999,7 +999,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect, MT_Vector3 vect; MT_Point3 campos, screenpos; - GLint viewport[4]; + const GLint *viewport; GLdouble win[3]; GLdouble modelmatrix[16]; GLdouble projmatrix[16]; @@ -1010,7 +1010,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect, m_modelmatrix.getValue(modelmatrix); m_projmatrix.getValue(projmatrix); - glGetIntegerv(GL_VIEWPORT, viewport); + viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort(); vect[0] = x * viewport[2]; vect[1] = y * viewport[3]; diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index d95d10e8384..6c1dc1edb51 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -321,5 +321,4 @@ public: #endif }; -#endif //__KX_CAMERA_H__ - +#endif /* __KX_CAMERA_H__ */ diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index c67174d2830..fb0a7d88dd9 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -131,9 +131,8 @@ private : static PyObject* pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_CAMERAACTUATOR_H__ - +#endif /* __KX_CAMERAACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_CameraIpoSGController.h b/source/gameengine/Ketsji/KX_CameraIpoSGController.h index 9b7c1eddf00..1f6f211622c 100644 --- a/source/gameengine/Ketsji/KX_CameraIpoSGController.h +++ b/source/gameengine/Ketsji/KX_CameraIpoSGController.h @@ -94,5 +94,4 @@ public: #endif }; -#endif // __KX_CAMERAIPOSGCONTROLLER_H__ - +#endif /* __KX_CAMERAIPOSGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 6fd1271160a..e947eb4be6d 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -84,5 +84,4 @@ public: #endif }; -#endif //__KX_CLIENTOBJECTINFO_H__ - +#endif /* __KX_CLIENTOBJECTINFO_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 786e4ff53d2..edb2e5e0180 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -145,5 +145,4 @@ protected: }; -#endif //__KX_CONSTRAINTACTUATOR_H__ - +#endif /* __KX_CONSTRAINTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index dbc3571cad6..eafc45b5a70 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -57,5 +57,4 @@ private: PHY_IPhysicsEnvironment* m_physenv; }; -#endif //__KX_CONSTRAINTWRAPPER_H__ - +#endif /* __KX_CONSTRAINTWRAPPER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 0f1ce403881..e71037d08a0 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -159,4 +159,4 @@ void KX_ClearBulletSharedShapes(); bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj); #endif -#endif //__KX_CONVERTPHYSICSOBJECT_H__ +#endif /* __KX_CONVERTPHYSICSOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 776953206fe..daa74ca14c0 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -29,8 +29,8 @@ * \ingroup ketsji */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "MT_assert.h" diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index fd3a18a9d2a..87b0cfc1269 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -90,8 +90,7 @@ KX_Dome::KX_Dome ( } //setting the viewport size - GLuint viewport[4]={0}; - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + const int *viewport = m_canvas->GetViewPort(); SetViewPort(viewport); @@ -178,7 +177,7 @@ KX_Dome::~KX_Dome (void) glDeleteLists(dlistId, (GLsizei) m_numimages); } -void KX_Dome::SetViewPort(GLuint viewport[4]) +void KX_Dome::SetViewPort(const int viewport[4]) { if (canvaswidth != m_viewport.GetWidth() || canvasheight != m_viewport.GetHeight()) { diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 24177af5d60..17eec3a5fcb 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -119,7 +119,7 @@ public: void RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i); void BindImages(int i); - void SetViewPort(GLuint viewport[4]); + void SetViewPort(const int viewport[4]); void CalculateFrustum(KX_Camera* cam); void RotateCamera(KX_Camera* cam, int i); diff --git a/source/gameengine/Ketsji/KX_EmptyObject.h b/source/gameengine/Ketsji/KX_EmptyObject.h index b99f44c38c5..63a0782a544 100644 --- a/source/gameengine/Ketsji/KX_EmptyObject.h +++ b/source/gameengine/Ketsji/KX_EmptyObject.h @@ -47,5 +47,4 @@ public: #endif }; -#endif //__KX_EMPTYOBJECT_H__ - +#endif /* __KX_EMPTYOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h index ae8b4166238..ac22de6fb6f 100644 --- a/source/gameengine/Ketsji/KX_FontObject.h +++ b/source/gameengine/Ketsji/KX_FontObject.h @@ -76,4 +76,4 @@ protected: }; -#endif //__KX_FONTOBJECT_H__ +#endif /* __KX_FONTOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fe8419d5343..dfc8073303e 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -30,6 +30,11 @@ * \ingroup ketsji */ +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) +#endif #if defined(_WIN64) && !defined(FREE_WINDOWS64) typedef unsigned __int64 uint_ptr; @@ -37,13 +42,6 @@ typedef unsigned __int64 uint_ptr; typedef unsigned long uint_ptr; #endif -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) -#endif - - #define KX_INERTIA_INFINITE 10000 #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" @@ -109,6 +107,8 @@ KX_GameObject::KX_GameObject( m_xray(false), m_pHitObject(NULL), m_pObstacleSimulation(NULL), + m_pInstanceObjects(NULL), + m_pDupliGroupObject(NULL), m_actionManager(NULL), m_isDeformable(false) #ifdef WITH_PYTHON @@ -168,6 +168,16 @@ KX_GameObject::~KX_GameObject() KX_GetActiveScene()->RemoveAnimatedObject(this); delete m_actionManager; } + + if (m_pDupliGroupObject) + { + m_pDupliGroupObject->Release(); + } + + if (m_pInstanceObjects) + { + m_pInstanceObjects->Release(); + } #ifdef WITH_PYTHON if (m_attr_dict) { PyDict_Clear(m_attr_dict); /* in case of circular refs or other weird cases */ @@ -229,6 +239,46 @@ KX_IPhysicsController* KX_GameObject::GetPhysicsController() return m_pPhysicsController1; } +KX_GameObject* KX_GameObject::GetDupliGroupObject() +{ + return m_pDupliGroupObject; +} + +CListValue* KX_GameObject::GetInstanceObjects() +{ + return m_pInstanceObjects; +} + +void KX_GameObject::AddInstanceObjects(KX_GameObject* obj) +{ + if(!m_pInstanceObjects) + m_pInstanceObjects = new CListValue(); + + obj->AddRef(); + m_pInstanceObjects->Add(obj); +} + +void KX_GameObject::RemoveInstanceObject(KX_GameObject* obj) +{ + assert(m_pInstanceObjects); + m_pInstanceObjects->RemoveValue(obj); + obj->Release(); +} + +void KX_GameObject::RemoveDupliGroupObject() +{ + if(m_pDupliGroupObject) { + m_pDupliGroupObject->Release(); + m_pDupliGroupObject = NULL; + } +} + +void KX_GameObject::SetDupliGroupObject(KX_GameObject* obj) +{ + obj->AddRef(); + m_pDupliGroupObject = obj; +} + KX_GameObject* KX_GameObject::GetParent() { KX_GameObject* result = NULL; @@ -1629,6 +1679,9 @@ PyMethodDef KX_GameObject::Methods[] = { PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent), + KX_PYATTRIBUTE_RO_FUNCTION("group_children", KX_GameObject, pyattr_get_group_children), + KX_PYATTRIBUTE_RO_FUNCTION("group_parent", KX_GameObject, pyattr_get_group_parent), + KX_PYATTRIBUTE_RO_FUNCTION("scene", KX_GameObject, pyattr_get_scene), KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life), KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass), KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min), @@ -1924,6 +1977,37 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE Py_RETURN_NONE; } +PyObject *KX_GameObject::pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + CListValue* instances = self->GetInstanceObjects(); + if (instances) { + return instances->GetProxy(); + } + Py_RETURN_NONE; +} + +PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject *self = static_cast<KX_GameObject*>(self_v); + SG_Node *node = self->GetSGNode(); + KX_Scene *scene = static_cast<KX_Scene *>(node->GetSGClientInfo()); + if (scene) { + return scene->GetProxy(); + } + Py_RETURN_NONE; +} + +PyObject *KX_GameObject::pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + KX_GameObject* pivot = self->GetDupliGroupObject(); + if (pivot) { + return pivot->GetProxy(); + } + Py_RETURN_NONE; +} + PyObject *KX_GameObject::pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast<KX_GameObject*>(self_v); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index ea75ca4a917..157e282b557 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -33,9 +33,9 @@ #ifndef __KX_GAMEOBJECT_H__ #define __KX_GAMEOBJECT_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// get rid of this stupid "warning 'this' used in initialiser list", generated by VC when including Solid/Sumo -#pragma warning (disable : 4355) +#ifdef _MSC_VER + /* get rid of this stupid "warning 'this' used in initialiser list", generated by VC when including Solid/Sumo */ +# pragma warning (disable:4355) #endif #include <stddef.h> @@ -116,9 +116,11 @@ protected: KX_ObstacleSimulation* m_pObstacleSimulation; + CListValue* m_pInstanceObjects; + KX_GameObject* m_pDupliGroupObject; // The action manager is used to play/stop/update actions - BL_ActionManager* m_actionManager; + BL_ActionManager* m_actionManager; BL_ActionManager* GetActionManager(); @@ -208,6 +210,33 @@ public: void RemoveParent(KX_Scene *scene); /********************************* + * group reference API + *********************************/ + + KX_GameObject* + GetDupliGroupObject( + ); + + CListValue* + GetInstanceObjects( + ); + + void + SetDupliGroupObject(KX_GameObject* + ); + + void + AddInstanceObjects(KX_GameObject* + ); + + void + RemoveDupliGroupObject( + ); + + void + RemoveInstanceObject(KX_GameObject* + ); + /********************************* * Animation API *********************************/ @@ -949,6 +978,10 @@ public: static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_scene(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); @@ -1008,5 +1041,4 @@ public: -#endif //__KX_GAMEOBJECT_H__ - +#endif /* __KX_GAMEOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 950e3c88a9e..60821fb5aab 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -37,10 +37,10 @@ typedef unsigned __int64 uint_ptr; typedef unsigned long uint_ptr; #endif -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning(disable:4786) #endif #include "KX_IPO_SGController.h" diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h index 266b89ff969..cecfa9804db 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.h +++ b/source/gameengine/Ketsji/KX_IPO_SGController.h @@ -126,6 +126,4 @@ public: #endif }; -#endif //__KX_IPO_SGCONTROLLER_H__ - - +#endif /* __KX_IPO_SGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index dd34549c1fb..280b1816a1e 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -145,5 +145,4 @@ public: #endif }; -#endif //__KX_IPHYSICSCONTROLLER_H__ - +#endif /* __KX_IPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index 919ae1d6de5..18fb336dbe0 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -93,5 +93,4 @@ public: #endif }; -#endif //__KX_ISCENECONVERTER_H__ - +#endif /* __KX_ISCENECONVERTER_H__ */ diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 58cdfc28742..1c2f4e49b72 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -150,5 +150,4 @@ public: }; -#endif //__KX_IPOACTUATOR_H__ - +#endif /* __KX_IPOACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index c2857141058..479e63a1f24 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -30,10 +30,9 @@ * \ingroup ketsji */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include <iostream> #include <stdio.h> @@ -46,7 +45,6 @@ #include "BoolValue.h" #include "FloatValue.h" -#define KX_NUM_ITERATIONS 4 #include "RAS_BucketManager.h" #include "RAS_Rect.h" #include "RAS_IRasterizer.h" @@ -275,8 +273,7 @@ void KX_KetsjiEngine::InitDome(short res, short mode, short angle, float resbuf, void KX_KetsjiEngine::RenderDome() { - GLuint viewport[4]={0}; - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + const GLint *viewport = m_canvas->GetViewPort(); m_dome->SetViewPort(viewport); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index e05ba652bbe..972594bd90f 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -447,6 +447,4 @@ protected: #endif }; -#endif //__KX_KETSJIENGINE_H__ - - +#endif /* __KX_KETSJIENGINE_H__ */ diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 8b80daa75d3..0e45684d2d0 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -29,8 +29,8 @@ * \ingroup ketsji */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include <stdio.h> @@ -50,9 +50,9 @@ #include "GPU_material.h" KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, - class RAS_IRenderTools* rendertools, - const RAS_LightObject& lightobj, - bool glsl) + class RAS_IRenderTools* rendertools, + const RAS_LightObject& lightobj, + bool glsl) : KX_GameObject(sgReplicationInfo,callbacks), m_rendertools(rendertools) { diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 7426896a92a..52f076c772a 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -83,5 +83,4 @@ public: #endif }; -#endif //__KX_LIGHT_H__ - +#endif /* __KX_LIGHT_H__ */ diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.h b/source/gameengine/Ketsji/KX_LightIpoSGController.h index 4a1ceba0963..c82fe7bcad5 100644 --- a/source/gameengine/Ketsji/KX_LightIpoSGController.h +++ b/source/gameengine/Ketsji/KX_LightIpoSGController.h @@ -102,5 +102,4 @@ public: #endif }; -#endif // __KX_LIGHTIPOSGCONTROLLER_H__ - +#endif /* __KX_LIGHTIPOSGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.h b/source/gameengine/Ketsji/KX_MaterialIpoController.h index ee5546641c2..a7e9c2cc1c5 100644 --- a/source/gameengine/Ketsji/KX_MaterialIpoController.h +++ b/source/gameengine/Ketsji/KX_MaterialIpoController.h @@ -62,7 +62,4 @@ public: #endif }; - - - -#endif//__KX_MATERIALIPOCONTROLLER_H__ +#endif /* __KX_MATERIALIPOCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index a05ef6ab2e7..98e73aa626f 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -77,7 +77,6 @@ public: static PyObject *pyattr_get_numPolygons(void * self, const KX_PYATTRIBUTE_DEF * attrdef); }; -#endif // WITH_PYTHON - -#endif //__KX_MESHPROXY_H__ +#endif /* WITH_PYTHON */ +#endif /* __KX_MESHPROXY_H__ */ diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h index 3bead93cbda..116e62f408f 100644 --- a/source/gameengine/Ketsji/KX_MotionState.h +++ b/source/gameengine/Ketsji/KX_MotionState.h @@ -62,5 +62,4 @@ public: #endif }; -#endif //__KX_MOTIONSTATE_H__ - +#endif /* __KX_MOTIONSTATE_H__ */ diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 3251cc4af46..f7dbbe5a86b 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -30,11 +30,10 @@ * \ingroup ketsji */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning(disable:4786) #endif #include "MT_Point3.h" @@ -60,14 +59,14 @@ /* ------------------------------------------------------------------------- */ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, - int startx, - int starty, - short int mousemode, - int focusmode, - bool bTouchPulse, - KX_Scene* kxscene, - KX_KetsjiEngine *kxengine, - SCA_IObject* gameobj) + int startx, + int starty, + short int mousemode, + int focusmode, + bool bTouchPulse, + KX_Scene* kxscene, + KX_KetsjiEngine *kxengine, + SCA_IObject* gameobj) : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj), m_focusmode(focusmode), m_bTouchPulse(bTouchPulse), diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index db9e3697492..a8376dcb4fb 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -111,7 +111,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor static PyObject* pyattr_get_hit_normal(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_hit_uv(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ /* --------------------------------------------------------------------- */ SCA_IObject* m_hitObject; @@ -183,5 +183,4 @@ class KX_MouseFocusSensor : public SCA_MouseSensor KX_KetsjiEngine* m_kxengine; }; -#endif //__KX_MOUSESENSOR - +#endif /* __KX_MOUSESENSOR */ diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.h b/source/gameengine/Ketsji/KX_NavMeshObject.h index db35a011c16..1599361b334 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.h +++ b/source/gameengine/Ketsji/KX_NavMeshObject.h @@ -74,8 +74,7 @@ public: KX_PYMETHOD_DOC(KX_NavMeshObject, raycast); KX_PYMETHOD_DOC(KX_NavMeshObject, draw); KX_PYMETHOD_DOC_NOARGS(KX_NavMeshObject, rebuild); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_NAVMESHOBJECT_H__ - +#endif /* __KX_NAVMESHOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 82f523283ed..ef6e15f602f 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -100,9 +100,8 @@ public: return 0; } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_NEARSENSOR_H__ - +#endif /* __KX_NEARSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h index 9a9b3dac098..a7b0b2c4ffc 100644 --- a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h +++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h @@ -77,5 +77,4 @@ public: #endif }; -#endif // __KX_OBCOLORIPOSGCONTROLLER_H__ - +#endif /* __KX_OBCOLORIPOSGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index 397234488b7..b0efee550af 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -218,9 +218,8 @@ public: return 0; } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_OBJECTACTUATOR_H__ - +#endif /* __KX_OBJECTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index f2f5acd3dfb..40baac6b2b2 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -84,9 +84,8 @@ public: static PyObject *pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_ParentActuator : public SCA_PropertyActuator */ -#endif - +#endif /* __KX_PARENTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h index 5cebedf8c30..ca99c2e7526 100644 --- a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h +++ b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h @@ -39,5 +39,4 @@ enum e_PhysicsEngine UseBullet = 5, }; -#endif //__KX_PHYSICSENGINEENUMS_H__ - +#endif /* __KX_PHYSICSENGINEENUMS_H__ */ diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h index a074ff9a3bd..171416c5e8f 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -49,12 +49,11 @@ public: KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetAngularVelocity); KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetActive); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: class PHY_IPhysicsController* m_ctrl; PHY_IPhysicsEnvironment* m_physenv; }; -#endif //__KX_PHYSICSOBJECTWRAPPER_H__ - +#endif /* __KX_PHYSICSOBJECTWRAPPER_H__ */ diff --git a/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h index 86ba2500763..ee685edb9c1 100644 --- a/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h +++ b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h @@ -58,5 +58,4 @@ struct KX_MaterialProps { bool m_fh_normal; // Should the object slide off slopes? }; -#endif //__KX_PHYSICSPROPERTIESOBSOLETE_H__ - +#endif /* __KX_PHYSICSPROPERTIESOBSOLETE_H__ */ diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index 9e3556a03f8..f02aa90998e 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -80,7 +80,6 @@ public: }; -#endif // WITH_PYTHON - -#endif //__KX_POLYPROXY +#endif /* WITH_PYTHON */ +#endif /* __KX_POLYPROXY */ diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 6384008fb7d..89bfb4ff9fb 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -153,5 +153,4 @@ public: }; -#endif // __KX_POLYGONMATERIAL_H__ - +#endif /* __KX_POLYGONMATERIAL_H__ */ diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h index 69a6e333cee..b4a520ce71b 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.h +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h @@ -39,7 +39,6 @@ PyObject* initPythonConstraintBinding(); void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env); PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment(); -#endif // WITH_PYTHON - -#endif //__KX_PYCONSTRAINTBINDING_H__ +#endif /* WITH_PYTHON */ +#endif /* __KX_PYCONSTRAINTBINDING_H__ */ diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index bc324c3b140..85303b143bd 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -31,9 +31,9 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #ifdef WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index d79397ed807..159506946e8 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -273,4 +273,4 @@ PyObject *PyObjectFrom(const MT_Tuple4 &pos); #endif -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 43fca40f2da..89799d065a4 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -30,54 +30,48 @@ * \ingroup ketsji */ - #include "GL/glew.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 - -#ifdef WITH_PYTHON - -#ifdef _POSIX_C_SOURCE -#undef _POSIX_C_SOURCE -#endif - -#ifdef _XOPEN_SOURCE -#undef _XOPEN_SOURCE +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif -#if defined(__sun) || defined(sun) -#if defined(_XPG4) -#undef _XPG4 -#endif -#endif - -#include <Python.h> +#ifdef WITH_PYTHON +# ifdef _POSIX_C_SOURCE +# undef _POSIX_C_SOURCE +# endif +# ifdef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +# endif +# if defined(__sun) || defined(sun) +# if defined(_XPG4) +# undef _XPG4 +# endif +# endif +# include <Python.h> extern "C" { - #include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ - #include "py_capi_utils.h" - #include "mathutils.h" // 'mathutils' module copied here so the blenderlayer can use. - #include "bgl.h" - #include "blf_py_api.h" + # include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ + # include "py_capi_utils.h" + # include "mathutils.h" // 'mathutils' module copied here so the blenderlayer can use. + # include "bgl.h" + # include "blf_py_api.h" - #include "marshal.h" /* python header for loading/saving dicts */ + # include "marshal.h" /* python header for loading/saving dicts */ } - #include "AUD_PyInit.h" -#endif +#endif /* WITH_PYTHON */ #include "KX_PythonInit.h" // directory header for py function getBlendFileList #ifndef WIN32 - #include <dirent.h> - #include <stdlib.h> +# include <dirent.h> +# include <stdlib.h> #else - #include <io.h> - #include "BLI_winstuff.h" +# include <io.h> +# include "BLI_winstuff.h" #endif //python physics binding diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 69517b2b1e9..859c31adcd3 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -89,5 +89,4 @@ void KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar rad const MT_Vector3& normal, int nsector); -#endif //__KX_PYTHONINIT_H__ - +#endif /* __KX_PYTHONINIT_H__ */ diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h index 47a01737cdb..568d59119c0 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.h +++ b/source/gameengine/Ketsji/KX_PythonSeq.h @@ -30,8 +30,8 @@ * \brief Readonly sequence wrapper for lookups on logic bricks */ -#ifndef _adr_py_seq_h_ // only process once, -#define _adr_py_seq_h_ // even if multiply included +#ifndef __KX_PYTHONSEQ_H__ +#define __KX_PYTHONSEQ_H__ #ifdef WITH_PYTHON @@ -63,6 +63,6 @@ typedef struct { PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ -#endif // _adr_py_seq_h_ +#endif /* __KX_PYTHONSEQ_H__ */ diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 2de58f8b3a0..6a2d50ffa3a 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -97,5 +97,4 @@ public: #endif }; -#endif //__KX_RADARSENSOR_H__ - +#endif /* __KX_RADARSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h index f795495d1c9..07506b9e32b 100644 --- a/source/gameengine/Ketsji/KX_RayEventManager.h +++ b/source/gameengine/Ketsji/KX_RayEventManager.h @@ -50,5 +50,4 @@ public: #endif }; -#endif //__KX_RAYEVENTMANAGER_H__ - +#endif /* __KX_RAYEVENTMANAGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 27aaa442dcd..9d40fb55747 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -96,9 +96,8 @@ public: /* Attributes */ static PyObject *pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_RAYSENSOR_H__ - +#endif /* __KX_RAYSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 9c8cbfa3d09..7dac93acd21 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -126,9 +126,8 @@ public: static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject *pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */ -#endif - +#endif /* __KX_SCA_ADDOBJECTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 52a20142442..4370b5d4a4f 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -89,9 +89,8 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,instantReplaceMesh); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif - +#endif /* __KX_SCA_REPLACEMESHACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 652ed2ab2dd..a6b7ed3f732 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -31,9 +31,9 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "KX_Scene.h" #include "KX_PythonInit.h" @@ -769,6 +769,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) // we can now add the graphic controller to the physic engine replica->ActivateGraphicController(true); + // set references for dupli-group + // groupobj holds a list of all objects, that belongs to this group + groupobj->AddInstanceObjects(replica); + + // every object gets the reference to its dupli-group object + replica->SetDupliGroupObject(groupobj); + // done with replica replica->Release(); } @@ -1017,6 +1024,20 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) m_timemgr->RemoveTimeProperty(propval); } } + + // if the object is the dupligroup proxy, you have to cleanup all m_pDupliGroupObject's in all + // instances refering to this group + if(newobj->GetInstanceObjects()) { + for (int i = 0; i < newobj->GetInstanceObjects()->GetCount(); i++) { + KX_GameObject* instance = (KX_GameObject*)newobj->GetInstanceObjects()->GetValue(i); + instance->RemoveDupliGroupObject(); + } + } + + // if this object was part of a group, make sure to remove it from that group's instance list + KX_GameObject* group = newobj->GetDupliGroupObject(); + if (group) + group->RemoveInstanceObject(newobj); newobj->RemoveMeshes(); ret = 1; @@ -1233,9 +1254,9 @@ KX_FontObject* KX_Scene::FindFont(KX_FontObject* font) { list<KX_FontObject*>::iterator it = m_fonts.begin(); - while ( (it != m_fonts.end()) - && ((*it) != font) ) { - ++it; + while ((it != m_fonts.end()) && ((*it) != font)) + { + ++it; } return ((it == m_fonts.end()) ? NULL : (*it)); @@ -1247,9 +1268,7 @@ KX_Camera* KX_Scene::FindCamera(KX_Camera* cam) { list<KX_Camera*>::iterator it = m_cameras.begin(); - while ( (it != m_cameras.end()) - && ((*it) != cam) ) - { + while ((it != m_cameras.end()) && ((*it) != cam)) { it++; } @@ -1261,9 +1280,7 @@ KX_Camera* KX_Scene::FindCamera(STR_String& name) { list<KX_Camera*>::iterator it = m_cameras.begin(); - while ( (it != m_cameras.end()) - && ((*it)->GetName() != name) ) - { + while ((it != m_cameras.end()) && ((*it)->GetName() != name)) { it++; } @@ -1481,7 +1498,15 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int planes[4].setValue(cplanes[2].getValue()); // top planes[5].setValue(cplanes[3].getValue()); // bottom CullingInfo info(layer); - dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res); + + double mvmat[16] = {0}; + cam->GetModelviewMatrix().getValue(mvmat); + double pmat[16] = {0}; + cam->GetProjectionMatrix().getValue(pmat); + + dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res, + KX_GetActiveEngine()->GetCanvas()->GetViewPort(), + mvmat, pmat); } if (!dbvt_culling) { // the physics engine couldn't help us, do it the hard way @@ -1610,8 +1635,8 @@ RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, - class RAS_IRasterizer* rasty, - class RAS_IRenderTools* rendertools) + class RAS_IRasterizer* rasty, + class RAS_IRenderTools* rendertools) { m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools); KX_BlenderMaterial::EndFrame(); diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index bb329da99de..c2e468e6da6 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -665,5 +665,4 @@ public: typedef std::vector<KX_Scene*> KX_SceneList; -#endif //__KX_SCENE_H__ - +#endif /* __KX_SCENE_H__ */ diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 0b633334cce..389e9208ef3 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -102,9 +102,8 @@ class KX_SceneActuator : public SCA_IActuator static PyObject *pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KXSceneActuator */ #endif - diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index fcaf214dd90..1ce44e942e8 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -122,9 +122,8 @@ public: static PyObject *pyattr_get_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_sound(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_SOUNDACTUATOR_H__ - +#endif /* __KX_SOUNDACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h index 341421d8948..1e8ac9a54f0 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.h +++ b/source/gameengine/Ketsji/KX_SteeringActuator.h @@ -114,9 +114,8 @@ public: static PyObject *pyattr_get_steeringVec(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_SteeringActuator : public SCA_PropertyActuator */ -#endif - +#endif /* __KX_STEERINGACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h index ea780739695..e097454fca7 100644 --- a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h +++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h @@ -32,8 +32,8 @@ #ifndef __KX_TIMECATEGORYLOGGER_H__ #define __KX_TIMECATEGORYLOGGER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* suppress stl-MSVC debug info warning */ #endif #include <map> @@ -133,5 +133,4 @@ protected: #endif }; -#endif // __KX_TIMECATEGORYLOGGER_H__ - +#endif /* __KX_TIMECATEGORYLOGGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_TimeLogger.h b/source/gameengine/Ketsji/KX_TimeLogger.h index 83c934ea81b..59d7bdc84e3 100644 --- a/source/gameengine/Ketsji/KX_TimeLogger.h +++ b/source/gameengine/Ketsji/KX_TimeLogger.h @@ -32,14 +32,14 @@ #ifndef __KX_TIMELOGGER_H__ #define __KX_TIMELOGGER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* suppress stl-MSVC debug info warning */ #endif #include <deque> #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif /** @@ -111,5 +111,4 @@ protected: #endif }; -#endif // __KX_TIMELOGGER_H__ - +#endif /* __KX_TIMELOGGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h index d9a0164fd05..63e9d15959e 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.h +++ b/source/gameengine/Ketsji/KX_TouchEventManager.h @@ -85,5 +85,4 @@ public: #endif }; -#endif //__KX_TOUCHEVENTMANAGER_H__ - +#endif /* __KX_TOUCHEVENTMANAGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index c80b8598e43..6bd606db8eb 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -134,5 +134,4 @@ public: }; -#endif //__KX_TOUCHSENSOR_H__ - +#endif /* __KX_TOUCHSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 6329c7b34d9..f5f5c4c2836 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -77,9 +77,8 @@ class KX_TrackToActuator : public SCA_IActuator static PyObject *pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_TrackToActuator : public KX_EditObjectActuator */ -#endif - +#endif /* __KX_TRACKTOACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index 3684019277c..ccd666e84f3 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -52,11 +52,11 @@ public: KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSuspensionCompression); KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetRollInfluence); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: PHY_IVehicle* m_vehicle; PHY_IPhysicsEnvironment* m_physenv; }; -#endif //__KX_VEHICLEWRAPPER_H__ +#endif /* __KX_VEHICLEWRAPPER_H__ */ diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index f56e2be26a3..6e193d35b4c 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -105,7 +105,6 @@ public: }; -#endif // WITH_PYTHON - -#endif //__KX_VERTEXPROXY_H__ +#endif /* WITH_PYTHON */ +#endif /* __KX_VERTEXPROXY_H__ */ diff --git a/source/gameengine/Ketsji/KX_WorldInfo.h b/source/gameengine/Ketsji/KX_WorldInfo.h index 5b35ca2ec54..a64ca5c191e 100644 --- a/source/gameengine/Ketsji/KX_WorldInfo.h +++ b/source/gameengine/Ketsji/KX_WorldInfo.h @@ -74,5 +74,4 @@ public: #endif }; -#endif //__KX_WORLDINFO_H__ - +#endif /* __KX_WORLDINFO_H__ */ diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.h b/source/gameengine/Ketsji/KX_WorldIpoController.h index 575d4e72f14..63983b3129b 100644 --- a/source/gameengine/Ketsji/KX_WorldIpoController.h +++ b/source/gameengine/Ketsji/KX_WorldIpoController.h @@ -100,5 +100,4 @@ public: #endif }; -#endif // __KX_WORLDIPOCONTROLLER_H__ - +#endif /* __KX_WORLDIPOCONTROLLER_H__ */ diff --git a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h index f9d2146a766..7581486c80a 100644 --- a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h +++ b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h @@ -60,5 +60,4 @@ public: virtual std::vector<NG_NetworkMessage*> RetrieveNetworkMessages(); }; -#endif //__NG_LOOPBACKNETWORKDEVICEINTERFACE_H__ - +#endif /* __NG_LOOPBACKNETWORKDEVICEINTERFACE_H__ */ diff --git a/source/gameengine/Network/NG_NetworkDeviceInterface.h b/source/gameengine/Network/NG_NetworkDeviceInterface.h index 8f903cc64fa..48edbdfc7fe 100644 --- a/source/gameengine/Network/NG_NetworkDeviceInterface.h +++ b/source/gameengine/Network/NG_NetworkDeviceInterface.h @@ -79,5 +79,4 @@ public: #endif }; -#endif //__NG_NETWORKDEVICEINTERFACE_H__ - +#endif /* __NG_NETWORKDEVICEINTERFACE_H__ */ diff --git a/source/gameengine/Network/NG_NetworkMessage.h b/source/gameengine/Network/NG_NetworkMessage.h index 25e7fd97596..5185849f8d7 100644 --- a/source/gameengine/Network/NG_NetworkMessage.h +++ b/source/gameengine/Network/NG_NetworkMessage.h @@ -135,5 +135,4 @@ public: #endif }; -#endif //__NG_NETWORKMESSAGE_H__ - +#endif /* __NG_NETWORKMESSAGE_H__ */ diff --git a/source/gameengine/Network/NG_NetworkObject.h b/source/gameengine/Network/NG_NetworkObject.h index b9858cd8d43..54459cad55d 100644 --- a/source/gameengine/Network/NG_NetworkObject.h +++ b/source/gameengine/Network/NG_NetworkObject.h @@ -52,5 +52,4 @@ public: #endif }; -#endif //__NG_NETWORKOBJECT_H__ - +#endif /* __NG_NETWORKOBJECT_H__ */ diff --git a/source/gameengine/Network/NG_NetworkScene.h b/source/gameengine/Network/NG_NetworkScene.h index 381b71da0d7..10dad210128 100644 --- a/source/gameengine/Network/NG_NetworkScene.h +++ b/source/gameengine/Network/NG_NetworkScene.h @@ -115,5 +115,4 @@ protected: #endif }; -#endif //__NG_NETWORKSCENE_H__ - +#endif /* __NG_NETWORKSCENE_H__ */ diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt index cdae3cc5526..43b1bfe7468 100644 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ b/source/gameengine/Physics/Bullet/CMakeLists.txt @@ -37,7 +37,6 @@ set(INC ../../../blender/blenkernel ../../../blender/blenlib ../../../blender/makesdna - ../../../../extern/bullet2/src ../../../../intern/container ../../../../intern/guardedalloc ../../../../intern/moto/include @@ -45,6 +44,7 @@ set(INC ) set(INC_SYS + ../../../../extern/bullet2/src ${GLEW_INCLUDE_PATH} ${PYTHON_INCLUDE_DIRS} ) diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h index 15edfeb5759..72eb699ce5b 100644 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.h +++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h @@ -87,4 +87,4 @@ private: #endif }; -#endif //BULLET2_PHYSICSCONTROLLER_H +#endif /* BULLET2_PHYSICSCONTROLLER_H */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 81bf66d9536..29a9b6481e9 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -215,8 +215,7 @@ bool CcdPhysicsController::CreateSoftbody() btSoftBody* psb = 0; btSoftBodyWorldInfo& worldInfo = m_cci.m_physicsEnv->getDynamicsWorld()->getWorldInfo(); - if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE) - { + if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE) { btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape; { int nvertices = convexHull->getNumPoints(); @@ -224,26 +223,25 @@ bool CcdPhysicsController::CreateSoftbody() HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); HullResult hres; - HullLibrary hlib;/*??*/ + HullLibrary hlib; /*??*/ hdsc.mMaxVertices=nvertices; hlib.CreateConvexHull(hdsc,hres); - psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices, - &hres.m_OutputVertices[0],0); - for (int i=0;i<(int)hres.mNumFaces;++i) - { - const int idx[]={ hres.m_Indices[i*3+0], - hres.m_Indices[i*3+1], - hres.m_Indices[i*3+2]}; - if (idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]); - if (idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]); - if (idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]); - psb->appendFace(idx[0],idx[1],idx[2]); + psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices, + &hres.m_OutputVertices[0], 0); + for (int i = 0; i < (int)hres.mNumFaces; ++i) { + const int idx[3] = {hres.m_Indices[i * 3 + 0], + hres.m_Indices[i * 3 + 1], + hres.m_Indices[i * 3 + 2]}; + if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]); + if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]); + if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]); + psb->appendFace(idx[0], idx[1], idx[2]); } hlib.ReleaseResult(hres); } - } else - { + } + else { int numtris = 0; if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { @@ -895,18 +893,22 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc return; } - // btRigidBody* body = GetRigidBody(); // not used anymore - btVector3 dloc(dlocX,dlocY,dlocZ); btTransform xform = m_object->getWorldTransform(); if (local) - { dloc = xform.getBasis()*dloc; + + if (m_characterController) + { + m_characterController->setWalkDirection(dloc/GetPhysicsEnvironment()->getNumTimeSubSteps()); } + else + { - xform.setOrigin(xform.getOrigin() + dloc); - SetCenterOfMassTransform(xform); + xform.setOrigin(xform.getOrigin() + dloc); + SetCenterOfMassTransform(xform); + } } } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 2204f224e7d..6df5c85f5c0 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -665,4 +665,4 @@ class DefaultMotionState : public PHY_IMotionState }; -#endif //__CCDPHYSICSCONTROLLER_H__ +#endif /* __CCDPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 55bbc0d33b9..82a60e756d7 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -57,7 +57,6 @@ btRaycastVehicle::btVehicleTuning gTuning; #include "LinearMath/btAabbUtil2.h" #include "MT_Matrix4x4.h" #include "MT_Vector3.h" -#include "GL/glew.h" #ifdef WIN32 void DrawRasterizerLine(const float* from,const float* to,int color); @@ -1309,22 +1308,19 @@ struct OcclusionBuffer m[14] = btScalar(m1[ 2]*m2[12]+m1[ 6]*m2[13]+m1[10]*m2[14]+m1[14]*m2[15]); m[15] = btScalar(m1[ 3]*m2[12]+m1[ 7]*m2[13]+m1[11]*m2[14]+m1[15]*m2[15]); } - void setup(int size) + void setup(int size, const int *view, double modelview[16], double projection[16]) { m_initialized=false; m_occlusion=false; // compute the size of the buffer - GLint v[4]; - GLdouble m[16],p[16]; int maxsize; double ratio; - glGetIntegerv(GL_VIEWPORT,v); - maxsize = (v[2] > v[3]) ? v[2] : v[3]; + maxsize = (view[2] > view[3]) ? view[2] : view[3]; assert(maxsize > 0); ratio = 1.0/(2*maxsize); // ensure even number - m_sizes[0] = 2*((int)(size*v[2]*ratio+0.5)); - m_sizes[1] = 2*((int)(size*v[3]*ratio+0.5)); + m_sizes[0] = 2*((int)(size*view[2]*ratio+0.5)); + m_sizes[1] = 2*((int)(size*view[3]*ratio+0.5)); m_scales[0]=btScalar(m_sizes[0]/2); m_scales[1]=btScalar(m_sizes[1]/2); m_offsets[0]=m_scales[0]+0.5f; @@ -1332,10 +1328,8 @@ struct OcclusionBuffer // prepare matrix // at this time of the rendering, the modelview matrix is the // world to camera transformation and the projection matrix is - // camera to clip transformation. combine both so that - glGetDoublev(GL_MODELVIEW_MATRIX,m); - glGetDoublev(GL_PROJECTION_MATRIX,p); - CMmat4mul(m_wtc,p,m); + // camera to clip transformation. combine both so that + CMmat4mul(m_wtc, projection, modelview); } void initialize() { @@ -1795,7 +1789,7 @@ struct DbvtCullingCallback : btDbvt::ICollide }; static OcclusionBuffer gOcb; -bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes) +bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) { if (!m_cullingTree) return false; @@ -1812,7 +1806,7 @@ bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* user // if occlusionRes != 0 => occlusion culling if (occlusionRes) { - gOcb.setup(occlusionRes); + gOcb.setup(occlusionRes, viewport, modelview, projection); dispatcher.m_ocb = &gOcb; // occlusion culling, the direction of the view is taken from the first plan which MUST be the near plane btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index c499a1ef75c..350ecd2588a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -115,6 +115,11 @@ protected: virtual void setLinearAirDamping(float damping); virtual void setUseEpa(bool epa); + int getNumTimeSubSteps() + { + return m_numTimeSubSteps; + } + virtual void beginFrame(); virtual void endFrame() {} /// Perform an integration step of duration 'timeStep'. @@ -178,12 +183,12 @@ protected: { return 0; } -#endif //NEW_BULLET_VEHICLE_SUPPORT +#endif /* NEW_BULLET_VEHICLE_SUPPORT */ btTypedConstraint* getConstraintById(int constraintId); virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes); + virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]); //Methods for gamelogic collision/physics callbacks @@ -292,4 +297,4 @@ protected: #endif }; -#endif //__CCDPHYSICSENVIRONMENT_H__ +#endif /* __CCDPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 9c109168b18..70de9c25553 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -73,7 +73,7 @@ public: } virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes) { return false; } + virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) { return false; } //gamelogic callbacks @@ -102,5 +102,4 @@ public: #endif }; -#endif //__DUMMYPHYSICSENVIRONMENT_H__ - +#endif /* __DUMMYPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h index 6994706ce2d..0fe2533cf93 100644 --- a/source/gameengine/Physics/common/PHY_DynamicTypes.h +++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h @@ -151,4 +151,4 @@ typedef enum PHY_ShapeType { typedef float PHY_Vector3[3]; -#endif //__PHY_DYNAMICTYPES_H__ +#endif /* __PHY_DYNAMICTYPES_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IController.h b/source/gameengine/Physics/common/PHY_IController.h index 729abd8ec04..003c4edf598 100644 --- a/source/gameengine/Physics/common/PHY_IController.h +++ b/source/gameengine/Physics/common/PHY_IController.h @@ -60,5 +60,4 @@ class PHY_IController #endif }; -#endif //__PHY_ICONTROLLER_H__ - +#endif /* __PHY_ICONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h index af337188818..cb13eda4f18 100644 --- a/source/gameengine/Physics/common/PHY_IGraphicController.h +++ b/source/gameengine/Physics/common/PHY_IGraphicController.h @@ -58,5 +58,4 @@ class PHY_IGraphicController : public PHY_IController #endif }; -#endif //__PHY_IGRAPHICCONTROLLER_H__ - +#endif /* __PHY_IGRAPHICCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h index 72ff37468ee..ccf7cf74724 100644 --- a/source/gameengine/Physics/common/PHY_IMotionState.h +++ b/source/gameengine/Physics/common/PHY_IMotionState.h @@ -65,5 +65,4 @@ class PHY_IMotionState #endif }; -#endif //__PHY_IMOTIONSTATE_H__ - +#endif /* __PHY_IMOTIONSTATE_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h index 7eea2a183a1..bc7671abe80 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h @@ -108,5 +108,4 @@ class PHY_IPhysicsController : public PHY_IController #endif }; -#endif //__PHY_IPHYSICSCONTROLLER_H__ - +#endif /* __PHY_IPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 3f8699d25d2..66ca037aa47 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -161,7 +161,7 @@ class PHY_IPhysicsEnvironment //culling based on physical broad phase // the plane number must be set as follow: near, far, left, right, top, botton // the near plane must be the first one and must always be present, it is used to get the direction of the view - virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber, int occlusionRes) = 0; + virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) = 0; //Methods for gamelogic collision/physics callbacks //todo: @@ -185,5 +185,4 @@ class PHY_IPhysicsEnvironment #endif }; -#endif //__PHY_IPHYSICSENVIRONMENT_H__ - +#endif /* __PHY_IPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IVehicle.h b/source/gameengine/Physics/common/PHY_IVehicle.h index 731e22d9f0f..ecf7a87c40f 100644 --- a/source/gameengine/Physics/common/PHY_IVehicle.h +++ b/source/gameengine/Physics/common/PHY_IVehicle.h @@ -66,4 +66,4 @@ public: #endif }; -#endif //__PHY_IVEHICLE_H__ +#endif /* __PHY_IVEHICLE_H__ */ diff --git a/source/gameengine/Physics/common/PHY_Pro.h b/source/gameengine/Physics/common/PHY_Pro.h index b930177d3a8..7c5d9c9638e 100644 --- a/source/gameengine/Physics/common/PHY_Pro.h +++ b/source/gameengine/Physics/common/PHY_Pro.h @@ -62,5 +62,4 @@ struct PHY_MaterialProps { bool m_fh_normal; // Should the object slide off slopes? }; -#endif //__PHY_PRO_H__ - +#endif /* __PHY_PRO_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 7312b521788..0ae8908e946 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -398,8 +398,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) if (num_filters <= 0) return; - GLuint viewport[4]={0}; - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + const GLint *viewport = canvas->GetViewPort(); RAS_Rect rect = canvas->GetWindowArea(); int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1; diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index 457fd0ad90c..3c49d6e5289 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -29,10 +29,9 @@ * \ingroup bgerast */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show these anoying STL warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show these anoying STL warnings */ +# pragma warning (disable:4786) #endif #include "CTR_Map.h" diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index 2650bc9f722..c85a9f65d27 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -90,5 +90,4 @@ private: #endif }; -#endif //__RAS_BUCKETMANAGER_H__ - +#endif /* __RAS_BUCKETMANAGER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 4a70df6e505..7a6bb541a1a 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -71,5 +71,4 @@ struct RAS_CameraData } }; -#endif //__RAS_CAMERADATA_H__ - +#endif /* __RAS_CAMERADATA_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index d70e56dc285..058f2304f3d 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -32,9 +32,9 @@ #ifndef __RAS_DEFORMER_H__ #define __RAS_DEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include <stdlib.h> #include "CTR_Map.h" diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h index 713a06845ac..53195d79768 100644 --- a/source/gameengine/Rasterizer/RAS_ICanvas.h +++ b/source/gameengine/Rasterizer/RAS_ICanvas.h @@ -180,6 +180,13 @@ public: int x2, int y2 ) = 0; + /** + * Get the visible viewport + */ + virtual + const int* + GetViewPort() = 0; + virtual void SetMouseState( @@ -224,5 +231,4 @@ protected: #endif }; -#endif //__RAS_ICANVAS_H__ - +#endif /* __RAS_ICANVAS_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 4af1753c2da..ddadd97b567 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -254,12 +254,18 @@ bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const { bool dolights = false; - if (m_flag & RAS_BLENDERMAT) - dolights = (m_flag &RAS_MULTILIGHT)!=0; - else if (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID); - else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW); - else + if (m_flag & RAS_BLENDERMAT) { + dolights = (m_flag & RAS_MULTILIGHT) != 0; + } + else if (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) { + /* pass */ + } + else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW) { + /* pass */ + } + else { dolights = m_light; + } return dolights; } diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 169bc6e4ee6..9fffc8bebc9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -202,5 +202,4 @@ inline bool operator < ( const RAS_IPolyMaterial & lhs, const RAS_IPolyMaterial return lhs.Less(rhs); } -#endif //__RAS_IPOLYGONMATERIAL_H__ - +#endif /* __RAS_IPOLYGONMATERIAL_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 8efc10f2118..e6948025999 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -32,8 +32,8 @@ #ifndef __RAS_IRASTERIZER_H__ #define __RAS_IRASTERIZER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "STR_HashedString.h" @@ -423,6 +423,4 @@ public: #endif }; -#endif //__RAS_IRASTERIZER_H__ - - +#endif /* __RAS_IRASTERIZER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index ca6f20b71ad..bccda634222 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -208,7 +208,4 @@ public: #endif }; -#endif //__RAS_IRENDERTOOLS_H__ - - - +#endif /* __RAS_IRENDERTOOLS_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h index ddf360683cd..79818def5f0 100644 --- a/source/gameengine/Rasterizer/RAS_LightObject.h +++ b/source/gameengine/Rasterizer/RAS_LightObject.h @@ -64,5 +64,4 @@ struct RAS_LightObject bool m_nospecular; }; -#endif //__RAS_LIGHTOBJECT_H__ - +#endif /* __RAS_LIGHTOBJECT_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 183da9d252e..0cb6bc7439a 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -32,8 +32,8 @@ #include "RAS_MaterialBucket.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #ifdef WIN32 @@ -147,7 +147,7 @@ void RAS_MeshSlot::begin(RAS_MeshSlot::iterator& it) int startvertex, endvertex; int startindex, endindex; - it.array = (m_displayArrays.size() > 0)? m_displayArrays[m_startarray]: NULL; + it.array = m_displayArrays.empty() ? NULL : m_displayArrays[m_startarray]; if (it.array == NULL || it.array->m_index.size() == 0 || it.array->m_vertex.size() == 0) { it.array = NULL; @@ -368,7 +368,7 @@ bool RAS_MeshSlot::Join(RAS_MeshSlot *target, MT_Scalar distance) size_t i; // verify if we can join - if (m_joinSlot || m_joinedSlots.size() || target->m_joinSlot) + if (m_joinSlot || (m_joinedSlots.empty() == false) || target->m_joinSlot) return false; if (!Equals(target)) @@ -461,7 +461,7 @@ bool RAS_MeshSlot::Split(bool force) abort(); } - if (target->m_displayArrays.size()) { + if (target->m_displayArrays.empty() == false) { target->m_endvertex = target->m_displayArrays.back()->m_vertex.size(); target->m_endindex = target->m_displayArrays.back()->m_index.size(); } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 295f2510313..16ecffb9a32 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -254,4 +254,4 @@ private: #endif }; -#endif //__RAS_MATERIAL_BUCKET +#endif /* __RAS_MATERIAL_BUCKET */ diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index c50aa28e9fc..21d2e6d5a7b 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -584,7 +584,7 @@ void RAS_MeshObject::CheckWeightCache(Object* obj) if (!m_mesh->key) return; - for (kbindex=0, kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next, kbindex++) + for (kbindex = 0, kb = (KeyBlock *)m_mesh->key->block.first; kb; kb = kb->next, kbindex++) { // first check the cases where the weight must be cleared if (kb->vgroup[0] == 0 || diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index eb8655c8b1f..281eae8734a 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -32,9 +32,9 @@ #ifndef __RAS_MESHOBJECT_H__ #define __RAS_MESHOBJECT_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// disable the STL warnings ("debug information length > 255") -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* disable the STL warnings ("debug information length > 255") */ +# pragma warning (disable:4786) #endif #include <vector> @@ -177,5 +177,4 @@ public: #endif }; -#endif //__RAS_MESHOBJECT_H__ - +#endif /* __RAS_MESHOBJECT_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_ObjectColor.h b/source/gameengine/Rasterizer/RAS_ObjectColor.h index f8fbe69e97b..77feffccffc 100644 --- a/source/gameengine/Rasterizer/RAS_ObjectColor.h +++ b/source/gameengine/Rasterizer/RAS_ObjectColor.h @@ -38,5 +38,4 @@ struct RAS_ObjectColor { float m_blue; }; -#endif //__RAS_OBJECTCOLOR_H__ - +#endif /* __RAS_OBJECTCOLOR_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 67423123a7a..a0da1c79baa 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -359,7 +359,7 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void) void RAS_OpenGLRasterizer::FlushDebugShapes() { - if (!m_debugShapes.size()) + if (m_debugShapes.empty()) return; // DrawDebugLines diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 8b54f507ee0..88bb0be531b 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -32,8 +32,8 @@ #ifndef __RAS_OPENGLRASTERIZER_H__ #define __RAS_OPENGLRASTERIZER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "MT_CmMatrix4x4.h" @@ -322,6 +322,4 @@ public: #endif }; -#endif //__RAS_OPENGLRASTERIZER_H__ - - +#endif /* __RAS_OPENGLRASTERIZER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h index e881192171f..6b159db05ed 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -67,5 +67,4 @@ private: #endif }; -#endif //__RAS_VAOPENGLRASTERIZER_H__ - +#endif /* __RAS_VAOPENGLRASTERIZER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp index a6912c0997d..f454d1c0204 100644 --- a/source/gameengine/Rasterizer/RAS_Polygon.cpp +++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp @@ -29,9 +29,8 @@ * \ingroup bgerast */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "RAS_Polygon.h" diff --git a/source/gameengine/Rasterizer/RAS_Rect.h b/source/gameengine/Rasterizer/RAS_Rect.h index cb5f7d47457..fc99c9159db 100644 --- a/source/gameengine/Rasterizer/RAS_Rect.h +++ b/source/gameengine/Rasterizer/RAS_Rect.h @@ -101,5 +101,4 @@ public: #endif }; -#endif // __RAS_RECT_H__ - +#endif /* __RAS_RECT_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_TexMatrix.h b/source/gameengine/Rasterizer/RAS_TexMatrix.h index 44ae1b0eb5d..a2dd291d016 100644 --- a/source/gameengine/Rasterizer/RAS_TexMatrix.h +++ b/source/gameengine/Rasterizer/RAS_TexMatrix.h @@ -39,5 +39,4 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Vector3& vdir); -#endif //__RAS_TEXMATRIX_H__ - +#endif /* __RAS_TEXMATRIX_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 15059a9cf12..889769da5ed 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -148,5 +148,4 @@ public: #endif }; -#endif //__RAS_TEXVERT_H__ - +#endif /* __RAS_TEXVERT_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h index 455aaf90d6d..a173633e13c 100644 --- a/source/gameengine/SceneGraph/SG_Controller.h +++ b/source/gameengine/SceneGraph/SG_Controller.h @@ -121,5 +121,4 @@ protected: #endif }; -#endif //__SG_CONTROLLER_H__ - +#endif /* __SG_CONTROLLER_H__ */ diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h index be1c1fda2f2..90153f14c07 100644 --- a/source/gameengine/SceneGraph/SG_DList.h +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -248,5 +248,4 @@ public: }; -#endif //__SG_DLIST_H__ - +#endif /* __SG_DLIST_H__ */ diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index 53b51507e97..885eb8e1e90 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -371,5 +371,4 @@ protected : #endif }; -#endif //__SG_IOBJECT_H__ - +#endif /* __SG_IOBJECT_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index 063eeaab01d..bde64f21305 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -275,5 +275,4 @@ private: #endif }; -#endif //__SG_NODE_H__ - +#endif /* __SG_NODE_H__ */ diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h index bcc56f05615..663f29ebd88 100644 --- a/source/gameengine/SceneGraph/SG_QList.h +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -161,5 +161,4 @@ public: #endif }; -#endif //__SG_QLIST_H__ - +#endif /* __SG_QLIST_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index 7630af51781..aa917fa70db 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -291,5 +291,4 @@ protected: #endif }; -#endif //__SG_SPATIAL_H__ - +#endif /* __SG_SPATIAL_H__ */ diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index cd0edfc09ef..d5b575851ee 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -209,6 +209,6 @@ inline VideoFFmpeg *getFFmpeg(PyImage *self) return static_cast<VideoFFmpeg*>(self->m_image); } -#endif //WITH_FFMPEG +#endif /* WITH_FFMPEG */ -#endif +#endif /* __VIDEOFFMPEG_H__ */ diff --git a/source/tests/batch_import.py b/source/tests/batch_import.py index 5c228c014ca..177ab8ea0b0 100644 --- a/source/tests/batch_import.py +++ b/source/tests/batch_import.py @@ -63,12 +63,12 @@ def clear_scene(): def batch_import(operator="", - path="", - save_path="", - match="", - start=0, - end=sys.maxsize, - ): + path="", + save_path="", + match="", + start=0, + end=sys.maxsize, + ): import addon_utils _reset_all = addon_utils.reset_all # XXX, hack diff --git a/source/tests/bl_load_addons.py b/source/tests/bl_load_addons.py index 21a0101d684..5d9ac750362 100644 --- a/source/tests/bl_load_addons.py +++ b/source/tests/bl_load_addons.py @@ -36,7 +36,7 @@ def reload_addons(do_reload=True, do_reverse=True): for mod_name in list(addons.keys()): addon_utils.disable(mod_name) - assert(bool(addons) == False) + assert(bool(addons) is False) # Run twice each time. for i in (0, 1): diff --git a/source/tests/bl_load_py_modules.py b/source/tests/bl_load_py_modules.py index 619cad67cb8..b634b4c4385 100644 --- a/source/tests/bl_load_py_modules.py +++ b/source/tests/bl_load_py_modules.py @@ -49,7 +49,7 @@ def load_addons(): for mod_name in list(addons.keys()): addon_utils.disable(mod_name) - assert(bool(addons) == False) + assert(bool(addons) is False) for mod in modules: mod_name = mod.__name__ diff --git a/source/tests/bl_mesh_modifiers.py b/source/tests/bl_mesh_modifiers.py index 390679800f6..92fae25df16 100644 --- a/source/tests/bl_mesh_modifiers.py +++ b/source/tests/bl_mesh_modifiers.py @@ -846,7 +846,7 @@ if __name__ == "__main__": @persistent def load_handler(dummy): print("Load Handler:", bpy.data.filepath) - if load_handler.first == False: + if load_handler.first is False: bpy.app.handlers.scene_update_post.remove(load_handler) try: main() |