diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-10-07 03:32:21 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-10-07 03:32:21 +0400 |
commit | 1fe70c07a008185c4e5925aff2c214c93ff396b7 (patch) | |
tree | 5dd9fc4a6be56243977b2670c8acfe4eb5543d96 | |
parent | cdc1e5a716c08e809b771388c6b5075d32a20c98 (diff) | |
parent | e7db06ad9db5a1a05b00fc835038d4366d637851 (diff) |
Merged changes in the trunk up to revision 51126.
Conflicts resolved:
source/blender/blenloader/intern/readfile.c
source/blender/windowmanager/WM_types.h
281 files changed, 6623 insertions, 4248 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 51d900ae35d..1f0ef41fe59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,6 +254,9 @@ set(CYCLES_CUDA_BINARIES_ARCH sm_13 sm_20 sm_21 sm_30 CACHE STRING "CUDA archite mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH) unset(PLATFORM_DEFAULT) +# LLVM +option(WITH_LLVM "Use LLVM" OFF) + # disable for now, but plan to support on all platforms eventually option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" OFF) mark_as_advanced(WITH_MEM_JEMALLOC) @@ -316,6 +319,9 @@ if(APPLE) option(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON) option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF) option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF) + if(CMAKE_OSX_ARCHITECTURES MATCHES x86_64) + set(USE_QTKIT ON CACHE BOOL "ON" FORCE) # no Quicktime in 64bit + endif() endif() @@ -371,6 +377,11 @@ if(WITH_CYCLES OR WITH_MOD_BOOLEAN) set(WITH_BOOST ON) endif() +# auto enable llvm for cycles_osl +if(WITH_CYCLES_OSL) + set(WITH_LLVM ON CACHE BOOL "ON" FORCE) +endif() + # don't store paths to libs for portable distribution if(WITH_INSTALL_PORTABLE) set(CMAKE_SKIP_BUILD_RPATH TRUE) @@ -569,7 +580,7 @@ if(UNIX AND NOT APPLE) # lame, but until we have proper find module for ffmpeg set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include) if(EXISTS "${FFMPEG}/include/ffmpeg/") - set(FFMPEG_INCLUDE_DIRS "${FFMPEG_INCLUDE_DIRS} ${FFMPEG}/include/ffmpeg") + list(APPEND FFMPEG_INCLUDE_DIRS "${FFMPEG}/include/ffmpeg") endif() # end lameness @@ -704,6 +715,56 @@ if(UNIX AND NOT APPLE) endif() endif() + if(WITH_LLVM) + set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation") + set(LLVM_VERSION "3.0" CACHE STRING "Version of LLVM to use" "") + set(LLVM_STATIC YES) + if(LLVM_DIRECTORY) + set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config") + else() + set(LLVM_CONFIG llvm-config) + endif() + execute_process(COMMAND ${LLVM_CONFIG} --version + OUTPUT_VARIABLE LLVM_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${LLVM_CONFIG} --prefix + OUTPUT_VARIABLE LLVM_DIRECTORY + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${LLVM_CONFIG} --libdir + OUTPUT_VARIABLE LLVM_LIB_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${LLVM_CONFIG} --includedir + OUTPUT_VARIABLE LLVM_INCLUDES + OUTPUT_STRIP_TRAILING_WHITESPACE) + find_library(LLVM_LIBRARY + NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get + PATHS ${LLVM_LIB_DIR}) + message(STATUS "LLVM version = ${LLVM_VERSION}") + message(STATUS "LLVM dir = ${LLVM_DIRECTORY}") + message(STATUS "LLVM includes = ${LLVM_INCLUDES}") + message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") + + if(LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR) + # ensure include directory is added (in case of non-standard locations + include_directories(BEFORE "${LLVM_INCLUDES}") + string(REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION}) + message(STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}") + add_definitions("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}") + if(LLVM_STATIC) + # if static LLVM libraries were requested, use llvm-config to generate + # the list of what libraries we need, and substitute that in the right + # way for LLVM_LIBRARY. + execute_process(COMMAND ${LLVM_CONFIG} --libfiles + OUTPUT_VARIABLE LLVM_LIBRARY + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY}) + endif() + message(STATUS "LLVM library = ${LLVM_LIBRARY}") + else() + message(FATAL_ERROR "LLVM not found.") + endif() + endif() + if(WITH_CYCLES_OSL) set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation") @@ -712,8 +773,9 @@ if(UNIX AND NOT APPLE) find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib) - # WARNING! depends on correct order of OSL libs linking - list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} ${OSL_LIB_EXEC} ${OSL_LIB_QUERY}) + # Note: --whole-archive is needed to force loading of all symbols in liboslexec, + # otherwise LLVM is missing the osl_allocate_closure_component function + list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -Wl,--whole-archive ${OSL_LIB_EXEC} -Wl,--no-whole-archive ${OSL_LIB_QUERY}) find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include) find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin) @@ -1559,6 +1621,56 @@ elseif(APPLE) set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD") endif() + if(WITH_LLVM) + set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation") + set(LLVM_VERSION "3.1" CACHE STRING "Version of LLVM to use" "") + set(LLVM_STATIC YES) + if(LLVM_DIRECTORY) + set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config") + else() + set(LLVM_CONFIG llvm-config) + endif() + execute_process(COMMAND ${LLVM_CONFIG} --version + OUTPUT_VARIABLE LLVM_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${LLVM_CONFIG} --prefix + OUTPUT_VARIABLE LLVM_DIRECTORY + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${LLVM_CONFIG} --libdir + OUTPUT_VARIABLE LLVM_LIB_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${LLVM_CONFIG} --includedir + OUTPUT_VARIABLE LLVM_INCLUDES + OUTPUT_STRIP_TRAILING_WHITESPACE) + find_library(LLVM_LIBRARY + NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get + PATHS ${LLVM_LIB_DIR}) + message(STATUS "LLVM version = ${LLVM_VERSION}") + message(STATUS "LLVM dir = ${LLVM_DIRECTORY}") + message(STATUS "LLVM includes = ${LLVM_INCLUDES}") + message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") + + if(LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR) + # ensure include directory is added (in case of non-standard locations + include_directories(BEFORE "${LLVM_INCLUDES}") + string(REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION}) + message(STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}") + add_definitions("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}") + if(LLVM_STATIC) + # if static LLVM libraries were requested, use llvm-config to generate + # the list of what libraries we need, and substitute that in the right + # way for LLVM_LIBRARY. + execute_process(COMMAND ${LLVM_CONFIG} --libfiles + OUTPUT_VARIABLE LLVM_LIBRARY + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY}) + endif() + message(STATUS "LLVM library = ${LLVM_LIBRARY}") + else() + message(FATAL_ERROR "LLVM not found.") + endif() + endif() + if(WITH_CYCLES_OSL) set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation") @@ -1582,78 +1694,19 @@ elseif(APPLE) endif() include_directories(${OSL_INCLUDES}) - - - # LLVM library setup, needed for osl - - set(LLVM_DIRECTORY "${LIBDIR}/llvm") - set(LLVM_STATIC YES) - if (LLVM_DIRECTORY) - set (LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config") - else () - set (LLVM_CONFIG llvm-config) - endif () - execute_process (COMMAND ${LLVM_CONFIG} --version - OUTPUT_VARIABLE LLVM_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND ${LLVM_CONFIG} --prefix - OUTPUT_VARIABLE LLVM_DIRECTORY - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND ${LLVM_CONFIG} --libdir - OUTPUT_VARIABLE LLVM_LIB_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND ${LLVM_CONFIG} --includedir - OUTPUT_VARIABLE LLVM_INCLUDES - OUTPUT_STRIP_TRAILING_WHITESPACE) - find_library ( LLVM_LIBRARY - NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get - PATHS ${LLVM_LIB_DIR}) - message (STATUS "LLVM version = ${LLVM_VERSION}") - message (STATUS "LLVM dir = ${LLVM_DIRECTORY}") - message (STATUS "LLVM includes = ${LLVM_INCLUDES}") - message (STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") - - if (LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR) - # ensure include directory is added (in case of non-standard locations - include_directories (BEFORE "${LLVM_INCLUDES}") - string (REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION}) - message (STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}") - add_definitions ("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}") - if (LLVM_STATIC) - # if static LLVM libraries were requested, use llvm-config to generate - # the list of what libraries we need, and substitute that in the right - # way for LLVM_LIBRARY. - set (LLVM_LIBRARY "") - execute_process (COMMAND ${LLVM_CONFIG} --libs - OUTPUT_VARIABLE llvm_library_list - OUTPUT_STRIP_TRAILING_WHITESPACE) - string (REPLACE "-l" "" llvm_library_list ${llvm_library_list}) - string (REPLACE " " ";" llvm_library_list ${llvm_library_list}) - foreach (f ${llvm_library_list}) - list (APPEND LLVM_LIBRARY "${LLVM_LIB_DIR}/lib${f}.a") - endforeach () - endif () - string (REPLACE ";" " " LLVM_LIBRARY "${LLVM_LIBRARY}") - message (STATUS "LLVM library = ${LLVM_LIBRARY}") - else () - message (FATAL_ERROR "LLVM not found.") - endif () - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} ${LLVM_LIBRARY}") - - # end LLVM library setup - endif() set(EXETYPE MACOSX_BUNDLE) set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g") set(CMAKE_CXX_FLAGS_DEBUG "-fno-strict-aliasing -g") - if(CMAKE_OSX_ARCHITECTURES MATCHES "i386") - set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller") - set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller") - elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64") - set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller") - set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller") + if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR CMAKE_OSX_ARCHITECTURES MATCHES "i386") + set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -msse -msse2 -msse3 -mssse3") + set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -msse -msse2 -msse3 -mssse3") + if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller") + endif() else() set(CMAKE_C_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing") set(CMAKE_CXX_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing") @@ -1676,6 +1729,12 @@ if(WITH_CYCLES) if(NOT WITH_BOOST) message(FATAL_ERROR "Cycles reqires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_CYCLES") endif() + + if(WITH_CYCLES_OSL) + if(NOT WITH_LLVM) + message(FATAL_ERROR "Cycles OSL reqires WITH_LLVM, the library may not have been found. Configure LLVM or disable WITH_CYCLES_OSL") + endif() + endif() endif() @@ -1827,9 +1886,6 @@ if(CMAKE_COMPILER_IS_GNUCC) 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) - # # this causes too many warnings, disable - # ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEFINED -Wundef) - # 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) @@ -1840,14 +1896,17 @@ if(CMAKE_COMPILER_IS_GNUCC) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare) - ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op) - ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef) 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) - ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEFINED -Wundef) + + # causes too many warnings + if(NOT APPLE) + ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef) + ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations) + endif() # flags to undo strict flags ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations) diff --git a/GNUmakefile b/GNUmakefile index 7b333a5fc77..90d76dfe432 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -171,6 +171,7 @@ help: @echo "" @echo "Static Source Code Checking (not associated with building blender)" @echo " * check_cppcheck - run blender source through cppcheck (C & C++)" + @echo " * check_clang_array - run blender source through clang array checking script (C & C++)" @echo " * check_splint - run blenders source through splint (C only)" @echo " * check_sparse - run blenders source through sparse (C only)" @echo " * check_smatch - run blenders source through smatch (C only)" @@ -244,6 +245,10 @@ check_cppcheck: $(CMAKE_CONFIG) cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py +check_clang_array: + $(CMAKE_CONFIG) + cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py + check_splint: $(CMAKE_CONFIG) cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py diff --git a/build_files/cmake/clang_array_check.py b/build_files/cmake/clang_array_check.py new file mode 100644 index 00000000000..df45648f975 --- /dev/null +++ b/build_files/cmake/clang_array_check.py @@ -0,0 +1,337 @@ +# --- +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# --- +# by Campbell Barton + +""" +Invocation: + + export CLANG_BIND_DIR="/dsk/src/llvm/tools/clang/bindings/python" + export CLANG_LIB_DIR="/opt/llvm/lib" + + python2 clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include + +... defines and includes are optional + +""" + +# ----------------------------------------------------------------------------- +# predefined function/arg sizes, handy sometimes, but not complete... + +defs_precalc = { + "glColor3bv": {0: 3}, + "glColor4bv": {0: 4}, + + "glColor3ubv": {0: 3}, + "glColor4ubv": {0: 4}, + + "glColor4usv": {0: 3}, + "glColor4usv": {0: 4}, + + "glColor3fv": {0: 3}, + "glColor4fv": {0: 4}, + + "glColor3dv": {0: 3}, + "glColor4dv": {0: 4}, + + "glVertex2fv": {0: 2}, + "glVertex3fv": {0: 3}, + "glVertex4fv": {0: 4}, + + "glEvalCoord1fv": {0: 1}, + "glEvalCoord1dv": {0: 1}, + "glEvalCoord2fv": {0: 2}, + "glEvalCoord2dv": {0: 2}, + + "glRasterPos2dv": {0: 2}, + "glRasterPos3dv": {0: 3}, + "glRasterPos4dv": {0: 4}, + + "glRasterPos2fv": {0: 2}, + "glRasterPos3fv": {0: 3}, + "glRasterPos4fv": {0: 4}, + + "glRasterPos2sv": {0: 2}, + "glRasterPos3sv": {0: 3}, + "glRasterPos4sv": {0: 4}, + + "glTexCoord2fv": {0: 2}, + "glTexCoord3fv": {0: 3}, + "glTexCoord4fv": {0: 4}, + + "glTexCoord2dv": {0: 2}, + "glTexCoord3dv": {0: 3}, + "glTexCoord4dv": {0: 4}, + + "glNormal3fv": {0: 3}, + "glNormal3dv": {0: 3}, + "glNormal3bv": {0: 3}, + "glNormal3iv": {0: 3}, + "glNormal3sv": {0: 3}, +} + +# ----------------------------------------------------------------------------- + +import sys + +if 0: + # Examples with LLVM as the root dir: '/dsk/src/llvm' + + # path containing 'clang/__init__.py' + CLANG_BIND_DIR = "/dsk/src/llvm/tools/clang/bindings/python" + + # path containing libclang.so + CLANG_LIB_DIR = "/opt/llvm/lib" +else: + import os + CLANG_BIND_DIR = os.environ.get("CLANG_BIND_DIR") + CLANG_LIB_DIR = os.environ.get("CLANG_LIB_DIR") + + if CLANG_BIND_DIR is None: + print("$CLANG_BIND_DIR python binding dir not set") + if CLANG_LIB_DIR is None: + print("$CLANG_LIB_DIR clang lib dir not set") + +sys.path.append(CLANG_BIND_DIR) + +import clang +import clang.cindex +from clang.cindex import (CursorKind, + TypeKind, + TokenKind) + +clang.cindex.Config.set_library_path(CLANG_LIB_DIR) + +index = clang.cindex.Index.create() + +args = sys.argv[2:] +# print(args) + +tu = index.parse(sys.argv[1], args) +print 'Translation unit:', tu.spelling + +# ----------------------------------------------------------------------------- + +def function_parm_wash_tokens(parm): + # print(parm.kind) + assert parm.kind in (CursorKind.PARM_DECL, + CursorKind.VAR_DECL, # XXX, double check this + CursorKind.FIELD_DECL, + ) + + """ + Return tolens without trailing commads and 'const' + """ + + tokens = [t for t in parm.get_tokens()] + if not tokens: + return tokens + + #if tokens[-1].kind == To + # remove trailing char + if tokens[-1].kind == TokenKind.PUNCTUATION: + if tokens[-1].spelling in (",", ")", ";"): + tokens.pop() + #else: + # print(tokens[-1].spelling) + + t_new = [] + for t in tokens: + t_kind = t.kind + t_spelling = t.spelling + ok = True + if t_kind == TokenKind.KEYWORD: + if t_spelling in ("const", "restrict", "volatile"): + ok = False + elif t_spelling.startswith("__"): + ok = False # __restrict + elif t_kind in (TokenKind.COMMENT, ): + ok = False + + # Use these + elif t_kind in (TokenKind.LITERAL, + TokenKind.PUNCTUATION, + TokenKind.IDENTIFIER): + # use but ignore + pass + + else: + print("Unknown!", t_kind, t_spelling) + + # if its OK we will add + if ok: + t_new.append(t) + return t_new + + +def parm_size(node_child): + tokens = function_parm_wash_tokens(node_child) + + # print(" ".join([t.spelling for t in tokens])) + + # NOT PERFECT CODE, EXTRACT SIZE FROM TOKENS + if len(tokens) >= 3: # foo [ 1 ] + if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and + (tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and + (tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")): + # --- + return int(tokens[-2].spelling) + return -1 + + + +def function_get_arg_sizes(node): + # Return a dict if (index: size) items + # {arg_indx: arg_array_size, ... ] + arg_sizes = {} + + if node.spelling == "BM_vert_create" or 1: + node_parms = [node_child for node_child in node.get_children() + if node_child.kind == CursorKind.PARM_DECL] + + for i, node_child in enumerate(node_parms): + + # print(node_child.kind, node_child.spelling) + #print(node_child.type.kind, node_child.spelling) # TypeKind.POINTER + + if node_child.type.kind == TypeKind.POINTER: + pointee = node_child.type.get_pointee() + if pointee.is_pod(): + size = parm_size(node_child) + if size != -1: + arg_sizes[i] = size + + return arg_sizes + + +# ----------------------------------------------------------------------------- +_defs = {} + +def lookup_function_size_def(func_id): + return _defs.get(func_id, ()) + +# ----------------------------------------------------------------------------- + +def file_check_arg_sizes(tu): + + # main checking function + def validate_arg_size(node): + """ + Loop over args and validate sizes for args we KNOW the size of. + """ + assert node.kind == CursorKind.CALL_EXPR + # print("---", " <~> ".join([" ".join([t.spelling for t in C.get_tokens()]) for C in node.get_children()])) + # print(node.location) + + # first child is the function call, skip that. + children = list(node.get_children()) + + if not children: + return # XXX, look into this, happens on C++ + + func = children[0] + + # get the func declaration! + # works but we can better scan for functions ahead of time. + if 0: + func_dec = func.get_definition() + if func_dec: + print("FD", " ".join([t.spelling for t in func_dec.get_tokens()])) + else: + # HRMP'f - why does this fail? + print("AA", " ".join([t.spelling for t in node.get_tokens()])) + else: + args_size_definition = () # dummy + + # get the key + tok = list(func.get_tokens()) + if tok: + func_id = tok[0].spelling + args_size_definition = lookup_function_size_def(func_id) + + if not args_size_definition: + return + + children = children[1:] + for i, node_child in enumerate(children): + children = list(node_child.get_children()) + + # skip if we dont have an index... + size_def = args_size_definition.get(i, -1) + + if size_def == -1: + continue + + #print([c.kind for c in children]) + # print(" ".join([t.spelling for t in node_child.get_tokens()])) + + if len(children) == 1: + arg = children[0] + if arg.kind in (CursorKind.DECL_REF_EXPR, + CursorKind.UNEXPOSED_EXPR): + + if arg.type.kind == TypeKind.POINTER: + dec = arg.get_definition() + if dec: + size = parm_size(dec) + + # size == 0 is for 'float *a' + if size != -1 and size != 0: + + # nice print! + ''' + 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: + location = node.location + print("%s:%d:%d: argument %d is size %d, should be %d" % + (location.file, + location.line, + location.column, + i + 1, size, size_def + )) + + + # we dont really care what we are looking at, just scan entire file for + # function calls. + + def recursive_func_call_check(node): + + if node.kind == CursorKind.CALL_EXPR: + validate_arg_size(node) + + for c in node.get_children(): + recursive_func_call_check(c) + + recursive_func_call_check(tu.cursor) + + +# -- first pass, cache function definitions sizes + +# PRINT FUNC DEFINES +def recursive_arg_sizes(node, ): + # print(node.kind, node.spelling) + if node.kind == CursorKind.FUNCTION_DECL: + args_sizes = function_get_arg_sizes(node) + #if args_sizes: + # print(node.spelling, args_sizes) + _defs[node.spelling] = args_sizes + # print("adding", node.spelling) + for c in node.get_children(): + recursive_arg_sizes(c) +# cache function sizes +recursive_arg_sizes(tu.cursor) +_defs.update(defs_precalc) + +# --- second pass, check against def's +file_check_arg_sizes(tu) diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py new file mode 100644 index 00000000000..ff15a130ee0 --- /dev/null +++ b/build_files/cmake/cmake_static_check_clang_array.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3.2 + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributor(s): Campbell Barton +# +# ***** END GPL LICENSE BLOCK ***** + +# <pep8 compliant> + +import project_source_info +import subprocess +import sys +import os + +CHECKER_IGNORE_PREFIX = [ + "extern", + "intern/moto", + ] + +CHECKER_BIN = "python2" + +CHECKER_ARGS = [ + os.path.join(os.path.dirname(__file__), "clang_array_check.py"), + # not sure why this is needed, but it is. + "-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"), + ] + + +def main(): + source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX) + + check_commands = [] + for c, inc_dirs, defs in source_info: + cmd = ([CHECKER_BIN] + + CHECKER_ARGS + + [c] + + [("-I%s" % i) for i in inc_dirs] + + [("-D%s" % d) for d in defs] + ) + + check_commands.append((c, cmd)) + + process_functions = [] + + def my_process(i, c, cmd): + percent = 100.0 * (i / (len(check_commands) - 1)) + percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:" + + sys.stdout.flush() + sys.stdout.write("%s " % percent_str) + + return subprocess.Popen(cmd) + + for i, (c, cmd) in enumerate(check_commands): + process_functions.append((my_process, (i, c, cmd))) + + project_source_info.queue_processes(process_functions) + + +if __name__ == "__main__": + main() diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 43cfb31c03c..750903b12d7 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -244,6 +244,9 @@ macro(SETUP_LIBDIRS) link_directories(${PCRE_LIBPATH}) link_directories(${EXPAT_LIBPATH}) endif() + if(WITH_LLVM) + link_directories(${LLVM_LIB_DIR}) + endif() if(WITH_MEM_JEMALLOC) link_directories(${JEMALLOC_LIBPATH}) endif() @@ -382,6 +385,9 @@ macro(setup_liblinks if(WITH_CYCLES_OSL) target_link_libraries(${target} ${OSL_LIBRARIES}) endif() + if(WITH_LLVM) + target_link_libraries(${target} ${LLVM_LIBRARY}) + endif() if(WIN32 AND NOT UNIX) target_link_libraries(${target} ${PTHREADS_LIBRARIES}) endif() diff --git a/build_files/package_spec/rpm/blender.spec.in b/build_files/package_spec/rpm/blender.spec.in index 85a689031a3..a95fce80103 100644 --- a/build_files/package_spec/rpm/blender.spec.in +++ b/build_files/package_spec/rpm/blender.spec.in @@ -76,6 +76,7 @@ fi || : %defattr(-,root,root,-) %{_bindir}/%{name} %{_datadir}/%{name}/%{blender_api}/datafiles/fonts +%{_datadir}/%{name}/%{blender_api}/datafiles/colormanagement %{_datadir}/%{name}/%{blender_api}/scripts %{_datadir}/icons/hicolor/*/apps/%{name}.* %{_datadir}/applications/%{name}.desktop diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1 index c7a762f08c7..e7164fcb96b 100644 --- a/doc/manpage/blender.1 +++ b/doc/manpage/blender.1 @@ -1,4 +1,4 @@ -.TH "BLENDER" "1" "July 19, 2012" "Blender Blender 2\&.63 (sub 14)" +.TH "BLENDER" "1" "October 04, 2012" "Blender Blender 2\&.64 (sub 0)" .SH NAME blender \- a 3D modelling and rendering package @@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business http://www.blender.org .SH OPTIONS -Blender 2.63 (sub 14) +Blender 2.64 (sub 0) Usage: blender [args ...] [file] [args ...] .br .SS "Render Options:" diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst index 0d1d0df88c3..260a86f7c59 100644 --- a/doc/python_api/rst/bge.logic.rst +++ b/doc/python_api/rst/bge.logic.rst @@ -2,9 +2,9 @@ Game Logic (bge.logic) ====================== -***** -Intro -***** +************ +Introduction +************ Module to access logic functions, imported automatically into the python controllers namespace. diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index 31ae45b9bf0..f4374f7f355 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -4,6 +4,33 @@ Game Types (bge.types) .. module:: bge.types +************ +Introduction +************ + +This module contains the classes that appear as instances in the Game Engine. A +script must interact with these classes if it is to affect the behaviour of +objects in a game. + +The following example would move an object (i.e. an instance of +:class:`KX_GameObject`) one unit up. + +.. code-block:: python + + # bge.types.SCA_PythonController + cont = bge.logic.getCurrentController() + + # bge.types.KX_GameObject + obj = cont.owner + obj.worldPosition.z += 1 + +To run the code, it could be placed in a Blender text block and executed with +a :class:`SCA_PythonController` logic brick. + +***** +Types +***** + .. class:: PyObjectPlus PyObjectPlus base class of most other types in the Game Engine. @@ -854,6 +881,52 @@ Game Types (bge.types) Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the :data:`invalid` attribute to check. + KX_GameObject can be subclassed to extend functionality. For example: + + .. code-block:: python + + import bge + + class CustomGameObject(bge.types.KX_GameObject): + RATE = 0.05 + + def __init__(self, old_owner): + # "old_owner" can just be ignored. At this point, "self" is + # already the object in the scene, and "old_owner" has been + # destroyed. + + # New attributes can be defined - but we could also use a game + # property, like "self['rate']". + self.rate = CustomGameObject.RATE + + def update(self): + self.worldPosition.z += self.rate + + # switch direction + if self.worldPosition.z > 1.0: + self.rate = -CustomGameObject.RATE + elif self.worldPosition.z < 0.0: + self.rate = CustomGameObject.RATE + + # Called first + def mutate(cont): + old_object = cont.owner + mutated_object = CustomGameObject(cont.owner) + + # After calling the constructor above, references to the old object + # should not be used. + assert(old_object is not mutated_object) + assert(old_object.invalid) + assert(mutated_object is cont.owner) + + # Called later - note we are now working with the mutated object. + def update(cont): + cont.owner.update() + + When subclassing objects other than empties and meshes, the specific type + should be used - e.g. inherit from :class:`BL_ArmatureObject` when the object + to mutate is an armature. + .. attribute:: name The object's name. (read-only). diff --git a/extern/carve/CMakeLists.txt b/extern/carve/CMakeLists.txt index 3916047ff32..5e917ac1e44 100644 --- a/extern/carve/CMakeLists.txt +++ b/extern/carve/CMakeLists.txt @@ -158,7 +158,7 @@ if(WITH_BOOST) -DCARVE_SYSTEM_BOOST ) - list(APPEND INC + list(APPEND INC_SYS ${BOOST_INCLUDE_DIR} ) endif() diff --git a/intern/bsp/CMakeLists.txt b/intern/bsp/CMakeLists.txt index e492c04423e..136c168bdb8 100644 --- a/intern/bsp/CMakeLists.txt +++ b/intern/bsp/CMakeLists.txt @@ -62,7 +62,7 @@ if(WITH_BOOST) -DCARVE_SYSTEM_BOOST ) - list(APPEND INC + list(APPEND INC_SYS ${BOOST_INCLUDE_DIR} ) endif() diff --git a/intern/bsp/intern/BOP_CarveInterface.cpp b/intern/bsp/intern/BOP_CarveInterface.cpp index 255d885007c..1f9c989cbc8 100644 --- a/intern/bsp/intern/BOP_CarveInterface.cpp +++ b/intern/bsp/intern/BOP_CarveInterface.cpp @@ -58,7 +58,7 @@ static bool isQuadPlanar(carve::geom3d::Vector &v1, carve::geom3d::Vector &v2, cross = carve::geom::cross(vec1, vec2); float production = carve::geom::dot(cross, vec3); - float magnitude = 1e-6 * cross.length(); + float magnitude = 1e-5 * cross.length(); return fabs(production) < magnitude; } diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 8d39b09ab0e..4f4b0371839 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -955,7 +955,7 @@ def draw_device(self, context): elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL': layout.prop(cscene, "device") - if cscene.feature_set == 'EXPERIMENTAL' and cscene.device == 'CPU' and engine.with_osl(): + if engine.with_osl() and (cscene.device == 'CPU' or device_type == 'None'): layout.prop(cscene, "shading_system") diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 46d5fefd4dc..e16677336d5 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -94,7 +94,7 @@ static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) return fabsf(transform_get_column(&mat, 3).z); } -static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob) +static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, bool skip_panorama = false) { BL::ID b_ob_data = b_ob.data(); @@ -111,7 +111,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob) bcam->type = CAMERA_ORTHOGRAPHIC; break; case BL::Camera::type_PANO: - bcam->type = CAMERA_PANORAMA; + if(!skip_panorama) + bcam->type = CAMERA_PANORAMA; + else + bcam->type = CAMERA_PERSPECTIVE; break; case BL::Camera::type_PERSP: default: @@ -378,7 +381,7 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion) /* Sync 3D View Camera */ -static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) +static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false) { /* 3d view parameters */ bcam->nearclip = b_v3d.clip_start(); @@ -391,7 +394,7 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL: BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); if(b_ob) { - blender_camera_from_object(bcam, b_ob); + blender_camera_from_object(bcam, b_ob, skip_panorama); /* magic zoom formula */ bcam->zoom = (float)b_rv3d.view_camera_zoom(); @@ -447,7 +450,7 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp /* get viewport viewplane */ BlenderCamera view_bcam; blender_camera_init(&view_bcam); - blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height); + blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true); blender_camera_viewplane(&view_bcam, width, height, &view_left, &view_right, &view_bottom, &view_top, &view_aspect, &sensor_size); @@ -460,7 +463,7 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp /* get camera viewplane */ BlenderCamera cam_bcam; blender_camera_init(&cam_bcam); - blender_camera_from_object(&cam_bcam, b_ob); + blender_camera_from_object(&cam_bcam, b_ob, true); width = (int)(r.resolution_x()*r.resolution_percentage()/100); height = (int)(r.resolution_y()*r.resolution_percentage()/100); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 8fbb223cbc5..27301026d35 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -194,8 +194,10 @@ void BlenderSync::sync_background_light() /* Object */ -void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion, int particle_id) +void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, int particle_id) { + BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent); + /* light is handled separately */ if(object_is_light(b_ob)) { if(!motion) @@ -274,6 +276,15 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, object->visibility &= ~PATH_RAY_CAMERA; } + if (b_dupli_ob) { + object->dupli_generated = get_float3(b_dupli_ob.orco()); + object->dupli_uv = get_float2(b_dupli_ob.uv()); + } + else { + object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f); + object->dupli_uv = make_float2(0.0f, 0.0f); + } + object->particle_id = particle_id; object->tag_update(scene); @@ -328,7 +339,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); if(!(b_dup->hide() || dup_hide)) { - sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); + sync_object(*b_ob, b_index, *b_dup, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); } ++b_index; @@ -346,7 +357,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) if(!hide) { /* object itself */ Transform tfm = get_transform(b_ob->matrix_world()); - sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion, 0); + sync_object(*b_ob, 0, PointerRNA_NULL, tfm, ob_layer, motion, 0); } particle_offset += num_particles; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index ebf8bb45420..b6d5cc623bb 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -490,7 +490,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph break; } case BL::ShaderNode::type_TEX_COORD: { - node = new TextureCoordinateNode(); + BL::ShaderNodeTexCoord b_tex_coord_node(b_node); + TextureCoordinateNode *tex_coord = new TextureCoordinateNode(); + tex_coord->from_dupli = b_tex_coord_node.from_dupli(); + node = tex_coord; break; } case BL::ShaderNode::type_TEX_SKY: { diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 27f6b6ee4ee..ce563087b4a 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -81,7 +81,7 @@ private: void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); - void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion, int particle_id); + void sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, int particle_id); void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); void sync_background_light(); void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 46fbead9bc1..da8f30ea169 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -36,7 +36,7 @@ struct RenderResult; ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings); void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh); -void rna_Object_create_duplilist(void *ob, void *reports, void *sce); +void rna_Object_create_duplilist(void *ob, void *reports, void *sce, int settings); void rna_Object_free_duplilist(void *ob); void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values); void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values); @@ -84,7 +84,7 @@ static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh) static inline void object_create_duplilist(BL::Object self, BL::Scene scene) { - rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data); + rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data, 2); } static inline void object_free_duplilist(BL::Object self) diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 222ade504cc..01da5050c8d 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,7 +23,8 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_POST = 12 + OBJECT_TRANSFORM_MOTION_POST = 12, + OBJECT_DUPLI = 16 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type) @@ -164,6 +165,27 @@ __device_inline uint object_particle_id(KernelGlobals *kg, int object) return __float_as_int(f.w); } +__device_inline float3 object_dupli_generated(KernelGlobals *kg, int object) +{ + if(object == ~0) + return make_float3(0.0f, 0.0f, 0.0f); + + int offset = object*OBJECT_SIZE + OBJECT_DUPLI; + float4 f = kernel_tex_fetch(__objects, offset); + return make_float3(f.x, f.y, f.z); +} + +__device_inline float3 object_dupli_uv(KernelGlobals *kg, int object) +{ + if(object == ~0) + return make_float3(0.0f, 0.0f, 0.0f); + + int offset = object*OBJECT_SIZE + OBJECT_DUPLI; + float4 f = kernel_tex_fetch(__objects, offset + 1); + return make_float3(f.x, f.y, 0.0f); +} + + __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) { return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index ce21ab994f0..48e271a9f3f 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 16 +#define OBJECT_SIZE 18 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 81812a46b6c..6290eed0af8 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -85,16 +85,25 @@ public: } }; -ClosureParam closure_background_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(GenericBackgroundClosure) -}; + +ClosureParam *closure_background_params() +{ + static ClosureParam params[] = { + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GenericBackgroundClosure) + }; + return params; +} CLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure) -ClosureParam closure_holdout_params[] = { - CLOSURE_FINISH_PARAM(HoldoutClosure) -}; +ClosureParam *closure_holdout_params() +{ + static ClosureParam params[] = { + CLOSURE_FINISH_PARAM(HoldoutClosure) + }; + return params; +} CLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) diff --git a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp index 2c545ca55e7..a1904d7f5d7 100644 --- a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp +++ b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp @@ -173,12 +173,16 @@ public: -ClosureParam bsdf_ashikhmin_velvet_params[] = { - CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), - CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/bsdf_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_diffuse.cpp index 582ac01d959..1e06d3b583f 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse.cpp @@ -168,17 +168,25 @@ public: } }; -ClosureParam bsdf_diffuse_params[] = { - CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DiffuseClosure) -}; - -ClosureParam bsdf_translucent_params[] = { - CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TranslucentClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/bsdf_microfacet.cpp b/intern/cycles/kernel/osl/bsdf_microfacet.cpp index 09730d8c3e1..8446dbbe982 100644 --- a/intern/cycles/kernel/osl/bsdf_microfacet.cpp +++ b/intern/cycles/kernel/osl/bsdf_microfacet.cpp @@ -503,35 +503,51 @@ public: -ClosureParam bsdf_microfacet_ggx_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) -}; - -ClosureParam bsdf_microfacet_ggx_refraction_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>) -}; - -ClosureParam bsdf_microfacet_beckmann_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) -}; - -ClosureParam bsdf_microfacet_beckmann_refraction_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>) -}; +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>) diff --git a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp index 83d0e583695..2a00100c256 100644 --- a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp +++ b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp @@ -125,12 +125,16 @@ private: } }; -ClosureParam bsdf_oren_nayar_params[] = { - CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N), - CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(OrenNayarClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/bsdf_phong.cpp b/intern/cycles/kernel/osl/bsdf_phong.cpp index 57745079d33..1f430cc6f5d 100644 --- a/intern/cycles/kernel/osl/bsdf_phong.cpp +++ b/intern/cycles/kernel/osl/bsdf_phong.cpp @@ -258,18 +258,28 @@ public: -ClosureParam bsdf_phong_params[] = { - CLOSURE_VECTOR_PARAM(PhongClosure, m_N), - CLOSURE_FLOAT_PARAM (PhongClosure, m_exponent), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(PhongClosure) }; - -ClosureParam bsdf_phong_ramp_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) }; +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) diff --git a/intern/cycles/kernel/osl/bsdf_reflection.cpp b/intern/cycles/kernel/osl/bsdf_reflection.cpp index 7041b4ced6f..1b85ec146d3 100644 --- a/intern/cycles/kernel/osl/bsdf_reflection.cpp +++ b/intern/cycles/kernel/osl/bsdf_reflection.cpp @@ -97,11 +97,15 @@ public: } }; -ClosureParam bsdf_reflection_params[] = { - CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(ReflectionClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/bsdf_refraction.cpp b/intern/cycles/kernel/osl/bsdf_refraction.cpp index f56ad7b127c..76ee53f7929 100644 --- a/intern/cycles/kernel/osl/bsdf_refraction.cpp +++ b/intern/cycles/kernel/osl/bsdf_refraction.cpp @@ -108,12 +108,16 @@ public: } }; -ClosureParam bsdf_refraction_params[] = { - CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), - CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(RefractionClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/bsdf_transparent.cpp b/intern/cycles/kernel/osl/bsdf_transparent.cpp index acde92530a2..29cef8e192f 100644 --- a/intern/cycles/kernel/osl/bsdf_transparent.cpp +++ b/intern/cycles/kernel/osl/bsdf_transparent.cpp @@ -87,10 +87,14 @@ public: -ClosureParam bsdf_transparent_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TransparentClosure) -}; +ClosureParam *bsdf_transparent_params() +{ + static ClosureParam params[] = { + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(TransparentClosure) + }; + return params; +} CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure) diff --git a/intern/cycles/kernel/osl/bsdf_ward.cpp b/intern/cycles/kernel/osl/bsdf_ward.cpp index 4aacbc4ffc3..9d8d2fc4b76 100644 --- a/intern/cycles/kernel/osl/bsdf_ward.cpp +++ b/intern/cycles/kernel/osl/bsdf_ward.cpp @@ -211,14 +211,18 @@ public: -ClosureParam bsdf_ward_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) -}; +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) diff --git a/intern/cycles/kernel/osl/bsdf_westin.cpp b/intern/cycles/kernel/osl/bsdf_westin.cpp index a476e8045f7..6716376ad3e 100644 --- a/intern/cycles/kernel/osl/bsdf_westin.cpp +++ b/intern/cycles/kernel/osl/bsdf_westin.cpp @@ -222,19 +222,27 @@ public: -ClosureParam bsdf_westin_backscatter_params[] = { - CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), - CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinBackscatterClosure) -}; - -ClosureParam bsdf_westin_sheen_params[] = { - CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), - CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinSheenClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp index b195cf513cd..889e8a54796 100644 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ b/intern/cycles/kernel/osl/bssrdf.cpp @@ -94,11 +94,15 @@ public: -ClosureParam closure_bssrdf_cubic_params[] = { - CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/debug.cpp b/intern/cycles/kernel/osl/debug.cpp index 768a9100e8a..ee5fb30371a 100644 --- a/intern/cycles/kernel/osl/debug.cpp +++ b/intern/cycles/kernel/osl/debug.cpp @@ -69,11 +69,15 @@ public: }; -ClosureParam closure_debug_params[] = { - CLOSURE_STRING_PARAM(DebugClosure, m_tag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DebugClosure) -}; +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) diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 0a582c3f558..3ee57cbe6b6 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -97,10 +97,14 @@ public: -ClosureParam closure_emission_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(GenericEmissiveClosure) -}; +ClosureParam *closure_emission_params() +{ + static ClosureParam params[] = { + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GenericEmissiveClosure) + }; + return params; +} CLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure) diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index a1a108a1b1d..9e99d4d2480 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -64,28 +64,28 @@ 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); + 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); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 00794183ca5..a69af45672d 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -64,28 +64,28 @@ enum { OSL_CLOSURE_SUBSURFACE_ID }; -extern OSL::ClosureParam bsdf_diffuse_params[]; -extern OSL::ClosureParam bsdf_oren_nayar_params[]; -extern OSL::ClosureParam bsdf_translucent_params[]; -extern OSL::ClosureParam bsdf_reflection_params[]; -extern OSL::ClosureParam bsdf_refraction_params[]; -extern OSL::ClosureParam bsdf_transparent_params[]; -extern OSL::ClosureParam bsdf_microfacet_ggx_params[]; -extern OSL::ClosureParam bsdf_microfacet_ggx_refraction_params[]; -extern OSL::ClosureParam bsdf_microfacet_beckmann_params[]; -extern OSL::ClosureParam bsdf_microfacet_beckmann_refraction_params[]; -extern OSL::ClosureParam bsdf_ward_params[]; -extern OSL::ClosureParam bsdf_phong_params[]; -extern OSL::ClosureParam bsdf_phong_ramp_params[]; -extern OSL::ClosureParam bsdf_ashikhmin_velvet_params[]; -extern OSL::ClosureParam bsdf_westin_backscatter_params[]; -extern OSL::ClosureParam bsdf_westin_sheen_params[]; -extern OSL::ClosureParam closure_bssrdf_cubic_params[]; -extern OSL::ClosureParam closure_emission_params[]; -extern OSL::ClosureParam closure_debug_params[]; -extern OSL::ClosureParam closure_background_params[]; -extern OSL::ClosureParam closure_holdout_params[]; -extern OSL::ClosureParam closure_subsurface_params[]; +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); diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 98ede0e4f60..ea508dcb660 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -139,15 +139,27 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, float sample_weight = fabsf(average(weight)) * albedo; sc.sample_weight = sample_weight; - sc.type = CLOSURE_BSDF_ID; /* scattering flags */ - if (scattering == OSL::Labels::DIFFUSE) + if (scattering == OSL::Labels::DIFFUSE) { sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; - else if (scattering == OSL::Labels::GLOSSY) + sc.type = CLOSURE_BSDF_DIFFUSE_ID; + } + else if (scattering == OSL::Labels::GLOSSY) { sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; - else + 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; + } /* add */ sd->closure[sd->num_closure++] = sc; diff --git a/intern/cycles/kernel/osl/vol_subsurface.cpp b/intern/cycles/kernel/osl/vol_subsurface.cpp index 818a057b6cc..5845428ed43 100644 --- a/intern/cycles/kernel/osl/vol_subsurface.cpp +++ b/intern/cycles/kernel/osl/vol_subsurface.cpp @@ -122,14 +122,18 @@ public: -ClosureParam closure_subsurface_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) -}; +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) diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index fbaf253177d..6bd8f2ac69c 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -92,6 +92,14 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack data = sd->I; break; } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } } stack_store_float3(stack, out_offset, data); @@ -141,6 +149,14 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa data = sd->I; break; } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } } stack_store_float3(stack, out_offset, data); @@ -193,6 +209,14 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa data = sd->I; break; } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } } stack_store_float3(stack, out_offset, data); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index c82eafc790a..ee423573cdf 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -43,6 +43,7 @@ typedef enum NodeType { NODE_TEX_IMAGE_BOX, NODE_TEX_SKY, NODE_GEOMETRY, + NODE_GEOMETRY_DUPLI, NODE_LIGHT_PATH, NODE_VALUE_F, NODE_VALUE_V, @@ -149,7 +150,9 @@ typedef enum NodeTexCoord { NODE_TEXCO_OBJECT, NODE_TEXCO_CAMERA, NODE_TEXCO_WINDOW, - NODE_TEXCO_REFLECTION + NODE_TEXCO_REFLECTION, + NODE_TEXCO_DUPLI_GENERATED, + NODE_TEXCO_DUPLI_UV } NodeTexCoord; typedef enum NodeMix { @@ -284,16 +287,18 @@ typedef enum ClosureType { CLOSURE_BSDF_DIFFUSE_ID, CLOSURE_BSDF_OREN_NAYAR_ID, + CLOSURE_BSDF_GLOSSY_ID, CLOSURE_BSDF_REFLECTION_ID, CLOSURE_BSDF_MICROFACET_GGX_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_ID, CLOSURE_BSDF_WARD_ID, + CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_WESTIN_SHEEN_ID, + CLOSURE_BSDF_TRANSMISSION_ID, CLOSURE_BSDF_TRANSLUCENT_ID, CLOSURE_BSDF_REFRACTION_ID, CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, - CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, CLOSURE_BSDF_GLASS_ID, @@ -317,8 +322,8 @@ typedef enum ClosureType { /* watch this, being lazy with memory usage */ #define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID) #define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_OREN_NAYAR_ID) -#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID) -#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_GLASS_ID) +#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID) +#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_GLASS_ID) #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID) #define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID) #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID) diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 6b8e3702d03..e75a3b37f3b 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -7,7 +7,6 @@ set(INC ../kernel/osl ../bvh ../util - ${GLEW_INCLUDE_PATH} ) set(INC_SYS ${GLEW_INCLUDE_PATH} diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 20fbfa0cf27..62758128a73 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -181,14 +181,14 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) assert(from && to); if(to->link) { - fprintf(stderr, "ShaderGraph connect: input already connected.\n"); + fprintf(stderr, "Cycles shader graph connect: input already connected.\n"); return; } if(from->type != to->type) { /* for closures we can't do automatic conversion */ if(from->type == SHADER_SOCKET_CLOSURE || to->type == SHADER_SOCKET_CLOSURE) { - fprintf(stderr, "ShaderGraph connect: can only connect closure to closure " + fprintf(stderr, "Cycles shader graph connect: can only connect closure to closure " "(ShaderNode:%s, ShaderOutput:%s , type:%d -> to ShaderNode:%s, ShaderInput:%s, type:%d).\n", from->parent->name.c_str(), from->name, (int)from->type, to->parent->name.c_str(), to->name, (int)to->type); @@ -363,7 +363,7 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b if(on_stack[depnode->id]) { /* break cycle */ disconnect(input); - fprintf(stderr, "ShaderGraph: detected cycle in graph, connection removed.\n"); + fprintf(stderr, "Cycles shader graph: detected cycle in graph, connection removed.\n"); } else if(!visited[depnode->id]) { /* visit dependencies */ diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 6445c04257f..5c1737bd60a 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -67,13 +67,19 @@ static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, main_task.shader_x = 0; 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); + main_task.split_max_size(split_tasks, 128*128); foreach(DeviceTask& task, split_tasks) { device->task_add(task); device->task_wait(); } +#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); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index eabb97e7238..4e16eea2774 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1644,14 +1644,18 @@ TextureCoordinateNode::TextureCoordinateNode() add_output("Camera", SHADER_SOCKET_POINT); add_output("Window", SHADER_SOCKET_POINT); add_output("Reflection", SHADER_SOCKET_NORMAL); + + from_dupli = false; } void TextureCoordinateNode::attributes(AttributeRequestSet *attributes) { - if(!output("Generated")->links.empty()) - attributes->add(ATTR_STD_GENERATED); - if(!output("UV")->links.empty()) - attributes->add(ATTR_STD_UV); + if(!from_dupli) { + if(!output("Generated")->links.empty()) + attributes->add(ATTR_STD_GENERATED); + if(!output("UV")->links.empty()) + attributes->add(ATTR_STD_UV); + } ShaderNode::attributes(attributes); } @@ -1681,9 +1685,15 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler) compiler.add_node(geom_node, NODE_GEOM_P, out->stack_offset); } else { - int attr = compiler.attribute(ATTR_STD_GENERATED); - compiler.stack_assign(out); - compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + if(from_dupli) { + compiler.stack_assign(out); + compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, out->stack_offset); + } + else { + int attr = compiler.attribute(ATTR_STD_GENERATED); + compiler.stack_assign(out); + compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + } } } @@ -1695,9 +1705,15 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler) out = output("UV"); if(!out->links.empty()) { - int attr = compiler.attribute(ATTR_STD_UV); - compiler.stack_assign(out); - compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + if(from_dupli) { + compiler.stack_assign(out); + compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, out->stack_offset); + } + else { + int attr = compiler.attribute(ATTR_STD_UV); + compiler.stack_assign(out); + compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + } } out = output("Object"); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 82bead7e41a..e8e584dd8ef 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -284,6 +284,8 @@ class TextureCoordinateNode : public ShaderNode { public: SHADER_NODE_CLASS(TextureCoordinateNode) void attributes(AttributeRequestSet *attributes); + + bool from_dupli; }; class LightPathNode : public ShaderNode { diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 7389b239627..d78a82d589a 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -235,6 +235,10 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene } } + /* 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); + /* object flag */ if(ob->use_holdout) flag |= SD_HOLDOUT_MASK; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 88677d79dff..e2c3ad4e071 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -49,6 +49,9 @@ public: bool use_motion; bool use_holdout; + float3 dupli_generated; + float2 dupli_uv; + int particle_id; Object(); diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 844ce01569f..da287a10199 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -274,6 +274,17 @@ 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/dualcon/intern/octree.cpp b/intern/dualcon/intern/octree.cpp index c74f8bf2f46..49c50c8240d 100644 --- a/intern/dualcon/intern/octree.cpp +++ b/intern/dualcon/intern/octree.cpp @@ -384,22 +384,22 @@ InternalNode *Octree::addTriangle(InternalNode *node, CubeTriangleIsect *p, int /* Pruning using intersection test */ if (subp->isIntersecting()) { - if (!hasChild(node, i)) { + if (!node->has_child(i)) { if (height == 1) node = addLeafChild(node, i, count, createLeaf(0)); else node = addInternalChild(node, i, count, createInternal(0)); } - Node *chd = getChild(node, count); + Node *chd = node->get_child(count); if (node->is_child_leaf(i)) - setChild(node, count, (Node *)updateCell(&chd->leaf, subp)); + node->set_child(count, (Node *)updateCell(&chd->leaf, subp)); else - setChild(node, count, (Node *)addTriangle(&chd->internal, subp, height - 1)); + node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1)); } } - if (hasChild(node, i)) + if (node->has_child(i)) count++; } @@ -450,11 +450,11 @@ void Octree::preparePrimalEdgesMask(InternalNode *node) { int count = 0; for (int i = 0; i < 8; i++) { - if (hasChild(node, i)) { + if (node->has_child(i)) { if (node->is_child_leaf(i)) - createPrimalEdgesMask(&getChild(node, count)->leaf); + createPrimalEdgesMask(&node->get_child(count)->leaf); else - preparePrimalEdgesMask(&getChild(node, count)->internal); + preparePrimalEdgesMask(&node->get_child(count)->internal); count++; } @@ -487,7 +487,7 @@ Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *& path // Get children paths int chdleaf[8]; - fillChildren(&newnode->internal, chd, chdleaf); + newnode->internal.fill_children(chd, chdleaf); // int count = 0; for (i = 0; i < 8; i++) { @@ -510,7 +510,7 @@ Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *& path int df[2] = {depth - 1, depth - 1}; int *nstf[2]; - fillChildren(&newnode->internal, chd, chdleaf); + newnode->internal.fill_children(chd, chdleaf); for (i = 0; i < 12; i++) { int c[2] = {cellProcFaceMask[i][0], cellProcFaceMask[i][1]}; @@ -590,7 +590,7 @@ void Octree::findPaths(Node *node[2], int leaf[2], int depth[2], int *st[2], int for (j = 0; j < 2; j++) { if (!leaf[j]) { - fillChildren(&node[j]->internal, chd[j], chdleaf[j]); + node[j]->internal.fill_children(chd[j], chdleaf[j]); int len = (dimen >> (maxDepth - depth[j] + 1)); for (i = 0; i < 8; i++) { @@ -966,10 +966,10 @@ Node *Octree::patch(Node *newnode, int st[3], int len, PathList *rings) st[1] + len * vertmap[i][1], st[2] + len * vertmap[i][2] }; - patch(getChild(&newnode->internal, count), nori, len, zlists[i]); + patch(newnode->internal.get_child(count), nori, len, zlists[i]); } - if (hasChild(&newnode->internal, i)) { + if (newnode->internal.has_child(i)) { count++; } } @@ -1408,16 +1408,16 @@ Node *Octree::locateCell(InternalNode *node, int st[3], int len, int ori[3], int rst[1] = st[1] + vertmap[ind][1] * len; rst[2] = st[2] + vertmap[ind][2] * len; - if (hasChild(node, ind)) { - int count = getChildCount(node, ind); - Node *chd = getChild(node, count); + if (node->has_child(ind)) { + int count = node->get_child_count(ind); + Node *chd = node->get_child(count); if (node->is_child_leaf(ind)) { rleaf = chd; rlen = len; } else { // Recur - setChild(node, count, locateCell(&chd->internal, rst, len, ori, dir, side, rleaf, rst, rlen)); + node->set_child(count, locateCell(&chd->internal, rst, len, ori, dir, side, rleaf, rst, rlen)); } } else { @@ -1724,7 +1724,7 @@ void Octree::buildSigns(unsigned char table[], Node *node, int isLeaf, int sg, i // Internal node Node *chd[8]; int leaf[8]; - fillChildren(&node->internal, chd, leaf); + node->internal.fill_children(chd, leaf); // Get the signs at the corners of the first cube rvalue[0] = sg; @@ -1784,8 +1784,8 @@ void Octree::clearProcessBits(Node *node, int height) // Internal cell, recur int count = 0; for (i = 0; i < 8; i++) { - if (hasChild(&node->internal, i)) { - clearProcessBits(getChild(&node->internal, count), height - 1); + if (node->internal.has_child(i)) { + clearProcessBits(node->internal.get_child(count), height - 1); count++; } } @@ -2016,13 +2016,13 @@ int Octree::floodFill(Node *node, int st[3], int len, int height, int threshold) int count = 0; len >>= 1; for (i = 0; i < 8; i++) { - if (hasChild((InternalNode *)node, i)) { + if (node->internal.has_child(i)) { int nst[3]; nst[0] = st[0] + vertmap[i][0] * len; nst[1] = st[1] + vertmap[i][1] * len; nst[2] = st[2] + vertmap[i][2] * len; - int d = floodFill(getChild((InternalNode *)node, count), nst, len, height - 1, threshold); + int d = floodFill(node->internal.get_child(count), nst, len, height - 1, threshold); if (d > maxtotal) { maxtotal = d; } @@ -2062,9 +2062,9 @@ void Octree::writeOut() void Octree::countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface) { if (height > 0) { - int total = getNumChildren(&node->internal); + int total = node->internal.get_num_children(); for (int i = 0; i < total; i++) { - countIntersection(getChild(&node->internal, i), height - 1, nedge, ncell, nface); + countIntersection(node->internal.get_child(i), height - 1, nedge, ncell, nface); } } else { @@ -2128,8 +2128,32 @@ static void solve_least_squares(const float halfA[], const float b[], rvalue[i] = result(i); } +static void mass_point(float mp[3], const float pts[12][3], const int parity[12]) +{ + int ec = 0; + + for (int i = 0; i < 12; i++) { + if (parity[i]) { + const float *p = pts[i]; + + mp[0] += p[0]; + mp[1] += p[1]; + mp[2] += p[2]; + + ec++; + } + } + + if (ec == 0) { + return; + } + mp[0] /= ec; + mp[1] /= ec; + mp[2] /= ec; +} + static void minimize(float rvalue[3], float mp[3], const float pts[12][3], - const float norms[12][3], const int parity[12]) + const float norms[12][3], const int parity[12]) { float ata[6] = {0, 0, 0, 0, 0, 0}; float atb[3] = {0, 0, 0}; @@ -2175,34 +2199,51 @@ static void minimize(float rvalue[3], float mp[3], const float pts[12][3], solve_least_squares(ata, atb, mp, rvalue); } -void Octree::computeMinimizer(LeafNode *leaf, int st[3], int len, float rvalue[3]) +void Octree::computeMinimizer(const LeafNode *leaf, int st[3], int len, + float rvalue[3]) const { // First, gather all edge intersections float pts[12][3], norms[12][3]; int parity[12]; fillEdgeIntersections(leaf, st, len, pts, norms, parity); - // Next, construct QEF and minimizer - float mp[3] = {0, 0, 0}; - minimize(rvalue, mp, pts, norms, parity); - - /* Restraining the location of the minimizer */ - float nh1 = hermite_num * len; - float nh2 = (1 + hermite_num) * len; - if ((mode == DUALCON_MASS_POINT || mode == DUALCON_CENTROID) || - (rvalue[0] < st[0] - nh1 || rvalue[1] < st[1] - nh1 || rvalue[2] < st[2] - nh1 || - rvalue[0] > st[0] + nh2 || rvalue[1] > st[1] + nh2 || rvalue[2] > st[2] + nh2)) { - if (mode == DUALCON_CENTROID) { - // Use centroids + switch (mode) { + case DUALCON_CENTROID: rvalue[0] = (float) st[0] + len / 2; rvalue[1] = (float) st[1] + len / 2; rvalue[2] = (float) st[2] + len / 2; - } - else { - // Use mass point instead - rvalue[0] = mp[0]; - rvalue[1] = mp[1]; - rvalue[2] = mp[2]; + break; + + case DUALCON_MASS_POINT: + rvalue[0] = rvalue[1] = rvalue[2] = 0; + mass_point(rvalue, pts, parity); + break; + + default: { + // Sharp features */ + + // construct QEF and minimizer + float mp[3] = {0, 0, 0}; + minimize(rvalue, mp, pts, norms, parity); + + /* Restraining the location of the minimizer */ + float nh1 = hermite_num * len; + float nh2 = (1 + hermite_num) * len; + + if (rvalue[0] < st[0] - nh1 || + rvalue[1] < st[1] - nh1 || + rvalue[2] < st[2] - nh1 || + + rvalue[0] > st[0] + nh2 || + rvalue[1] > st[1] + nh2 || + rvalue[2] > st[2] + nh2) + { + // Use mass point instead + rvalue[0] = mp[0]; + rvalue[1] = mp[1]; + rvalue[2] = mp[2]; + } + break; } } } @@ -2253,13 +2294,13 @@ void Octree::generateMinimizer(Node *node, int st[3], int len, int height, int& int count = 0; len >>= 1; for (i = 0; i < 8; i++) { - if (hasChild(&node->internal, i)) { + if (node->internal.has_child(i)) { int nst[3]; nst[0] = st[0] + vertmap[i][0] * len; nst[1] = st[1] + vertmap[i][1] * len; nst[2] = st[2] + vertmap[i][2] * len; - generateMinimizer(getChild(&node->internal, count), + generateMinimizer(node->internal.get_child(count), nst, len, height - 1, offset); count++; } @@ -2344,9 +2385,9 @@ void Octree::edgeProcContour(Node *node[4], int leaf[4], int depth[4], int maxde Node *chd[4][8]; for (j = 0; j < 4; j++) { for (i = 0; i < 8; i++) { - chd[j][i] = ((!leaf[j]) && hasChild(&node[j]->internal, i)) ? - getChild(&node[j]->internal, - getChildCount(&node[j]->internal, i)) : NULL; + chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ? + node[j]->internal.get_child( + node[j]->internal.get_child_count(i)) : NULL; } } @@ -2391,9 +2432,9 @@ void Octree::faceProcContour(Node *node[2], int leaf[2], int depth[2], int maxde Node *chd[2][8]; for (j = 0; j < 2; j++) { for (i = 0; i < 8; i++) { - chd[j][i] = ((!leaf[j]) && hasChild(&node[j]->internal, i)) ? - getChild(&node[j]->internal, - getChildCount(&node[j]->internal, i)) : NULL; + chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ? + node[j]->internal.get_child( + node[j]->internal.get_child_count(i)) : NULL; } } @@ -2460,9 +2501,8 @@ void Octree::cellProcContour(Node *node, int leaf, int depth) // Fill children nodes Node *chd[8]; for (i = 0; i < 8; i++) { - chd[i] = ((!leaf) && hasChild(&node->internal, i)) ? - getChild(&node->internal, - getChildCount(&node->internal, i)) : NULL; + chd[i] = ((!leaf) && node->internal.has_child(i)) ? + node->internal.get_child(node->internal.get_child_count(i)) : NULL; } // 8 Cell calls @@ -2539,8 +2579,8 @@ void Octree::edgeProcParity(Node *node[4], int leaf[4], int depth[4], int maxdep Node *chd[4][8]; for (j = 0; j < 4; j++) { for (i = 0; i < 8; i++) { - chd[j][i] = ((!leaf[j]) && hasChild(&node[j]->internal, i)) ? - getChild(&node[j]->internal, getChildCount(&node[j]->internal, i)) : NULL; + chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ? + node[j]->internal.get_child( node[j]->internal.get_child_count(i)) : NULL; } } @@ -2589,9 +2629,9 @@ void Octree::faceProcParity(Node *node[2], int leaf[2], int depth[2], int maxdep Node *chd[2][8]; for (j = 0; j < 2; j++) { for (i = 0; i < 8; i++) { - chd[j][i] = ((!leaf[j]) && hasChild(&node[j]->internal, i)) ? - getChild(&node[j]->internal, - getChildCount(&node[j]->internal, i)) : NULL; + chd[j][i] = ((!leaf[j]) && node[j]->internal.has_child(i)) ? + node[j]->internal.get_child( + node[j]->internal.get_child_count(i)) : NULL; } } @@ -2658,9 +2698,8 @@ void Octree::cellProcParity(Node *node, int leaf, int depth) // Fill children nodes Node *chd[8]; for (i = 0; i < 8; i++) { - chd[i] = ((!leaf) && hasChild((InternalNode *)node, i)) ? - getChild((InternalNode *)node, - getChildCount((InternalNode *)node, i)) : NULL; + chd[i] = ((!leaf) && node->internal.has_child(i)) ? + node->internal.get_child(node->internal.get_child_count(i)) : NULL; } // 8 Cell calls @@ -2803,3 +2842,7 @@ const int dirEdge[3][4] = { {7, 6, 5, 4}, {11, 10, 9, 8} }; + +int InternalNode::numChildrenTable[256]; +int InternalNode::childrenCountTable[256][8]; +int InternalNode::childrenIndexTable[256][8]; diff --git a/intern/dualcon/intern/octree.h b/intern/dualcon/intern/octree.h index 550d584baa7..6cbdc9fb3d8 100644 --- a/intern/dualcon/intern/octree.h +++ b/intern/dualcon/intern/octree.h @@ -56,12 +56,18 @@ #define EDGE_FLOATS 4 union Node; +struct LeafNode; struct InternalNode { - /* Treat as bitfield, bit N indicates whether child N exists or not */ - unsigned char has_child; - /* Treat as bitfield, bit N indicates whether child N is a leaf or not */ - unsigned char child_is_leaf; + /* Initialized in Octree::BuildTable */ + static int numChildrenTable[256]; + static int childrenCountTable[256][8]; + static int childrenIndexTable[256][8]; + + /* Bit N indicates whether child N exists or not */ + unsigned char has_child_bitfield; + /* Bit N indicates whether child N is a leaf or not */ + unsigned char child_is_leaf_bitfield; /* Can have up to eight children */ Node *children[0]; @@ -69,7 +75,78 @@ struct InternalNode { /// Test if child is leaf int is_child_leaf(int index) const { - return (child_is_leaf >> index) & 1; + return (child_is_leaf_bitfield >> index) & 1; + } + + /// If child index exists + int has_child(int index) const + { + return (has_child_bitfield >> index) & 1; + } + + /// Get the pointer to child index + Node *get_child(int count) + { + return children[count]; + } + + const Node *get_child(int count) const + { + return children[count]; + } + + /// Get total number of children + int get_num_children() const + { + return numChildrenTable[has_child_bitfield]; + } + + /// Get the count of children + int get_child_count(int index) const + { + return childrenCountTable[has_child_bitfield][index]; + } + int get_child_index(int count) + { + return childrenIndexTable[has_child_bitfield][count]; + } + const int *get_child_counts() const + { + return childrenCountTable[has_child_bitfield]; + } + + /// Get all children + void fill_children(Node *children[8], int leaf[8]) + { + int count = 0; + for (int i = 0; i < 8; i++) { + leaf[i] = is_child_leaf(i); + if (has_child(i)) { + children[i] = get_child(count); + count++; + } + else { + children[i] = NULL; + leaf[i] = 0; + } + } + } + + /// Sets the child pointer + void set_child(int count, Node *chd) + { + children[count] = chd; + } + void set_internal_child(int index, int count, InternalNode *chd) + { + set_child(count, (Node *)chd); + has_child_bitfield |= (1 << index); + } + void set_leaf_child(int index, int count, LeafNode *chd) + { + set_child(count, (Node *)chd); + has_child_bitfield |= (1 << index); + child_is_leaf_bitfield |= (1 << index); } }; @@ -345,7 +422,8 @@ class Octree void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface); void generateMinimizer(Node * node, int st[3], int len, int height, int& offset); - void computeMinimizer(LeafNode * leaf, int st[3], int len, float rvalue[3]); + void computeMinimizer(const LeafNode * leaf, int st[3], int len, + float rvalue[3]) const; /** * Traversal functions to generate polygon model * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY @@ -365,9 +443,6 @@ class Octree /************ Operators for all nodes ************/ /// Lookup table - int numChildrenTable[256]; - int childrenCountTable[256][8]; - int childrenIndexTable[256][8]; int numEdgeTable[8]; int edgeCountTable[8][3]; @@ -375,12 +450,12 @@ class Octree void buildTable() { for (int i = 0; i < 256; i++) { - numChildrenTable[i] = 0; + InternalNode::numChildrenTable[i] = 0; int count = 0; for (int j = 0; j < 8; j++) { - numChildrenTable[i] += ((i >> j) & 1); - childrenCountTable[i][j] = count; - childrenIndexTable[i][count] = j; + InternalNode::numChildrenTable[i] += ((i >> j) & 1); + InternalNode::childrenCountTable[i][j] = count; + InternalNode::childrenIndexTable[i][count] = j; count += ((i >> j) & 1); } } @@ -402,15 +477,15 @@ class Octree return getSign(&node->leaf, index); } else { - if (hasChild(&node->internal, index)) { - return getSign(getChild(&node->internal, getChildCount(&node->internal, index)), + if (node->internal.has_child(index)) { + return getSign(node->internal.get_child(node->internal.get_child_count(index)), height - 1, index); } else { - return getSign(getChild(&node->internal, 0), + return getSign(node->internal.get_child(0), height - 1, - 7 - getChildIndex(&node->internal, 0)); + 7 - node->internal.get_child_index(0)); } } } @@ -469,7 +544,7 @@ class Octree leaf->signs |= ((sign & 1) << index); } - int getSignMask(const LeafNode *leaf) + int getSignMask(const LeafNode *leaf) const { return leaf->signs; } @@ -536,7 +611,7 @@ class Octree } /// Get edge parity - int getEdgeParity(LeafNode *leaf, int index) + int getEdgeParity(const LeafNode *leaf, int index) const { assert(index >= 0 && index <= 11); @@ -597,7 +672,8 @@ class Octree leaf->primary_edge_intersections |= (1 << pindex); } - int getStoredEdgesParity(LeafNode *leaf, int pindex) + + int getStoredEdgesParity(const LeafNode *leaf, int pindex) const { assert(pindex <= 2 && pindex >= 0); @@ -652,7 +728,7 @@ class Octree InternalNode *parent = locateParent(node, len, st, count); // Update - setChild(parent, count, (Node *)leaf); + parent->set_child(count, (Node *)leaf); } void updateParent(InternalNode *node, int len, int st[3]) @@ -667,14 +743,14 @@ class Octree InternalNode *parent = locateParent(len, st, count); // UPdate - setChild(parent, count, (Node *)node); + parent->set_child(count, (Node *)node); } /// Find edge intersection on a given edge - int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) + int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) const { // First, locat the leaf - LeafNode *leaf; + const LeafNode *leaf; if (check) { leaf = locateLeafCheck(st); } @@ -697,7 +773,7 @@ class Octree } /// Retrieve number of edges intersected - int getPrimalEdgesMask(LeafNode *leaf) + int getPrimalEdgesMask(const LeafNode *leaf) const { return leaf->primary_edge_intersections; } @@ -710,7 +786,7 @@ class Octree } /// Get the count for a primary edge - int getEdgeCount(LeafNode *leaf, int index) + int getEdgeCount(const LeafNode *leaf, int index) const { return edgeCountTable[getPrimalEdgesMask(leaf)][index]; } @@ -744,7 +820,7 @@ class Octree } /// Retrieve edge intersection - float getEdgeOffset(LeafNode *leaf, int count) + float getEdgeOffset(const LeafNode *leaf, int count) const { return leaf->edge_intersections[4 * count]; } @@ -834,10 +910,11 @@ class Octree } /// Retrieve complete edge intersection - void getEdgeIntersectionByIndex(LeafNode *leaf, int index, int st[3], int len, float pt[3], float nm[3]) + void getEdgeIntersectionByIndex(const LeafNode *leaf, int index, int st[3], + int len, float pt[3], float nm[3]) const { int count = getEdgeCount(leaf, index); - float *pts = leaf->edge_intersections; + const float *pts = leaf->edge_intersections; float off = pts[4 * count]; @@ -865,7 +942,8 @@ class Octree return off; } - void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3]) + void fillEdgeIntersections(const LeafNode *leaf, int st[3], int len, + float pts[12][3], float norms[12][3]) const { int i; // int stt[3] = {0, 0, 0}; @@ -890,7 +968,7 @@ class Octree nst[i] += len; // int nstt[3] = {0, 0, 0}; // nstt[i] += 1; - LeafNode *node = locateLeaf(nst); + const LeafNode *node = locateLeaf(nst); if (e1) { // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]], norms[fmask[i][0]]); @@ -912,7 +990,7 @@ class Octree nst[i] -= len; // int nstt[3] = {1, 1, 1}; // nstt[i] -= 1; - LeafNode *node = locateLeaf(nst); + const LeafNode *node = locateLeaf(nst); // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]); getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]); @@ -921,7 +999,9 @@ class Octree } - void fillEdgeIntersections(LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3], int parity[12]) + void fillEdgeIntersections(const LeafNode *leaf, int st[3], int len, + float pts[12][3], float norms[12][3], + int parity[12]) const { int i; for (i = 0; i < 12; i++) { @@ -948,7 +1028,7 @@ class Octree nst[i] += len; // int nstt[3] = {0, 0, 0}; // nstt[i] += 1; - LeafNode *node = locateLeafCheck(nst); + const LeafNode *node = locateLeafCheck(nst); if (node == NULL) { continue; } @@ -979,7 +1059,7 @@ class Octree nst[i] -= len; // int nstt[3] = {1, 1, 1}; // nstt[i] -= 1; - LeafNode *node = locateLeafCheck(nst); + const LeafNode *node = locateLeafCheck(nst); if (node == NULL) { continue; } @@ -1088,7 +1168,20 @@ class Octree int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1)); - node = getChild(&node->internal, getChildCount(&node->internal, index)); + node = node->internal.get_child(node->internal.get_child_count(index)); + } + + return &node->leaf; + } + + const LeafNode *locateLeaf(int st[3]) const + { + const Node *node = root; + for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) { + int index = (((st[0] >> i) & 1) << 2) | + (((st[1] >> i) & 1) << 1) | + (((st[2] >> i) & 1)); + node = node->internal.get_child(node->internal.get_child_count(index)); } return &node->leaf; @@ -1102,8 +1195,7 @@ class Octree index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0)); - node = getChild(&node->internal, - getChildCount(&node->internal, index)); + node = node->internal.get_child(node->internal.get_child_count(index)); } return &node->leaf; @@ -1116,10 +1208,26 @@ class Octree int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1)); - if (!hasChild(&node->internal, index)) { + if (!node->internal.has_child(index)) { + return NULL; + } + node = node->internal.get_child(node->internal.get_child_count(index)); + } + + return &node->leaf; + } + + const LeafNode *locateLeafCheck(int st[3]) const + { + const Node *node = root; + for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) { + int index = (((st[0] >> i) & 1) << 2) | + (((st[1] >> i) & 1) << 1) | + (((st[2] >> i) & 1)); + if (!node->internal.has_child(index)) { return NULL; } - node = getChild(&node->internal, getChildCount(&node->internal, index)); + node = node->internal.get_child(node->internal.get_child_count(index)); } return &node->leaf; @@ -1135,10 +1243,10 @@ class Octree ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0)); pre = node; - node = &getChild(node, getChildCount(node, index))->internal; + node = &node->get_child(node->get_child_count(index))->internal; } - count = getChildCount(pre, index); + count = pre->get_child_count(index); return pre; } @@ -1152,88 +1260,21 @@ class Octree ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0)); pre = node; - node = (InternalNode *)getChild(node, getChildCount(node, index)); + node = &node->get_child(node->get_child_count(index))->internal; } - count = getChildCount(pre, index); + count = pre->get_child_count(index); return pre; } /************ Operators for internal nodes ************/ - /// If child index exists - int hasChild(InternalNode *node, int index) - { - return (node->has_child >> index) & 1; - } - - /// Get the pointer to child index - Node *getChild(InternalNode *node, int count) - { - return node->children[count]; - }; - - /// Get total number of children - int getNumChildren(InternalNode *node) - { - return numChildrenTable[node->has_child]; - } - - /// Get the count of children - int getChildCount(InternalNode *node, int index) - { - return childrenCountTable[node->has_child][index]; - } - int getChildIndex(InternalNode *node, int count) - { - return childrenIndexTable[node->has_child][count]; - } - int *getChildCounts(InternalNode *node) - { - return childrenCountTable[node->has_child]; - } - - /// Get all children - void fillChildren(InternalNode *node, Node *children[8], int leaf[8]) - { - int count = 0; - for (int i = 0; i < 8; i++) { - leaf[i] = node->is_child_leaf(i); - if (hasChild(node, i)) { - children[i] = getChild(node, count); - count++; - } - else { - children[i] = NULL; - leaf[i] = 0; - } - } - } - - /// Sets the child pointer - void setChild(InternalNode *node, int count, Node *chd) - { - node->children[count] = chd; - } - void setInternalChild(InternalNode *node, int index, int count, InternalNode *chd) - { - setChild(node, count, (Node *)chd); - node->has_child |= (1 << index); - } - void setLeafChild(InternalNode *node, int index, int count, LeafNode *chd) - { - setChild(node, count, (Node *)chd); - node->has_child |= (1 << index); - node->child_is_leaf |= (1 << index); - } /// Add a kid to an existing internal node - /// Fix me: can we do this without wasting memory ? - /// Fixed: using variable memory InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf) { // Create new internal node - int num = getNumChildren(node); + int num = node->get_num_children(); InternalNode *rnode = createInternal(num + 1); // Establish children @@ -1242,19 +1283,19 @@ class Octree for (i = 0; i < 8; i++) { if (i == index) { if (aLeaf) { - setLeafChild(rnode, i, count2, &child->leaf); + rnode->set_leaf_child(i, count2, &child->leaf); } else { - setInternalChild(rnode, i, count2, &child->internal); + rnode->set_internal_child(i, count2, &child->internal); } count2++; } - else if (hasChild(node, i)) { + else if (node->has_child(i)) { if (node->is_child_leaf(i)) { - setLeafChild(rnode, i, count2, &getChild(node, count1)->leaf); + rnode->set_leaf_child(i, count2, &node->get_child(count1)->leaf); } else { - setInternalChild(rnode, i, count2, &getChild(node, count1)->internal); + rnode->set_internal_child(i, count2, &node->get_child(count1)->internal); } count1++; count2++; @@ -1269,8 +1310,8 @@ class Octree InternalNode *createInternal(int length) { InternalNode *inode = (InternalNode *)alloc[length]->allocate(); - inode->has_child = 0; - inode->child_is_leaf = 0; + inode->has_child_bitfield = 0; + inode->child_is_leaf_bitfield = 0; return inode; } @@ -1301,21 +1342,21 @@ class Octree InternalNode *addLeafChild(InternalNode *par, int index, int count, LeafNode *leaf) { - int num = getNumChildren(par) + 1; + int num = par->get_num_children() + 1; InternalNode *npar = createInternal(num); *npar = *par; if (num == 1) { - setLeafChild(npar, index, 0, leaf); + npar->set_leaf_child(index, 0, leaf); } else { int i; for (i = 0; i < count; i++) { - setChild(npar, i, getChild(par, i)); + npar->set_child(i, par->get_child(i)); } - setLeafChild(npar, index, count, leaf); + npar->set_leaf_child(index, count, leaf); for (i = count + 1; i < num; i++) { - setChild(npar, i, getChild(par, i - 1)); + npar->set_child(i, par->get_child(i - 1)); } } @@ -1326,21 +1367,21 @@ class Octree InternalNode *addInternalChild(InternalNode *par, int index, int count, InternalNode *node) { - int num = getNumChildren(par) + 1; + int num = par->get_num_children() + 1; InternalNode *npar = createInternal(num); *npar = *par; if (num == 1) { - setInternalChild(npar, index, 0, node); + npar->set_internal_child(index, 0, node); } else { int i; for (i = 0; i < count; i++) { - setChild(npar, i, getChild(par, i)); + npar->set_child(i, par->get_child(i)); } - setInternalChild(npar, index, count, node); + npar->set_internal_child(index, count, node); for (i = count + 1; i < num; i++) { - setChild(npar, i, getChild(par, i - 1)); + npar->set_child(i, par->get_child(i - 1)); } } diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index 479bbd3ab0a..d46b09cf76a 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -23,40 +23,42 @@ # # ***** END GPL LICENSE BLOCK ***** +set(INC + . + ../guardedalloc + ../../source/blender/blenlib +) + +set(INC_SYS +) + +set(SRC + ocio_capi.cc + fallback_impl.cc + + ocio_capi.h + ocio_impl.h +) + if(WITH_OPENCOLORIO) - set(INC - . + add_definitions( + -DWITH_OCIO + ) + + list(APPEND INC_SYS ${OPENCOLORIO_INCLUDE_DIRS} ) - set(SRC - ocio_capi.cpp - ocio_capi.h + list(APPEND SRC + ocio_impl.cc ) if(WIN32 AND NOT MINGW) - list(APPEND INC + list(APPEND INC_SYS ${BOOST_INCLUDE_DIR} ) endif() -else() - set(INC - . - ../../source/blender/blenlib - ) - - set(SRC - ocio_capi_stub.cpp - ocio_capi.h - ) endif() -set(INC_SYS - ../guardedalloc -) - -add_definitions( -) blender_add_lib(bf_intern_opencolorio "${SRC}" "${INC}" "${INC_SYS}") - diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index fec07662735..a4d21f3e440 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -2,18 +2,18 @@ Import('env') -sources = env.Glob('*.cpp') +sources = env.Glob('*.cc') incs = '. ../guardedalloc ../../source/blender/blenlib' +defs = [] if env['WITH_BF_OCIO']: - sources.remove('ocio_capi_stub.cpp') - + defs.append('WITH_OCIO') incs += ' ' + env['BF_OCIO_INC'] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): incs += ' ' + env['BF_BOOST_INC'] else: - sources.remove('ocio_capi.cpp') + sources.remove('ocio_impl.cc') -env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), [], libtype=['extern','player'], priority=[10, 185]) +env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185]) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc new file mode 100644 index 00000000000..44c02d1442b --- /dev/null +++ b/intern/opencolorio/fallback_impl.cc @@ -0,0 +1,382 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Brecht van Lommel + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" +#include "BLI_math_color.h" + +#include "ocio_impl.h" + +#define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr*)1) + +#define PROCESSOR_LINEAR_TO_SRGB ((OCIO_ConstProcessorRcPtr*)1) +#define PROCESSOR_SRGB_TO_LINEAR ((OCIO_ConstProcessorRcPtr*)2) +#define PROCESSOR_UNKNOWN ((OCIO_ConstProcessorRcPtr*)3) + +#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr*)1) +#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr*)2) + +typedef struct OCIO_PackedImageDescription { + float *data; + long width; + long height; + long numChannels; + long chanStrideBytes; + long xStrideBytes; + long yStrideBytes; +} OCIO_PackedImageDescription; + +OCIO_ConstConfigRcPtr *FallbackImpl::getCurrentConfig(void) +{ + return CONFIG_DEFAULT; +} + +void FallbackImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *) +{ +} + +OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromEnv(void) +{ + return CONFIG_DEFAULT; +} + +OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromFile(const char *) +{ + return CONFIG_DEFAULT; +} + +void FallbackImpl::configRelease(OCIO_ConstConfigRcPtr *) +{ +} + +int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *) +{ + return 2; +} + +const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *, int index) +{ + if (index == 0) + return "Linear"; + else if (index == 1) + return "sRGB"; + + return NULL; +} + +OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *, const char *name) +{ + if (strcmp(name, "scene_linear") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "color_picking") == 0) + return COLORSPACE_SRGB; + else if (strcmp(name, "texture_paint") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "default_byte") == 0) + return COLORSPACE_SRGB; + else if (strcmp(name, "default_float") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "default_sequencer") == 0) + return COLORSPACE_SRGB; + else if (strcmp(name, "Linear") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "sRGB") == 0) + return COLORSPACE_SRGB; + + return NULL; +} + +int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name); + + if (cs == COLORSPACE_LINEAR) + return 0; + else if (cs == COLORSPACE_SRGB) + return 1; + + return -1; +} + +const char *FallbackImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *) +{ + return "sRGB"; +} + +int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr* config) +{ + return 1; +} + +const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr *, int index) +{ + if (index == 0) + return "sRGB"; + + return NULL; +} + +const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *, const char *) +{ + return "Default"; +} + +int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr *, const char *) +{ + return 1; +} + +const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr *, const char *, int index) +{ + if (index == 0) + return "Default"; + + return NULL; +} + +const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *, const char *, const char *) +{ + return "sRGB"; +} + +int FallbackImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) +{ + return 1; +} + +int FallbackImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) +{ + return 0; +} + +void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) +{ +} + +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +{ + OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName); + OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName); + + if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) + return PROCESSOR_LINEAR_TO_SRGB; + else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) + return PROCESSOR_SRGB_TO_LINEAR; + + return 0; +} + +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr *, OCIO_ConstTransformRcPtr *tfm) +{ + return (OCIO_ConstProcessorRcPtr*)tfm; +} + +void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + /* OCIO_TODO stride not respected, channels must be 3 or 4 */ + OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; + int channels = desc->numChannels; + float *pixels = desc->data; + int width = desc->width; + int height = desc->height; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + float *pixel = pixels + channels * (y * width + x); + + if (channels == 4) + processorApplyRGBA(processor, pixel); + else if (channels == 3) + processorApplyRGB(processor, pixel); + } + } +} + +void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + /* OCIO_TODO stride not respected, channels must be 3 or 4 */ + OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; + int channels = desc->numChannels; + float *pixels = desc->data; + int width = desc->width; + int height = desc->height; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + float *pixel = pixels + channels * (y * width + x); + + if (channels == 4) + processorApplyRGBA_predivide(processor, pixel); + else if (channels == 3) + processorApplyRGB(processor, pixel); + } + } +} + +void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (processor == PROCESSOR_LINEAR_TO_SRGB) + linearrgb_to_srgb_v3_v3(pixel, pixel); + else if (processor == PROCESSOR_SRGB_TO_LINEAR) + srgb_to_linearrgb_v3_v3(pixel, pixel); +} + +void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (processor == PROCESSOR_LINEAR_TO_SRGB) + linearrgb_to_srgb_v4(pixel, pixel); + else if (processor == PROCESSOR_SRGB_TO_LINEAR) + srgb_to_linearrgb_v4(pixel, pixel); +} + +void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (pixel[3] == 1.0f || pixel[3] == 0.0f) { + processorApplyRGBA(processor, pixel); + } + else { + float alpha, inv_alpha; + + alpha = pixel[3]; + inv_alpha = 1.0f / alpha; + + pixel[0] *= inv_alpha; + pixel[1] *= inv_alpha; + pixel[2] *= inv_alpha; + + processorApplyRGBA(processor, pixel); + + pixel[0] *= alpha; + pixel[1] *= alpha; + pixel[2] *= alpha; + } +} + +void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *) +{ +} + +const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) +{ + if (cs == COLORSPACE_LINEAR) + return "Linear"; + else if (cs == COLORSPACE_SRGB) + return "sRGB"; + + return NULL; +} + +const char *FallbackImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *) +{ + return ""; +} + +const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *) +{ + return ""; +} + +OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void) +{ + return (OCIO_DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB; +} + +void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *, const char *) +{ +} + +void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *, const char *) +{ +} + +void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr *, const char *) +{ +} + +void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *, OCIO_ConstTransformRcPtr *) +{ +} + +void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *, OCIO_ConstTransformRcPtr *) +{ +} + +void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *) +{ +} + +OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) +{ + OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription"); + + desc->data = data; + desc->width = width; + desc->height = height; + desc->numChannels = numChannels; + desc->chanStrideBytes = chanStrideBytes; + desc->xStrideBytes = xStrideBytes; + desc->yStrideBytes = yStrideBytes; + + return (OCIO_PackedImageDesc*)desc; +} + +void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +{ + MEM_freeN(id); +} + +OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void) +{ + return (OCIO_ExponentTransformRcPtr*)PROCESSOR_UNKNOWN; +} + +void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *, const float *) +{ +} + +void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *) +{ +} + +OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void) +{ + return (OCIO_MatrixTransformRcPtr*)PROCESSOR_UNKNOWN; +} + +void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *, const float *, const float *) +{ +} + +void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *) +{ +} + +void FallbackImpl::matrixTransformScale(float * , float * , const float *) +{ +} diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc new file mode 100644 index 00000000000..18fa4b7cb1b --- /dev/null +++ b/intern/opencolorio/ocio_capi.cc @@ -0,0 +1,284 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +static IOCIOImpl *impl = NULL; + +void OCIO_init(void) +{ +#ifdef WITH_OCIO + impl = new OCIOImpl(); +#else + impl = new FallbackImpl(); +#endif +} + +void OCIO_exit(void) +{ + delete impl; + impl = NULL; +} + +OCIO_ConstConfigRcPtr *OCIO_getCurrentConfig(void) +{ + return impl->getCurrentConfig(); +} + +OCIO_ConstConfigRcPtr *OCIO_configCreateFallback(void) +{ + delete impl; + impl = new FallbackImpl(); + + return impl->getCurrentConfig(); +} + +void OCIO_setCurrentConfig(const OCIO_ConstConfigRcPtr *config) +{ + impl->setCurrentConfig(config); +} + +OCIO_ConstConfigRcPtr *OCIO_configCreateFromEnv(void) +{ + return impl->configCreateFromEnv(); +} + +OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename) +{ + return impl->configCreateFromFile(filename); +} + +void OCIO_configRelease(OCIO_ConstConfigRcPtr *config) +{ + impl->configRelease(config); +} + +int OCIO_configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) +{ + return impl->configGetNumColorSpaces(config); +} + +const char *OCIO_configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) +{ + return impl->configGetColorSpaceNameByIndex(config, index); +} + +OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + return impl->configGetColorSpace(config, name); +} + +int OCIO_configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + return impl->configGetIndexForColorSpace(config, name); +} + +const char *OCIO_configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) +{ + return impl->configGetDefaultDisplay(config); +} + +int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr* config) +{ + return impl->configGetNumDisplays(config); +} + +const char *OCIO_configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) +{ + return impl->configGetDisplay(config, index); +} + +const char *OCIO_configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) +{ + return impl->configGetDefaultView(config, display); +} + +int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) +{ + return impl->configGetNumViews(config, display); +} + +const char *OCIO_configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) +{ + return impl->configGetView(config, display, index); +} + +const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) +{ + return impl->configGetDisplayColorSpaceName(config, display, view); +} + +int OCIO_colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceIsInvertible(cs); +} + +int OCIO_colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceIsData(cs); +} + +void OCIO_colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) +{ + impl->colorSpaceRelease(cs); +} + +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +{ + return impl->configGetProcessorWithNames(config, srcName, dstName); +} + +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) +{ + return impl->configGetProcessor(config, transform); +} + +void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + impl->processorApply(processor, img); +} + +void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + impl->processorApply_predivide(processor, img); +} + +void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + impl->processorApplyRGB(processor, pixel); +} + +void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + impl->processorApplyRGBA(processor, pixel); +} + +void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + impl->processorApplyRGBA_predivide(processor, pixel); +} + +void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p) +{ + impl->processorRelease(p); +} + +const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceGetName(cs); +} + +const char *OCIO_colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceGetDescription(cs); +} + +const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceGetFamily(cs); +} + +OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void) +{ + return impl->createDisplayTransform(); +} + +void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + impl->displayTransformSetInputColorSpaceName(dt, name); +} + +void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + impl->displayTransformSetDisplay(dt, name); +} + +void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + impl->displayTransformSetView(dt, name); +} + +void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + impl->displayTransformSetDisplayCC(dt, t); +} + +void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + impl->displayTransformSetLinearCC(dt, t); +} + +void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) +{ + impl->displayTransformRelease(dt); +} + +OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) +{ + return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); +} + +void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +{ + impl->OCIO_PackedImageDescRelease(id); +} + +OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void) +{ + return impl->createExponentTransform(); +} + +void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) +{ + impl->exponentTransformSetValue(et, exponent); +} + +void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) +{ + impl->exponentTransformRelease(et); +} + +OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void) +{ + return impl->createMatrixTransform(); +} + +void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4) +{ + impl->matrixTransformSetValue(mt, m44, offset4); +} + +void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) +{ + impl->matrixTransformRelease(mt); +} + +void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4f) +{ + impl->matrixTransformScale(m44, offset4, scale4f); +} diff --git a/intern/opencolorio/ocio_capi.cpp b/intern/opencolorio/ocio_capi.cpp deleted file mode 100644 index 152b537ab9b..00000000000 --- a/intern/opencolorio/ocio_capi.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* - * ***** 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) 2012 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Xavier Thomas - * Lukas Toene, - * Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <iostream> -#include <string.h> - -#include <OpenColorIO/OpenColorIO.h> - -#include "MEM_guardedalloc.h" - -#define OCIO_CAPI_IMPLEMENTATION -#include "ocio_capi.h" - -#if !defined(WITH_ASSERT_ABORT) -# define OCIO_abort() -#else -# include <stdlib.h> -# define OCIO_abort() abort() -#endif - -#if defined(_MSC_VER) -# define __func__ __FUNCTION__ -#endif - -#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() -#define MEM_DELETE(what, type) if(what) { what->~type(); MEM_freeN(what); } (void)0 - -static void OCIO_reportError(const char *err) -{ - std::cerr << "OpenColorIO Error: " << err << std::endl; - - OCIO_abort(); -} - -static void OCIO_reportException(Exception &exception) -{ - OCIO_reportError(exception.what()); -} - -ConstConfigRcPtr *OCIO_getCurrentConfig(void) -{ - ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); - - try { - *config = GetCurrentConfig(); - - if(*config) - return config; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(config, ConstConfigRcPtr); - - return NULL; -} - -ConstConfigRcPtr *OCIO_getDefaultConfig(void) -{ - return NULL; -} - -void OCIO_setCurrentConfig(const ConstConfigRcPtr *config) -{ - try { - SetCurrentConfig(*config); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } -} - -ConstConfigRcPtr *OCIO_configCreateFromEnv(void) -{ - ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); - - try { - *config = Config::CreateFromEnv(); - - if (*config) - return config; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(config, ConstConfigRcPtr); - - return NULL; -} - - -ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename) -{ - ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); - - try { - *config = Config::CreateFromFile(filename); - - if (*config) - return config; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(config, ConstConfigRcPtr); - - return NULL; -} - -void OCIO_configRelease(ConstConfigRcPtr *config) -{ - MEM_DELETE(config, ConstConfigRcPtr); -} - -int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *config) -{ - try { - return (*config)->getNumColorSpaces(); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return 0; -} - -const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *config, int index) -{ - try { - return (*config)->getColorSpaceNameByIndex(index); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *config, const char *name) -{ - ConstColorSpaceRcPtr *cs = MEM_NEW(ConstColorSpaceRcPtr); - - try { - *cs = (*config)->getColorSpace(name); - - if (*cs) - return cs; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(cs, ConstColorSpaceRcPtr); - - return NULL; -} - -int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name) -{ - try { - return (*config)->getIndexForColorSpace(name); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return -1; -} - -const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *config) -{ - try { - return (*config)->getDefaultDisplay(); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -int OCIO_configGetNumDisplays(ConstConfigRcPtr* config) -{ - try { - return (*config)->getNumDisplays(); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return 0; -} - -const char *OCIO_configGetDisplay(ConstConfigRcPtr *config, int index) -{ - try { - return (*config)->getDisplay(index); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -const char *OCIO_configGetDefaultView(ConstConfigRcPtr *config, const char *display) -{ - try { - return (*config)->getDefaultView(display); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -int OCIO_configGetNumViews(ConstConfigRcPtr *config, const char *display) -{ - try { - return (*config)->getNumViews(display); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return 0; -} - -const char *OCIO_configGetView(ConstConfigRcPtr *config, const char *display, int index) -{ - try { - return (*config)->getView(display, index); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *config, const char *display, const char *view) -{ - try { - return (*config)->getDisplayColorSpaceName(display, view); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs) -{ - const char *family = (*cs)->getFamily(); - - if (!strcmp(family, "rrt") || !strcmp(family, "display")) { - /* assume display and rrt transformations are not invertible - * in fact some of them could be, but it doesn't make much sense to allow use them as invertible - */ - return false; - } - - if ((*cs)->isData()) { - /* data color spaces don't have transformation at all */ - return true; - } - - if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) { - /* if there's defined transform to reference space, color space could be converted to scene linear */ - return true; - } - - return true; -} - -int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs) -{ - return ((*cs)->isData()); -} - -void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs) -{ - MEM_DELETE(cs, ConstColorSpaceRcPtr); -} - -ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName) -{ - ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); - - try { - *p = (*config)->getProcessor(srcName, dstName); - - if (*p) - return p; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(p, ConstProcessorRcPtr); - - return 0; -} - -ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *config, ConstTransformRcPtr *transform) -{ - ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); - - try { - *p = (*config)->getProcessor(*transform); - - if (*p) - return p; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(p, ConstProcessorRcPtr); - - return NULL; -} - -void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - try { - (*processor)->apply(*img); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } -} - -void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - try { - int channels = img->getNumChannels(); - - if (channels == 4) { - float *pixels = img->getData(); - - int width = img->getWidth(); - int height = img->getHeight(); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - float *pixel = pixels + 4 * (y * width + x); - - OCIO_processorApplyRGBA_predivide(processor, pixel); - } - } - } - else { - (*processor)->apply(*img); - } - } - catch (Exception &exception) { - OCIO_reportException(exception); - } -} - -void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel) -{ - (*processor)->applyRGB(pixel); -} - -void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel) -{ - (*processor)->applyRGBA(pixel); -} - -void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel) -{ - if (pixel[3] == 1.0f || pixel[3] == 0.0f) { - (*processor)->applyRGBA(pixel); - } - else { - float alpha, inv_alpha; - - alpha = pixel[3]; - inv_alpha = 1.0f / alpha; - - pixel[0] *= inv_alpha; - pixel[1] *= inv_alpha; - pixel[2] *= inv_alpha; - - (*processor)->applyRGBA(pixel); - - pixel[0] *= alpha; - pixel[1] *= alpha; - pixel[2] *= alpha; - } -} - -void OCIO_processorRelease(ConstProcessorRcPtr *p) -{ - p->~ConstProcessorRcPtr(); - MEM_freeN(p); -} - -const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs) -{ - return (*cs)->getName(); -} - -const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *cs) -{ - return (*cs)->getDescription(); -} - -const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *cs) -{ - return (*cs)->getFamily(); -} - -DisplayTransformRcPtr *OCIO_createDisplayTransform(void) -{ - DisplayTransformRcPtr *dt = MEM_NEW(DisplayTransformRcPtr); - - *dt = DisplayTransform::Create(); - - return dt; -} - -void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *dt, const char *name) -{ - (*dt)->setInputColorSpaceName(name); -} - -void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *dt, const char *name) -{ - (*dt)->setDisplay(name); -} - -void OCIO_displayTransformSetView(DisplayTransformRcPtr *dt, const char *name) -{ - (*dt)->setView(name); -} - -void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *t) -{ - (*dt)->setDisplayCC(*t); -} - -void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *t) -{ - (*dt)->setLinearCC(*t); -} - -void OCIO_displayTransformRelease(DisplayTransformRcPtr *dt) -{ - MEM_DELETE(dt, DisplayTransformRcPtr); -} - -PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) -{ - try { - void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__); - PackedImageDesc *id = new(mem) PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); - - return id; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -void OCIO_packedImageDescRelease(PackedImageDesc* id) -{ - MEM_DELETE(id, PackedImageDesc); -} - -ExponentTransformRcPtr *OCIO_createExponentTransform(void) -{ - ExponentTransformRcPtr *et = MEM_NEW(ExponentTransformRcPtr); - - *et = ExponentTransform::Create(); - - return et; -} - -void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *et, const float *exponent) -{ - (*et)->setValue(exponent); -} - -void OCIO_exponentTransformRelease(ExponentTransformRcPtr *et) -{ - MEM_DELETE(et, ExponentTransformRcPtr); -} - -MatrixTransformRcPtr *OCIO_createMatrixTransform(void) -{ - MatrixTransformRcPtr *mt = MEM_NEW(MatrixTransformRcPtr); - - *mt = MatrixTransform::Create(); - - return mt; -} - -void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *mt, const float *m44, const float *offset4) -{ - (*mt)->setValue(m44, offset4); -} - -void OCIO_matrixTransformRelease(MatrixTransformRcPtr *mt) -{ - MEM_DELETE(mt, MatrixTransformRcPtr); -} - -void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4f) -{ - MatrixTransform::Scale(m44, offset4, scale4f); -} diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 0218ccfafcd..0ce5f8a1456 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -28,98 +28,94 @@ #ifndef __OCIO_CAPI_H__ #define __OCIO_CAPI_H__ - - #ifdef __cplusplus -using namespace OCIO_NAMESPACE; extern "C" { #endif #define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name - -#ifndef OCIO_CAPI_IMPLEMENTATION - #define OCIO_ROLE_SCENE_LINEAR "scene_linear" - #define OCIO_ROLE_COLOR_PICKING "color_picking" - #define OCIO_ROLE_TEXTURE_PAINT "texture_paint" - #define OCIO_ROLE_DEFAULT_BYTE "default_byte" - #define OCIO_ROLE_DEFAULT_FLOAT "default_float" - #define OCIO_ROLE_DEFAULT_SEQUENCER "default_sequencer" - - OCIO_DECLARE_HANDLE(ConstConfigRcPtr); - OCIO_DECLARE_HANDLE(ConstColorSpaceRcPtr); - OCIO_DECLARE_HANDLE(ConstProcessorRcPtr); - OCIO_DECLARE_HANDLE(ConstContextRcPtr); - OCIO_DECLARE_HANDLE(PackedImageDesc); - OCIO_DECLARE_HANDLE(DisplayTransformRcPtr); - OCIO_DECLARE_HANDLE(ConstTransformRcPtr); - OCIO_DECLARE_HANDLE(ExponentTransformRcPtr); - OCIO_DECLARE_HANDLE(MatrixTransformRcPtr); -#endif - - -ConstConfigRcPtr *OCIO_getCurrentConfig(void); -ConstConfigRcPtr *OCIO_getDefaultConfig(void); -void OCIO_setCurrentConfig(const ConstConfigRcPtr *config); - -ConstConfigRcPtr *OCIO_configCreateFromEnv(void); -ConstConfigRcPtr *OCIO_configCreateFromFile(const char* filename); - -void OCIO_configRelease(ConstConfigRcPtr *config); - -int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *config); -const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *config, int index); -ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *config, const char *name); -int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name); - -int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs); -int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs); - -void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs); - -const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *config); -int OCIO_configGetNumDisplays(ConstConfigRcPtr *config); -const char *OCIO_configGetDisplay(ConstConfigRcPtr *config, int index); -const char *OCIO_configGetDefaultView(ConstConfigRcPtr *config, const char *display); -int OCIO_configGetNumViews(ConstConfigRcPtr *config, const char *display); -const char *OCIO_configGetView(ConstConfigRcPtr *config, const char *display, int index); -const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *config, const char *display, const char *view); - -ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName); -ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *config, ConstTransformRcPtr *transform); - -void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img); -void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img); -void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel); -void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel); -void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel); - -void OCIO_processorRelease(ConstProcessorRcPtr *p); - -const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs); -const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *cs); -const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *cs); - -DisplayTransformRcPtr *OCIO_createDisplayTransform(void); -void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *dt, const char *name); -void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *dt, const char *name); -void OCIO_displayTransformSetView(DisplayTransformRcPtr *dt, const char *name); -void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *et); -void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *et); -void OCIO_displayTransformRelease(DisplayTransformRcPtr *dt); - -PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels, +#define OCIO_ROLE_SCENE_LINEAR "scene_linear" +#define OCIO_ROLE_COLOR_PICKING "color_picking" +#define OCIO_ROLE_TEXTURE_PAINT "texture_paint" +#define OCIO_ROLE_DEFAULT_BYTE "default_byte" +#define OCIO_ROLE_DEFAULT_FLOAT "default_float" +#define OCIO_ROLE_DEFAULT_SEQUENCER "default_sequencer" + +OCIO_DECLARE_HANDLE(OCIO_ConstConfigRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstColorSpaceRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstProcessorRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstContextRcPtr); +OCIO_DECLARE_HANDLE(OCIO_PackedImageDesc); +OCIO_DECLARE_HANDLE(OCIO_DisplayTransformRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstTransformRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ExponentTransformRcPtr); +OCIO_DECLARE_HANDLE(OCIO_MatrixTransformRcPtr); + +void OCIO_init(void); +void OCIO_exit(void); + +OCIO_ConstConfigRcPtr *OCIO_getCurrentConfig(void); +void OCIO_setCurrentConfig(const OCIO_ConstConfigRcPtr *config); + +OCIO_ConstConfigRcPtr *OCIO_configCreateFromEnv(void); +OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char* filename); +OCIO_ConstConfigRcPtr *OCIO_configCreateFallback(void); + +void OCIO_configRelease(OCIO_ConstConfigRcPtr *config); + +int OCIO_configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config); +const char *OCIO_configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index); +OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); +int OCIO_configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + +int OCIO_colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs); +int OCIO_colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs); + +void OCIO_colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs); + +const char *OCIO_configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config); +int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr *config); +const char *OCIO_configGetDisplay(OCIO_ConstConfigRcPtr *config, int index); +const char *OCIO_configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display); +int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display); +const char *OCIO_configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index); +const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view); + +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName); +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform); + +void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); +void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); +void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel); +void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel); +void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel); + +void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p); + +const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs); +const char *OCIO_colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs); +const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs); + +OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void); +void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name); +void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name); +void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name); +void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); +void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); +void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); + +OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, long chanStrideBytes, long xStrideBytes, long yStrideBytes); -void OCIO_packedImageDescRelease(PackedImageDesc *p); +void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); -ExponentTransformRcPtr *OCIO_createExponentTransform(void); -void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *et, const float *exponent); -void OCIO_exponentTransformRelease(ExponentTransformRcPtr *et); +OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void); +void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); +void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et); -MatrixTransformRcPtr *OCIO_createMatrixTransform(void); -void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *et, const float *m44, const float *offset4); -void OCIO_matrixTransformRelease(MatrixTransformRcPtr *mt); +OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void); +void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4); +void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4); @@ -127,4 +123,4 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale } #endif -#endif //OCIO_CAPI_H +#endif /* OCIO_CAPI_H */ diff --git a/intern/opencolorio/ocio_capi_stub.cpp b/intern/opencolorio/ocio_capi_stub.cpp deleted file mode 100644 index 2112b88ad72..00000000000 --- a/intern/opencolorio/ocio_capi_stub.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * ***** 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) 2012 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Brecht van Lommel - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <string.h> - -#include "MEM_guardedalloc.h" -#include "BLI_math_color.h" - -namespace OCIO_NAMESPACE {}; - -#include "ocio_capi.h" - -#define CONFIG_DEFAULT ((ConstConfigRcPtr*)1) - -#define PROCESSOR_LINEAR_TO_SRGB ((ConstProcessorRcPtr*)1) -#define PROCESSOR_SRGB_TO_LINEAR ((ConstProcessorRcPtr*)2) -#define PROCESSOR_UNKNOWN ((ConstProcessorRcPtr*)3) - -#define COLORSPACE_LINEAR ((ConstColorSpaceRcPtr*)1) -#define COLORSPACE_SRGB ((ConstColorSpaceRcPtr*)2) - -typedef struct PackedImageDescription { - float *data; - long width; - long height; - long numChannels; - long chanStrideBytes; - long xStrideBytes; - long yStrideBytes; -} PackedImageDescription; - -ConstConfigRcPtr *OCIO_getCurrentConfig(void) -{ - return CONFIG_DEFAULT; -} - -ConstConfigRcPtr *OCIO_getDefaultConfig(void) -{ - return CONFIG_DEFAULT; -} - -void OCIO_setCurrentConfig(const ConstConfigRcPtr *) -{ -} - -ConstConfigRcPtr *OCIO_configCreateFromEnv(void) -{ - return CONFIG_DEFAULT; -} - -ConstConfigRcPtr *OCIO_configCreateFromFile(const char *) -{ - return CONFIG_DEFAULT; -} - -void OCIO_configRelease(ConstConfigRcPtr *) -{ -} - -int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *) -{ - return 2; -} - -const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *, int index) -{ - if (index == 0) - return "Linear"; - else if (index == 1) - return "sRGB"; - - return NULL; -} - -ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *, const char *name) -{ - if (strcmp(name, "scene_linear") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "color_picking") == 0) - return COLORSPACE_SRGB; - else if (strcmp(name, "texture_paint") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "default_byte") == 0) - return COLORSPACE_SRGB; - else if (strcmp(name, "default_float") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "default_sequencer") == 0) - return COLORSPACE_SRGB; - else if (strcmp(name, "Linear") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "sRGB") == 0) - return COLORSPACE_SRGB; - - return NULL; -} - -int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name) -{ - ConstColorSpaceRcPtr *cs = OCIO_configGetColorSpace(config, name); - - if (cs == COLORSPACE_LINEAR) - return 0; - else if (cs == COLORSPACE_SRGB) - return 1; - - return -1; -} - -const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *) -{ - return "sRGB"; -} - -int OCIO_configGetNumDisplays(ConstConfigRcPtr* config) -{ - return 1; -} - -const char *OCIO_configGetDisplay(ConstConfigRcPtr *, int index) -{ - if (index == 0) - return "sRGB"; - - return NULL; -} - -const char *OCIO_configGetDefaultView(ConstConfigRcPtr *, const char *) -{ - return "Default"; -} - -int OCIO_configGetNumViews(ConstConfigRcPtr *, const char *) -{ - return 1; -} - -const char *OCIO_configGetView(ConstConfigRcPtr *, const char *, int index) -{ - if (index == 0) - return "Default"; - - return NULL; -} - -const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *, const char *, const char *) -{ - return "sRGB"; -} - -int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs) -{ - return 1; -} - -int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs) -{ - return 0; -} - -void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs) -{ -} - -ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName) -{ - ConstColorSpaceRcPtr *cs_src = OCIO_configGetColorSpace(config, srcName); - ConstColorSpaceRcPtr *cs_dst = OCIO_configGetColorSpace(config, dstName); - - if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) - return PROCESSOR_LINEAR_TO_SRGB; - else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) - return PROCESSOR_SRGB_TO_LINEAR; - - return 0; -} - -ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *, ConstTransformRcPtr *tfm) -{ - return (ConstProcessorRcPtr*)tfm; -} - -void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - /* OCIO_TODO stride not respected, channels must be 3 or 4 */ - PackedImageDescription *desc = (PackedImageDescription*)img; - int channels = desc->numChannels; - float *pixels = desc->data; - int width = desc->width; - int height = desc->height; - int x, y; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float *pixel = pixels + channels * (y * width + x); - - if (channels == 4) - OCIO_processorApplyRGBA(processor, pixel); - else if (channels == 3) - OCIO_processorApplyRGB(processor, pixel); - } - } -} - -void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - /* OCIO_TODO stride not respected, channels must be 3 or 4 */ - PackedImageDescription *desc = (PackedImageDescription*)img; - int channels = desc->numChannels; - float *pixels = desc->data; - int width = desc->width; - int height = desc->height; - int x, y; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float *pixel = pixels + channels * (y * width + x); - - if (channels == 4) - OCIO_processorApplyRGBA_predivide(processor, pixel); - else if (channels == 3) - OCIO_processorApplyRGB(processor, pixel); - } - } -} - -void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel) -{ - if (processor == PROCESSOR_LINEAR_TO_SRGB) - linearrgb_to_srgb_v3_v3(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) - srgb_to_linearrgb_v3_v3(pixel, pixel); -} - -void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel) -{ - if (processor == PROCESSOR_LINEAR_TO_SRGB) - linearrgb_to_srgb_v4(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) - srgb_to_linearrgb_v4(pixel, pixel); -} - -void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel) -{ - if (pixel[3] == 1.0f || pixel[3] == 0.0f) { - OCIO_processorApplyRGBA(processor, pixel); - } - else { - float alpha, inv_alpha; - - alpha = pixel[3]; - inv_alpha = 1.0f / alpha; - - pixel[0] *= inv_alpha; - pixel[1] *= inv_alpha; - pixel[2] *= inv_alpha; - - OCIO_processorApplyRGBA(processor, pixel); - - pixel[0] *= alpha; - pixel[1] *= alpha; - pixel[2] *= alpha; - } -} - -void OCIO_processorRelease(ConstProcessorRcPtr *) -{ -} - -const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs) -{ - if (cs == COLORSPACE_LINEAR) - return "Linear"; - else if (cs == COLORSPACE_SRGB) - return "sRGB"; - - return NULL; -} - -const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *) -{ - return ""; -} - -const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *) -{ - return ""; -} - -DisplayTransformRcPtr *OCIO_createDisplayTransform(void) -{ - return (DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB; -} - -void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *, const char *) -{ -} - -void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *, const char *) -{ -} - -void OCIO_displayTransformSetView(DisplayTransformRcPtr *, const char *) -{ -} - -void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *, ConstTransformRcPtr *) -{ -} - -void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *, ConstTransformRcPtr *) -{ -} - -void OCIO_displayTransformRelease(DisplayTransformRcPtr *) -{ -} - -PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) -{ - PackedImageDescription *desc = (PackedImageDescription*)MEM_callocN(sizeof(PackedImageDescription), "PackedImageDescription"); - - desc->data = data; - desc->width = width; - desc->height = height; - desc->numChannels = numChannels; - desc->chanStrideBytes = chanStrideBytes; - desc->xStrideBytes = xStrideBytes; - desc->yStrideBytes = yStrideBytes; - - return (PackedImageDesc*)desc; -} - -void OCIO_packedImageDescRelease(PackedImageDesc* id) -{ - MEM_freeN(id); -} - -ExponentTransformRcPtr *OCIO_createExponentTransform(void) -{ - return (ExponentTransformRcPtr*)PROCESSOR_UNKNOWN; -} - -void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *, const float *) -{ -} - -void OCIO_exponentTransformRelease(ExponentTransformRcPtr *) -{ -} - -MatrixTransformRcPtr *OCIO_createMatrixTransform(void) -{ - return (MatrixTransformRcPtr*)PROCESSOR_UNKNOWN; -} - -void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *, const float *, const float *) -{ -} - -void OCIO_matrixTransformRelease(MatrixTransformRcPtr *) -{ -} - -void OCIO_matrixTransformScale(float * , float * , const float *) -{ -} - diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc new file mode 100644 index 00000000000..49fc44d1e12 --- /dev/null +++ b/intern/opencolorio/ocio_impl.cc @@ -0,0 +1,544 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Xavier Thomas + * Lukas Toene, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <iostream> +#include <string.h> + +#include <OpenColorIO/OpenColorIO.h> + +using namespace OCIO_NAMESPACE; + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +#if !defined(WITH_ASSERT_ABORT) +# define OCIO_abort() +#else +# include <stdlib.h> +# define OCIO_abort() abort() +#endif + +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ +#endif + +#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() +#define MEM_DELETE(what, type) if(what) { (what)->~type(); MEM_freeN(what); } (void)0 + +static void OCIO_reportError(const char *err) +{ + std::cerr << "OpenColorIO Error: " << err << std::endl; + + OCIO_abort(); +} + +static void OCIO_reportException(Exception &exception) +{ + OCIO_reportError(exception.what()); +} + +OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void) +{ + ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); + + try { + *config = GetCurrentConfig(); + + if (*config) + return (OCIO_ConstConfigRcPtr *) config; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(config, ConstConfigRcPtr); + + return NULL; +} + +void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config) +{ + try { + SetCurrentConfig(*(ConstConfigRcPtr *) config); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } +} + +OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void) +{ + ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); + + try { + *config = Config::CreateFromEnv(); + + if (*config) + return (OCIO_ConstConfigRcPtr *) config; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(config, ConstConfigRcPtr); + + return NULL; +} + + +OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename) +{ + ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); + + try { + *config = Config::CreateFromFile(filename); + + if (*config) + return (OCIO_ConstConfigRcPtr *) config; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(config, ConstConfigRcPtr); + + return NULL; +} + +void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config) +{ + MEM_DELETE((ConstConfigRcPtr *) config, ConstConfigRcPtr); +} + +int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) +{ + try { + return (*(ConstConfigRcPtr *) config)->getNumColorSpaces(); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return 0; +} + +const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) +{ + try { + return (*(ConstConfigRcPtr *) config)->getColorSpaceNameByIndex(index); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + ConstColorSpaceRcPtr *cs = MEM_NEW(ConstColorSpaceRcPtr); + + try { + *cs = (*(ConstConfigRcPtr *) config)->getColorSpace(name); + + if (*cs) + return (OCIO_ConstColorSpaceRcPtr *) cs; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(cs, ConstColorSpaceRcPtr); + + return NULL; +} + +int OCIOImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + try { + return (*(ConstConfigRcPtr *) config)->getIndexForColorSpace(name); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return -1; +} + +const char *OCIOImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDefaultDisplay(); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +int OCIOImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr* config) +{ + try { + return (*(ConstConfigRcPtr *) config)->getNumDisplays(); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return 0; +} + +const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDisplay(index); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDefaultView(display); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +int OCIOImpl::configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) +{ + try { + return (*(ConstConfigRcPtr *) config)->getNumViews(display); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return 0; +} + +const char *OCIOImpl::configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) +{ + try { + return (*(ConstConfigRcPtr *) config)->getView(display, index); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDisplayColorSpaceName(display, view); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_) +{ + ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *) cs_; + const char *family = (*cs)->getFamily(); + + if (!strcmp(family, "rrt") || !strcmp(family, "display")) { + /* assume display and rrt transformations are not invertible + * in fact some of them could be, but it doesn't make much sense to allow use them as invertible + */ + return false; + } + + if ((*cs)->isData()) { + /* data color spaces don't have transformation at all */ + return true; + } + + if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) { + /* if there's defined transform to reference space, color space could be converted to scene linear */ + return true; + } + + return true; +} + +int OCIOImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *) cs)->isData(); +} + +void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) +{ + MEM_DELETE((ConstColorSpaceRcPtr *) cs, ConstColorSpaceRcPtr); +} + +OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +{ + ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); + + try { + *p = (*(ConstConfigRcPtr *) config)->getProcessor(srcName, dstName); + + if (*p) + return (OCIO_ConstProcessorRcPtr *) p; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(p, ConstProcessorRcPtr); + + return 0; +} + +OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) +{ + ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); + + try { + *p = (*(ConstConfigRcPtr *) config)->getProcessor(*(ConstTransformRcPtr *) transform); + + if (*p) + return (OCIO_ConstProcessorRcPtr *) p; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(p, ConstProcessorRcPtr); + + return NULL; +} + +void OCIOImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + try { + (*(ConstProcessorRcPtr *) processor)->apply(*(PackedImageDesc *) img); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } +} + +void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img_) +{ + try { + PackedImageDesc *img = (PackedImageDesc *) img_; + int channels = img->getNumChannels(); + + if (channels == 4) { + float *pixels = img->getData(); + + int width = img->getWidth(); + int height = img->getHeight(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + float *pixel = pixels + 4 * (y * width + x); + + processorApplyRGBA_predivide(processor, pixel); + } + } + } + else { + (*(ConstProcessorRcPtr *) processor)->apply(*img); + } + } + catch (Exception &exception) { + OCIO_reportException(exception); + } +} + +void OCIOImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + (*(ConstProcessorRcPtr *) processor)->applyRGB(pixel); +} + +void OCIOImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel); +} + +void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (pixel[3] == 1.0f || pixel[3] == 0.0f) { + (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel); + } + else { + float alpha, inv_alpha; + + alpha = pixel[3]; + inv_alpha = 1.0f / alpha; + + pixel[0] *= inv_alpha; + pixel[1] *= inv_alpha; + pixel[2] *= inv_alpha; + + (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel); + + pixel[0] *= alpha; + pixel[1] *= alpha; + pixel[2] *= alpha; + } +} + +void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *p) +{ + p->~OCIO_ConstProcessorRcPtr(); + MEM_freeN(p); +} + +const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *) cs)->getName(); +} + +const char *OCIOImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *) cs)->getDescription(); +} + +const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *)cs)->getFamily(); +} + +OCIO_DisplayTransformRcPtr *OCIOImpl::createDisplayTransform(void) +{ + DisplayTransformRcPtr *dt = MEM_NEW(DisplayTransformRcPtr); + + *dt = DisplayTransform::Create(); + + return (OCIO_DisplayTransformRcPtr *) dt; +} + +void OCIOImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + (*(DisplayTransformRcPtr *) dt)->setInputColorSpaceName(name); +} + +void OCIOImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + (*(DisplayTransformRcPtr *) dt)->setDisplay(name); +} + +void OCIOImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + (*(DisplayTransformRcPtr *) dt)->setView(name); +} + +void OCIOImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + (*(DisplayTransformRcPtr *) dt)->setDisplayCC(* (ConstTransformRcPtr *) t); +} + +void OCIOImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + (*(DisplayTransformRcPtr *) dt)->setLinearCC(*(ConstTransformRcPtr *) t); +} + +void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) +{ + MEM_DELETE((DisplayTransformRcPtr *) dt, DisplayTransformRcPtr); +} + +OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) +{ + try { + void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__); + PackedImageDesc *id = new(mem) PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); + + return (OCIO_PackedImageDesc *) id; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +{ + MEM_DELETE((PackedImageDesc *) id, PackedImageDesc); +} + +OCIO_ExponentTransformRcPtr *OCIOImpl::createExponentTransform(void) +{ + ExponentTransformRcPtr *et = MEM_NEW(ExponentTransformRcPtr); + + *et = ExponentTransform::Create(); + + return (OCIO_ExponentTransformRcPtr *) et; +} + +void OCIOImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) +{ + (*(ExponentTransformRcPtr *) et)->setValue(exponent); +} + +void OCIOImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) +{ + MEM_DELETE((ExponentTransformRcPtr *) et, ExponentTransformRcPtr); +} + +OCIO_MatrixTransformRcPtr *OCIOImpl::createMatrixTransform(void) +{ + MatrixTransformRcPtr *mt = MEM_NEW(MatrixTransformRcPtr); + + *mt = MatrixTransform::Create(); + + return (OCIO_MatrixTransformRcPtr *) mt; +} + +void OCIOImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4) +{ + (*(MatrixTransformRcPtr *) mt)->setValue(m44, offset4); +} + +void OCIOImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) +{ + MEM_DELETE((MatrixTransformRcPtr *) mt, MatrixTransformRcPtr); +} + +void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *scale4f) +{ + MatrixTransform::Scale(m44, offset4, scale4f); +} diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h new file mode 100644 index 00000000000..64cf5ec3322 --- /dev/null +++ b/intern/opencolorio/ocio_impl.h @@ -0,0 +1,240 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __OCIO_IMPL_H__ +#define __OCIO_IMPL_H__ + +#include "ocio_capi.h" + +class IOCIOImpl { +public: + virtual ~IOCIOImpl() {}; + + virtual OCIO_ConstConfigRcPtr *getCurrentConfig(void) = 0; + virtual void setCurrentConfig(const OCIO_ConstConfigRcPtr *config) = 0; + + virtual OCIO_ConstConfigRcPtr *configCreateFromEnv(void) = 0; + virtual OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename) = 0; + + virtual void configRelease(OCIO_ConstConfigRcPtr *config) = 0; + + virtual int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) = 0; + virtual const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0; + virtual OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0; + virtual int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0; + + virtual int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) = 0; + virtual int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) = 0; + + virtual void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) = 0; + + virtual const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) = 0; + virtual int configGetNumDisplays(OCIO_ConstConfigRcPtr *config) = 0; + virtual const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) = 0; + virtual const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) = 0; + virtual int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) = 0; + virtual const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) = 0; + virtual const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) = 0; + + virtual OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) = 0; + virtual OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) = 0; + + virtual void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0; + virtual void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0; + virtual void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0; + virtual void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0; + virtual void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0; + + virtual void processorRelease(OCIO_ConstProcessorRcPtr *p) = 0; + + virtual const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) = 0; + virtual const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) = 0; + virtual const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) = 0; + + virtual OCIO_DisplayTransformRcPtr *createDisplayTransform(void) = 0; + virtual void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0; + virtual void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0; + virtual void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0; + virtual void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et) = 0; + virtual void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et) = 0; + virtual void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) = 0; + + virtual OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) = 0; + + virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 0; + + virtual OCIO_ExponentTransformRcPtr *createExponentTransform(void) = 0; + virtual void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) = 0; + virtual void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) = 0; + + virtual OCIO_MatrixTransformRcPtr *createMatrixTransform(void) = 0; + virtual void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4) = 0; + virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0; + + virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0; +}; + +class FallbackImpl : public IOCIOImpl { +public: + FallbackImpl() {}; + + OCIO_ConstConfigRcPtr *getCurrentConfig(void); + void setCurrentConfig(const OCIO_ConstConfigRcPtr *config); + + OCIO_ConstConfigRcPtr *configCreateFromEnv(void); + OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename); + + void configRelease(OCIO_ConstConfigRcPtr *config); + + int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config); + const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index); + OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + + int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs); + int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs); + + void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs); + + const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config); + int configGetNumDisplays(OCIO_ConstConfigRcPtr *config); + const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index); + const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display); + int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display); + const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index); + const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view); + + OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName); + OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform); + + void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel); + + void processorRelease(OCIO_ConstProcessorRcPtr *p); + + const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs); + + OCIO_DisplayTransformRcPtr *createDisplayTransform(void); + void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); + + OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes); + + void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); + + OCIO_ExponentTransformRcPtr *createExponentTransform(void); + void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); + void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et); + + OCIO_MatrixTransformRcPtr *createMatrixTransform(void); + void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4); + void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); + + void matrixTransformScale(float * m44, float * offset4, const float * scale4); +}; + +#ifdef WITH_OCIO +class OCIOImpl : public IOCIOImpl { +public: + OCIOImpl() {}; + + OCIO_ConstConfigRcPtr *getCurrentConfig(void); + void setCurrentConfig(const OCIO_ConstConfigRcPtr *config); + + OCIO_ConstConfigRcPtr *configCreateFromEnv(void); + OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename); + + void configRelease(OCIO_ConstConfigRcPtr *config); + + int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config); + const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index); + OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + + int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs); + int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs); + + void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs); + + const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config); + int configGetNumDisplays(OCIO_ConstConfigRcPtr *config); + const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index); + const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display); + int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display); + const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index); + const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view); + + OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName); + OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform); + + void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel); + + void processorRelease(OCIO_ConstProcessorRcPtr *p); + + const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs); + + OCIO_DisplayTransformRcPtr *createDisplayTransform(void); + void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); + + OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes); + + void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); + + OCIO_ExponentTransformRcPtr *createExponentTransform(void); + void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); + void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et); + + OCIO_MatrixTransformRcPtr *createMatrixTransform(void); + void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4); + void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); + + void matrixTransformScale(float * m44, float * offset4, const float * scale4); +}; +#endif + +#endif /* OCIO_IMPL_H */ diff --git a/intern/opennl/intern/opennl.c b/intern/opennl/intern/opennl.c index 71809cc7480..f9c63e9ecf6 100644 --- a/intern/opennl/intern/opennl.c +++ b/intern/opennl/intern/opennl.c @@ -137,14 +137,14 @@ static void __nl_should_not_have_reached(char* file, int line) { /************************************************************************************/ /* memory management */ -#define __NL_NEW(T) (T*)(calloc(1, sizeof(T))) -#define __NL_NEW_ARRAY(T,NB) (T*)(calloc((NB),sizeof(T))) +#define __NL_NEW(T) (T*)(calloc(1, sizeof(T))) +#define __NL_NEW_ARRAY(T,NB) (T*)(calloc(MAX(NB, 1),sizeof(T))) #define __NL_RENEW_ARRAY(T,x,NB) (T*)(realloc(x,(NB)*sizeof(T))) -#define __NL_DELETE(x) free(x); x = NULL -#define __NL_DELETE_ARRAY(x) free(x); x = NULL +#define __NL_DELETE(x) if(x) free(x); x = NULL +#define __NL_DELETE_ARRAY(x) if(x) free(x); x = NULL -#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T)) -#define __NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (NB)*sizeof(T)) +#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T)) +#define __NL_CLEAR_ARRAY(T,x,NB) if(NB) memset(x, 0, (NB)*sizeof(T)) /************************************************************************************/ /* Dynamic arrays for sparse row/columns */ @@ -1042,6 +1042,9 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) NLuint n = context->n; NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */ + /*if(n > 10) + n = 10;*/ + /* Compressed Row Storage matrix representation */ NLint *xa = __NL_NEW_ARRAY(NLint, n+1); NLfloat *rhs = __NL_NEW_ARRAY(NLfloat, n); diff --git a/intern/opennl/superlu/get_perm_c.c b/intern/opennl/superlu/get_perm_c.c index 320fe3471f4..59889645988 100644 --- a/intern/opennl/superlu/get_perm_c.c +++ b/intern/opennl/superlu/get_perm_c.c @@ -173,17 +173,19 @@ getata( /* Flag the diagonal so it's not included in the B matrix */ marker[j] = j; - for (i = colptr[j]; i < colptr[j+1]; ++i) { - /* A_kj is nonzero, add pattern of column T_*k to B_*j */ - k = rowind[i]; - for (ti = t_colptr[k]; ti < t_colptr[k+1]; ++ti) { - trow = t_rowind[ti]; - if ( marker[trow] != j ) { - marker[trow] = j; - b_rowind[num_nz++] = trow; + if ( *atanz ) { + for (i = colptr[j]; i < colptr[j+1]; ++i) { + /* A_kj is nonzero, add pattern of column T_*k to B_*j */ + k = rowind[i]; + for (ti = t_colptr[k]; ti < t_colptr[k+1]; ++ti) { + trow = t_rowind[ti]; + if ( marker[trow] != j ) { + marker[trow] = j; + b_rowind[num_nz++] = trow; + } + } + } } - } - } } b_colptr[n] = num_nz; @@ -305,21 +307,23 @@ at_plus_a( marker[j] = j; /* Add pattern of column A_*k to B_*j */ - for (i = colptr[j]; i < colptr[j+1]; ++i) { - k = rowind[i]; - if ( marker[k] != j ) { - marker[k] = j; - (*b_rowind)[num_nz++] = k; - } - } + if (*bnz) { + for (i = colptr[j]; i < colptr[j+1]; ++i) { + k = rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + (*b_rowind)[num_nz++] = k; + } + } - /* Add pattern of column T_*k to B_*j */ - for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { - k = t_rowind[i]; - if ( marker[k] != j ) { - marker[k] = j; - (*b_rowind)[num_nz++] = k; - } + /* Add pattern of column T_*k to B_*j */ + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + k = t_rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + (*b_rowind)[num_nz++] = k; + } + } } } (*b_colptr)[n] = num_nz; diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png Binary files differindex 2dab9257905..7f40ead3911 100644 --- a/release/datafiles/splash.png +++ b/release/datafiles/splash.png diff --git a/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py b/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py index 5ee5c71be8b..d28f87cf042 100755 --- a/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py +++ b/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py @@ -34,6 +34,7 @@ import sys import ctypes +import re try: import settings @@ -87,44 +88,64 @@ FRIBIDI_FLAGS_ARABIC = FRIBIDI_FLAG_SHAPE_ARAB_PRES | \ FRIBIDI_FLAG_SHAPE_ARAB_LIGA +MENU_DETECT_REGEX = re.compile("%x\\d+\\|") + + ##### Kernel processing funcs. ##### def protect_format_seq(msg): """ Find some specific escaping/formating sequences (like \", %s, etc., and protect them from any modification! """ +# LRM = "\u200E" +# RLM = "\u200F" LRE = "\u202A" + RLE = "\u202B" PDF = "\u202C" + LRO = "\u202D" + RLO = "\u202E" + uctrl = {LRE, RLE, PDF, LRO, RLO} # Most likely incomplete, but seems to cover current needs. format_codes = set("tslfd") digits = set(".0123456789") + if not msg: + return msg + elif MENU_DETECT_REGEX.search(msg): + # An ugly "menu" message, just force it whole LRE if not yet done. + if msg[0] not in {LRE, LRO}: + msg = LRE + msg + idx = 0 ret = [] ln = len(msg) while idx < ln: dlt = 1 +# # If we find a control char, skip any additional protection! +# if msg[idx] in uctrl: +# ret.append(msg[idx:]) +# break # \" or \' if idx < (ln - 1) and msg[idx] == '\\' and msg[idx + 1] in "\"\'": dlt = 2 - # %x12 - elif idx < (ln - 2) and msg[idx] == '%' and msg[idx + 1] in "x" and \ - msg[idx + 2] in digits: + # %x12| + elif idx < (ln - 2) and msg[idx] == '%' and msg[idx + 1] in "x" and msg[idx + 2] in digits: dlt = 2 - while (idx + dlt + 1) < ln and msg[idx + dlt + 1] in digits: + while (idx + dlt) < ln and msg[idx + dlt] in digits: + dlt += 1 + if (idx + dlt) < ln and msg[idx + dlt] is '|': dlt += 1 # %.4f elif idx < (ln - 3) and msg[idx] == '%' and msg[idx + 1] in digits: dlt = 2 - while (idx + dlt + 1) < ln and msg[idx + dlt + 1] in digits: + while (idx + dlt) < ln and msg[idx + dlt] in digits: dlt += 1 - if (idx + dlt + 1) < ln and msg[idx + dlt + 1] in format_codes: + if (idx + dlt) < ln and msg[idx + dlt] in format_codes: dlt += 1 else: dlt = 1 # %s - elif idx < (ln - 1) and msg[idx] == '%' and \ - msg[idx + 1] in format_codes: + elif idx < (ln - 1) and msg[idx] == '%' and msg[idx + 1] in format_codes: dlt = 2 if dlt > 1: diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml index 24f135e8548..805aa9bd184 100644 --- a/release/scripts/presets/interface_theme/back_to_black.xml +++ b/release/scripts/presets/interface_theme/back_to_black.xml @@ -9,6 +9,7 @@ handle_auto="#909000" handle_sel_auto="#f0ff40" bone_pose="#50c8ff" + bone_pose_active="#8cffff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" camera="#000000" diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml index 79d1ed4ecf4..232276e300e 100644 --- a/release/scripts/presets/interface_theme/blender_24x.xml +++ b/release/scripts/presets/interface_theme/blender_24x.xml @@ -9,6 +9,7 @@ handle_auto="#909000" handle_sel_auto="#f0ff40" bone_pose="#50c8ff" + bone_pose_active="#8cffff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" camera="#000000" diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml index bfeb3a0175e..581f5ce82d6 100644 --- a/release/scripts/presets/interface_theme/elsyiun.xml +++ b/release/scripts/presets/interface_theme/elsyiun.xml @@ -9,6 +9,7 @@ handle_auto="#909000" handle_sel_auto="#f0ff40" bone_pose="#50c8ff" + bone_pose_active="#8cffff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" camera="#000000" @@ -282,7 +283,7 @@ <ThemeInfo> <space> <ThemeSpaceGeneric header="#3b3b3b" - header_text="#8b8b8b" + header_text="#000000" header_text_hi="#000000" button="#3b3b3b" button_text="#000000" diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml index 7727d860a90..61730583396 100644 --- a/release/scripts/presets/interface_theme/hexagon.xml +++ b/release/scripts/presets/interface_theme/hexagon.xml @@ -9,6 +9,7 @@ handle_auto="#909000" handle_sel_auto="#f0ff40" bone_pose="#50c8ff" + bone_pose_active="#8cffff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" camera="#000000" diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index 72852e27604..d54766ec88f 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -9,6 +9,7 @@ handle_auto="#909000" handle_sel_auto="#f0ff40" bone_pose="#50c8ff" + bone_pose_active="#8cffff" bone_solid="#c8c8c8" bundle_solid="#c8c8c8" camera="#000000" diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index 98bad276109..c5fc3c50f3f 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -189,7 +189,7 @@ class BakeAction(Operator): name="Only Selected", default=True, ) - clear_consraints = BoolProperty( + clear_constraints = BoolProperty( name="Clear Constraints", default=False, ) @@ -212,7 +212,7 @@ class BakeAction(Operator): self.only_selected, 'POSE' in self.bake_types, 'OBJECT' in self.bake_types, - self.clear_consraints, + self.clear_constraints, True, ) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 07d4096632f..21843d80742 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1028,7 +1028,7 @@ class WM_OT_properties_edit(Operator): min = rna_min max = rna_max description = StringProperty( - name="Tip", + name="Tooltip", ) def execute(self, context): diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 2d15c534e9f..8308c7fc425 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -65,10 +65,13 @@ class MotionPathButtonsPanel(): sub.prop(mpath, "frame_start", text="From") sub.prop(mpath, "frame_end", text="To") + sub = col.row(align=True) if bones: - col.operator("pose.paths_update", text="Update Paths", icon='BONE_DATA') + sub.operator("pose.paths_update", text="Update Paths", icon='BONE_DATA') + sub.operator("pose.paths_clear", text="", icon='X') else: - col.operator("object.paths_update", text="Update Paths", icon='OBJECT_DATA') + sub.operator("object.paths_update", text="Update Paths", icon='OBJECT_DATA') + sub.operator("object.paths_clear", text="", icon='X') else: sub = col.column(align=True) sub.label(text="Nothing to show yet...", icon='ERROR') diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 3d671a0d1b7..fba7bd8712a 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -212,6 +212,7 @@ class ConstraintButtonsPanel(): def FOLLOW_PATH(self, context, layout, con): self.target_template(layout, con) + layout.operator("constraint.followpath_path_animate", text="Animate Path", icon='ANIM_DATA') split = layout.split() diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index efac7a66086..b0e8a847084 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -790,42 +790,45 @@ class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel): sc = context.space_data clip = sc.clip - layout.active = clip.use_proxy + col = layout.column() + col.active = clip.use_proxy - layout.label(text="Build Original:") + col.label(text="Build Original:") - row = layout.row(align=True) + row = col.row(align=True) row.prop(clip.proxy, "build_25", toggle=True) row.prop(clip.proxy, "build_50", toggle=True) row.prop(clip.proxy, "build_75", toggle=True) row.prop(clip.proxy, "build_100", toggle=True) - layout.label(text="Build Undistorted:") + col.label(text="Build Undistorted:") - row = layout.row(align=True) + row = col.row(align=True) row.prop(clip.proxy, "build_undistorted_25", toggle=True) row.prop(clip.proxy, "build_undistorted_50", toggle=True) row.prop(clip.proxy, "build_undistorted_75", toggle=True) row.prop(clip.proxy, "build_undistorted_100", toggle=True) - layout.prop(clip.proxy, "quality") + col.prop(clip.proxy, "quality") - layout.prop(clip, "use_proxy_custom_directory") + col.prop(clip, "use_proxy_custom_directory") if clip.use_proxy_custom_directory: - layout.prop(clip.proxy, "directory") + col.prop(clip.proxy, "directory") - layout.operator("clip.rebuild_proxy", text="Build Proxy") + col.operator("clip.rebuild_proxy", text="Build Proxy") if clip.source == 'MOVIE': - col = layout.column() + col2 = col.column() - col.label(text="Use timecode index:") - col.prop(clip.proxy, "timecode", text="") + col2.label(text="Use timecode index:") + col2.prop(clip.proxy, "timecode", text="") - col = layout.column() - col.label(text="Proxy render size:") + col2 = col.column() + col2.label(text="Proxy render size:") col.prop(sc.clip_user, "proxy_render_size", text="") + + col = layout.column() col.prop(sc.clip_user, "use_render_undistorted") diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 04ea6b818ac..9ab2a772df0 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -192,7 +192,7 @@ class INFO_MT_mesh_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("mesh.primitive_plane_add", icon='MESH_PLANE', text="Plane") layout.operator("mesh.primitive_cube_add", icon='MESH_CUBE', text="Cube") layout.operator("mesh.primitive_circle_add", icon='MESH_CIRCLE', text="Circle") @@ -203,7 +203,7 @@ class INFO_MT_mesh_add(Menu): layout.separator() layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid") layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey") - layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS') + layout.operator("mesh.primitive_torus_add", icon='MESH_TORUS', text="Torus") class INFO_MT_curve_add(Menu): @@ -213,7 +213,7 @@ class INFO_MT_curve_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("curve.primitive_bezier_curve_add", icon='CURVE_BEZCURVE', text="Bezier") layout.operator("curve.primitive_bezier_circle_add", icon='CURVE_BEZCIRCLE', text="Circle") layout.operator("curve.primitive_nurbs_curve_add", icon='CURVE_NCURVE', text="Nurbs Curve") @@ -221,22 +221,6 @@ class INFO_MT_curve_add(Menu): layout.operator("curve.primitive_nurbs_path_add", icon='CURVE_PATH', text="Path") -class INFO_MT_edit_curve_add(Menu): - bl_idname = "INFO_MT_edit_curve_add" - bl_label = "Add" - - def draw(self, context): - is_surf = context.active_object.type == 'SURFACE' - - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - - if is_surf: - INFO_MT_surface_add.draw(self, context) - else: - INFO_MT_curve_add.draw(self, context) - - class INFO_MT_surface_add(Menu): bl_idname = "INFO_MT_surface_add" bl_label = "Surface" @@ -244,7 +228,7 @@ class INFO_MT_surface_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("surface.primitive_nurbs_surface_curve_add", icon='SURFACE_NCURVE', text="NURBS Curve") layout.operator("surface.primitive_nurbs_surface_circle_add", icon='SURFACE_NCIRCLE', text="NURBS Circle") layout.operator("surface.primitive_nurbs_surface_surface_add", icon='SURFACE_NSURFACE', text="NURBS Surface") @@ -253,6 +237,22 @@ class INFO_MT_surface_add(Menu): layout.operator("surface.primitive_nurbs_surface_torus_add", icon='SURFACE_NTORUS', text="NURBS Torus") +class INFO_MT_edit_curve_add(Menu): + bl_idname = "INFO_MT_edit_curve_add" + bl_label = "Add" + + def draw(self, context): + is_surf = context.active_object.type == 'SURFACE' + + layout = self.layout + layout.operator_context = 'EXEC_REGION_WIN' + + if is_surf: + INFO_MT_surface_add.draw(self, context) + else: + INFO_MT_curve_add.draw(self, context) + + class INFO_MT_armature_add(Menu): bl_idname = "INFO_MT_armature_add" bl_label = "Armature" @@ -260,7 +260,7 @@ class INFO_MT_armature_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA') @@ -272,7 +272,9 @@ class INFO_MT_add(Menu): # note, don't use 'EXEC_SCREEN' or operators wont get the 'v3d' context. - layout.operator_context = 'EXEC_AREA' + # Note: was EXEC_AREA, but this context does not have the 'rv3d', which prevents + # "align_view" to work on first call (see [#32719]). + layout.operator_context = 'EXEC_REGION_WIN' #layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH') layout.menu("INFO_MT_mesh_add", icon='OUTLINER_OB_MESH') @@ -282,20 +284,18 @@ class INFO_MT_add(Menu): #layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE') layout.menu("INFO_MT_surface_add", icon='OUTLINER_OB_SURFACE') layout.operator_menu_enum("object.metaball_add", "type", text="Metaball", icon='OUTLINER_OB_META') - layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT') layout.separator() layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE') layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE' - layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY' + layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY') layout.separator() layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER') layout.separator() layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA') - layout.operator_context = 'EXEC_AREA' layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP') layout.separator() @@ -303,7 +303,7 @@ class INFO_MT_add(Menu): layout.separator() if(len(bpy.data.groups) > 10): - layout.operator_context = 'INVOKE_DEFAULT' + layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_EMPTY') else: layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_EMPTY') diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 444e9349e9f..64bf1e29348 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -20,7 +20,6 @@ import bpy from bpy.types import Header, Menu, Panel import os -import addon_utils def ui_items_general(col, context): @@ -1033,6 +1032,8 @@ class USERPREF_PT_addons(Panel): box.label(l) def draw(self, context): + import addon_utils + layout = self.layout userpref = context.user_preferences diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 92255275966..d113853eaed 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -807,7 +807,8 @@ class VIEW3D_MT_object_animation(Menu): layout = self.layout layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...") - layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframe...") + layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframes...") + layout.operator("anim.keyframe_clear_v3d", text="Clear Keyframes...") layout.operator("anim.keying_set_active_set", text="Change Keying Set...") layout.separator() diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index 56eabf4bb43..278c45dac52 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -97,6 +97,8 @@ const char *BLF_translate_do_tooltip(const char *contex, const char *msgid); /* Default context for operator names/labels. */ #define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator" +/* Audio disambiguation context. */ +#define BLF_I18NCONTEXT_AUDIO "Audio" #endif /* __BLF_TRANSLATION_H__ */ diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index f506c67a36c..11537964e32 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -65,8 +65,8 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl /* ---------------------------------------------------- */ /* Dupli-Geometry */ -struct ListBase *object_duplilist_ex(struct Scene *sce, struct Object *ob, int update); -struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob); +struct ListBase *object_duplilist_ex(struct Scene *sce, struct Object *ob, int update, int for_render); +struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob, int for_render); void free_object_duplilist(struct ListBase *lb); int count_duplilist(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index d750e88ac04..a3f3beefbaf 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -132,6 +132,7 @@ 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)) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index dd45ab19eb1..56dfdf404f8 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,8 +41,8 @@ extern "C" { /* these lines are grep'd, watch out for our not-so-awesome regex * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ -#define BLENDER_VERSION 263 -#define BLENDER_SUBVERSION 22 +#define BLENDER_VERSION 264 +#define BLENDER_SUBVERSION 1 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ @@ -51,9 +51,9 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR a +#define BLENDER_VERSION_CHAR /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE rc +#define BLENDER_VERSION_CYCLE alpha extern char versionstr[]; /* from blender.c */ diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index f3223fb4af1..3cb20ead39e 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -44,7 +44,7 @@ void free_gpencil_layers(struct ListBase *list); void BKE_gpencil_free(struct bGPdata *gpd); struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe); -struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd); +struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd, const char *name, int setactive); struct bGPdata *gpencil_data_addnew(const char name[]); struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src); @@ -62,6 +62,6 @@ struct bGPDframe *gpencil_layer_getframe(struct bGPDlayer *gpl, int cframe, shor void gpencil_layer_delframe(struct bGPDlayer *gpl, struct bGPDframe *gpf); struct bGPDlayer *gpencil_layer_getactive(struct bGPdata *gpd); void gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active); -void gpencil_layer_delactive(struct bGPdata *gpd); +void gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl); #endif /* __BKE_GPENCIL_H__ */ diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index 913e8653b9b..7a0eea1b009 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -59,8 +59,12 @@ void BKE_mball_properties_copy(struct Scene *scene, struct Object *active_object int BKE_mball_minmax(struct MetaBall *mb, float min[3], float max[3]); int BKE_mball_center_median(struct MetaBall *mb, float r_cent[3]); int BKE_mball_center_bounds(struct MetaBall *mb, float r_cent[3]); -void BKE_mball_translate(struct MetaBall *mb, float offset[3]); +void BKE_mball_translate(struct MetaBall *mb, const float offset[3]); struct MetaElem *BKE_mball_element_add(struct MetaBall *mb, const int type); +void BKE_mball_select_all(struct MetaBall *mb); +void BKE_mball_deselect_all(struct MetaBall *mb); +void BKE_mball_select_swap(struct MetaBall *mb); + #endif diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 6ad2ad924e2..acd6f120f93 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -475,6 +475,8 @@ struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBa void register_node_type_frame(struct bNodeTreeType *ttype); void register_node_type_reroute(struct bNodeTreeType *ttype); +void BKE_node_tree_unlink_id_cb(void *calldata, struct ID *owner_id, struct bNodeTree *ntree); + /* ************** SHADER NODES *************** */ struct ShadeInput; diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 023b7e85c40..c12e913be45 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -109,6 +109,7 @@ float get_render_aosss_error(struct RenderData *r, float error); int BKE_scene_use_new_shading_nodes(struct Scene *scene); void BKE_scene_disable_color_management(struct Scene *scene); +int BKE_scene_check_color_management_enabled(const struct Scene *scene); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 0c571f62f0e..cecff2d9516 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -64,29 +64,29 @@ typedef struct SeqIterator { int valid; } SeqIterator; -void BKE_seqence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_pointer); -void BKE_seqence_iterator_next(SeqIterator *iter); -void BKE_seqence_iterator_end(SeqIterator *iter); +void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_pointer); +void BKE_sequence_iterator_next(SeqIterator *iter); +void BKE_sequence_iterator_end(SeqIterator *iter); #define SEQP_BEGIN(ed, _seq) \ { \ SeqIterator iter; \ - for (BKE_seqence_iterator_begin(ed, &iter, 1); \ + for (BKE_sequence_iterator_begin(ed, &iter, 1); \ iter.valid; \ - BKE_seqence_iterator_next(&iter)) { \ + BKE_sequence_iterator_next(&iter)) { \ _seq = iter.seq; #define SEQ_BEGIN(ed, _seq) \ { \ SeqIterator iter; \ - for (BKE_seqence_iterator_begin(ed, &iter, 0); \ + for (BKE_sequence_iterator_begin(ed, &iter, 0); \ iter.valid; \ - BKE_seqence_iterator_next(&iter)) { \ + BKE_sequence_iterator_next(&iter)) { \ _seq = iter.seq; #define SEQ_END \ } \ - BKE_seqence_iterator_end(&iter); \ + BKE_sequence_iterator_end(&iter); \ } typedef struct SeqRenderData { @@ -307,7 +307,7 @@ int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char int BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur); void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq); -void BKE_sequence_invalidate_deendent(struct Scene *scene, struct Sequence *seq); +void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq); void BKE_sequence_invalidate_cache_for_modifier(struct Scene *scene, struct Sequence *seq); void BKE_sequencer_update_sound_bounds_all(struct Scene *scene); @@ -315,9 +315,9 @@ void BKE_sequencer_update_sound_bounds(struct Scene *scene, struct Sequence *seq void BKE_sequencer_update_muting(struct Editing *ed); void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound); -void BKE_seqence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); +void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag); -int BKE_seqence_is_valid_check(struct Sequence *seq); +int BKE_sequence_is_valid_check(struct Sequence *seq); void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 5e13fe78a43..9aaeb4c8baf 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -578,6 +578,13 @@ void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask) CustomData_set_only_copy(&dm->vertData, mask); CustomData_set_only_copy(&dm->edgeData, mask); CustomData_set_only_copy(&dm->faceData, mask); + /* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with + * weight paint mode when there are modifiers applied, needs further investigation, + * see replies to r50969, Campbell */ +#if 0 + CustomData_set_only_copy(&dm->loopData, mask); + CustomData_set_only_copy(&dm->polyData, mask); +#endif } void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 925658b84f4..66df7eccbd0 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -539,6 +539,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) outPose->iksolver = src->iksolver; outPose->ikdata = NULL; outPose->ikparam = MEM_dupallocN(src->ikparam); + outPose->avs = src->avs; for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { /* TODO: rename this argument... */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ec15e2ea87f..58d20fff2bc 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -75,7 +75,7 @@ /* forward declarations */ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short animated, short update); + int level, short flag); /* ******************************************************************** */ /* Animation Visualization */ @@ -700,7 +700,11 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua /* ******************************************************************** */ /* Dupli-Geometry */ -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short animated) +#define DUPLILIST_DO_UPDATE 1 +#define DUPLILIST_FOR_RENDER 2 +#define DUPLILIST_ANIMATED 4 + +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -712,14 +716,14 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i dob->index = index; dob->particle_index = par_index; dob->type = type; - dob->animated = (type == OB_DUPLIGROUP) && animated; + dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED); ob->lay = lay; return dob; } static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, - int level, short animated, short update) + int level, short flag) { DupliObject *dob; Group *group; @@ -735,13 +739,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ - if (update) { + if (flag & DUPLILIST_DO_UPDATE) { /* note: update is optional because we don't always need object * transformations to be correct. Also fixes bug [#29616]. */ group_handle_recalc_and_update(scene, ob, group); } - animated = animated || group_is_animated(ob, group); + if (group_is_animated(ob, group)) + flag |= DUPLILIST_ANIMATED; for (go = group->gobject.first; go; go = go->next) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ @@ -757,7 +762,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } - dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, animated); + dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, flag); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ((dob->origlay & group->layer) == 0 || @@ -772,14 +777,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); - object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated, update); + object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, flag); copy_m4_m4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short animated) +static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short flag) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -827,7 +832,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); - dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, animated); + dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, flag); copy_m4_m4(dob->omat, copyob.obmat); } } @@ -851,8 +856,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind typedef struct VertexDupliData { ID *id; /* scene or group, for recursive loops */ int level; - short animated; - short update; + short flag; ListBase *lb; float pmat[4][4]; float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ @@ -896,7 +900,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], origlay = vdd->ob->lay; - dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->animated); + dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->flag); /* restore the original layer so that each dupli will have proper dob->origlay */ vdd->ob->lay = origlay; @@ -908,13 +912,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated, vdd->update); + object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->flag); copy_m4_m4(vdd->ob->obmat, tmpmat); } } static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { Object *ob, *ob_iter; Mesh *me = par->data; @@ -942,7 +946,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl else dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); - if (G.is_rendering) { + if (flag & DUPLILIST_FOR_RENDER) { vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0); } @@ -992,8 +996,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl vdd.id = id; vdd.level = level; - vdd.animated = animated; - vdd.update = update; + vdd.flag = flag; vdd.lb = lb; vdd.ob = ob; vdd.scene = scene; @@ -1039,7 +1042,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl } static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { Object *ob, *ob_iter; Base *base = NULL; @@ -1076,8 +1079,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa mloop = dm->getLoopArray(dm); mvert = dm->getVertArray(dm); - if (G.is_rendering) { - + if (flag & DUPLILIST_FOR_RENDER) { orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0); mloopuv = me->mloopuv; @@ -1182,8 +1184,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); - dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, animated); - if (G.is_rendering) { + dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED)); + if (flag & DUPLILIST_FOR_RENDER) { w = 1.0f / (float)mp->totloop; if (orco) { @@ -1205,7 +1207,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated, update); + object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, flag); copy_m4_m4(ob->obmat, tmpmat); } } @@ -1226,7 +1228,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa } static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, - int level, short animated, short update) + int level, short flag) { GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; @@ -1309,7 +1311,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* gather list of objects or single object */ if (part->ren_as == PART_DRAW_GR) { - if (update) { + if (flag & DUPLILIST_DO_UPDATE) { group_handle_recalc_and_update(scene, par, part->dup_group); } @@ -1452,9 +1454,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else copy_m4_m4(mat, tmat); - dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); copy_m4_m4(dob->omat, obcopylist[b].obmat); - if (G.is_rendering) + if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } @@ -1512,9 +1514,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); copy_m4_m4(dob->omat, oldobmat); - if (G.is_rendering) + if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } @@ -1566,7 +1568,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short animated) +static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short flag) { Object *ob, *obar[256] = {NULL}; Curve *cu; @@ -1605,7 +1607,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde copy_m4_m4(obmat, par->obmat); copy_v3_v3(obmat[3], vec); - new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, animated); + new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, flag); } } @@ -1615,7 +1617,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde /* ------------- */ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { if ((ob->transflag & OB_DUPLI) == 0) return; @@ -1635,31 +1637,31 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas if (ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; for (; psys; psys = psys->next) - new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated, update); + new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, flag); } else if (ob->transflag & OB_DUPLIVERTS) { if (ob->type == OB_MESH) { - vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); + vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); } else if (ob->type == OB_FONT) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, scene, ob, par_index, level + 1, animated); + font_duplilist(duplilist, scene, ob, par_index, level + 1, flag); } } } else if (ob->transflag & OB_DUPLIFACES) { if (ob->type == OB_MESH) - face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); + face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); } else if (ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, scene, ob, par_index, level + 1, animated); + frames_duplilist(duplilist, scene, ob, par_index, level + 1, flag); } } else if (ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, scene, ob, par_index, level + 1, animated, update); /* now recursive */ + group_duplilist(duplilist, scene, ob, par_index, level + 1, flag); /* now recursive */ if (level == 0) { for (dob = duplilist->first; dob; dob = dob->next) @@ -1671,19 +1673,24 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas /* Returns a list of DupliObject * note; group dupli's already set transform matrix. see note in group_duplilist() */ -ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update) +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; + duplilist->first = duplilist->last = NULL; - object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0, update); + object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); return duplilist; } /* note: previously updating was always done, this is why it defaults to be on * but there are likely places it can be called without updating */ -ListBase *object_duplilist(Scene *sce, Object *ob) +ListBase *object_duplilist(Scene *sce, Object *ob, int for_render) { - return object_duplilist_ex(sce, ob, TRUE); + return object_duplilist_ex(sce, ob, TRUE, for_render); } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index b66bd1fd32b..1bd5786debd 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1289,9 +1289,9 @@ void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_se void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings) { /* OCIO_TODO: use default view transform here when OCIO is completely integrated - * and proper versioning stuff is added. - * for now use NONE to be compatible with all current files - */ + * and proper versioning stuff is added. + * for now use NONE to be compatible with all current files + */ BLI_strncpy(settings->view_transform, "Default", sizeof(settings->view_transform)); settings->gamma = 1.0f; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index ba859cadf92..de55751f2ec 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1999,7 +1999,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest, } /* if there are no more dest layers, we're done */ - if (dest_i >= dest->totlayer) return; + if (dest_i >= dest->totlayer) break; /* if we found a matching layer, copy the data */ if (dest->layers[dest_i].type == source->layers[src_i].type) { diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 2ec5801746c..84871375788 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -163,7 +163,7 @@ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe) } /* add a new gp-layer and make it the active layer */ -bGPDlayer *gpencil_layer_addnew(bGPdata *gpd) +bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive) { bGPDlayer *gpl; @@ -182,11 +182,12 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd) gpl->thickness = 3; /* auto-name */ - strcpy(gpl->info, "GP_Layer"); + strcpy(gpl->info, name); BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); /* make this one the active one */ - gpencil_layer_setactive(gpd, gpl); + if (setactive) + gpencil_layer_setactive(gpd, gpl); /* return layer */ return gpl; @@ -509,10 +510,8 @@ void gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active) } /* delete the active gp-layer */ -void gpencil_layer_delactive(bGPdata *gpd) +void gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl) { - bGPDlayer *gpl = gpencil_layer_getactive(gpd); - /* error checking */ if (ELEM(NULL, gpd, gpl)) return; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 3d3afa7c4b3..c003a86a0b7 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2563,7 +2563,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ *lock_r = re; } - /* this gives active layer, composite or seqence result */ + /* this gives active layer, composite or sequence result */ rect = (unsigned int *)rres.rect32; rectf = rres.rectf; rectz = rres.rectz; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 953ee673f6b..5216aefab58 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1757,13 +1757,13 @@ void do_versions_ipos_to_animato(Main *main) { /* If we have any empty action actuators, assume they were - converted IPO Actuators using the object IPO */ + * converted IPO Actuators using the object IPO */ bActuator *act; bActionActuator *aa; for (act = ob->actuators.first; act; act = act->next) { /* Any actuators set to ACT_IPO at this point are actually Action Actuators that - need this converted IPO to finish converting the actuator. */ + * need this converted IPO to finish converting the actuator. */ if (act->type == ACT_IPO) { aa = (bActionActuator *)act->data; aa->act = ob->adt->action; diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 3564071334c..aa19350c456 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -916,19 +916,6 @@ void BKE_mask_free_nolib(Mask *mask) BKE_mask_layer_free_list(&mask->masklayers); } - -static void ntree_unlink_mask_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree) -{ - ID *id = (ID *)calldata; - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id == id) { - node->id = NULL; - } - } -} - void BKE_mask_free(Main *bmain, Mask *mask) { bScreen *scr; @@ -975,21 +962,11 @@ void BKE_mask_free(Main *bmain, Mask *mask) } SEQ_END } - - - if (scene->nodetree) { - bNode *node; - for (node = scene->nodetree->nodes.first; node; node = node->next) { - if (node->id == &mask->id) { - node->id = NULL; - } - } - } } { bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT); - treetype->foreach_nodetree(bmain, (void *)mask, &ntree_unlink_mask_cb); + treetype->foreach_nodetree(bmain, (void *)mask, &BKE_node_tree_unlink_id_cb); } /* free mask data */ @@ -1548,7 +1525,7 @@ void BKE_mask_parent_init(MaskParent *parent) } -/* *** own animation/shapekey implimentation *** +/* *** own animation/shapekey implementation *** * BKE_mask_layer_shape_XXX */ int BKE_mask_layer_shape_totvert(MaskLayer *masklay) diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 2030ab0f552..592101fbd31 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -2388,7 +2388,7 @@ int BKE_mball_center_bounds(MetaBall *mb, float r_cent[3]) return 0; } -void BKE_mball_translate(MetaBall *mb, float offset[3]) +void BKE_mball_translate(MetaBall *mb, const float offset[3]) { MetaElem *ml; @@ -2396,3 +2396,32 @@ void BKE_mball_translate(MetaBall *mb, float offset[3]) add_v3_v3(&ml->x, offset); } } + +/* *** select funcs *** */ +void BKE_mball_select_all(struct MetaBall *mb) +{ + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + ml->flag |= SELECT; + } +} + +void BKE_mball_deselect_all(MetaBall *mb) +{ + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + ml->flag &= ~SELECT; + } +} + +void BKE_mball_select_swap(struct MetaBall *mb) +{ + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + ml->flag ^= SELECT; + } +} + diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e45a052db4d..1aaeebf5109 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2043,7 +2043,7 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, int side, corners; if (CustomData_external_test(fdata, CD_MDISPS)) { - if (id) { + if (id && fdata->external) { CustomData_external_add(ldata, id, CD_MDISPS, totloop, fdata->external->filename); } diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 72c3cda9272..dc3d4a89e62 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -49,7 +49,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) MLoop *mloop, *ml; BMVert *v, **vtable, **verts = NULL; BMEdge *e, **etable, **edges = NULL; - float has_face_normals; + float (*face_normals)[3]; BMFace *f; BMIter liter; BLI_array_declare(verts); @@ -72,8 +72,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); - vtable = MEM_callocN(sizeof(void **) * totvert, "vert table in BMDM_Copy"); - etable = MEM_callocN(sizeof(void **) * totedge, "edge table in BMDM_Copy"); + vtable = MEM_callocN(sizeof(void **) * totvert, __func__); + etable = MEM_callocN(sizeof(void **) * totedge, __func__); /*do verts*/ mv = mvert = dm->dupVertArray(dm); @@ -110,7 +110,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) /*do faces*/ mp = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); - has_face_normals = CustomData_has_layer(&dm->polyData, CD_NORMAL); + face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */ for (i = 0; i < dm->numPolyData; i++, mp++) { BMLoop *l; @@ -129,8 +129,9 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE); - if (!f) + if (UNLIKELY(f == NULL)) { continue; + } f->head.hflag = BM_face_flag_from_mflag(mp->flag); f->mat_nr = mp->mat_nr; @@ -143,11 +144,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data); - if (has_face_normals) { - float *fno; - - fno = CustomData_bmesh_get(&bm->pdata, &f->head.data, CD_NORMAL); - copy_v3_v3(f->no, fno); + if (face_normals) { + copy_v3_v3(f->no, face_normals[i]); + } + else { + BM_face_normal_update(f); } } diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 386e4163fd2..0aa1f9e0822 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -52,6 +52,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_movieclip_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_view3d_types.h" @@ -71,6 +72,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_movieclip.h" +#include "BKE_node.h" #include "BKE_image.h" /* openanim */ #include "BKE_tracking.h" @@ -624,24 +626,22 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist return undistibuf; } -static int need_undistortion_postprocess(MovieClipUser *user, int flag) +static int need_undistortion_postprocess(MovieClipUser *user) { int result = 0; /* only full undistorted render can be used as on-fly undistorting image */ - if (flag & MCLIP_USE_PROXY) { - result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) && - (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0; - } + result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) && + (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0; return result; } -static int need_postprocessed_frame(MovieClipUser *user, int flag, int postprocess_flag) +static int need_postprocessed_frame(MovieClipUser *user, int postprocess_flag) { int result = postprocess_flag; - result |= need_undistortion_postprocess(user, flag); + result |= need_undistortion_postprocess(user); return result; } @@ -688,7 +688,7 @@ static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *use if (cache->postprocessed.flag != postprocess_flag) return NULL; - if (need_undistortion_postprocess(user, flag)) { + if (need_undistortion_postprocess(user)) { if (!check_undistortion_cache_flags(clip)) return NULL; } @@ -719,7 +719,7 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u cache->postprocessed.render_flag = 0; } - if (need_undistortion_postprocess(user, flag)) { + if (need_undistortion_postprocess(user)) { copy_v2_v2(cache->postprocessed.principal, camera->principal); copy_v3_v3(&cache->postprocessed.k1, &camera->k1); cache->postprocessed.undistortion_used = TRUE; @@ -763,7 +763,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u BLI_lock_thread(LOCK_MOVIECLIP); /* try to obtain cached postprocessed frame first */ - if (need_postprocessed_frame(user, flag, postprocess_flag)) { + if (need_postprocessed_frame(user, postprocess_flag)) { ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag); if (!ibuf) @@ -1326,6 +1326,11 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip) } } + { + bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT); + treetype->foreach_nodetree(bmain, (void *)clip, &BKE_node_tree_unlink_id_cb); + } + clip->id.us = 0; } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 1c06d95a70b..591524e5156 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -666,7 +666,9 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) mdisp->totdisp = totdisp; mdisp->level = lvl; - multires_grid_paint_mask_downsample(&gpm[g], lvl); + if (gpm) { + multires_grid_paint_mask_downsample(&gpm[g], lvl); + } } } } @@ -893,15 +895,16 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl CCGKey highGridKey, lowGridKey; CCGSubSurf *ss; int i, numGrids, highGridSize; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); /* create subsurf DM from original mesh at high level */ cddm = CDDM_from_mesh(me, NULL); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); ss = ((CCGDerivedMesh *)highdm)->ss; /* create multires DM from original mesh at low level */ - lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, TRUE); + lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask); cddm->release(cddm); /* copy subsurf grids and replace them with low displaced grids */ @@ -1164,17 +1167,18 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) CCGKey highGridKey, lowGridKey; CCGSubSurf *ss; int i, j, numGrids, highGridSize, lowGridSize; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); /* create subsurf DM from original mesh at high level */ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); else cddm = CDDM_from_mesh(me, NULL); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); ss = ((CCGDerivedMesh *)highdm)->ss; /* create multires DM from original mesh and displacements */ - lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, TRUE); + lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask); cddm->release(cddm); /* gather grid data */ @@ -1226,12 +1230,13 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) } else { DerivedMesh *cddm, *subdm; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); else cddm = CDDM_from_mesh(me, NULL); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE); + subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); cddm->release(cddm); multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl); @@ -2107,7 +2112,7 @@ void multires_load_old(Object *ob, Mesh *me) * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), * which implicitly expects both subsurfs from its first dm and oldGridData parameters to * be of the same "format"! */ - dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK); + dm = multires_make_derived_from_derived(orig, mmd, ob, 0); multires_load_old_dm(dm, me, mmd->totlvl + 1); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index ade418e409f..8cede4f51a5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1030,9 +1030,18 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) next = node->next; /* ntreeUserIncrefID inline */ + + /* XXX, this is correct, however when freeing the entire database + * this ends up accessing freed data which isn't properly unlinking + * its self from scene nodes, SO - for now prefer invalid usercounts + * on free rather then bad memory access - Campbell */ +#if 0 if (do_id_user) { id_us_min(node->id); } +#else + (void)do_id_user; +#endif nodeFreeNode(ntree, node); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8b3d7b3d974..2e379e10c60 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2271,7 +2271,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u Curve *cu = ob->data; /* Use the object bounding box so that modifier output - gets taken into account */ + * gets taken into account */ if (ob->bb) bb = *(ob->bb); else { @@ -2372,7 +2372,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma ListBase *lb; DupliObject *dob; - lb = object_duplilist(scene, ob); + lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) { if ((use_hidden == FALSE) && (dob->no_draw != 0)) { /* pass */ @@ -2449,7 +2449,7 @@ void BKE_scene_foreach_display_point( ListBase *lb; DupliObject *dob; - lb = object_duplilist(scene, ob); + lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) { if (dob->no_draw == 0) { BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 0d01bb33fc5..8c0d19ba1fd 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1030,7 +1030,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup ListBase *lb_dupli_ob; /* don't update the dupli groups, we only wan't their pid's */ - if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE))) { + if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE, FALSE))) { DupliObject *dob; for (dob= lb_dupli_ob->first; dob; dob= dob->next) { if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 4b91943f740..b519a59b6d6 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -751,7 +751,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob) * this enters eternal loop because of * makeDispListMBall getting called inside of group_duplilist */ if ((*base)->object->dup_group == NULL) { - duplilist = object_duplilist((*scene), (*base)->object); + duplilist = object_duplilist((*scene), (*base)->object, FALSE); dupob = duplilist->first; @@ -1286,3 +1286,8 @@ void BKE_scene_disable_color_management(Scene *scene) BLI_strncpy(view_settings->view_transform, view, sizeof(view_settings->view_transform)); } } + +int BKE_scene_check_color_management_enabled(const Scene *scene) +{ + return strcmp(scene->display_settings.display_device, "None") != 0; +} diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index eaf3ec384c8..33519483843 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -609,9 +609,9 @@ static void makeGammaTables(float gamma) /* The end of the table should match 1.0 carefully. In order to avoid * rounding errors, we just set this explicitly. The last segment may - * have a different length than the other segments, but our - * interpolation is insensitive to that - */ + * have a different length than the other segments, but our + * interpolation is insensitive to that + */ color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index bb845400cef..90c3347a1df 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -461,7 +461,7 @@ static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_point seq_build_array(&ed->seqbase, &array, 0); } -void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) +void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) { memset(iter, 0, sizeof(*iter)); seq_array(ed, &iter->array, &iter->tot, use_pointer); @@ -473,7 +473,7 @@ void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) } } -void BKE_seqence_iterator_next(SeqIterator *iter) +void BKE_sequence_iterator_next(SeqIterator *iter) { if (++iter->cur < iter->tot) iter->seq = iter->array[iter->cur]; @@ -481,7 +481,7 @@ void BKE_seqence_iterator_next(SeqIterator *iter) iter->valid = 0; } -void BKE_seqence_iterator_end(SeqIterator *iter) +void BKE_sequence_iterator_end(SeqIterator *iter) { if (iter->array) MEM_freeN(iter->array); @@ -843,7 +843,7 @@ static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt) return 1; } -void BKE_seqence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) +void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) { SeqUniqueInfo sui; char *dot; @@ -3032,10 +3032,27 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur) return TRUE; } +static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase) +{ + Sequence *cur; + + for (cur = seqbase->first; cur; cur = cur->next) { + if (cur == seq) + continue; + + if (BKE_sequence_check_depend(seq, cur)) { + BKE_sequencer_cache_cleanup_sequence(cur); + BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); + } + + if (cur->seqbase.first) + sequence_do_invalidate_dependent(seq, &cur->seqbase); + } +} + static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_self, int invalidate_preprocess) { Editing *ed = scene->ed; - Sequence *cur; /* invalidate cache for current sequence */ if (invalidate_self) @@ -3049,17 +3066,11 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); /* invalidate cache for all dependent sequences */ - SEQ_BEGIN (ed, cur) - { - if (cur == seq) - continue; - if (BKE_sequence_check_depend(seq, cur)) { - BKE_sequencer_cache_cleanup_sequence(cur); - BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); - } - } - SEQ_END + /* NOTE: can not use SEQ_BEGIN/SEQ_END here because that macro will change sequence's depth, + * which makes transformation routines work incorrect + */ + sequence_do_invalidate_dependent(seq, &ed->seqbase); } void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) @@ -3067,7 +3078,7 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) sequence_invalidate_cache(scene, seq, TRUE, TRUE); } -void BKE_sequence_invalidate_deendent(Scene *scene, Sequence *seq) +void BKE_sequence_invalidate_dependent(Scene *scene, Sequence *seq) { sequence_invalidate_cache(scene, seq, FALSE, TRUE); } @@ -3872,7 +3883,7 @@ static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) { if (seq) { BLI_strncpy(seq->name + 2, seq_load->name, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); if (seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) { seq_load->start_frame += (seq->enddisp - seq->startdisp); @@ -3959,10 +3970,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad sound = sound_new_file(bmain, seq_load->path); /* handles relative paths */ if (sound == NULL || sound->playback_handle == NULL) { - /* +#if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); - */ +#endif return NULL; } @@ -3971,10 +3982,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad if (info.specs.channels == AUD_CHANNELS_INVALID) { sound_delete(bmain, sound); - /* +#if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); - */ +#endif return NULL; } @@ -3983,7 +3994,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->type = SEQ_TYPE_SOUND_RAM; seq->sound = sound; BLI_strncpy(seq->name + 2, "Sound", SEQ_NAME_MAXSTR - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -4043,7 +4054,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -4155,7 +4166,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup } if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seqn); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqn); if (dupe_flag & SEQ_DUPE_ANIM) BKE_sequencer_dupe_animdata(scene, seq->name + 2, seqn->name + 2); @@ -4210,7 +4221,7 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase * /* called on draw, needs to be fast, * we could cache and use a flag if we want to make checks for file paths resolving for eg. */ -int BKE_seqence_is_valid_check(Sequence *seq) +int BKE_sequence_is_valid_check(Sequence *seq) { switch (seq->type) { case SEQ_TYPE_MASK: diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index bdd9b424f3b..9dd83181521 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1073,19 +1073,21 @@ void set_current_material_texture(Material *ma, Tex *newtex) { Tex *tex = NULL; bNode *node; - - if (ma && ma->use_nodes && ma->nodetree) { - node = nodeGetActiveID(ma->nodetree, ID_TE); - if (node) { - tex = (Tex *)node->id; - id_us_min(&tex->id); + if ((ma->use_nodes && ma->nodetree) && + (node = nodeGetActiveID(ma->nodetree, ID_TE))) + { + tex = (Tex *)node->id; + id_us_min(&tex->id); + if (newtex) { node->id = &newtex->id; id_us_plus(&newtex->id); - ma = NULL; + } + else { + node->id = NULL; } } - if (ma) { + else { int act = (int)ma->texact; tex = (ma->mtex[act]) ? ma->mtex[act]->tex : NULL; diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index e8d6336a994..c278370d211 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -96,6 +96,8 @@ void BLI_file_free_lines(struct LinkNode *lines); # ifndef O_BINARY # define O_BINARY 0 # endif +#else +void BLI_get_short_name(char short_name[256], const char *filename); #endif #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_lasso.h b/source/blender/blenlib/BLI_lasso.h index 85a000b000c..a7e90a51e86 100644 --- a/source/blender/blenlib/BLI_lasso.h +++ b/source/blender/blenlib/BLI_lasso.h @@ -34,8 +34,8 @@ struct rcti; -void BLI_lasso_boundbox(struct rcti *rect, int mcords[][2], short moves); -int BLI_lasso_is_point_inside(int mcords[][2], short moves, const int sx, const int sy, const int error_value); -int BLI_lasso_is_edge_inside(int mcords[][2], short moves, int x0, int y0, int x1, int y1, const int error_value); +void BLI_lasso_boundbox(struct rcti *rect, const int mcords[][2], const short moves); +int BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value); +int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value); #endif diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index 20d04f7881e..810b3b56386 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -233,7 +233,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, if (vi.grid) { \ vi.co = CCG_elem_co(vi.key, vi.grid); \ vi.fno = CCG_elem_no(vi.key, vi.grid); \ - vi.mask = CCG_elem_mask(vi.key, vi.grid); \ + vi.mask = vi.key->has_mask ? CCG_elem_mask(vi.key, vi.grid) : NULL; \ vi.grid = CCG_elem_next(vi.key, vi.grid); \ if (vi.gh) { \ if (BLI_BITMAP_GET(vi.gh, vi.gy * vi.gridsize + vi.gx)) \ diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 5bafb75d9c0..bdcb3cb9806 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -552,8 +552,8 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int case ID_ME: { Mesh *me = (Mesh *)id; - if (me->fdata.external) { - rewrite_path_fixed(me->fdata.external->filename, visit_cb, absbase, bpath_user_data); + if (me->ldata.external) { + rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data); } } break; diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 453463beaa8..1df904f617a 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -210,6 +210,22 @@ FILE *BLI_fopen(const char *filename, const char *mode) return ufopen(filename, mode); } +void BLI_get_short_name(char short_name[256], const char *filename) +{ + wchar_t short_name_16[256]; + int i = 0; + + UTF16_ENCODE(filename); + + GetShortPathNameW(filename_16, short_name_16, 256); + + for (i = 0; i < 256; i++) { + short_name[i] = (char)short_name_16[i]; + } + + UTF16_UN_ENCODE(filename); +} + void *BLI_gzopen(const char *filename, const char *mode) { gzFile gzfile; @@ -218,25 +234,15 @@ void *BLI_gzopen(const char *filename, const char *mode) return 0; } else { - wchar_t short_name_16[256]; char short_name[256]; - int i = 0; /* xxx Creates file before transcribing the path */ if (mode[0] == 'w') fclose(ufopen(filename, "a")); - UTF16_ENCODE(filename); - - GetShortPathNameW(filename_16, short_name_16, 256); - - for (i = 0; i < 256; i++) { - short_name[i] = (char)short_name_16[i]; - } + BLI_get_short_name(short_name, filename); gzfile = gzopen(short_name, mode); - - UTF16_UN_ENCODE(filename); } return gzfile; diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c index 7df4da80e16..5cd8bb813a1 100644 --- a/source/blender/blenlib/intern/lasso.c +++ b/source/blender/blenlib/intern/lasso.c @@ -37,7 +37,7 @@ #include "BLI_lasso.h" /* own include */ -void BLI_lasso_boundbox(rcti *rect, int mcords[][2], short moves) +void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const short moves) { short a; @@ -53,14 +53,14 @@ void BLI_lasso_boundbox(rcti *rect, int mcords[][2], short moves) } -int BLI_lasso_is_point_inside(int mcords[][2], short moves, +int BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value) { /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */ float angletot = 0.0, dot, ang, cross, fp1[2], fp2[2]; int a; - int *p1, *p2; + const int *p1, *p2; if (sx == error_value) { return 0; @@ -100,7 +100,7 @@ int BLI_lasso_is_point_inside(int mcords[][2], short moves, } /* edge version for lasso select. we assume boundbox check was done */ -int BLI_lasso_is_edge_inside(int mcords[][2], short moves, +int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value) { diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index c409e536b45..2cfe999e032 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -689,7 +689,7 @@ MINLINE void normal_float_to_short_v3(short out[3], const float in[3]) /********************************* Comparison ********************************/ -MINLINE int is_zero_v2(const float v[3]) +MINLINE int is_zero_v2(const float v[2]) { return (v[0] == 0 && v[1] == 0); } diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 0bd9e68cb71..d3d8d371f60 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -1169,14 +1169,10 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) break; case PBVH_FACES: GPU_update_mesh_buffers(node->draw_buffers, - bvh->faces, - node->prim_indices, - node->totprim, bvh->verts, node->vert_indices, node->uniq_verts + node->face_verts, - node->face_vert_indices, CustomData_get_layer(bvh->vdata, CD_PAINT_MASK)); break; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0f0a77ca9c1..b6c793bcdba 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -207,7 +207,7 @@ * - join all Mains * - link all LibBlocks and indirect pointers to libblocks * - initialize FileGlobal and copy pointers to Global -*/ + */ /* also occurs in library.c */ /* GS reads the memory pointed at in a specific ordering. There are, @@ -3666,7 +3666,14 @@ static void lib_link_mesh(FileData *fd, Main *main) if (me->mr && me->mr->levels.first) lib_link_customdata_mtface(fd, me, &me->mr->fdata, ((MultiresLevel*)me->mr->levels.first)->totface); - + } + } + + /* convert texface options to material */ + convert_tface_mt(fd, main); + + for (me = main->mesh.first; me; me = me->id.next) { + if (me->id.flag & LIB_NEED_LINK) { /*check if we need to convert mfaces to mpolys*/ if (me->totface && !me->totpoly) { /* temporarily switch main so that reading from @@ -3678,14 +3685,7 @@ static void lib_link_mesh(FileData *fd, Main *main) G.main = gmain; } - } - } - - /* convert texface options to material */ - convert_tface_mt(fd, main); - for (me = main->mesh.first; me; me = me->id.next) { - if (me->id.flag & LIB_NEED_LINK) { /* * Re-tessellate, even if the polys were just created from tessfaces, this * is important because it: @@ -3842,35 +3842,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) direct_link_customdata(fd, &mesh->ldata, mesh->totloop); direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); - -#ifdef USE_BMESH_FORWARD_COMPAT - /* NEVER ENABLE THIS CODE INTO BMESH! - * THIS IS FOR LOADING BMESH INTO OLDER FILES ONLY */ - mesh->mpoly = newdataadr(fd, mesh->mpoly); - mesh->mloop = newdataadr(fd, mesh->mloop); - - direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); - direct_link_customdata(fd, &mesh->ldata, mesh->totloop); - - if (mesh->mpoly) { - /* be clever and load polygons as mfaces */ - mesh->totface= BKE_mesh_mpoly_to_mface(&mesh->fdata, &mesh->ldata, &mesh->pdata, - mesh->totface, mesh->totloop, mesh->totpoly); - - CustomData_free(&mesh->pdata, mesh->totpoly); - memset(&mesh->pdata, 0, sizeof(CustomData)); - mesh->totpoly = 0; - - CustomData_free(&mesh->ldata, mesh->totloop); - memset(&mesh->ldata, 0, sizeof(CustomData)); - mesh->totloop = 0; - - mesh_update_customdata_pointers(mesh); - } - -#endif - - mesh->bb = NULL; mesh->edit_btmesh = NULL; @@ -4369,13 +4340,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->flow = NULL; smd->domain = NULL; smd->coll = newdataadr(fd, smd->coll); - smd->coll->smd = smd; if (smd->coll) { + smd->coll->smd = smd; smd->coll->points = NULL; smd->coll->numpoints = 0; } - else + else { smd->type = 0; + } } } else if (md->type == eModifierType_DynamicPaint) { @@ -7255,6 +7227,15 @@ static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUS } } +static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) + if (node->type == SH_NODE_TEX_COORD) + node->flag |= NODE_OPTIONS; +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -8196,6 +8177,34 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* correction for files saved in blender version when BKE_pose_copy_data + * didn't copy animation visualization, which lead to deadlocks on motion + * path calculation for proxied armatures, see [#32742] + */ + if (main->versionfile < 264) { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + if (ob->pose) { + if (ob->pose->avs.path_step == 0) { + animviz_settings_init(&ob->pose->avs); + } + } + } + } + + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 1)) { + bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); + bNodeTree *ntree; + + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_coord_from_dupli_264); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + if (ntree->type==NTREE_SHADER) + do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree); + } + /* default values in Freestyle settings */ { Scene *sce; diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index a4f190c8167..a3cfa4413a8 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -652,7 +652,7 @@ static void do_versions_seq_unique_name_all_strips(Scene * sce, ListBase *seqbas Sequence * seq = seqbasep->first; while (seq) { - BKE_seqence_base_unique_name_recursive(&sce->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&sce->ed->seqbase, seq); if (seq->seqbase.first) { do_versions_seq_unique_name_all_strips(sce, &seq->seqbase); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 6fb7faae69c..e6d68294cf4 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -30,46 +30,46 @@ /* -FILEFORMAT: IFF-style structure (but not IFF compatible!) - -start file: - BLENDER_V100 12 bytes (versie 1.00) - V = big endian, v = little endian - _ = 4 byte pointer, - = 8 byte pointer - -datablocks: also see struct BHead - <bh.code> 4 chars - <bh.len> int, len data after BHead - <bh.old> void, old pointer - <bh.SDNAnr> int - <bh.nr> int, in case of array: amount of structs - data - ... - ... - -Almost all data in Blender are structures. Each struct saved -gets a BHead header. With BHead the struct can be linked again -and compared with StructDNA . - -WRITE - -Preferred writing order: (not really a must, but why would you do it random?) -Any case: direct data is ALWAYS after the lib block - -(Local file data) -- for each LibBlock - - write LibBlock - - write associated direct data -(External file data) -- per library - - write library block - - per LibBlock - - write the ID of LibBlock -- write TEST (128x128, blend file preview, optional) -- write FileGlobal (some global vars) -- write SDNA -- write USER if filename is ~/X.XX/config/startup.blend -*/ + * FILEFORMAT: IFF-style structure (but not IFF compatible!) + * + * start file: + * BLENDER_V100 12 bytes (versie 1.00) + * V = big endian, v = little endian + * _ = 4 byte pointer, - = 8 byte pointer + * + * datablocks: also see struct BHead + * <bh.code> 4 chars + * <bh.len> int, len data after BHead + * <bh.old> void, old pointer + * <bh.SDNAnr> int + * <bh.nr> int, in case of array: amount of structs + * data + * ... + * ... + * + * Almost all data in Blender are structures. Each struct saved + * gets a BHead header. With BHead the struct can be linked again + * and compared with StructDNA . + * + * WRITE + * + * Preferred writing order: (not really a must, but why would you do it random?) + * Any case: direct data is ALWAYS after the lib block + * + * (Local file data) + * - for each LibBlock + * - write LibBlock + * - write associated direct data + * (External file data) + * - per library + * - write library block + * - per LibBlock + * - write the ID of LibBlock + * - write TEST (128x128, blend file preview, optional) + * - write FileGlobal (some global vars) + * - write SDNA + * - write USER if filename is ~/X.XX/config/startup.blend + */ #include <math.h> diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 691465388e9..6ccd0cbc491 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -902,8 +902,9 @@ BMesh *BM_mesh_copy(BMesh *bm_old) } f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, FALSE); - if (!f2) + if (UNLIKELY(f2 == NULL)) { continue; + } /* use totface in case adding some faces fails */ BM_elem_index_set(f2, (bm_new->totface - 1)); /* set_inline */ diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index ccbbb6f170b..d50c94d5e6a 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1021,7 +1021,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del /* create region face */ newf = BM_face_create_ngon(bm, v1, v2, edges, tote, FALSE); - if (!newf || BMO_error_occurred(bm)) { + if (UNLIKELY(!newf || BMO_error_occurred(bm))) { if (!BMO_error_occurred(bm)) err = "Invalid boundary region to join faces"; goto error; diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index e6827b1f2cd..b0a9168ffda 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -314,7 +314,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) f = BM_face_create(bm, verts, fedges, mpoly->totloop, FALSE); - if (!f) { + if (UNLIKELY(f == NULL)) { printf("%s: Warning! Bad face in mesh" " \"%s\" at index %d!, skipping\n", __func__, me->id.name + 2, i); diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 8210ea973e6..10a9d511c77 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -475,7 +475,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) BLI_array_append(edges, e); f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), FALSE); - if (!f) { + if (UNLIKELY(f == NULL)) { printf("%s: could not make face!\n", __func__); continue; } @@ -592,7 +592,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) *d3 = (d1 + d2) * 0.5f; } - if (!f) { + if (UNLIKELY(f == NULL)) { fprintf(stderr, "%s: face index out of range! (bmesh internal error)\n", __func__); continue; } @@ -771,7 +771,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) continue; f = BM_face_create_ngon(bm, lastv, vstart, edges, BLI_array_count(edges), FALSE); - if (!f) { + if (UNLIKELY(f == NULL)) { fprintf(stderr, "%s: in bevel vert fill! (bmesh internal error)\n", __func__); } else { diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index bb2e49d043c..fde475c2d6a 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -506,7 +506,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) vv2[i2next], vv1[i1next], f_example, TRUE); - if (!f || f->len != 4) { + if (UNLIKELY((f == NULL) || (f->len != 4))) { fprintf(stderr, "%s: in bridge! (bmesh internal error)\n", __func__); } else { diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index 519778cb638..731170f963c 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -275,8 +275,9 @@ static int UNUSED_FUNCTION(rotsys_fill_faces)(BMesh *bm, EdgeData *edata, VertDa continue; f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), TRUE); - if (!f) + if (UNLIKELY(f == NULL)) { continue; + } } } diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index c8be7c9ce34..81cad277bee 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -87,7 +87,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, f, EXT_DEL); f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, FALSE); - if (!f2) { + if (UNLIKELY(f2 == NULL)) { BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed; could not create face"); BLI_array_free(edges); return; @@ -104,6 +104,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op) l4 = l2->next; f3 = BM_face_create_quad_tri(bm, l3->v, l4->v, l2->v, l->v, f, FALSE); + /* XXX, no error check here, why? - Campbell */ l_tmp = BM_FACE_FIRST_LOOP(f3); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 4d4f26561e3..f37f065b03b 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -88,8 +88,8 @@ extern "C" { /* - COLLADA Importer limitations: - - no multiple scene import, all objects are added to active scene + * COLLADA Importer limitations: + * - no multiple scene import, all objects are added to active scene */ // #define COLLADA_DEBUG @@ -878,7 +878,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) } break; /* XXX correct way to do following four is probably to get also render - size and determine proper settings from that somehow */ + * size and determine proper settings from that somehow */ case COLLADAFW::Camera::ASPECTRATIO_AND_X: case COLLADAFW::Camera::SINGLE_X: case COLLADAFW::Camera::X_AND_Y: diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h index 13f23b23388..e878a5a5b48 100644 --- a/source/blender/collada/DocumentImporter.h +++ b/source/blender/collada/DocumentImporter.h @@ -78,8 +78,9 @@ public: void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*); void translate_anim_recursive(COLLADAFW::Node*, COLLADAFW::Node*, Object*); - /** This method will be called if an error in the loading process occurred and the loader cannot - continue to load. The writer should undo all operations that have been performed. + /** + * This method will be called if an error in the loading process occurred and the loader cannot + * continue to load. The writer should undo all operations that have been performed. \param errorMessage A message containing informations about the error that occurred. */ void cancel(const COLLADAFW::String& errorMessage); diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 27700444ba9..e2332b7cd55 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -358,8 +358,8 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) param.push_back("X"); param.push_back("Y"); param.push_back("Z"); - /*main function, it creates <source id = "">, <float_array id = "" - count = ""> */ + /* main function, it creates <source id = "">, <float_array id = "" + * count = ""> */ source.prepareToAppendValues(); //appends data to <float_array> int i = 0; diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 5bd2f78d8a6..5cfc29ecce2 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -95,6 +95,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont operationx->setbNode(editorNode); operationx->setData(data); operationx->setQuality(quality); + operationx->setFalloff(PROP_SMOOTH); this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph); // this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); // no size input yet graph->addOperation(operationx); @@ -102,6 +103,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont operationy->setbNode(editorNode); operationy->setData(data); operationy->setQuality(quality); + operationy->setFalloff(PROP_SMOOTH); this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket()); graph->addOperation(operationy); addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0)); diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 984119b926a..3ab60a1faa9 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -108,8 +108,10 @@ void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *d void GaussianXBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); - MEM_freeN(this->m_gausstab); - this->m_gausstab = NULL; + if (this->m_gausstab) { + MEM_freeN(this->m_gausstab); + this->m_gausstab = NULL; + } deinitMutex(); } diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index 192bc29e1ae..7ab00b202e1 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -109,8 +109,10 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d void GaussianYBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); - MEM_freeN(this->m_gausstab); - this->m_gausstab = NULL; + if (this->m_gausstab) { + MEM_freeN(this->m_gausstab); + this->m_gausstab = NULL; + } deinitMutex(); } diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index fe6ebcebf97..1fa484ea2b6 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -24,7 +24,7 @@ MapUVOperation::MapUVOperation() : NodeOperation() { - this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addInputSocket(COM_DT_VECTOR); this->addOutputSocket(COM_DT_COLOR); this->m_alpha = 0.0f; diff --git a/source/blender/compositor/operations/COM_MixColorOperation.cpp b/source/blender/compositor/operations/COM_MixColorOperation.cpp index f8aca92abc7..56aca27eaef 100644 --- a/source/blender/compositor/operations/COM_MixColorOperation.cpp +++ b/source/blender/compositor/operations/COM_MixColorOperation.cpp @@ -53,9 +53,12 @@ void MixColorOperation::executePixel(float output[4], float x, float y, PixelSam float tmpr, tmpg, tmpb; rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb); - output[0] = valuem * (inputColor1[0]) + value * tmpr; - output[1] = valuem * (inputColor1[1]) + value * tmpg; - output[2] = valuem * (inputColor1[2]) + value * tmpb; + output[0] = (valuem * inputColor1[0]) + (value * tmpr); + output[1] = (valuem * inputColor1[1]) + (value * tmpg); + output[2] = (valuem * inputColor1[2]) + (value * tmpb); + } + else { + copy_v3_v3(output, inputColor1); } output[3] = inputColor1[3]; diff --git a/source/blender/compositor/operations/COM_MixGlareOperation.cpp b/source/blender/compositor/operations/COM_MixGlareOperation.cpp index b6a9aa3da3c..1c6555206da 100644 --- a/source/blender/compositor/operations/COM_MixGlareOperation.cpp +++ b/source/blender/compositor/operations/COM_MixGlareOperation.cpp @@ -40,9 +40,13 @@ void MixGlareOperation::executePixel(float output[4], float x, float y, PixelSam value = inputValue[0]; float mf = 2.f - 2.f * fabsf(value - 0.5f); - output[0] = mf * ((inputColor1[0]) + value * (inputColor2[0] - inputColor1[0])); - output[1] = mf * ((inputColor1[1]) + value * (inputColor2[1] - inputColor1[1])); - output[2] = mf * ((inputColor1[2]) + value * (inputColor2[2] - inputColor1[2])); + if (inputColor1[0] < 0.0f) inputColor1[0] = 0.0f; + if (inputColor1[1] < 0.0f) inputColor1[1] = 0.0f; + if (inputColor1[2] < 0.0f) inputColor1[2] = 0.0f; + + output[0] = mf * max(inputColor1[0] + value * (inputColor2[0] - inputColor1[0]), 0.0f); + output[1] = mf * max(inputColor1[1] + value * (inputColor2[1] - inputColor1[1]), 0.0f); + output[2] = mf * max(inputColor1[2] + value * (inputColor2[2] - inputColor1[2]), 0.0f); output[3] = inputColor1[3]; clampIfNeeded(output); diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index c8b6a4ee330..b3c2df7230f 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -129,7 +129,7 @@ void OutputSingleLayerOperation::deinitExecution() if (this->getWidth() * this->getHeight() != 0) { int size = get_datatype_size(this->m_datatype); - ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), size * 8, 0); + ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), this->m_format->planes, 0); Main *bmain = G.main; /* TODO, have this passed along */ char filename[FILE_MAX]; diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index 3a9e6f25cd9..b934719a92b 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -35,8 +35,8 @@ #include "BLI_listbase.h" /** - * Class with implementation of green screen gradient rasterization - */ + * Class with implementation of green screen gradient rasterization + */ class TrackPositionOperation : public NodeOperation { protected: enum { @@ -58,8 +58,8 @@ protected: float m_relativePos[2]; /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); public: diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp index 7e23e7290f8..5e4f90b0269 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cpp +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -69,7 +69,7 @@ void ZCombineAlphaOperation::executePixel(float output[4], float x, float y, Pix this->m_depth1Reader->read(depth1, x, y, sampler); this->m_depth2Reader->read(depth2, x, y, sampler); - if (depth1[0] < depth2[0]) { + if (depth1[0] <= depth2[0]) { this->m_image1Reader->read(color1, x, y, sampler); this->m_image2Reader->read(color2, x, y, sampler); } @@ -79,10 +79,10 @@ void ZCombineAlphaOperation::executePixel(float output[4], float x, float y, Pix } float fac = color1[3]; float ifac = 1.0f - fac; - output[0] = color1[0] + ifac * color2[0]; - output[1] = color1[1] + ifac * color2[1]; - output[2] = color1[2] + ifac * color2[2]; - output[3] = MAX2(color1[3], color2[3]); + output[0] = fac * color1[0] + ifac * color2[0]; + output[1] = fac * color1[1] + ifac * color2[1]; + output[2] = fac * color1[2] + ifac * color2[2]; + output[3] = max(color1[3], color2[3]); } void ZCombineOperation::deinitExecution() diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index cf84eb04b10..bc07bf091de 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -50,7 +50,9 @@ void ANIM_OT_keyframe_delete(struct wmOperatorType *ot); * required for each space. */ void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot); + void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot); +void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot); /* Keyframe managment operators for UI buttons (RMB menu). */ void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index e24a4d49a05..f2711ec3bb5 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -290,6 +290,7 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_keyframe_delete); WM_operatortype_append(ANIM_OT_keyframe_insert_menu); WM_operatortype_append(ANIM_OT_keyframe_delete_v3d); + WM_operatortype_append(ANIM_OT_keyframe_clear_v3d); WM_operatortype_append(ANIM_OT_keyframe_insert_button); WM_operatortype_append(ANIM_OT_keyframe_delete_button); WM_operatortype_append(ANIM_OT_keyframe_clear_button); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 1791d84d90b..0454e88e320 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1186,10 +1186,9 @@ static int modify_key_op_poll(bContext *C) /* if Outliner, don't allow in some views */ if (so) { - if (ELEM4(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_VERSE_SESSION, SO_VERSE_SESSION)) - return 0; - if (ELEM3(so->outlinevis, SO_SEQUENCE, SO_USERDEF, SO_KEYMAP)) + if (ELEM5(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_SEQUENCE, SO_USERDEF, SO_KEYMAP)) { return 0; + } } /* TODO: checks for other space types can be added here */ @@ -1440,46 +1439,122 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot) } /* Delete Key Operator ------------------------ */ - -/* XXX WARNING: - * This is currently just a basic operator, which work in 3d-view context on objects only. - * Should this be kept? It does have advantages over a version which requires selecting a keyingset to use... - * -- Joshua Leung, Jan 2009 +/* NOTE: Although this version is simpler than the more generic version for KeyingSets, + * it is more useful for animators working in the 3D view. */ +static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + /* just those in active action... */ + if ((ob->adt) && (ob->adt->action)) { + AnimData *adt = ob->adt; + bAction *act = adt->action; + FCurve *fcu, *fcn; + + for (fcu = act->curves.first; fcu; fcu = fcn) { + short can_delete = FALSE; + + fcn = fcu->next; + + /* in pose mode, only delete the F-Curve if it belongs to a selected bone */ + if (ob->mode & OB_MODE_POSE) { + if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) { + bPoseChannel *pchan; + char *bone_name; + + /* get bone-name, and check if this bone is selected */ + bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + if (bone_name) MEM_freeN(bone_name); + + /* delete if bone is selected*/ + if ((pchan) && (pchan->bone)) { + if (pchan->bone->flag & BONE_SELECTED) + can_delete = TRUE; + } + } + } + else { + /* object mode - all of Object's F-Curves are affected */ + can_delete = TRUE; + } + + /* delete F-Curve completely */ + if (can_delete) { + ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); + } + } + } + + /* update... */ + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + /* send updates */ + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Animation"; + ot->description = "Remove all keyframe animation for selected objects"; + ot->idname = "ANIM_OT_keyframe_clear_v3d"; + + /* callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = clear_anim_v3d_exec; + + ot->poll = ED_operator_areaactive; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + static int delete_key_v3d_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; - // XXX more comprehensive tests will be needed CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - ID *id = (ID *)ob; - FCurve *fcu, *fcn; - short success = 0; + ID *id = &ob->id; + int success = 0; - /* loop through all curves in animdata and delete keys on this frame */ + /* just those in active action... */ if ((ob->adt) && (ob->adt->action)) { AnimData *adt = ob->adt; bAction *act = adt->action; + FCurve *fcu, *fcn; for (fcu = act->curves.first; fcu; fcu = fcn) { fcn = fcu->next; + + /* delete keyframes on current frame + * WARNING: this can delete the next F-Curve, hence the "fcn" copying + */ success += delete_keyframe(op->reports, id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0); } } - BKE_reportf(op->reports, RPT_INFO, "Ob '%s' - Successfully had %d keyframes removed", id->name + 2, success); - + /* report success (or failure) */ + BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %d keyframes removed", id->name + 2, success); ob->recalc |= OB_RECALC_OB; } CTX_DATA_END; /* send updates */ DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); return OPERATOR_FINISHED; @@ -1489,7 +1564,7 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete Keyframe"; - ot->description = "Remove keyframes on current frame for selected object"; + ot->description = "Remove keyframes on current frame for selected objects"; ot->idname = "ANIM_OT_keyframe_delete_v3d"; /* callbacks */ @@ -1512,7 +1587,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) PointerRNA ptr = {{NULL}}; PropertyRNA *prop = NULL; char *path; - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; short success = 0; int a, index, length, all = RNA_boolean_get(op->ptr, "all"); short flag = 0; @@ -1683,20 +1758,20 @@ static int clear_key_button_exec(bContext *C, wmOperator *op) if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); - + if (path) { if (all) { length = RNA_property_array_length(&ptr, prop); - + if (length) index = 0; else length = 1; } else length = 1; - + for (a = 0; a < length; a++) success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index + a, 0); - + MEM_freeN(path); } else if (G.debug & G_DEBUG) @@ -1710,9 +1785,9 @@ static int clear_key_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ uiContextAnimUpdate(C); - + DAG_ids_flush_update(bmain, 0); - + /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index b8b89785e17..707594ff590 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -1831,7 +1831,7 @@ void ED_armature_deselect_all_visible(Object *obedit) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { /* first and foremost, bone must be visible and selected */ - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } @@ -4106,7 +4106,7 @@ static void select_similar_length(bArmature *arm, EditBone *ebone_act, const flo const float len_max = ebone_act->length * (1.0f + thresh); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { if ((ebone->length >= len_min) && (ebone->length <= len_max)) { @@ -4123,7 +4123,7 @@ static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const sub_v3_v3v3(dir_act, ebone_act->head, ebone_act->tail); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { float dir[3]; sub_v3_v3v3(dir, ebone->head, ebone->tail); @@ -4139,7 +4139,7 @@ static void select_similar_layer(bArmature *arm, EditBone *ebone_act) EditBone *ebone; for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { if (ebone->layer & ebone_act->layer) { ED_armature_edit_bone_select(ebone); } @@ -4161,7 +4161,7 @@ static void select_similar_prefix(bArmature *arm, EditBone *ebone_act) /* Find matches */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { char prefix_other[MAX_VGROUP_NAME]; BKE_deform_split_prefix(ebone->name, prefix_other, body_tmp); if (!strcmp(prefix_act, prefix_other)) { @@ -4185,7 +4185,7 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act) /* Find matches */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { char suffix_other[MAX_VGROUP_NAME]; BKE_deform_split_suffix(ebone->name, body_tmp, suffix_other); if (!strcmp(suffix_act, suffix_other)) { @@ -4270,7 +4270,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) for (curbone = arm->edbo->first; curbone; curbone = curbone->next) { /* only work on bone if it is visible and its selection can change */ - if (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, curbone)) { if (curbone == arm->act_edbone) { if (direction == BONE_SELECT_PARENT) { if (curbone->parent == NULL) continue; @@ -4290,7 +4290,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) chbone = editbone_get_child(arm, curbone, 1); if (chbone == NULL) continue; - if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, chbone)) { chbone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_edbone = chbone; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index f3f985fa97d..5ba4a232250 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -41,6 +41,8 @@ #include "BLI_graph.h" #include "BLI_ghash.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_sketch.h" @@ -175,7 +177,7 @@ void BIF_makeListTemplates(const bContext *C) const char *BIF_listTemplates(const bContext *UNUSED(C)) { GHashIterator ghi; - char menu_header[] = "Template%t|None%x0|"; + const char *menu_header = IFACE_("Template %t|None %x0|"); char *p; if (TEMPLATES_MENU != NULL) { @@ -194,7 +196,7 @@ const char *BIF_listTemplates(const bContext *UNUSED(C)) Object *ob = BLI_ghashIterator_getValue(&ghi); int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi)); - p += sprintf(p, "|%s%%x%i", ob->id.name + 2, key); + p += sprintf(p, "|%s %%x%i", ob->id.name + 2, key); BLI_ghashIterator_step(&ghi); } @@ -644,16 +646,17 @@ static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], in short pval[2]; int pdist; - ED_view3d_project_short_noclip(ar, stk->points[i].p, pval); + if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); + pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - if (pdist < *dist) { - *dist = pdist; - pt = stk->points + i; + if (pdist < *dist) { + *dist = pdist; + pt = stk->points + i; - if (index != NULL) { - *index = i; + if (index != NULL) { + *index = i; + } } } } @@ -679,32 +682,34 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { copy_v3_v3(vec, bone->head); mul_m4_v3(ob->obmat, vec); - ED_view3d_project_short_noclip(ar, vec, pval); + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); + pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - if (pdist < *dist) - { - *dist = pdist; - pt = &boneSnap; - copy_v3_v3(pt->p, vec); - pt->type = PT_EXACT; + if (pdist < *dist) + { + *dist = pdist; + pt = &boneSnap; + copy_v3_v3(pt->p, vec); + pt->type = PT_EXACT; + } } } copy_v3_v3(vec, bone->tail); mul_m4_v3(ob->obmat, vec); - ED_view3d_project_short_noclip(ar, vec, pval); + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); + pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - if (pdist < *dist) - { - *dist = pdist; - pt = &boneSnap; - copy_v3_v3(pt->p, vec); - pt->type = PT_EXACT; + if (pdist < *dist) + { + *dist = pdist; + pt = &boneSnap; + copy_v3_v3(pt->p, vec); + pt->type = PT_EXACT; + } } } @@ -905,9 +910,9 @@ static void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, for (i = start; i <= end; i++) { float ray_start[3], ray_normal[3]; float delta = len_v3v3(stk->points[i].p, stk->points[i + 1].p); - float pval[2]; + float pval[2] = {0, 0}; - ED_view3d_project_float(ar, stk->points[i].p, pval); + ED_view3d_project_float_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP); ED_view3d_win_to_ray(ar, v3d, pval, ray_start, ray_normal); mul_v3_fl(ray_normal, distance * progress / length); @@ -934,10 +939,14 @@ 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() */ - ED_view3d_project_short_noclip(ar, fp, cval); - VECSUB2D(mval_f, cval, dd->mval); - ED_view3d_win_to_delta(ar, mval_f, dvec); - sub_v3_v3v3(vec, fp, dvec); + if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + VECSUB2D(mval_f, cval, dd->mval); + ED_view3d_win_to_delta(ar, mval_f, dvec); + sub_v3_v3v3(vec, fp, dvec); + } + else { + zero_v3(vec); + } } static int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *UNUSED(sketch), SK_Stroke *stk, SK_DrawData *dd) @@ -1453,8 +1462,8 @@ static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gestu float s_p2[3] = {0, 0, 0}; int g_i; - ED_view3d_project_float(ar, gesture->points[s_i].p, s_p1); - ED_view3d_project_float(ar, gesture->points[s_i + 1].p, s_p2); + ED_view3d_project_float_global(ar, gesture->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, gesture->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP); /* start checking from second next, because two consecutive cannot intersect */ for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++) { @@ -1463,8 +1472,8 @@ static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gestu float vi[3]; float lambda; - ED_view3d_project_float(ar, gesture->points[g_i].p, g_p1); - ED_view3d_project_float(ar, gesture->points[g_i + 1].p, g_p2); + ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP); if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) { SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); @@ -1531,8 +1540,8 @@ static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, S float s_p2[3] = {0, 0, 0}; int g_i; - ED_view3d_project_float(ar, stk->points[s_i].p, s_p1); - ED_view3d_project_float(ar, stk->points[s_i + 1].p, s_p2); + ED_view3d_project_float_global(ar, stk->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, stk->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP); for (g_i = 0; g_i < gesture->nb_points - 1; g_i++) { float g_p1[3] = {0, 0, 0}; @@ -1540,8 +1549,8 @@ static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, S float vi[3]; float lambda; - ED_view3d_project_float(ar, gesture->points[g_i].p, g_p1); - ED_view3d_project_float(ar, gesture->points[g_i + 1].p, g_p2); + ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP); if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) { SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); @@ -1717,8 +1726,8 @@ void sk_applyCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UN SK_Intersection *isect; int command = 1; -// XXX -// command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); +/* XXX */ +/* command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); */ if (command < 1) return; for (isect = gest->intersections.first; isect; isect = isect->next) { @@ -1784,33 +1793,35 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc short start_val[2], end_val[2]; short dist; - ED_view3d_project_short_noclip(ar, gest->stk->points[0].p, start_val); - ED_view3d_project_short_noclip(ar, sk_lastStrokePoint(gest->stk)->p, end_val); + 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)) + { - dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); + dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); - /* if gesture is a circle */ - if (dist <= 20) { - SK_Intersection *isect; + /* if gesture is a circle */ + if (dist <= 20) { + SK_Intersection *isect; - /* check if it circled around an exact point */ - for (isect = gest->intersections.first; isect; isect = isect->next) { - /* only delete strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) { - int start_index, end_index; - int i; + /* check if it circled around an exact point */ + for (isect = gest->intersections.first; isect; isect = isect->next) { + /* only delete strokes that are crossed twice */ + if (isect->next && isect->next->stroke == isect->stroke) { + int start_index, end_index; + int i; - start_index = MIN2(isect->after, isect->next->after); - end_index = MAX2(isect->before, isect->next->before); + start_index = MIN2(isect->after, isect->next->after); + end_index = MAX2(isect->before, isect->next->before); - for (i = start_index; i <= end_index; i++) { - if (isect->stroke->points[i].type == PT_EXACT) { - return 1; /* at least one exact point found, stop detect here */ + for (i = start_index; i <= end_index; i++) { + if (isect->stroke->points[i].type == PT_EXACT) { + return 1; /* at least one exact point found, stop detect here */ + } } - } - /* skip next */ - isect = isect->next; + /* skip next */ + isect = isect->next; + } } } } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 346ed0002bd..522622ec5c4 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1113,6 +1113,9 @@ typedef struct MeshDeformBind { /* direct solver */ int *varidx; + + BVHTree *bvhtree; + BVHTreeFromMesh bvhdata; } MeshDeformBind; typedef struct MeshDeformIsect { @@ -1130,8 +1133,9 @@ typedef struct MeshDeformIsect { /* our own triangle intersection, so we can fully control the epsilons and * prevent corner case from going wrong*/ -static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], - float vert1[3], float vert2[3], float *isectco, float *uvw) +static int meshdeform_tri_intersect(const float orig[3], const float end[3], const float vert0[3], + const float vert1[3], const float vert2[3], + float r_isectco[3], float r_uvw[3]) { float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; float det, inv_det, u, v, dir[3], isectdir[3]; @@ -1148,8 +1152,10 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], /* if determinant is near zero, ray lies in plane of triangle */ det = dot_v3v3(edge1, pvec); - if (det == 0.0f) + if (UNLIKELY(det == 0.0f)) { return 0; + } + inv_det = 1.0f / det; /* calculate distance from vert0 to ray origin */ @@ -1168,16 +1174,16 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], if (v < -EPSILON || u + v > 1.0f + EPSILON) return 0; - isectco[0] = (1.0f - u - v) * vert0[0] + u * vert1[0] + v * vert2[0]; - isectco[1] = (1.0f - u - v) * vert0[1] + u * vert1[1] + v * vert2[1]; - isectco[2] = (1.0f - u - v) * vert0[2] + u * vert1[2] + v * vert2[2]; + r_isectco[0] = (1.0f - u - v) * vert0[0] + u * vert1[0] + v * vert2[0]; + r_isectco[1] = (1.0f - u - v) * vert0[1] + u * vert1[1] + v * vert2[1]; + r_isectco[2] = (1.0f - u - v) * vert0[2] + u * vert1[2] + v * vert2[2]; - uvw[0] = 1.0f - u - v; - uvw[1] = u; - uvw[2] = v; + r_uvw[0] = 1.0f - u - v; + r_uvw[1] = u; + r_uvw[2] = v; /* check if it is within the length of the line segment */ - sub_v3_v3v3(isectdir, isectco, orig); + sub_v3_v3v3(isectdir, r_isectco, orig); if (dot_v3v3(dir, isectdir) < -EPSILON) return 0; @@ -1188,83 +1194,77 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], return 1; } -static int meshdeform_intersect(MeshDeformBind *mdb, MeshDeformIsect *isec) -{ - MFace *mface; - float face[4][3], co[3], uvw[3], len, nor[3], end[3]; - int f, hit, is = 0, totface; - - isec->labda = 1e10; - - mface = mdb->cagedm->getTessFaceArray(mdb->cagedm); - totface = mdb->cagedm->getNumTessFaces(mdb->cagedm); - - add_v3_v3v3(end, isec->start, isec->vec); - - for (f = 0; f < totface; f++, mface++) { - copy_v3_v3(face[0], mdb->cagecos[mface->v1]); - copy_v3_v3(face[1], mdb->cagecos[mface->v2]); - copy_v3_v3(face[2], mdb->cagecos[mface->v3]); - - if (mface->v4) { - copy_v3_v3(face[3], mdb->cagecos[mface->v4]); - hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); - - if (hit) { - normal_tri_v3(nor, face[0], face[1], face[2]); - } - else { - hit = meshdeform_tri_intersect(isec->start, end, face[0], face[2], face[3], co, uvw); - normal_tri_v3(nor, face[0], face[2], face[3]); - } - } - else { - hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); - normal_tri_v3(nor, face[0], face[1], face[2]); - } - - if (hit) { - len = len_v3v3(isec->start, co) / len_v3v3(isec->start, end); - if (len < isec->labda) { - isec->labda = len; - isec->face = mface; - isec->isect = (dot_v3v3(isec->vec, nor) <= 0.0f); - is = 1; - } - } +static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) + { + void **data = userdata; + MeshDeformBind *mdb = data[1]; + MFace *mface = data[0], *mf; + MeshDeformIsect *isec = data[2]; + float no[3], co[3], end[3], uvw[3], dist, face[4][3]; + + mf = mface + index; + + copy_v3_v3(face[0], mdb->cagecos[mf->v1]); + copy_v3_v3(face[1], mdb->cagecos[mf->v2]); + copy_v3_v3(face[2], mdb->cagecos[mf->v3]); + if (mf->v4) + copy_v3_v3(face[3], mdb->cagecos[mf->v4]); + + add_v3_v3v3(end, isec->start, isec->vec); + + if (!meshdeform_tri_intersect(ray->origin, end, face[0], face[1], face[2], co, uvw)) + if (!mf->v4 || !meshdeform_tri_intersect(ray->origin, end, face[0], face[2], face[3], co, uvw)) + return; + + if (!mf->v4) + normal_tri_v3(no, face[0], face[1], face[2]); + else + normal_quad_v3(no, face[0], face[1], face[2], face[3]); + + dist = len_v3v3(ray->origin, co)/len_v3(isec->vec); + if (dist < hit->dist) { + hit->index = index; + hit->dist = dist; + copy_v3_v3(hit->co, co); + + isec->isect = dot_v3v3(no, ray->direction) <= 0.0; + isec->labda = dist; + isec->face = mf; } - - return is; } static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float *co1, float *co2) { MDefBoundIsect *isect; - MeshDeformIsect isec; + BVHTreeRayHit hit; + MeshDeformIsect isect_mdef; float (*cagecos)[3]; - MFace *mface; + void *data[3] = {mdb->cagedm->getTessFaceArray(mdb->cagedm), mdb, &isect_mdef}; + MFace *mface1 = data[0], *mface; float vert[4][3], len, end[3]; static float epsilon[3] = {0, 0, 0}; //1e-4, 1e-4, 1e-4}; /* setup isec */ - memset(&isec, 0, sizeof(isec)); - isec.labda = 1e10f; + memset(&isect_mdef, 0, sizeof(isect_mdef)); + isect_mdef.labda = 1e10f; - add_v3_v3v3(isec.start, co1, epsilon); + add_v3_v3v3(isect_mdef.start, co1, epsilon); add_v3_v3v3(end, co2, epsilon); - sub_v3_v3v3(isec.vec, end, isec.start); + sub_v3_v3v3(isect_mdef.vec, end, isect_mdef.start); - if (meshdeform_intersect(mdb, &isec)) { - len = isec.labda; - mface = (MFace *)isec.face; + 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; + isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ isect = BLI_memarena_alloc(mdb->memarena, sizeof(*isect)); /* compute intersection coordinate */ - isect->co[0] = co1[0] + isec.vec[0] * len; - isect->co[1] = co1[1] + isec.vec[1] * len; - isect->co[2] = co1[2] + isec.vec[2] * len; + isect->co[0] = co1[0] + isect_mdef.vec[0] * len; + isect->co[1] = co1[1] + isect_mdef.vec[1] * len; + isect->co[2] = co1[2] + isect_mdef.vec[2] * len; isect->len = len_v3v3(co1, isect->co); if (isect->len < MESHDEFORM_LEN_THRESHOLD) @@ -1276,7 +1276,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float isect->v[3] = mface->v4; isect->nvert = (mface->v4) ? 4 : 3; - isect->facing = isec.isect; + isect->facing = isect_mdef.isect; /* compute mean value coordinates for interpolation */ cagecos = mdb->cagecos; @@ -1766,7 +1766,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi"); mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect"); mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound"); - + mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6); mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside"); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) @@ -1882,6 +1882,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa MEM_freeN(mdb->boundisect); MEM_freeN(mdb->semibound); BLI_memarena_free(mdb->memarena); + free_bvhtree_from_mesh(&mdb->bvhdata); } #if 0 diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 2f5eaabc12b..189b2e977c2 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -492,7 +492,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (pchan->parent == NULL) continue; else pabone = pchan->parent->bone; - if (PBONE_VISIBLE(arm, pabone)) { + if (PBONE_SELECTABLE(arm, pabone)) { if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; pabone->flag |= BONE_SELECTED; arm->act_bone = pabone; @@ -514,7 +514,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) for (pchan_child = ob->pose->chanbase.first; pchan_child; pchan_child = pchan_child->next) { /* possible we have multiple children, some invisible */ - if (PBONE_VISIBLE(arm, pchan_child->bone)) { + if (PBONE_SELECTABLE(arm, pchan_child->bone)) { if (pchan_child->parent == pchan) { chbone = pchan_child->bone; break; @@ -526,7 +526,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (chbone == NULL) continue; #endif - if (PBONE_VISIBLE(arm, chbone)) { + if (PBONE_SELECTABLE(arm, chbone)) { if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; chbone->flag |= BONE_SELECTED; arm->act_bone = chbone; @@ -719,9 +719,7 @@ static int pose_select_same_keyingset(bContext *C, Object *ob, short extend) if (pchan) { /* select if bone is visible and can be affected */ - if ((PBONE_VISIBLE(arm, pchan->bone)) && - (pchan->bone->flag & BONE_UNSELECTABLE) == 0) - { + if (PBONE_SELECTABLE(arm, pchan->bone)) { pchan->bone->flag |= BONE_SELECTED; changed = 1; } @@ -888,16 +886,16 @@ static void pose_copy_menu(Scene *scene) if (pose_has_protected_selected(ob, 0)) { i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5"); else - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4"); } else { i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8"); else - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8"); } if (nr <= 0) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 9c13f4be6a9..afd6bc4c4b5 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6567,18 +6567,18 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) if (!isSurf) { /* adding curve */ if (obedit == NULL || obedit->type != OB_CURVE) { Curve *cu; - + obedit = ED_object_add_type(C, OB_CURVE, loc, rot, TRUE, layer); newob = 1; cu = (Curve *)obedit->data; cu->flag |= CU_DEFORM_FILL; - + if (type & CU_PRIM_PATH) cu->flag |= CU_PATH | CU_3D; - } + } else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - } + } else { /* adding surface */ if (obedit == NULL || obedit->type != OB_SURF) { obedit = ED_object_add_type(C, OB_SURF, loc, rot, TRUE, layer); @@ -6589,7 +6589,6 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) /* rename here, the undo stack checks name for valid undo pushes */ if (newob) { - if (obedit->type == OB_CURVE) { rename_id((ID *)obedit, get_curve_defname(type)); rename_id((ID *)obedit->data, get_curve_defname(type)); @@ -6599,11 +6598,11 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) rename_id((ID *)obedit->data, get_surf_defname(type)); } } - + /* ED_object_add_type doesnt do an undo, is needed for redo operator on primitive */ if (newob && enter_editmode) ED_undo_push(C, "Enter Editmode"); - + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); nu = add_nurbs_primitive(C, obedit, mat, type, newob); @@ -6643,12 +6642,11 @@ void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot) ot->name = "Add Bezier"; ot->description = "Construct a Bezier Curve"; ot->idname = "CURVE_OT_primitive_bezier_curve_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_bezier_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6666,12 +6664,11 @@ void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot) ot->name = "Add Bezier Circle"; ot->description = "Construct a Bezier Circle"; ot->idname = "CURVE_OT_primitive_bezier_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_bezier_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6689,12 +6686,11 @@ void CURVE_OT_primitive_nurbs_curve_add(wmOperatorType *ot) ot->name = "Add Nurbs Curve"; ot->description = "Construct a Nurbs Curve"; ot->idname = "CURVE_OT_primitive_nurbs_curve_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_curve_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6712,12 +6708,11 @@ void CURVE_OT_primitive_nurbs_circle_add(wmOperatorType *ot) ot->name = "Add Nurbs Circle"; ot->description = "Construct a Nurbs Circle"; ot->idname = "CURVE_OT_primitive_nurbs_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6735,12 +6730,11 @@ void CURVE_OT_primitive_nurbs_path_add(wmOperatorType *ot) ot->name = "Add Path"; ot->description = "Construct a Path"; ot->idname = "CURVE_OT_primitive_nurbs_path_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_curve_path_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6759,12 +6753,11 @@ void SURFACE_OT_primitive_nurbs_surface_curve_add(wmOperatorType *ot) ot->name = "Add Surface Curve"; ot->description = "Construct a Nurbs surface Curve"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_curve_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_curve_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6782,12 +6775,11 @@ void SURFACE_OT_primitive_nurbs_surface_circle_add(wmOperatorType *ot) ot->name = "Add Surface Circle"; ot->description = "Construct a Nurbs surface Circle"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6805,12 +6797,11 @@ void SURFACE_OT_primitive_nurbs_surface_surface_add(wmOperatorType *ot) ot->name = "Add Surface Patch"; ot->description = "Construct a Nurbs surface Patch"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_surface_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_surface_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6828,12 +6819,11 @@ void SURFACE_OT_primitive_nurbs_surface_cylinder_add(wmOperatorType *ot) ot->name = "Add Surface Cylinder"; ot->description = "Construct a Nurbs surface Cylinder"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_cylinder_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_cylinder_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6851,12 +6841,11 @@ void SURFACE_OT_primitive_nurbs_surface_sphere_add(wmOperatorType *ot) ot->name = "Add Surface Sphere"; ot->description = "Construct a Nurbs surface Sphere"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_sphere_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_sphere_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6874,12 +6863,11 @@ void SURFACE_OT_primitive_nurbs_surface_torus_add(wmOperatorType *ot) ot->name = "Add Surface Torus"; ot->description = "Construct a Nurbs surface Torus"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_torus_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_torus_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index d90ec02b0c1..8a3c996a481 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -75,17 +75,15 @@ static void gp_ui_activelayer_cb(bContext *C, void *gpd, void *gpl) /* make sure the layer we want to remove is the active one */ gpencil_layer_setactive(gpd, gpl); - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); /* XXX please work! */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } /* delete 'active' layer */ static void gp_ui_dellayer_cb(bContext *C, void *gpd, void *gpl) { - /* make sure the layer we want to remove is the active one */ - gpencil_layer_setactive(gpd, gpl); - gpencil_layer_delactive(gpd); + gpencil_layer_delete((bGPdata *)gpd, (bGPDlayer *)gpl); - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); /* XXX please work! */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 659e99607f0..46df8ba5fac 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -224,7 +224,7 @@ static int gp_data_add_exec(bContext *C, wmOperator *op) } /* notifiers */ - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); // XXX need a nicer one that will work + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -272,7 +272,7 @@ static int gp_data_unlink_exec(bContext *C, wmOperator *op) } /* notifiers */ - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); // XXX need a nicer one that will work + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -306,10 +306,10 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op) *gpd_ptr = gpencil_data_addnew("GPencil"); /* add new layer now */ - gpencil_layer_addnew(*gpd_ptr); + gpencil_layer_addnew(*gpd_ptr, "GP_Layer", 1); /* notifiers */ - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); // XXX please work! + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -360,7 +360,7 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op) gpencil_layer_delframe(gpl, gpf); /* notifiers */ - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); // XXX please work! + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 5909c4fc270..de7c2c41a6d 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -278,11 +278,15 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] gp_get_3d_reference(p, rvec); /* method taken from editview.c - mouse_cursor() */ - ED_view3d_project_int_noclip(p->ar, rvec, mval_prj); - - VECSUB2D(mval_f, mval_prj, mval); - ED_view3d_win_to_delta(p->ar, mval_f, dvec); - sub_v3_v3v3(out, rvec, dvec); + /* 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) { + VECSUB2D(mval_f, mval_prj, mval); + ED_view3d_win_to_delta(p->ar, mval_f, dvec); + sub_v3_v3v3(out, rvec, dvec); + } + else { + zero_v3(out); + } } } @@ -808,9 +812,14 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, else if (gps->totpoints == 1) { /* get coordinates */ if (gps->flag & GP_STROKE_3DSPACE) { - ED_view3d_project_int(p->ar, &gps->points->x, xyval); - x0 = xyval[0]; - y0 = xyval[1]; + 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); @@ -847,13 +856,22 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* get coordinates */ if (gps->flag & GP_STROKE_3DSPACE) { - ED_view3d_project_int(p->ar, &pt1->x, xyval); - x0 = xyval[0]; - y0 = xyval[1]; - - ED_view3d_project_int(p->ar, &pt2->x, xyval); - x1 = xyval[0]; - y1 = xyval[1]; + 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); @@ -1125,7 +1143,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) /* get active layer (or add a new one if non-existent) */ p->gpl = gpencil_layer_getactive(p->gpd); if (p->gpl == NULL) { - p->gpl = gpencil_layer_addnew(p->gpd); + p->gpl = gpencil_layer_addnew(p->gpd, "GP_Layer", 1); if (p->custom_color[3]) copy_v3_v3(p->gpl->color, p->custom_color); @@ -1598,7 +1616,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) gpencil_draw_exit(C, op); /* refreshes */ - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); // XXX need a nicer one that will work + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* done */ return OPERATOR_FINISHED; @@ -1659,7 +1677,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event) //printf("\tGP - hotkey invoked... waiting for click-drag\n"); } - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL, NULL); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* add a modal handler for this operator, so that we can then draw continuous strokes */ WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -1772,7 +1790,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) estate = OPERATOR_RUNNING_MODAL; /* stroke could be smoothed, send notifier to refresh screen */ - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); } else { //printf("\t\tGP - end of stroke + op\n"); @@ -1862,7 +1880,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) case OPERATOR_FINISHED: /* one last flush before we're done */ gpencil_draw_exit(C, op); - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); // XXX need a nicer one that will work + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); break; case OPERATOR_CANCELLED: diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c index fa9f5196866..3d2cd260fb9 100644 --- a/source/blender/editors/gpencil/gpencil_undo.c +++ b/source/blender/editors/gpencil/gpencil_undo.c @@ -111,7 +111,7 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name) } } - WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 4e33404be7e..b9996c87194 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -94,6 +94,7 @@ typedef struct EditBone { /* useful macros */ #define EBONE_VISIBLE(arm, ebone) (((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)) /* used in bone_select_hierachy() */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 02c7d52f08d..093872c79f6 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -138,7 +138,7 @@ int EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, sh int EDBM_backbuf_check(unsigned int index); void EDBM_backbuf_free(void); -int EDBM_backbuf_border_mask_init(struct ViewContext *vc, int mcords[][2], short tot, +int EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax); int EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); @@ -149,7 +149,7 @@ struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, int *dist); int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short deselect, short toggle); void EDBM_selectmode_set(struct BMEditMesh *em); -void EDBM_selectmode_convert(struct BMEditMesh *em, short selectmode_old, const short selectmode_new); +void EDBM_selectmode_convert(struct BMEditMesh *em, const short selectmode_old, const short selectmode_new); void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select); @@ -174,7 +174,7 @@ void ED_spacetypes_init(void); /* editmesh_tools.c (could be moved) */ -void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct Object *obedit, struct BMEditMesh *em); +void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEditMesh *em); /* editface.c */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 26c8b865377..9836d690e53 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -126,7 +126,6 @@ float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob, const float loc[3], const float rot[3], float primmat[][4]); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); -int ED_object_add_generic_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, float loc[3], float rot[3], int *enter_editmode, unsigned int *layer, int *is_view_aligned); diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index 0076b08da99..dee97c7882a 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -61,7 +61,7 @@ void PE_update_object(struct Scene *scene, struct Object *ob, int useflag); int PE_mouse_particles(struct bContext *C, const int mval[2], int extend, int deselect, int toggle); int PE_border_select(struct bContext *C, struct rcti *rect, int select, int extend); int PE_circle_select(struct bContext *C, int selecting, const int mval[2], float rad); -int PE_lasso_select(struct bContext *C, int mcords[][2], short moves, short extend, short select); +int PE_lasso_select(struct bContext *C, const int mcords[][2], const short moves, short extend, short select); void PE_deselect_all_visible(struct PTCacheEdit *edit); /* undo */ diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index e908868df75..0381ecc1fb3 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -45,8 +45,12 @@ void sculpt_get_redraw_planes(float planes[4][4], struct ARegion *ar, void ED_sculpt_force_update(struct bContext *C); float *ED_sculpt_get_last_stroke(struct Object *ob); int ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]); -void ED_sculpt_mask_layers_ensure(struct Object *ob, +int ED_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd); +enum { + ED_SCULPT_MASK_LAYER_CALC_VERT = (1 << 0), + ED_SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1) +}; /* paint_ops.c */ void ED_operatortypes_paint(void); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 9536dd76581..b81e08ed7ef 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -40,9 +40,11 @@ struct BPoint; struct BezTriple; struct BezTriple; struct BoundBox; +struct EditBone; struct ImBuf; struct MVert; struct Main; +struct MetaElem; struct Nurb; struct Nurb; struct Object; @@ -113,15 +115,49 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* TODO, these functions work quite differently, we should make them behave in a uniform way * otherwise we can't be sure bugs are not added when we need to move from short->float types for eg * - Campbell */ -void ED_view3d_project_short(struct ARegion *ar, const float co[3], short r_co[2]); -void ED_view3d_project_short_noclip(struct ARegion *ar, const float vec[3], short r_co[2]); -void ED_view3d_project_int(struct ARegion *ar, const float co[3], int r_co[2]); -void ED_view3d_project_int_noclip(struct ARegion *ar, const float co[3], int r_co[2]); -void ED_view3d_project_float(struct ARegion *ar, const float co[3], float r_co[2]); -void ED_view3d_project_float_noclip(struct ARegion *ar, const float co[3], float r_co[2]); + + +/* return values for ED_view3d_project_...() */ +typedef enum { + V3D_PROJ_RET_SUCCESS = 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 */ + V3D_PROJ_RET_OVERFLOW = 4 /* outside range (mainly for short), (can't avoid) */ +} eV3DProjStatus; + +/* some clipping tests are optional */ +typedef enum { + V3D_PROJ_TEST_NOP = 0, + V3D_PROJ_TEST_CLIP_BB = (1 << 0), + V3D_PROJ_TEST_CLIP_WIN = (1 << 1), +} eV3DProjTest; + + +/* *** 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); + +/* *** 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); + +/* *** 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); + 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]); +/* 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); @@ -135,7 +171,11 @@ void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, 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]); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 32132f497a8..5d2709f0488 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -421,7 +421,6 @@ void uiBlockSetDirection(uiBlock *block, int direction); void uiBlockFlipOrder(uiBlock *block); void uiBlockSetFlag(uiBlock *block, int flag); void uiBlockClearFlag(uiBlock *block, int flag); -void uiBlockSetXOfs(uiBlock *block, int xofs); int uiButGetRetVal(uiBut *but); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 810cbc25862..2c00e39766c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -996,24 +996,20 @@ void ui_fontscale(short *points, float aspect) /* project button or block (but==NULL) to pixels in regionspace */ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but) { - float gx, gy; - float getsizex, getsizey; + rctf rectf = (but)? but->rect: block->rect; - getsizex = ar->winx; - getsizey = ar->winy; + ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin); + ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax); - gx = (but ? but->rect.xmin : block->rect.xmin) + (block->panel ? block->panel->ofsx : 0.0f); - gy = (but ? but->rect.ymin : block->rect.ymin) + (block->panel ? block->panel->ofsy : 0.0f); - - rect->xmin = floorf(getsizex * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0]))); - rect->ymin = floorf(getsizey * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1]))); - - gx = (but ? but->rect.xmax : block->rect.xmax) + (block->panel ? block->panel->ofsx : 0.0f); - gy = (but ? but->rect.ymax : block->rect.ymax) + (block->panel ? block->panel->ofsy : 0.0f); - - rect->xmax = floorf(getsizex * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0]))); - rect->ymax = floorf(getsizey * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1]))); + rectf.xmin -= ar->winrct.xmin; + rectf.ymin -= ar->winrct.ymin; + rectf.xmax -= ar->winrct.xmin; + rectf.ymax -= ar->winrct.ymin; + rect->xmin = floorf(rectf.xmin); + rect->ymin = floorf(rectf.ymin); + rect->xmax = floorf(rectf.xmax); + rect->ymax = floorf(rectf.ymax); } /* uses local copy of style, to scale things down, and allow widgets to change stuff */ @@ -2160,8 +2156,6 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor wm_subwindow_getmatrix(window, region->swinid, block->winmat); wm_subwindow_getsize(window, region->swinid, &getsizex, &getsizey); - /* TODO - investigate why block->winmat[0][0] is negative - * in the image view when viewRedrawForce is called */ block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); } else { @@ -3423,11 +3417,6 @@ void uiBlockClearFlag(uiBlock *block, int flag) block->flag &= ~flag; } -void uiBlockSetXOfs(uiBlock *block, int xofs) -{ - block->xofs = xofs; -} - void uiButSetFlag(uiBut *but, int flag) { but->flag |= flag; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index bfa9cc2727c..60e4c2aa90f 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2167,6 +2167,16 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data) } } +int ui_button_open_menu_direction(uiBut *but) +{ + uiHandleButtonData *data = but->active; + + if (data && data->menu) + return data->menu->direction; + + return 0; +} + /* ***************** events for different button types *************** */ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index b48c9bcab7e..b4b0686d6fc 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -315,7 +315,6 @@ struct uiBlock { char tooltipdisabled; /* to avoid tooltip after click */ char endblock; /* uiEndBlock done? */ - float xofs, yofs; /* offset to parent button */ eBlockBoundsCalc bounds_type; /* for doing delayed */ int mx, my; int bounds, minbounds; /* for doing delayed */ @@ -365,7 +364,8 @@ extern void ui_set_but_hsv(uiBut *but); extern void ui_get_but_vectorf(uiBut *but, float vec[3]); extern void ui_set_but_vectorf(uiBut *but, const float vec[3]); -extern void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my); +extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect, + const float mx, const float my); extern void ui_get_but_string(uiBut *but, char *str, size_t maxlen); extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen); @@ -418,6 +418,9 @@ struct uiPopupBlockHandle { int menuretval; float retvalue; float retvec[4]; + + /* menu direction */ + int direction; }; uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but); @@ -480,6 +483,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wc extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but); extern void ui_button_active_free(const struct bContext *C, uiBut *but); extern int ui_button_is_active(struct ARegion *ar); +extern int ui_button_open_menu_direction(uiBut *but); /* interface_widgets.c */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 8ffbcd6d399..7a369019ac4 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2870,12 +2870,12 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); RNA_string_set(&op_ptr, "operator", op->type->idname); - op_ptr = uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMIN, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); + uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMIN, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); RNA_string_set(&op_ptr, "operator", op->type->idname); RNA_boolean_set(&op_ptr, "remove_active", TRUE); - op_ptr = uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMOUT, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); + uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMOUT, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); } if (op->type->ui) { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 605233cd96f..4dafb4b2d4b 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1341,6 +1341,14 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, ui_block_to_window_fl(butregion, but->block, &butrct.xmin, &butrct.ymin); ui_block_to_window_fl(butregion, but->block, &butrct.xmax, &butrct.ymax); + /* widget_roundbox_set has this correction too, keep in sync */ + if (but->type != PULLDOWN) { + if (but->flag & UI_BUT_ALIGN_TOP) + butrct.ymax += 1.0f; + if (but->flag & UI_BUT_ALIGN_LEFT) + butrct.xmin -= 1.0f; + } + /* calc block rect */ if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { if (block->buttons.first) { @@ -1467,9 +1475,6 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, } } - /* apply requested offset in the block */ - xof += block->xofs / block->aspect; - yof += block->yofs / block->aspect; #if 0 /* clamp to window bounds, could be made into an option if its ever annoying */ if ( (offscreen = (block->rect.ymin + yof)) < 0) yof -= offscreen; /* bottom */ @@ -1659,12 +1664,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut /* if this is being created from a button */ if (but) { - if (ELEM(but->type, BLOCK, PULLDOWN)) - block->xofs = -2; /* for proper alignment */ - block->aspect = but->block->aspect; ui_block_position(window, butregion, but, block); + handle->direction = block->direction; } else { /* keep a list of these, needed for pulldown menus */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 9a41d32e8ca..974d492a364 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -363,6 +363,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str type = idptr.type; if (flag & UI_ID_PREVIEWS) { + template->preview = TRUE; but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, TIP_(template_id_browse_tip(type))); @@ -375,7 +376,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str uiButSetFlag(but, UI_BUT_DISABLED); uiLayoutRow(layout, TRUE); - template->preview = 1; } else if (flag & UI_ID_BROWSE) { but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 87a7d1957c5..3fc20309264 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1889,53 +1889,47 @@ static void ui_hsv_cursor(float x, float y) } -void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my) +void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect, + const float mx, const float my) { /* duplication of code... well, simple is better now */ - float centx = BLI_rcti_cent_x_fl(rect); - float centy = BLI_rcti_cent_y_fl(rect); - float radius, dist; - - if (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect)) - radius = (float)BLI_rcti_size_y(rect) / 2; - else - radius = (float)BLI_rcti_size_x(rect) / 2; + const float centx = BLI_rcti_cent_x_fl(rect); + const float centy = BLI_rcti_cent_y_fl(rect); + const float radius = (float)mini(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + const float m_delta[2] = {mx - centx, my - centy}; + const float dist_squared = len_squared_v2(m_delta); - mx -= centx; - my -= centy; - dist = sqrt(mx * mx + my * my); - if (dist < radius) - *valdist = dist / radius; - else - *valdist = 1.0f; - - *valrad = atan2f(mx, my) / (2.0f * (float)M_PI) + 0.5f; + *val_dist = (dist_squared < (radius * radius)) ? sqrtf(dist_squared) / radius : 1.0f; + *val_rad = atan2f(m_delta[0], m_delta[1]) / (2.0f * (float)M_PI) + 0.5f; } -static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect) +static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *rect) { + const int tot = 32; + const float radstep = 2.0f * (float)M_PI / (float)tot; + + const float centx = BLI_rcti_cent_x_fl(rect); + const float centy = BLI_rcti_cent_y_fl(rect); + float radius = (float)mini(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + /* gouraud triangle fan */ - float radstep, ang = 0.0f; - float centx, centy, radius, cursor_radius; + const float *hsv_ptr = ui_block_hsv_get(but->block); + float ang = 0.0f; + float cursor_radius; float rgb[3], hsvo[3], hsv[3], col[3], colcent[3]; - int a, tot = 32; + int a; int color_profile = but->block->color_profile; if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) color_profile = FALSE; - radstep = 2.0f * (float)M_PI / (float)tot; - centx = BLI_rcti_cent_x_fl(rect); - centy = BLI_rcti_cent_y_fl(rect); - - if (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect)) - radius = (float)BLI_rcti_size_y(rect) / 2; - else - radius = (float)BLI_rcti_size_x(rect) / 2; - /* color */ ui_get_but_vectorf(but, rgb); - /* copy_v3_v3(hsv, ui_block_hsv_get(but->block)); */ /* UNUSED */ + + /* since we use compat functions on both 'hsv' and 'hsvo', they need to be initialized */ + hsvo[0] = hsv[0] = hsv_ptr[0]; + hsvo[1] = hsv[1] = hsv_ptr[1]; + hsvo[2] = hsv[2] = hsv_ptr[2]; rgb_to_hsv_compat_v(rgb, hsvo); @@ -2708,16 +2702,16 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat *wcol = wcol_backup; } -static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) +static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { if (state & UI_ACTIVE) { uiWidgetBase wtb; - float rad = 0.5f * BLI_rcti_size_y(rect); /* 4.0f */ - + float rad = 0.25f * BLI_rcti_size_y(rect); /* 4.0f */ + widget_init(&wtb); - + /* half rounded */ - round_box_edges(&wtb, UI_CNR_ALL, rect, rad); + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); } @@ -3054,9 +3048,12 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) static int widget_roundbox_set(uiBut *but, rcti *rect) { + int roundbox = UI_CNR_ALL; + /* alignment */ - if (but->flag & UI_BUT_ALIGN) { + if ((but->flag & UI_BUT_ALIGN) && but->type != PULLDOWN) { + /* ui_block_position has this correction too, keep in sync */ if (but->flag & UI_BUT_ALIGN_TOP) rect->ymax += 1; if (but->flag & UI_BUT_ALIGN_LEFT) @@ -3064,27 +3061,50 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) switch (but->flag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: - return UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; + roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; + break; case UI_BUT_ALIGN_DOWN: - return UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; + roundbox = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; + break; case UI_BUT_ALIGN_LEFT: - return UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT; + roundbox = UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT; + break; case UI_BUT_ALIGN_RIGHT: - return UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; + roundbox = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; + break; case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT: - return UI_CNR_TOP_LEFT; + roundbox = UI_CNR_TOP_LEFT; + break; case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT: - return UI_CNR_TOP_RIGHT; + roundbox = UI_CNR_TOP_RIGHT; + break; case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT: - return UI_CNR_BOTTOM_LEFT; + roundbox = UI_CNR_BOTTOM_LEFT; + break; case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT: - return UI_CNR_BOTTOM_RIGHT; + roundbox = UI_CNR_BOTTOM_RIGHT; + break; default: - return 0; + roundbox = 0; + break; } } - return UI_CNR_ALL; + /* align with open menu */ + 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); + } + + return roundbox; } /* conversion from old to new buttons, so still messy */ diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index 57be5a2234a..25fb9cb6430 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -30,10 +30,10 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc - ${GLEW_INCLUDE_PATH} ) set(INC_SYS + ${GLEW_INCLUDE_PATH} ) set(SRC diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index fe6567424b6..a60b771d179 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -202,16 +202,16 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, glLineWidth(3); glColor4ubv(rgb_gray); glBegin(GL_LINES); - glVertex3fv(vert); - glVertex3fv(handle); + glVertex2fv(vert); + glVertex2fv(handle); glEnd(); glLineWidth(1); } glColor3ubv(rgb_spline); glBegin(GL_LINES); - glVertex3fv(vert); - glVertex3fv(handle); + glVertex2fv(vert); + glVertex2fv(handle); glEnd(); } @@ -226,7 +226,7 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, glColor3f(0.5f, 0.5f, 0.0f); glBegin(GL_POINTS); - glVertex3fv(vert); + glVertex2fv(vert); glEnd(); /* draw handle points */ @@ -242,7 +242,7 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, } glBegin(GL_POINTS); - glVertex3fv(handle); + glVertex2fv(handle); glEnd(); } } diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 55bad39f4f2..69cfdf4e51b 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -485,7 +485,7 @@ void MASK_OT_select_border(wmOperatorType *ot) WM_operator_properties_gesture_border(ot, TRUE); } -static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, short select) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -549,7 +549,7 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short static int clip_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index a677f1272a3..5fd848ccb13 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -426,7 +426,7 @@ void seam_mark_clear_tface(Scene *scene, short mode) if (me == 0 || me->totpoly == 0) return; if (mode == 0) - mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2"); + mode = pupmenu("Seams %t|Mark Border Seam %x1|Clear Seam %x2"); if (mode != 1 && mode != 2) return; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index fdaddec5246..0cf4ac48bf7 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -64,7 +64,7 @@ static Object *make_prim_init(bContext *C, const char *idname, *state = 0; if (obedit == NULL || obedit->type != OB_MESH) { obedit = ED_object_add_type(C, OB_MESH, loc, rot, FALSE, layer); - + rename_id((ID *)obedit, idname); rename_id((ID *)obedit->data, idname); @@ -103,7 +103,7 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Plane", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -125,12 +125,11 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) ot->name = "Add Plane"; ot->description = "Construct a filled planar mesh with 4 vertices"; ot->idname = "MESH_OT_primitive_plane_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_plane_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -145,7 +144,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -153,7 +152,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) { return OPERATOR_CANCELLED; } - + /* BMESH_TODO make plane side this: M_SQRT2 - plane (diameter of 1.41 makes it unit size) */ make_prim_finish(C, obedit, &state, enter_editmode); @@ -166,12 +165,11 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) ot->name = "Add Cube"; ot->description = "Construct a cube mesh"; ot->idname = "MESH_OT_primitive_cube_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_cube_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -192,10 +190,10 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; - + cap_end = RNA_enum_get(op->ptr, "fill_type"); cap_tri = (cap_end == 2); - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -207,9 +205,9 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); - + return OPERATOR_FINISHED; } @@ -221,15 +219,14 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot) ot->name = "Add Circle"; ot->description = "Construct a circle mesh"; ot->idname = "MESH_OT_primitive_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); @@ -247,10 +244,10 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; - + cap_end = RNA_enum_get(op->ptr, "end_fill_type"); cap_tri = (cap_end == 2); - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Cylinder", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -266,9 +263,9 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); - + return OPERATOR_FINISHED; } @@ -280,15 +277,14 @@ void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) ot->name = "Add Cylinder"; ot->description = "Construct a cylinder mesh"; ot->idname = "MESH_OT_primitive_cylinder_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_cylinder_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); @@ -308,10 +304,10 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; - + cap_end = RNA_enum_get(op->ptr, "end_fill_type"); cap_tri = (cap_end == 2); - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Cone", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -324,7 +320,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); return OPERATOR_FINISHED; @@ -338,15 +334,14 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) ot->name = "Add Cone"; ot->description = "Construct a conic mesh"; ot->idname = "MESH_OT_primitive_cone_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_cone_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); prop = RNA_def_float(ot->srna, "radius1", 1.0f, 0.0, FLT_MAX, "Radius 1", "", 0.001, 100.00); @@ -368,7 +363,7 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -381,8 +376,9 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); + return OPERATOR_FINISHED; } @@ -394,15 +390,14 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) ot->name = "Add Grid"; ot->description = "Construct a grid mesh"; ot->idname = "MESH_OT_primitive_grid_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_grid_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000); RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000); @@ -420,19 +415,20 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) int enter_editmode; int state, view_aligned; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &view_aligned); if (!view_aligned) rot[0] += (float)M_PI / 2.0f; - + obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); + return OPERATOR_FINISHED; } @@ -442,12 +438,11 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) ot->name = "Add Monkey"; ot->description = "Construct a Suzanne mesh"; ot->idname = "MESH_OT_primitive_monkey_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_monkey_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -462,7 +457,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -474,7 +469,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); return OPERATOR_FINISHED; @@ -488,15 +483,14 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) ot->name = "Add UV Sphere"; ot->description = "Construct a UV sphere mesh"; ot->idname = "MESH_OT_primitive_uv_sphere_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_uvsphere_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "segments", 32, 3, INT_MAX, "Segments", "", 3, 500); RNA_def_int(ot->srna, "ring_count", 16, 3, INT_MAX, "Rings", "", 3, 500); @@ -514,7 +508,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Icosphere", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -527,10 +521,10 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) @@ -541,15 +535,14 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) ot->name = "Add Ico Sphere"; ot->description = "Construct an Icosphere mesh"; ot->idname = "MESH_OT_primitive_ico_sphere_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_icosphere_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "subdivisions", 2, 1, INT_MAX, "Subdivisions", "", 1, 8); prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 790fd0a7cf1..4f4fc27582c 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -73,6 +73,9 @@ #define KMAXDIST 10 /* max mouse distance from edge before not detecting it */ +#define KNIFE_FLT_EPS 0.00001f +#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS) + typedef struct KnifeColors { unsigned char line[3]; unsigned char edge[3]; @@ -430,7 +433,7 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float float perc, cageco[3], l12; l12 = len_v3v3(kfe->v1->co, kfe->v2->co); - if (l12 < FLT_EPSILON * 80) { + if (l12 < KNIFE_FLT_EPS) { copy_v3_v3(cageco, kfe->v1->cageco); } else { @@ -446,8 +449,8 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float } else { /* kfe cuts across an existing face. - If v1 and v2 are in multiple faces together (e.g., if they - are in doubled polys) then this arbitrarily chooses one of them */ + * If v1 and v2 are in multiple faces together (e.g., if they + * are in doubled polys) then this arbitrarily chooses one of them */ f = knife_find_common_face(&kfe->v1->faces, &kfe->v2->faces); if (f) knife_append_list(kcd, &newkfe->v2->faces, f); @@ -589,7 +592,7 @@ static void knife_sort_linehits(KnifeTool_OpData *kcd) * successor faces connected to the linehits at either end of the range */ for (i = 0; i < kcd->totlinehit - 1; i = nexti) { for (j = i + 1; j < kcd->totlinehit; j++) { - if (fabsf(kcd->linehits[j].l - kcd->linehits[i].l) > 80 * FLT_EPSILON) + if (fabsf(kcd->linehits[j].l - kcd->linehits[i].l) > KNIFE_FLT_EPS) break; } nexti = j; @@ -797,7 +800,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd) for (i = 0; i < kcd->totlinehit; i++, (lastlh = lh), lh++) { BMFace *f = lastlh ? lastlh->f : lh->f; - if (lastlh && len_v3v3(lastlh->hit, lh->hit) == 0.0f) { + if (lastlh && len_squared_v3v3(lastlh->hit, lh->hit) == 0.0f) { if (!firstlh) firstlh = lastlh; continue; @@ -816,13 +819,13 @@ static void knife_add_cut(KnifeTool_OpData *kcd) lastlh = firstlh = NULL; } - if (len_v3v3(kcd->prev.cage, lh->realhit) < FLT_EPSILON * 80) + if (len_squared_v3v3(kcd->prev.cage, lh->realhit) < KNIFE_FLT_EPS_SQUARED) continue; - if (len_v3v3(kcd->curr.cage, lh->realhit) < FLT_EPSILON * 80) + if (len_squared_v3v3(kcd->curr.cage, lh->realhit) < KNIFE_FLT_EPS_SQUARED) continue; /* first linehit may be down face parallel to view */ - if (!lastlh && fabsf(lh->l) < FLT_EPSILON * 80) + if (!lastlh && fabsf(lh->l) < KNIFE_FLT_EPS) continue; if (kcd->prev.is_space) { @@ -843,7 +846,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd) copy_v3_v3(kcd->curr.cage, lh->cagehit); /* don't draw edges down faces parallel to view */ - if (lastlh && fabsf(lastlh->l - lh->l) < FLT_EPSILON * 80) { + if (lastlh && fabsf(lastlh->l - lh->l) < KNIFE_FLT_EPS) { kcd->prev = kcd->curr; continue; } @@ -1044,6 +1047,9 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) } if (kcd->totlinehit > 0) { + const float vthresh4 = kcd->vthresh / 4.0f; + const float vthresh4_squared = vthresh4 * vthresh4; + BMEdgeHit *lh; int i; @@ -1062,12 +1068,12 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) knife_project_v3(kcd, lh->kfe->v2->cageco, sv2); knife_project_v3(kcd, lh->cagehit, lh->schit); - if (len_v2v2(lh->schit, sv1) < kcd->vthresh / 4.0f) { + if (len_squared_v2v2(lh->schit, sv1) < vthresh4_squared) { copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco); glVertex3fv(lh->cagehit); lh->v = lh->kfe->v1; } - else if (len_v2v2(lh->schit, sv2) < kcd->vthresh / 4.0f) { + else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_squared) { copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco); glVertex3fv(lh->cagehit); lh->v = lh->kfe->v2; @@ -1136,11 +1142,11 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) static float len_v3_tri_side_max(const float v1[3], const float v2[3], const float v3[3]) { - const float s1 = len_v3v3(v1, v2); - const float s2 = len_v3v3(v2, v3); - const float s3 = len_v3v3(v3, v1); + const float s1 = len_squared_v3v3(v1, v2); + const float s2 = len_squared_v3v3(v2, v3); + const float s3 = len_squared_v3v3(v3, v1); - return MAX3(s1, s2, s3); + return sqrtf(MAX3(s1, s2, s3)); } static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, @@ -1158,7 +1164,7 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, /* for comparing distances, error of intersection depends on triangle scale. * need to scale down before squaring for accurate comparison */ - const float depsilon = 50 *FLT_EPSILON * len_v3_tri_side_max(v1, v2, v3); + const float depsilon = (KNIFE_FLT_EPS / 2.0f) * len_v3_tri_side_max(v1, v2, v3); const float depsilon_squared = depsilon * depsilon; copy_v3_v3(cos + 0, v1); @@ -1985,7 +1991,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd) ScanFillFace *sf_tri; ScanFillVert *sf_vert, *sf_vert_last; int j; - float rndscale = FLT_EPSILON * 25; + float rndscale = (KNIFE_FLT_EPS / 4.0f); f = faces[i]; BLI_smallhash_init(hash); @@ -3058,14 +3064,9 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event) { - Object *obedit; + Object *obedit = CTX_data_edit_object(C); KnifeTool_OpData *kcd = op->customdata; - if (!C) { - return OPERATOR_FINISHED; - } - - obedit = CTX_data_edit_object(C); if (!obedit || obedit->type != OB_MESH || BMEdit_FromObject(obedit) != kcd->em) { knifetool_exit(C, op); ED_area_headerprint(CTX_wm_area(C), NULL); @@ -3129,6 +3130,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event) break; case KNF_MODAL_CUT_THROUGH_TOGGLE: kcd->cut_through = !kcd->cut_through; + knifetool_update_mval(kcd, event->mval); /* refresh knife path */ knife_update_header(C, kcd); break; case KNF_MODAL_NEW_CUT: diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 53b877f2a6e..001d584416f 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -57,7 +57,7 @@ /* 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[2], const float mvalf[2]) + const float co1[3], const float co2[3], const float mvalf[2]) { float vec1[3], vec2[3]; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index f6ae661a369..ae2d090fef3 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -131,7 +131,7 @@ unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; /* set in dr static char *selbuf = NULL; /* opengl doesn't support concave... */ -static void draw_triangulated(int mcords[][2], short tot) +static void draw_triangulated(const int mcords[][2], const short tot) { ListBase lb = {NULL, NULL}; DispList *dl; @@ -227,7 +227,7 @@ void EDBM_backbuf_free(void) * - grab again and compare * returns 'OK' */ -int EDBM_backbuf_border_mask_init(ViewContext *vc, int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) +int EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { unsigned int *dr, *drm; struct ImBuf *buf, *bufmask; @@ -448,7 +448,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } /* returns labda for closest distance v1 to line-piece v2 - v3 */ -float labda_PdistVL2Dfl(const float v1[3], const float v2[3], const float v3[3]) +float labda_PdistVL2Dfl(const float v1[2], const float v2[2], const float v3[2]) { float rc[2], len; @@ -1052,21 +1052,27 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) /* sets as active, useful for other tools */ if (select) { if (em->selectmode & SCE_SELECT_VERTEX) { - /* Find nearest vert from mouse. */ + /* Find nearest vert from mouse + * (initialize to large values incase only one vertex can be projected) */ float v1_co[2], v2_co[2]; + float length_1 = FLT_MAX; + float length_2 = FLT_MAX; /* We can't be sure this has already been set... */ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); - ED_view3d_project_float_noclip(vc.ar, eed->v1->co, v1_co); - ED_view3d_project_float_noclip(vc.ar, eed->v2->co, v2_co); + + if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + 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) { + length_2 = len_squared_v2v2(mvalf, v2_co); + } #if 0 printf("mouse to v1: %f\nmouse to v2: %f\n", len_squared_v2v2(mvalf, v1_co), len_squared_v2v2(mvalf, v2_co)); #endif - if (len_squared_v2v2(mvalf, v1_co) < len_squared_v2v2(mvalf, v2_co)) - BM_select_history_store(em->bm, eed->v1); - else - BM_select_history_store(em->bm, eed->v2); + BM_select_history_store(em->bm, (length_1 < length_2) ? eed->v1 : eed->v2); } else if (em->selectmode & SCE_SELECT_EDGE) { BM_select_history_store(em->bm, eed); @@ -1086,12 +1092,13 @@ 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); - ED_view3d_project_float_noclip(vc.ar, cent, co); - tdist = len_squared_v2v2(mvalf, co); - if (tdist < best_dist) { -/* printf("Best face: %p (%f)\n", f, tdist);*/ - best_dist = tdist; - efa = f; + if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + tdist = len_squared_v2v2(mvalf, co); + if (tdist < best_dist) { +/* printf("Best face: %p (%f)\n", f, tdist);*/ + best_dist = tdist; + efa = f; + } } } } diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index bd1d13f3528..e42b95c6013 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -381,22 +381,23 @@ static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2]) BMEdge *edge = NULL; float v1_proj[3], v2_proj[3]; - float dist = 0; float min_dist = FLT_MAX; for (i = 0; i < vso->disk_edges; i++) { edge = vso->edge_frame[i]; mul_v3_m4v3(v1_proj, vso->obj->obmat, edge->v1->co); - ED_view3d_project_float_noclip(vso->active_region, v1_proj, v1_proj); - mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co); - ED_view3d_project_float_noclip(vso->active_region, v2_proj, v2_proj); - dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); - if (dist < min_dist) { - min_dist = dist; - cl_edge = edge; + /* 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)) + { + const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); + if (dist < min_dist) { + min_dist = dist; + cl_edge = edge; + } } } } @@ -448,17 +449,21 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) /* Calculate interpolation value for preview */ float t_val; - float mval_float[] = { (float)event->mval[0], (float)event->mval[1]}; + float mval_float[2] = { (float)event->mval[0], (float)event->mval[1]}; float closest_2d[2]; other = BM_edge_other_vert(edge, vso->start_vtx); /* Project points onto screen and do interpolation in 2D */ mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co); - ED_view3d_project_float_noclip(vso->active_region, start_vtx_proj, start_vtx_proj); - mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co); - ED_view3d_project_float_noclip(vso->active_region, edge_other_proj, edge_other_proj); + + 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)) + { + /* not much we can do here */ + return; + } closest_to_line_v2(closest_2d, mval_float, start_vtx_proj, edge_other_proj); @@ -470,7 +475,7 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) if (edge_len <= 0.0f) edge_len = VTX_SLIDE_SNAP_THRSH; - edge_len = (len_v3v3(edge->v1->co, edge->v2->co) * VTX_SLIDE_SNAP_THRSH) / edge_len; + edge_len = (BM_edge_calc_length(edge) * VTX_SLIDE_SNAP_THRSH) / edge_len; vso->snap_threshold = edge_len; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 7c700cc9731..d73e7d81b9f 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -153,19 +153,22 @@ void MESH_OT_subdivide(wmOperatorType *ot) } -void EMBM_project_snap_verts(bContext *C, ARegion *ar, Object *obedit, BMEditMesh *em) +void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) { + Object *obedit = em->ob; BMIter iter; BMVert *eve; + ED_view3d_init_mats_rv3d(obedit, ar->regiondata); + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - float mval[2], vec[3], no_dummy[3]; + float mval[2], co_proj[3], no_dummy[3]; int dist_dummy; - mul_v3_m4v3(vec, obedit->obmat, eve->co); - ED_view3d_project_float_noclip(ar, vec, mval); - if (snapObjectsContext(C, mval, &dist_dummy, vec, no_dummy, SNAP_NOT_OBEDIT)) { - mul_v3_m4v3(eve->co, obedit->imat, vec); + if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (snapObjectsContext(C, mval, &dist_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) { + mul_v3_m4v3(eve->co, obedit->imat, co_proj); + } } } } @@ -439,16 +442,17 @@ static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOpe zero_v3(nor); + /* XXX If those popup menus were to be enabled again, please get rid of this "menu string" syntax! */ if (em->selectmode & SCE_SELECT_VERTEX) { if (em->bm->totvertsel == 0) nr = 0; else if (em->bm->totvertsel == 1) nr = 4; else if (em->bm->totedgesel == 0) nr = 4; else if (em->bm->totfacesel == 0) - nr = 3; // pupmenu("Extrude %t|Only Edges%x3|Only Vertices%x4"); + nr = 3; /* pupmenu("Extrude %t|Only Edges %x3|Only Vertices %x4"); */ else if (em->bm->totfacesel == 1) - nr = 1; // pupmenu("Extrude %t|Region %x1|Only Edges%x3|Only Vertices%x4"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges% x3|Only Vertices %x4"); */ else - nr = 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3|Only Vertices%x4"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3|Only Vertices %x4"); */ } else if (em->selectmode & SCE_SELECT_EDGE) { if (em->bm->totedgesel == 0) nr = 0; @@ -458,16 +462,16 @@ static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOpe else if (em->totedgesel == 1) nr = 3; else if (em->totfacesel == 0) nr = 3; else if (em->totfacesel == 1) - nr = 1; // pupmenu("Extrude %t|Region %x1|Only Edges%x3"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges %x3"); */ else - nr = 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3"); */ #endif } else { if (em->bm->totfacesel == 0) nr = 0; else if (em->bm->totfacesel == 1) nr = 1; else - nr = 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2"); */ } if (nr < 1) return 'g'; @@ -730,7 +734,10 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent short use_proj; em_setup_viewcontext(C, &vc); - + + ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); + + use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); @@ -759,26 +766,26 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent 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]; - mul_v3_m4v3(co1, vc.obedit->obmat, eed->v1->co); - mul_v3_m4v3(co2, vc.obedit->obmat, eed->v2->co); - ED_view3d_project_float_noclip(vc.ar, co1, co1); - ED_view3d_project_float_noclip(vc.ar, co2, co2); - - /* 2D rotate by 90d while adding. - * (x, y) = (y, -x) - * - * accumulate the screenspace normal in 2D, - * with screenspace edge length weighting the result. */ - if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) { - nor[0] += (co1[1] - co2[1]); - nor[1] += -(co1[0] - co2[0]); - } - else { - nor[0] += (co2[1] - co1[1]); - nor[1] += -(co2[0] - co1[0]); + + 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)) + { + /* 2D rotate by 90d while adding. + * (x, y) = (y, -x) + * + * accumulate the screenspace normal in 2D, + * with screenspace edge length weighting the result. */ + if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) { + nor[0] += (co1[1] - co2[1]); + nor[1] += -(co1[0] - co2[0]); + } + else { + nor[0] += (co2[1] - co1[1]); + nor[1] += -(co2[0] - co1[0]); + } + done = TRUE; } } - done = TRUE; } if (done) { @@ -835,7 +842,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent /* also project the source, for retopo workflow */ if (use_proj) - EMBM_project_snap_verts(C, vc.ar, vc.obedit, vc.em); + EMBM_project_snap_verts(C, vc.ar, vc.em); } edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor); @@ -868,7 +875,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent } if (use_proj) - EMBM_project_snap_verts(C, vc.ar, vc.obedit, vc.em); + EMBM_project_snap_verts(C, vc.ar, vc.em); /* This normally happens when pushing undo but modal operators * like this one don't push undo data until after modal mode is @@ -2140,7 +2147,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) } /* if those are not found, because vertices where selected by e.g. - border or circle select, find two selected vertices */ + * border or circle select, find two selected vertices */ if (svert == NULL) { BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) @@ -2150,7 +2157,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) else if (evert == NULL) evert = eve; else { /* more than two vertices are selected, - show warning message and cancel operator */ + * show warning message and cancel operator */ svert = evert = NULL; break; } @@ -2526,11 +2533,6 @@ void MESH_OT_solidify(wmOperatorType *ot) RNA_def_property_ui_range(prop, -10, 10, 0.1, 4); } -typedef struct CutCurve { - float x; - float y; -} CutCurve; - /* ******************************************************************** */ /* Knife Subdivide Tool. Subdivides edges intersected by a mouse trail * drawn by user. @@ -2564,15 +2566,14 @@ static EnumPropertyItem knife_items[] = { /* bm_edge_seg_isect() Determines if and where a mouse trail intersects an BMEdge */ -static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, - struct GHash *gh, int *isected) +static float bm_edge_seg_isect(const float sco_a[2], const float sco_b[2], + float (*mouse_path)[2], int len, char mode, int *isected) { #define MAXSLOPE 100000 float x11, y11, x12 = 0, y12 = 0, x2max, x2min, y2max; float y2min, dist, lastdist = 0, xdiff2, xdiff1; float m1, b1, m2, b2, x21, x22, y21, y22, xi; float yi, x1min, x1max, y1max, y1min, perc = 0; - float *scr; float threshold = 0.0; int i; @@ -2580,13 +2581,11 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, // XXX threshold = scene->toolsettings->select_thresh / 100; /* Get screen coords of verts */ - scr = BLI_ghash_lookup(gh, e->v1); - x21 = scr[0]; - y21 = scr[1]; + x21 = sco_a[0]; + y21 = sco_a[1]; - scr = BLI_ghash_lookup(gh, e->v2); - x22 = scr[0]; - y22 = scr[1]; + x22 = sco_b[0]; + y22 = sco_b[1]; xdiff2 = (x22 - x21); if (xdiff2) { @@ -2608,11 +2607,11 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, y11 = y12; } else { - x11 = c[i].x; - y11 = c[i].y; + x11 = mouse_path[i][0]; + y11 = mouse_path[i][1]; } - x12 = c[i].x; - y12 = c[i].y; + x12 = mouse_path[i][0]; + y12 = mouse_path[i][1]; /* test e->v1 */ if ((x11 == x21 && y11 == y21) || (x12 == x21 && y12 == y21)) { @@ -2636,11 +2635,11 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, y11 = y12; } else { - x11 = c[i].x; - y11 = c[i].y; + x11 = mouse_path[i][0]; + y11 = mouse_path[i][1]; } - x12 = c[i].x; - y12 = c[i].y; + x12 = mouse_path[i][0]; + y12 = mouse_path[i][1]; /* Perp. Distance from point to line */ if (m2 != MAXSLOPE) dist = (y12 - m2 * x12 - b2); /* /sqrt(m2 * m2 + 1); Only looking for */ @@ -2718,9 +2717,9 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, lastdist = dist; } return perc; -} +} -#define MAX_CUTS 2048 +#define ELE_EDGE_CUT 1 static int edbm_knife_cut_exec(bContext *C, wmOperator *op) { @@ -2732,76 +2731,93 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) BMIter iter; BMEdge *be; BMOperator bmop; - CutCurve curve[MAX_CUTS]; - struct GHash *gh; float isect = 0.0f; - float *scr, co[4]; - int len = 0, isected; + int len = 0, isected, i; short numcuts = 1, mode = RNA_int_get(op->ptr, "type"); + + /* allocd vars */ + float (*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2]; /* edit-object needed for matrix, and ar->regiondata for projections to work */ if (ELEM3(NULL, obedit, ar, ar->regiondata)) return OPERATOR_CANCELLED; if (bm->totvertsel < 2) { - //error("No edges are selected to operate on"); + BKE_report(op->reports, RPT_ERROR, "No edges are selected to operate on"); + return OPERATOR_CANCELLED; + } + + len = RNA_collection_length(op->ptr, "path"); + + if (len < 2) { + BKE_report(op->reports, RPT_ERROR, "Mouse path too short"); return OPERATOR_CANCELLED; } + mouse_path = MEM_mallocN(len * sizeof(*mouse_path), __func__); + /* get the cut curve */ RNA_BEGIN(op->ptr, itemptr, "path") { - RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]); - len++; - if (len >= MAX_CUTS) { - break; - } + RNA_float_get_array(&itemptr, "loc", (float *)&mouse_path[len]); } RNA_END; - - if (len < 2) { - return OPERATOR_CANCELLED; - } + + /* for ED_view3d_project_float_object */ + ED_view3d_init_mats_rv3d(obedit, ar->regiondata); + + /* TODO, investigate using index lookup for screen_vert_coords() rather then a hash table */ /* the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer */ - gh = BLI_ghash_ptr_new("knife cut exec"); - for (bv = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); bv; bv = BM_iter_step(&iter)) { - scr = MEM_mallocN(sizeof(float) * 2, "Vertex Screen Coordinates"); - copy_v3_v3(co, bv->co); - co[3] = 1.0f; - mul_m4_v4(obedit->obmat, co); - ED_view3d_project_float(ar, co, scr); - BLI_ghash_insert(gh, bv, scr); + 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) { + copy_v2_fl(*sco, FLT_MAX); /* set error value */ + } + BM_elem_index_set(bv, i); /* set_ok */ + sco++; + } + bm->elem_index_dirty &= ~BM_VERT; /* clear dirty flag */ if (!EDBM_op_init(em, &bmop, op, "subdivide_edges")) { + MEM_freeN(mouse_path); + MEM_freeN(screen_vert_coords); return OPERATOR_CANCELLED; } /* store percentage of edge cut for KNIFE_EXACT here.*/ for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) { + int is_cut = FALSE; if (BM_elem_flag_test(be, BM_ELEM_SELECT)) { - isect = bm_edge_seg_isect(be, curve, len, mode, gh, &isected); - - if (isect != 0.0f) { - if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) { - BMO_slot_map_float_insert(bm, &bmop, - "edgepercents", - be, isect); - + const float *sco_a = screen_vert_coords[BM_elem_index_get(be->v1)]; + const float *sco_b = screen_vert_coords[BM_elem_index_get(be->v2)]; + + /* check for error value (vert cant be projected) */ + if ((sco_a[0] != FLT_MAX) && (sco_b[0] != FLT_MAX)) { + isect = bm_edge_seg_isect(sco_a, sco_b, mouse_path, len, mode, &isected); + + if (isect != 0.0f) { + if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) { + BMO_slot_map_float_insert(bm, &bmop, + "edgepercents", + be, isect); + } } - BMO_elem_flag_enable(bm, be, 1); - } - else { - BMO_elem_flag_disable(bm, be, 1); } } - else { - BMO_elem_flag_disable(bm, be, 1); - } + + BMO_elem_flag_set(bm, be, ELE_EDGE_CUT, is_cut); } - - BMO_slot_buffer_from_enabled_flag(bm, &bmop, "edges", BM_EDGE, 1); + + + /* free all allocs */ + MEM_freeN(screen_vert_coords); + MEM_freeN(mouse_path); + + + BMO_slot_buffer_from_enabled_flag(bm, &bmop, "edges", BM_EDGE, ELE_EDGE_CUT); if (mode == KNIFE_MIDPOINT) numcuts = 1; BMO_slot_int_set(&bmop, "numcuts", numcuts); @@ -2816,14 +2832,14 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; } - - BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN); EDBM_update_generic(C, em, TRUE); return OPERATOR_FINISHED; } +#undef ELE_EDGE_CUT + void MESH_OT_knife_cut(wmOperatorType *ot) { PropertyRNA *prop; @@ -4776,7 +4792,7 @@ void MESH_OT_bevel(wmOperatorType *ot) ot->poll = ED_operator_editmesh; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; 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. */ @@ -5195,7 +5211,7 @@ void MESH_OT_inset(wmOperatorType *ot) ot->poll = ED_operator_editmesh; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; /* properties */ RNA_def_boolean(ot->srna, "use_boundary", TRUE, "Boundary", "Inset face boundaries"); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 4637d926a62..735492cb553 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -761,7 +761,12 @@ static int mesh_customdata_clear_exec__internal(bContext *C, BLI_assert(CustomData_layertype_is_singleton(type) == TRUE); if (CustomData_has_layer(data, type)) { - CustomData_free_layers(data, type, tot); + if (me->edit_btmesh) { + BM_data_layer_free(me->edit_btmesh->bm, data, type); + } + else { + CustomData_free_layers(data, type, tot); + } DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index ef826c07cc1..42d82fff38e 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1237,11 +1237,12 @@ 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); - ED_view3d_project_float_noclip(ar, co, sco); - len = len_squared_v2v2(mval_f, sco); - if (len < len_best) { - len_best = len; - v_idx_best = v_idx; + if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + len = len_squared_v2v2(mval_f, sco); + if (len < len_best) { + len_best = len; + v_idx_best = v_idx; + } } } while (fidx--); } diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 22ccd7bbed8..e9063687506 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -129,37 +129,33 @@ static int mball_select_all_exec(bContext *C, wmOperator *op) MetaElem *ml; int action = RNA_enum_get(op->ptr, "action"); - ml = mb->editelems->first; - if (ml) { - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - while (ml) { - if (ml->flag & SELECT) { - action = SEL_DESELECT; - break; - } - ml = ml->next; - } - } + if (mb->editelems->first == NULL) + return OPERATOR_CANCELLED; - ml = mb->editelems->first; - while (ml) { - switch (action) { - case SEL_SELECT: - ml->flag |= SELECT; - break; - case SEL_DESELECT: - ml->flag &= ~SELECT; - break; - case SEL_INVERT: - ml->flag ^= SELECT; - break; + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + for (ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & SELECT) { + action = SEL_DESELECT; + break; } - ml = ml->next; } - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); } + switch (action) { + case SEL_SELECT: + BKE_mball_select_all(mb); + break; + case SEL_DESELECT: + BKE_mball_deselect_all(mb); + break; + case SEL_INVERT: + BKE_mball_select_swap(mb); + break; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); + return OPERATOR_FINISHED; } @@ -421,7 +417,7 @@ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int to Object *obedit = CTX_data_edit_object(C); ViewContext vc; MetaBall *mb = (MetaBall *)obedit->data; - MetaElem *ml, *act = NULL; + MetaElem *ml, *ml_act = NULL; int a, hits; unsigned int buffer[4 * MAXPICKBUF]; rcti rect; @@ -451,14 +447,14 @@ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int to /* index converted for gl stuff */ if (ml->selcol1 == buffer[4 * a + 3]) { ml->flag |= MB_SCALE_RAD; - act = ml; + ml_act = ml; } if (ml->selcol2 == buffer[4 * a + 3]) { ml->flag &= ~MB_SCALE_RAD; - act = ml; + ml_act = ml; } } - if (act) break; + if (ml_act) break; ml = ml->next; if (ml == NULL) ml = mb->editelems->first; if (ml == startelem) break; @@ -466,31 +462,28 @@ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int to /* When some metaelem was found, then it is necessary to select or * deselect it. */ - if (act) { + if (ml_act) { if (extend) { - act->flag |= SELECT; + ml_act->flag |= SELECT; } else if (deselect) { - act->flag &= ~SELECT; + ml_act->flag &= ~SELECT; } else if (toggle) { - if (act->flag & SELECT) - act->flag &= ~SELECT; + if (ml_act->flag & SELECT) + ml_act->flag &= ~SELECT; else - act->flag |= SELECT; + ml_act->flag |= SELECT; } else { /* Deselect all existing metaelems */ - ml = mb->editelems->first; - while (ml) { - ml->flag &= ~SELECT; - ml = ml->next; - } + BKE_mball_deselect_all(mb); + /* Select only metaelem clicked on */ - act->flag |= SELECT; + ml_act->flag |= SELECT; } - mb->lastelem = act; + mb->lastelem = ml_act; WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4942b9e4390..43a32cd662e 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -43,6 +43,7 @@ #include "DNA_meta_types.h" #include "DNA_object_fluidsim.h" #include "DNA_object_force.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_speaker_types.h" #include "DNA_vfont_types.h" @@ -110,7 +111,7 @@ #include "object_intern.h" /* this is an exact copy of the define in rna_lamp.c - * kept here because of linking order. + * kept here because of linking order. * Icons are only defined here */ EnumPropertyItem lamp_type_items[] = { {LA_LOCAL, "POINT", ICON_LAMP_POINT, "Point", "Omnidirectional point light source"}, @@ -121,6 +122,23 @@ EnumPropertyItem lamp_type_items[] = { {0, NULL, 0, NULL, NULL} }; +/* copy from rna_object_force.c */ +static EnumPropertyItem field_type_items[] = { + {PFIELD_FORCE, "FORCE", ICON_FORCE_FORCE, "Force", ""}, + {PFIELD_WIND, "WIND", ICON_FORCE_WIND, "Wind", ""}, + {PFIELD_VORTEX, "VORTEX", ICON_FORCE_VORTEX, "Vortex", ""}, + {PFIELD_MAGNET, "MAGNET", ICON_FORCE_MAGNETIC, "Magnetic", ""}, + {PFIELD_HARMONIC, "HARMONIC", ICON_FORCE_HARMONIC, "Harmonic", ""}, + {PFIELD_CHARGE, "CHARGE", ICON_FORCE_CHARGE, "Charge", ""}, + {PFIELD_LENNARDJ, "LENNARDJ", ICON_FORCE_LENNARDJONES, "Lennard-Jones", ""}, + {PFIELD_TEXTURE, "TEXTURE", ICON_FORCE_TEXTURE, "Texture", ""}, + {PFIELD_GUIDE, "GUIDE", ICON_FORCE_CURVE, "Curve Guide", ""}, + {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, + {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, + {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, + {0, NULL, 0, NULL, NULL} +}; + /************************** Exported *****************************/ void ED_object_location_from_view(bContext *C, float loc[3]) @@ -128,7 +146,7 @@ void ED_object_location_from_view(bContext *C, float loc[3]) View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); float *cursor; - + cursor = give_cursor(scene, v3d); copy_v3_v3(loc, cursor); @@ -152,44 +170,44 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], { Object *ob = base->object; Scene *scene = CTX_data_scene(C); - + if (!scene) return; - + if (loc) copy_v3_v3(ob->loc, loc); - + if (rot) copy_v3_v3(ob->rot, rot); - + BKE_object_where_is_calc(scene, ob); } -/* uses context to figure out transform for primitive */ -/* returns standard diameter */ +/* 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]) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3]; - + unit_m4(primmat); - + eul_to_mat3(rmat, rot); invert_m3(rmat); - + /* inverse transform for initial rotation and object */ copy_m3_m4(mat, obedit->obmat); mul_m3_m3m3(cmat, rmat, mat); invert_m3_m3(imat, cmat); copy_m4_m3(primmat, imat); - + /* center */ copy_v3_v3(primmat[3], loc); sub_v3_v3v3(primmat[3], primmat[3], obedit->obmat[3]); invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); - + if (v3d) return ED_view3d_grid_scale(scene, v3d, NULL); @@ -206,7 +224,7 @@ static void view_align_update(struct Main *UNUSED(main), struct Scene *UNUSED(sc void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode) { PropertyRNA *prop; - + /* note: this property gets hidden for add-camera operator */ prop = RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view"); RNA_def_property_update_runtime(prop, view_align_update); @@ -216,112 +234,112 @@ void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode) "Enter editmode when adding this object"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } - + prop = RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object", -FLT_MAX, FLT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - + prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -static void object_add_generic_invoke_options(bContext *C, wmOperator *op) +int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], float rot[3], + int *enter_editmode, unsigned int *layer, int *is_view_aligned) { - if (RNA_struct_find_property(op->ptr, "enter_editmode")) /* optional */ - if (!RNA_struct_property_is_set(op->ptr, "enter_editmode")) - RNA_boolean_set(op->ptr, "enter_editmode", U.flag & USER_ADD_EDITMODE); - - if (!RNA_struct_property_is_set(op->ptr, "location")) { - float loc[3]; - - ED_object_location_from_view(C, loc); - RNA_float_set_array(op->ptr, "location", loc); - } - - if (!RNA_struct_property_is_set(op->ptr, "layers")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - int a, values[20], layer; + View3D *v3d = CTX_wm_view3d(C); - if (v3d) { - layer = (v3d->scenelock && !v3d->localvd) ? scene->layact : v3d->layact; - } + /* Switch to Edit mode? */ + if (RNA_struct_find_property(op->ptr, "enter_editmode")) { /* optional */ + int _enter_editmode; + if (!enter_editmode) + enter_editmode = &_enter_editmode; + + if (RNA_struct_property_is_set(op->ptr, "enter_editmode") && enter_editmode) + *enter_editmode = RNA_boolean_get(op->ptr, "enter_editmode"); else { - layer = scene->layact; + *enter_editmode = U.flag & USER_ADD_EDITMODE; + RNA_boolean_set(op->ptr, "enter_editmode", *enter_editmode); } + } - for (a = 0; a < 20; a++) { - values[a] = (layer & (1 << a)); + /* Get layers! */ + { + int a, layer_values[20]; + unsigned int _layer; + if (!layer) + layer = &_layer; + + if (RNA_struct_property_is_set(op->ptr, "layers")) { + RNA_boolean_get_array(op->ptr, "layers", layer_values); + *layer = 0; + for (a = 0; a < 20; a++) { + if (layer_values[a]) + *layer |= (1 << a); + } + } + else { + Scene *scene = CTX_data_scene(C); + if (v3d) + *layer = (v3d->scenelock && !v3d->localvd) ? scene->layact : v3d->layact; + else + *layer = scene->layact; + for (a = 0; a < 20; a++) { + layer_values[a] = *layer & (1 << a); + } + RNA_boolean_set_array(op->ptr, "layers", layer_values); } - RNA_boolean_set_array(op->ptr, "layers", values); + /* in local view we additionally add local view layers, + * not part of operator properties */ + if (v3d && v3d->localvd) + *layer |= v3d->lay; } -} -int ED_object_add_generic_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - object_add_generic_invoke_options(C, op); - return op->type->exec(C, op); -} - -int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], float rot[3], - int *enter_editmode, unsigned int *layer, int *is_view_aligned) -{ - View3D *v3d = CTX_wm_view3d(C); - int a, layer_values[20]; - int view_align; - - *enter_editmode = FALSE; - if (RNA_struct_find_property(op->ptr, "enter_editmode") && RNA_boolean_get(op->ptr, "enter_editmode")) { - *enter_editmode = TRUE; - } + /* Location! */ + { + float _loc[3]; + if (!loc) + loc = _loc; - if (RNA_struct_property_is_set(op->ptr, "layers")) { - RNA_boolean_get_array(op->ptr, "layers", layer_values); - *layer = 0; - for (a = 0; a < 20; a++) { - if (layer_values[a]) - *layer |= (1 << a); - else - *layer &= ~(1 << a); + if (RNA_struct_property_is_set(op->ptr, "location")) { + RNA_float_get_array(op->ptr, "location", loc); + } + else { + ED_object_location_from_view(C, loc); + RNA_float_set_array(op->ptr, "location", loc); } - } - else { - /* not set, use the scenes layers */ - Scene *scene = CTX_data_scene(C); - *layer = scene->layact; } - /* in local view we additionally add local view layers, - * not part of operator properties */ - if (v3d && v3d->localvd) - *layer |= v3d->lay; + /* Rotation! */ + { + int _is_view_aligned; + float _rot[3]; + if (!is_view_aligned) + is_view_aligned = &_is_view_aligned; + if (!rot) + rot = _rot; + + if (RNA_struct_property_is_set(op->ptr, "rotation")) + *is_view_aligned = FALSE; + else if (RNA_struct_property_is_set(op->ptr, "view_align")) + *is_view_aligned = RNA_boolean_get(op->ptr, "view_align"); + else { + *is_view_aligned = U.flag & USER_ADD_VIEWALIGNED; + RNA_boolean_set(op->ptr, "view_align", *is_view_aligned); + } - if (RNA_struct_property_is_set(op->ptr, "rotation")) - view_align = FALSE; - else if (RNA_struct_property_is_set(op->ptr, "view_align")) - view_align = RNA_boolean_get(op->ptr, "view_align"); - else { - view_align = U.flag & USER_ADD_VIEWALIGNED; - RNA_boolean_set(op->ptr, "view_align", view_align); - } - - if (view_align) { - ED_object_rotation_from_view(C, rot); - RNA_float_set_array(op->ptr, "rotation", rot); + if (*is_view_aligned) { + ED_object_rotation_from_view(C, rot); + RNA_float_set_array(op->ptr, "rotation", rot); + } + else + RNA_float_get_array(op->ptr, "rotation", rot); } - else - RNA_float_get_array(op->ptr, "rotation", rot); - - if (is_view_aligned) - *is_view_aligned = view_align; - - RNA_float_get_array(op->ptr, "location", loc); - - if (*layer == 0) { + + if (layer && *layer == 0) { BKE_report(op->reports, RPT_ERROR, "Property 'layer' has no values set"); return 0; } @@ -329,19 +347,19 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl return 1; } -/* for object add primitive operators */ -/* do not call undo push in this function (users of this function have to) */ +/* For object add primitive operators. + * Do not call undo push in this function (users of this function have to). */ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const float rot[3], int enter_editmode, unsigned int layer) { Main *bmain = CTX_data_main(C); 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 */ - + /* deselects all, sets scene->basact */ ob = BKE_object_add(scene, type); BASACT->lay = ob->lay = layer; @@ -371,12 +389,12 @@ static int object_add_exec(bContext *C, wmOperator *op) int enter_editmode; unsigned int layer; float loc[3], rot[3]; - + if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); - + return OPERATOR_FINISHED; } @@ -386,89 +404,62 @@ void OBJECT_OT_add(wmOperatorType *ot) ot->name = "Add Object"; ot->description = "Add an object to the scene"; ot->idname = "OBJECT_OT_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = object_add_exec; - ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", ""); ED_object_add_generic_props(ot, TRUE); } /********************* Add Effector Operator ********************/ -/* copy from rna_object_force.c*/ -static EnumPropertyItem field_type_items[] = { - {PFIELD_FORCE, "FORCE", ICON_FORCE_FORCE, "Force", ""}, - {PFIELD_WIND, "WIND", ICON_FORCE_WIND, "Wind", ""}, - {PFIELD_VORTEX, "VORTEX", ICON_FORCE_VORTEX, "Vortex", ""}, - {PFIELD_MAGNET, "MAGNET", ICON_FORCE_MAGNETIC, "Magnetic", ""}, - {PFIELD_HARMONIC, "HARMONIC", ICON_FORCE_HARMONIC, "Harmonic", ""}, - {PFIELD_CHARGE, "CHARGE", ICON_FORCE_CHARGE, "Charge", ""}, - {PFIELD_LENNARDJ, "LENNARDJ", ICON_FORCE_LENNARDJONES, "Lennard-Jones", ""}, - {PFIELD_TEXTURE, "TEXTURE", ICON_FORCE_TEXTURE, "Texture", ""}, - {PFIELD_GUIDE, "GUIDE", ICON_FORCE_CURVE, "Curve Guide", ""}, - {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, - {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, - {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, - {0, NULL, 0, NULL, NULL}}; -/* for effector add primitive operators */ -static Object *effector_add_type(bContext *C, wmOperator *op, int type) +/* for object add operator */ +static int effector_add_exec(bContext *C, wmOperator *op) { Object *ob; - int enter_editmode; + int type, enter_editmode; unsigned int layer; float loc[3], rot[3]; float mat[4][4]; - - object_add_generic_invoke_options(C, op); if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) - return NULL; + return OPERATOR_CANCELLED; + + type = RNA_enum_get(op->ptr, "type"); if (type == PFIELD_GUIDE) { ob = ED_object_add_type(C, OB_CURVE, loc, rot, FALSE, layer); - rename_id(&ob->id, "CurveGuide"); + if (!ob) + return OPERATOR_CANCELLED; + 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); 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); } else { ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer); - rename_id(&ob->id, "Field"); + if (!ob) + return OPERATOR_CANCELLED; - switch (type) { - case PFIELD_WIND: - case PFIELD_VORTEX: - ob->empty_drawtype = OB_SINGLE_ARROW; - break; - } + rename_id(&ob->id, "Field"); + if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) + ob->empty_drawtype = OB_SINGLE_ARROW; } ob->pd = object_add_collision_fields(type); DAG_scene_sort(CTX_data_main(C), CTX_data_scene(C)); - return ob; -} - -/* for object add operator */ -static int effector_add_exec(bContext *C, wmOperator *op) -{ - if (effector_add_type(C, op, RNA_enum_get(op->ptr, "type")) == NULL) - return OPERATOR_CANCELLED; - return OPERATOR_FINISHED; } @@ -478,22 +469,20 @@ void OBJECT_OT_effector_add(wmOperatorType *ot) ot->name = "Add Effector"; ot->description = "Add an empty object with a physics effector to the scene"; ot->idname = "OBJECT_OT_effector_add"; - + /* api callbacks */ - ot->invoke = WM_menu_invoke; ot->exec = effector_add_exec; - ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + ot->prop = RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", ""); ED_object_add_generic_props(ot, TRUE); } -/* ***************** Add Camera *************** */ +/********************* Add Camera Operator ********************/ static int object_camera_add_exec(bContext *C, wmOperator *op) { @@ -503,17 +492,15 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) int enter_editmode; unsigned int layer; float loc[3], rot[3]; - + /* force view align for cameras */ RNA_boolean_set(op->ptr, "view_align", TRUE); - - object_add_generic_invoke_options(C, op); if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_CAMERA, loc, rot, FALSE, layer); - + if (v3d) { if (v3d->camera == NULL) v3d->camera = ob; @@ -528,81 +515,60 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) void OBJECT_OT_camera_add(wmOperatorType *ot) { PropertyRNA *prop; - + /* identifiers */ ot->name = "Add Camera"; ot->description = "Add a camera object to the scene"; ot->idname = "OBJECT_OT_camera_add"; - + /* api callbacks */ ot->exec = object_camera_add_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + ED_object_add_generic_props(ot, TRUE); - + /* hide this for cameras, default */ prop = RNA_struct_type_find_property(ot->srna, "view_align"); RNA_def_property_flag(prop, PROP_HIDDEN); - } -/* ***************** add primitives *************** */ +/********************* Add Metaball Operator ********************/ + static int object_metaball_add_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); - /*MetaElem *elem;*/ /*UNUSED*/ int newob = 0; int enter_editmode; unsigned int layer; float loc[3], rot[3]; float mat[4][4]; - object_add_generic_invoke_options(C, op); /* XXX these props don't get set right when only exec() is called */ - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; - + if (obedit == NULL || obedit->type != OB_MBALL) { obedit = ED_object_add_type(C, OB_MBALL, loc, rot, TRUE, layer); newob = 1; } - else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - + else + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); - - /* elem= (MetaElem *) */ add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); + + add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); /* userdef */ if (newob && !enter_editmode) { ED_object_exit_editmode(C, EM_FREEDATA); } - - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - -static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - Object *obedit = CTX_data_edit_object(C); - uiPopupMenu *pup; - uiLayout *layout; - - object_add_generic_invoke_options(C, op); - pup = uiPupMenuBegin(C, op->type->name, ICON_NONE); - layout = uiPupMenuLayout(pup); - if (!obedit || obedit->type == OB_MBALL) - uiItemsEnumO(layout, op->type->idname, "type"); - else - uiItemsEnumO(layout, "OBJECT_OT_metaball_add", "type"); - uiPupMenuEnd(C, pup); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void OBJECT_OT_metaball_add(wmOperatorType *ot) @@ -613,35 +579,37 @@ void OBJECT_OT_metaball_add(wmOperatorType *ot) ot->idname = "OBJECT_OT_metaball_add"; /* api callbacks */ - ot->invoke = object_metaball_add_invoke; + ot->invoke = WM_menu_invoke;/* object_metaball_add_invoke; */ ot->exec = object_metaball_add_exec; ot->poll = ED_operator_scene_editable; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", metaelem_type_items, 0, "Primitive", ""); + + ot->prop = RNA_def_enum(ot->srna, "type", metaelem_type_items, 0, "Primitive", ""); + ED_object_add_generic_props(ot, TRUE); } +/********************* Add Text Operator ********************/ + static int object_add_text_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); int enter_editmode; unsigned int layer; float loc[3], rot[3]; - - object_add_generic_invoke_options(C, op); /* XXX these props don't get set right when only exec() is called */ + if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; - + if (obedit && obedit->type == OB_FONT) return OPERATOR_CANCELLED; obedit = ED_object_add_type(C, OB_FONT, loc, rot, enter_editmode, layer); - + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - + return OPERATOR_FINISHED; } @@ -651,17 +619,18 @@ void OBJECT_OT_text_add(wmOperatorType *ot) ot->name = "Add Text"; ot->description = "Add a text object to the scene"; ot->idname = "OBJECT_OT_text_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = object_add_text_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ED_object_add_generic_props(ot, TRUE); } +/********************* Add Armature Operator ********************/ + static int object_armature_add_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -672,7 +641,6 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; - object_add_generic_invoke_options(C, op); /* XXX these props don't get set right when only exec() is called */ if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; @@ -687,36 +655,76 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature"); return OPERATOR_CANCELLED; } - + /* v3d and rv3d are allowed to be NULL */ add_primitive_bone(CTX_data_scene(C), v3d, rv3d); /* userdef */ if (newob && !enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); - + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - + return OPERATOR_FINISHED; } void OBJECT_OT_armature_add(wmOperatorType *ot) -{ +{ /* identifiers */ ot->name = "Add Armature"; ot->description = "Add an armature object to the scene"; ot->idname = "OBJECT_OT_armature_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = object_armature_add_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ED_object_add_generic_props(ot, TRUE); } +/********************* Add Empty Operator ********************/ + +static int object_empty_add_exec(bContext *C, wmOperator *op) +{ + Object *ob; + int type = RNA_enum_get(op->ptr, "type"); + unsigned int layer; + float loc[3], rot[3]; + + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) + return OPERATOR_CANCELLED; + + ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer); + ob->empty_drawtype = type; + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_empty_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Empty"; + ot->description = "Add an empty object to the scene"; + ot->idname = "OBJECT_OT_empty_add"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = object_empty_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", object_empty_drawtype_items, 0, "Type", ""); + + ED_object_add_generic_props(ot, FALSE); +} + +/********************* Add Lamp Operator ********************/ + static const char *get_lamp_defname(int type) { switch (type) { @@ -736,12 +744,10 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) Object *ob; Lamp *la; int type = RNA_enum_get(op->ptr, "type"); - int enter_editmode; unsigned int layer; float loc[3], rot[3]; - - object_add_generic_invoke_options(C, op); - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) + + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_LAMP, loc, rot, FALSE, layer); @@ -755,7 +761,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) ED_node_shader_default(scene, &la->id); la->use_nodes = TRUE; } - + return OPERATOR_FINISHED; } @@ -765,12 +771,12 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ot->name = "Add Lamp"; ot->description = "Add a lamp object to the scene"; ot->idname = "OBJECT_OT_lamp_add"; - + /* api callbacks */ ot->invoke = WM_menu_invoke; ot->exec = object_lamp_add_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -780,16 +786,16 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ED_object_add_generic_props(ot, FALSE); } +/********************* Add Group Instance Operator ********************/ + static int group_instance_add_exec(bContext *C, wmOperator *op) { Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); - int enter_editmode; unsigned int layer; float loc[3], rot[3]; - - object_add_generic_invoke_options(C, op); - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) + + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; if (group) { @@ -812,20 +818,45 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } +/* only used as menu */ +void OBJECT_OT_group_instance_add(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Add Group Instance"; + ot->description = "Add a dupligroup instance"; + ot->idname = "OBJECT_OT_group_instance_add"; + + /* api callbacks */ + ot->invoke = WM_enum_search_invoke; + ot->exec = group_instance_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); + RNA_def_enum_funcs(prop, RNA_group_itemf); + ot->prop = prop; + ED_object_add_generic_props(ot, FALSE); +} + +/********************* Add Speaker Operator ********************/ + static int object_speaker_add_exec(bContext *C, wmOperator *op) { Object *ob; - int enter_editmode; unsigned int layer; float loc[3], rot[3]; Scene *scene = CTX_data_scene(C); - object_add_generic_invoke_options(C, op); - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_SPEAKER, loc, rot, FALSE, layer); - + /* to make it easier to start using this immediately in NLA, a default sound clip is created * ready to be moved around to retime the sound and/or make new sound clips */ @@ -836,14 +867,14 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) NlaStrip *strip = add_nla_soundstrip(CTX_data_scene(C), ob->data); strip->start = CFRA; strip->end += strip->start; - + /* hook them up */ BKE_nlatrack_add_strip(nlt, strip); - + /* auto-name the strip, and give the track an interesting name */ strcpy(nlt->name, "SoundTrack"); BKE_nlastrip_validate_name(adt, strip); - + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL); } @@ -867,32 +898,6 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot) ED_object_add_generic_props(ot, TRUE); } -/* only used as menu */ -void OBJECT_OT_group_instance_add(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name = "Add Group Instance"; - ot->description = "Add a dupligroup instance"; - ot->idname = "OBJECT_OT_group_instance_add"; - - /* api callbacks */ - ot->invoke = WM_enum_search_invoke; - ot->exec = group_instance_add_exec; - - ot->poll = ED_operator_objectmode; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); - RNA_def_enum_funcs(prop, RNA_group_itemf); - ot->prop = prop; - ED_object_add_generic_props(ot, FALSE); -} - /**************************** Delete Object *************************/ static void object_delete_check_glsl_update(Object *ob) @@ -901,7 +906,7 @@ static void object_delete_check_glsl_update(Object *ob) * are being tagged to be updated when object is removing from scene */ if (ob->type == OB_LAMP) { - if (ob->gpulamp.first) + if (ob->gpulamp.first) GPU_lamp_free(ob); } } @@ -923,16 +928,12 @@ static int object_delete_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); const short use_global = RNA_boolean_get(op->ptr, "use_global"); - /* int is_lamp = FALSE; */ /* UNUSED */ - + if (CTX_data_edit_object(C)) return OPERATOR_CANCELLED; - + CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - - /* if (base->object->type==OB_LAMP) is_lamp = TRUE; */ - /* deselect object -- it could be used in other scenes */ base->object->flag &= ~SELECT; @@ -959,10 +960,10 @@ static int object_delete_exec(bContext *C, wmOperator *op) DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); - + WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); - + return OPERATOR_FINISHED; } @@ -972,12 +973,12 @@ void OBJECT_OT_delete(wmOperatorType *ot) ot->name = "Delete"; ot->description = "Delete selected objects"; ot->idname = "OBJECT_OT_delete"; - + /* api callbacks */ ot->invoke = WM_operator_confirm; ot->exec = object_delete_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -993,29 +994,29 @@ static void copy_object_set_idnew(bContext *C, int dupflag) Material *ma, *mao; ID *id; int a; - + /* XXX check object pointers */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { BKE_object_relink(ob); } CTX_DATA_END; - + /* materials */ if (dupflag & USER_DUP_MAT) { mao = bmain->mat.first; while (mao) { if (mao->id.newid) { - ma = (Material *)mao->id.newid; - + if (dupflag & USER_DUP_TEX) { for (a = 0; a < MAX_MTEX; a++) { if (ma->mtex[a]) { id = (ID *)ma->mtex[a]->tex; if (id) { ID_NEW_US(ma->mtex[a]->tex) - else ma->mtex[a]->tex = BKE_texture_copy(ma->mtex[a]->tex); + else + ma->mtex[a]->tex = BKE_texture_copy(ma->mtex[a]->tex); id->us--; } } @@ -1025,7 +1026,8 @@ static void copy_object_set_idnew(bContext *C, int dupflag) id = (ID *)ma->ipo; if (id) { ID_NEW_US(ma->ipo) - else ma->ipo = copy_ipo(ma->ipo); + else + ma->ipo = copy_ipo(ma->ipo); id->us--; } #endif // XXX old animation system @@ -1033,7 +1035,7 @@ static void copy_object_set_idnew(bContext *C, int dupflag) mao = mao->id.next; } } - + #if 0 // XXX old animation system /* lamps */ if (dupflag & USER_DUP_IPO) { @@ -1044,14 +1046,15 @@ static void copy_object_set_idnew(bContext *C, int dupflag) id = (ID *)lan->ipo; if (id) { ID_NEW_US(lan->ipo) - else lan->ipo = copy_ipo(lan->ipo); + else + lan->ipo = copy_ipo(lan->ipo); id->us--; } } la = la->id.next; } } - + /* ipos */ ipo = bmain->ipo.first; while (ipo) { @@ -1067,9 +1070,9 @@ static void copy_object_set_idnew(bContext *C, int dupflag) ipo = ipo->id.next; } #endif // XXX old animation system - + set_sca_new_poins(); - + clear_id_newpoins(); } @@ -1082,17 +1085,17 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ListBase *lb; DupliObject *dob; GHash *dupli_gh = NULL, *parent_gh = NULL; - + if (!(base->object->transflag & OB_DUPLI)) return; - - lb = object_duplilist(scene, base->object); + + lb = object_duplilist(scene, base->object, FALSE); if (use_hierarchy || use_base_parent) { dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh"); parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh"); } - + for (dob = lb->first; dob; dob = dob->next) { Base *basen; Object *ob = BKE_object_copy(dob->ob); @@ -1100,24 +1103,24 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, * should be implemented better... */ if (ob->mat == NULL) ob->totcol = 0; - + basen = MEM_dupallocN(base); basen->flag &= ~(OB_FROMDUPLI | OB_FROMGROUP); ob->flag = basen->flag; basen->lay = base->lay; BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */ basen->object = ob; - + /* make sure apply works */ BKE_free_animdata(&ob->id); ob->adt = NULL; - + ob->parent = NULL; ob->constraints.first = ob->constraints.last = NULL; ob->disp.first = ob->disp.last = NULL; ob->transflag &= ~OB_DUPLI; ob->lay = base->lay; - + copy_m4_m4(ob->obmat, dob->mat); BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE); @@ -1126,7 +1129,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (parent_gh) BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->index)), ob); } - + if (use_hierarchy) { for (dob = lb->first; dob; dob = dob->next) { /* original parents */ @@ -1186,8 +1189,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, invert_m4_m4(ob_dst->parentinv, dob->mat); BKE_object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE); DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB); - - } } @@ -1197,9 +1198,9 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL); copy_object_set_idnew(C, 0); - + free_object_duplilist(lb); - + base->object->transflag &= ~OB_DUPLI; } @@ -1210,9 +1211,9 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) const short use_base_parent = RNA_boolean_get(op->ptr, "use_base_parent"); const short use_hierarchy = RNA_boolean_get(op->ptr, "use_hierarchy"); - + clear_id_newpoins(); - + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { make_object_duplilist_real(C, scene, base, use_base_parent, use_hierarchy); @@ -1226,23 +1227,22 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SCENE, scene); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); - + return OPERATOR_FINISHED; } void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) { - /* identifiers */ ot->name = "Make Duplicates Real"; ot->description = "Make dupli objects attached to this object real"; ot->idname = "OBJECT_OT_duplicates_make_real"; - + /* api callbacks */ ot->exec = object_duplicates_make_real_exec; - + ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1616,12 +1616,12 @@ void OBJECT_OT_convert(wmOperatorType *ot) ot->name = "Convert to"; ot->description = "Convert selected objects to another type"; ot->idname = "OBJECT_OT_convert"; - + /* api callbacks */ ot->invoke = WM_menu_invoke; ot->exec = convert_exec; ot->poll = convert_poll; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1655,12 +1655,12 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base else { obn = BKE_object_copy(ob); obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; - + basen = MEM_mallocN(sizeof(Base), "duplibase"); *basen = *base; BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ basen->object = obn; - + if (basen->flag & OB_FROMGROUP) { Group *group; for (group = bmain->group.first; group; group = group->id.next) { @@ -1668,20 +1668,21 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base add_to_group(group, obn, scene, basen); } } - + /* duplicates using userflags */ if (dupflag & USER_DUP_ACT) { BKE_copy_animdata_id_action(&obn->id); } - + if (dupflag & USER_DUP_MAT) { for (a = 0; a < obn->totcol; a++) { id = (ID *)obn->mat[a]; if (id) { ID_NEW_US(obn->mat[a]) - else obn->mat[a] = BKE_material_copy(obn->mat[a]); + else + obn->mat[a] = BKE_material_copy(obn->mat[a]); id->us--; - + if (dupflag & USER_DUP_ACT) { BKE_copy_animdata_id_action(&obn->mat[a]->id); } @@ -1694,8 +1695,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id = (ID *) psys->part; if (id) { ID_NEW_US(psys->part) - else psys->part = BKE_particlesettings_copy(psys->part); - + else + psys->part = BKE_particlesettings_copy(psys->part); + if (dupflag & USER_DUP_ACT) { BKE_copy_animdata_id_action(&psys->part->id); } @@ -1704,21 +1706,19 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } } } - + id = obn->data; didit = 0; - + switch (obn->type) { case OB_MESH: if (dupflag & USER_DUP_MESH) { ID_NEW_US2(obn->data) else { obn->data = BKE_mesh_copy(obn->data); - if (obn->fluidsimSettings) { obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; } - didit = 1; } id->us--; @@ -1774,11 +1774,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id->us--; } break; - case OB_ARMATURE: obn->recalc |= OB_RECALC_DATA; - if (obn->pose) obn->pose->flag |= POSE_RECALC; - + if (obn->pose) + obn->pose->flag |= POSE_RECALC; if (dupflag & USER_DUP_ARM) { ID_NEW_US2(obn->data) else { @@ -1788,9 +1787,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } id->us--; } - break; - case OB_LATTICE: if (dupflag != 0) { ID_NEW_US2(obn->data) @@ -1821,13 +1818,12 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id->us--; } break; - } /* check if obdata is copied */ if (didit) { Key *key = BKE_key_from_object(obn); - + if (dupflag & USER_DUP_ACT) { bActuator *act; @@ -1846,7 +1842,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } } } - + if (dupflag & USER_DUP_MAT) { matarar = give_matarar(obn); if (matarar) { @@ -1854,8 +1850,8 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id = (ID *)(*matarar)[a]; if (id) { ID_NEW_US((*matarar)[a]) - else (*matarar)[a] = BKE_material_copy((*matarar)[a]); - + else + (*matarar)[a] = BKE_material_copy((*matarar)[a]); id->us--; } } @@ -1906,14 +1902,14 @@ static int duplicate_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); int linked = RNA_boolean_get(op->ptr, "linked"); int dupflag = (linked) ? 0 : U.dupflag; - + clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag); - + /* note that this is safe to do with this context iterator, * the list is made in advance */ ED_base_object_select(base, BA_DESELECT); @@ -1945,19 +1941,19 @@ static int duplicate_exec(bContext *C, wmOperator *op) void OBJECT_OT_duplicate(wmOperatorType *ot) { PropertyRNA *prop; - + /* identifiers */ ot->name = "Duplicate Objects"; ot->description = "Duplicate selected objects"; ot->idname = "OBJECT_OT_duplicate"; - + /* api callbacks */ ot->exec = duplicate_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* to give to transform */ RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data"); prop = RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); @@ -1966,7 +1962,6 @@ void OBJECT_OT_duplicate(wmOperatorType *ot) /* **************** add named object, for dragdrop ************* */ - static int add_named_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -2021,34 +2016,32 @@ void OBJECT_OT_add_named(wmOperatorType *ot) ot->name = "Add Named Object"; ot->description = "Add named object"; ot->idname = "OBJECT_OT_add_named"; - + /* api callbacks */ ot->exec = add_named_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data"); RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME - 2, "Name", "Object name to add"); } - - /**************************** Join *************************/ + static int join_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - + if (!ob || ob->id.lib) return 0; - + if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE)) return ED_operator_screenactive(C); else return 0; } - static int join_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -2069,7 +2062,7 @@ static int join_exec(bContext *C, wmOperator *op) return join_curve_exec(C, op); else if (ob->type == OB_ARMATURE) return join_armature_exec(C, op); - + return OPERATOR_CANCELLED; } @@ -2079,22 +2072,23 @@ void OBJECT_OT_join(wmOperatorType *ot) ot->name = "Join"; ot->description = "Join selected objects into active object"; ot->idname = "OBJECT_OT_join"; - + /* api callbacks */ ot->exec = join_exec; ot->poll = join_poll; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /**************************** Join as Shape Key*************************/ + static int join_shapes_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - + if (!ob || ob->id.lib) return 0; - + /* only meshes supported at the moment */ if (ob->type == OB_MESH) return ED_operator_screenactive(C); @@ -2106,7 +2100,7 @@ static int join_shapes_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - + if (scene->obedit) { BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode"); return OPERATOR_CANCELLED; @@ -2115,10 +2109,10 @@ static int join_shapes_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata"); return OPERATOR_CANCELLED; } - + if (ob->type == OB_MESH) return join_mesh_shapes_exec(C, op); - + return OPERATOR_CANCELLED; } @@ -2128,11 +2122,11 @@ void OBJECT_OT_join_shapes(wmOperatorType *ot) ot->name = "Join as Shapes"; ot->description = "Merge selected objects to shapes of active object"; ot->idname = "OBJECT_OT_join_shapes"; - + /* api callbacks */ ot->exec = join_shapes_exec; ot->poll = join_shapes_poll; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 0ea2f78a415..6d124377821 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -1031,7 +1031,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = *lvl; tmp_mmd.sculptlvl = *lvl; dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, - MULTIRES_USE_LOCAL_MMD); + 0); cddm->release(cddm); } @@ -1052,7 +1052,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = mmd->totlvl; tmp_mmd.sculptlvl = mmd->totlvl; dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, - MULTIRES_USE_LOCAL_MMD); + 0); cddm->release(cddm); return dm; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 1ef7c12b409..56f2426b1b0 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -40,6 +40,7 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "DNA_anim_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_scene_types.h" @@ -51,6 +52,7 @@ #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_object.h" @@ -71,6 +73,7 @@ #include "ED_object.h" #include "ED_armature.h" +#include "ED_keyframing.h" #include "ED_screen.h" #include "UI_interface.h" @@ -655,12 +658,15 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_stretchto_reset"; ot->description = "Reset original length of bone for Stretch To Constraint"; - ot->exec = stretchto_reset_exec; + /* callbacks */ ot->invoke = stretchto_reset_invoke; + ot->exec = stretchto_reset_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -698,12 +704,15 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_limitdistance_reset"; ot->description = "Reset limiting distance for Limit Distance Constraint"; - ot->exec = limitdistance_reset_exec; + /* callbacks */ ot->invoke = limitdistance_reset_invoke; + ot->exec = limitdistance_reset_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -824,12 +833,15 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_childof_set_inverse"; ot->description = "Set inverse correction for ChildOf constraint"; - ot->exec = childof_set_inverse_exec; + /* callbacks */ ot->invoke = childof_set_inverse_invoke; + ot->exec = childof_set_inverse_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -868,13 +880,140 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_childof_clear_inverse"; ot->description = "Clear inverse correction for ChildOf constraint"; - ot->exec = childof_clear_inverse_exec; + /* callbacks */ ot->invoke = childof_clear_inverse_invoke; + ot->exec = childof_clear_inverse_exec; + ot->poll = edit_constraint_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + edit_constraint_properties(ot); +} + +/* --------------- Follow Path Constraint ------------------ */ + +static int followpath_path_animate_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_FOLLOWPATH); + bFollowPathConstraint *data = (con) ? (bFollowPathConstraint *)con->data : NULL; + + bAction *act = NULL; + FCurve *fcu = NULL; + int sfra = RNA_int_get(op->ptr, "frame_start"); + int len = RNA_int_get(op->ptr, "length"); + float standardRange = 1.0; + + /* nearly impossible sanity check */ + if (data == NULL) { + BKE_report(op->reports, RPT_ERROR, "Follow Path constraint not found"); + return OPERATOR_CANCELLED; + } + + /* add F-Curve as appropriate */ + if (data->tar) { + Curve *cu = (Curve *)data->tar->data; + + if ( ELEM(NULL, cu->adt, cu->adt->action) || + (list_find_fcurve(&cu->adt->action->curves, "eval_time", 0) == NULL)) + { + /* create F-Curve for path animation */ + act = verify_adt_action(&cu->id, 1); + fcu = verify_fcurve(act, NULL, NULL, "eval_time", 0, 1); + + /* standard vertical range - 1:1 = 100 frames */ + standardRange = 100.0f; + } + else { + /* path anim exists already - abort for now as this may well be what was intended */ + BKE_report(op->reports, RPT_WARNING, "Path is already animated"); + return OPERATOR_CANCELLED; + } + } + else { + /* animate constraint's "fixed offset" */ + PointerRNA ptr; + PropertyRNA *prop; + char *path; + + /* get RNA pointer to constraint's "offset_factor" property - to build RNA path */ + RNA_pointer_create(&ob->id, &RNA_FollowPathConstraint, con, &ptr); + prop = RNA_struct_find_property(&ptr, "offset_factor"); + + path = RNA_path_from_ID_to_property(&ptr, prop); + + /* create F-Curve for constraint */ + act = verify_adt_action(&ob->id, 1); + fcu = verify_fcurve(act, NULL, NULL, path, 0, 1); + + /* standard vertical range - 0.0 to 1.0 */ + standardRange = 1.0f; + + /* enable "Use Fixed Position" so that animating this has effect */ + data->followflag |= FOLLOWPATH_STATIC; + + /* path needs to be freed */ + if (path) + MEM_freeN(path); + } + + /* setup dummy 'generator' modifier here to get 1-1 correspondence still working + * and define basic slope of this curve based on the properties + */ + if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) { + FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + FMod_Generator *gen = fcm->data; + + /* Assume that we have the following equation: + * y = Ax + B + * 1 0 <-- coefficients array indices + */ + float A = standardRange / (float)(len); + float B = (float)(-sfra) * A; + + gen->coefficients[1] = A; + gen->coefficients[0] = B; + } + + /* updates... */ + WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); + return OPERATOR_FINISHED; +} + +static int followpath_path_animate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + /* hook up invoke properties for figuring out which constraint we're dealing with */ + if (edit_constraint_invoke_properties(C, op)) { + return followpath_path_animate_exec(C, op); + } + else { + return OPERATOR_CANCELLED; + } +} + +void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Auto Animate Path"; + ot->idname = "CONSTRAINT_OT_followpath_path_animate"; + ot->description = "Add default animation for path used by constraint if it isn't animated already"; + + /* callbacks */ + ot->invoke = followpath_path_animate_invoke; + ot->exec = followpath_path_animate_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ edit_constraint_properties(ot); + RNA_def_int(ot->srna, "frame_start", 1, MINAFRAME, MAXFRAME, "Start Frame", + "First frame of path animation", MINAFRAME, MAXFRAME); + RNA_def_int(ot->srna, "length", 100, 0, MAXFRAME, "Length", + "Number of frames that path animation should take", 0, MAXFRAME); } /* ------------- Object Solver Constraint ------------------ */ @@ -914,13 +1053,16 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot) ot->name = "Set Inverse"; ot->idname = "CONSTRAINT_OT_objectsolver_set_inverse"; ot->description = "Set inverse correction for ObjectSolver constraint"; - - ot->exec = objectsolver_set_inverse_exec; + + /* callbacks */ ot->invoke = objectsolver_set_inverse_invoke; + ot->exec = objectsolver_set_inverse_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -957,13 +1099,16 @@ void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot) ot->name = "Clear Inverse"; ot->idname = "CONSTRAINT_OT_objectsolver_clear_inverse"; ot->description = "Clear inverse correction for ObjectSolver constraint"; - - ot->exec = objectsolver_clear_inverse_exec; + + /* callbacks */ ot->invoke = objectsolver_clear_inverse_invoke; + ot->exec = objectsolver_clear_inverse_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -983,13 +1128,14 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con) void ED_object_constraint_update(Object *ob) { - if (ob->pose) BKE_pose_update_constraint_flags(ob->pose); object_test_constraints(ob); - if (ob->type == OB_ARMATURE) DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); - else DAG_id_tag_update(&ob->id, OB_RECALC_OB); + if (ob->type == OB_ARMATURE) + DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); + else + DAG_id_tag_update(&ob->id, OB_RECALC_OB); } void ED_object_constraint_dependency_update(Main *bmain, Scene *scene, Object *ob) @@ -1006,6 +1152,7 @@ static int constraint_poll(bContext *C) return (ptr.id.data && ptr.data); } + static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); @@ -1020,12 +1167,12 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op)) constraints_set_active(lb, NULL); ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */ - + /* ITASC needs to be rebuilt once a constraint is removed [#26920] */ if (is_ik) { BIK_clear_data(ob->pose); } - + /* notifiers */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); @@ -1052,6 +1199,7 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + static int constraint_move_down_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); @@ -1081,7 +1229,6 @@ static int constraint_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNU return OPERATOR_CANCELLED; } - void CONSTRAINT_OT_move_down(wmOperatorType *ot) { /* identifiers */ @@ -1090,12 +1237,14 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot) ot->description = "Move constraint down in constraint stack"; /* callbacks */ - ot->exec = constraint_move_down_exec; ot->invoke = constraint_move_down_invoke; + ot->exec = constraint_move_down_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index bdc7699ee96..43c6c332791 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1017,9 +1017,9 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D if (!(ob = OBACT)) return; - if (scene->obedit) { // XXX get from context -// if (ob->type == OB_MESH) -// XXX mesh_copy_menu(); + if (scene->obedit) { /* XXX get from context */ +/* if (ob->type == OB_MESH) */ +/* XXX mesh_copy_menu(); */ return; } @@ -1030,34 +1030,34 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D */ strcpy(str, - "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|" - "Time Offset%x5|Dupli%x6|Object Color%x31|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|" - "Logic Bricks%x10|Protected Transform%x29|%l"); + "Copy Attributes %t|Location %x1|Rotation %x2|Size %x3|Draw Options %x4|" + "Time Offset %x5|Dupli %x6|Object Color %x31|%l|Mass %x7|Damping %x8|All Physical Attributes %x11|Properties %x9|" + "Logic Bricks %x10|Protected Transform %x29|%l"); - strcat(str, "|Object Constraints%x22"); - strcat(str, "|NLA Strips%x26"); + strcat(str, "|Object Constraints %x22"); + strcat(str, "|NLA Strips %x26"); -// XXX if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) { -// strcat(str, "|Texture Space%x17"); -// } +/* XXX if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) { */ +/* strcat(str, "|Texture Space %x17"); */ +/* } */ - if (ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19"); - if (ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28"); + if (ob->type == OB_FONT) strcat(str, "|Font Settings %x18|Bevel Settings %x19"); + if (ob->type == OB_CURVE) strcat(str, "|Bevel Settings %x19|UV Orco %x28"); if ((ob->type == OB_FONT) || (ob->type == OB_CURVE)) { - strcat(str, "|Curve Resolution%x25"); + strcat(str, "|Curve Resolution %x25"); } if (ob->type == OB_MESH) { - strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27"); + strcat(str, "|Subsurf Settings %x21|AutoSmooth %x27"); } - if (ob->soft) strcat(str, "|Soft Body Settings%x23"); + if (ob->soft) strcat(str, "|Soft Body Settings %x23"); - strcat(str, "|Pass Index%x30"); + strcat(str, "|Pass Index %x30"); if (ob->type == OB_MESH || ob->type == OB_CURVE || ob->type == OB_LATTICE || ob->type == OB_SURF) { - strcat(str, "|Modifiers ...%x24"); + strcat(str, "|Modifiers ... %x24"); } event = pupmenu(str); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b62ff676066..4c83f6ef2ce 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -112,6 +112,7 @@ void OBJECT_OT_add_named(struct wmOperatorType *ot); void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); +void OBJECT_OT_empty_add(struct wmOperatorType *ot); void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_camera_add(struct wmOperatorType *ot); @@ -193,6 +194,7 @@ void CONSTRAINT_OT_childof_set_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_childof_clear_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_objectsolver_set_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_objectsolver_clear_inverse(struct wmOperatorType *ot); +void CONSTRAINT_OT_followpath_path_animate(struct wmOperatorType *ot); /* object_vgroup.c */ void OBJECT_OT_vertex_group_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 6fe7ad05a70..d75ef78fc4c 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -159,8 +159,10 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc /* set totlvl from existing MDISPS layer if object already had it */ multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob); - /* ensure that grid paint mask layer is created */ - ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md); + if (ob->mode & OB_MODE_SCULPT) { + /* ensure that grid paint mask layer is created */ + ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md); + } } else if (type == eModifierType_Skin) { /* ensure skin-node customdata exists */ @@ -710,11 +712,6 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi BLI_remlink(&ob->modifiers, md); modifier_free(md); - if (ob->type == OB_MESH) { - /* ensure mesh paint mask layer remains after applying */ - ED_sculpt_mask_layers_ensure(ob, NULL); - } - return 1; } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index cec849efca7..fa40d579e2b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -113,6 +113,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_delete); WM_operatortype_append(OBJECT_OT_text_add); WM_operatortype_append(OBJECT_OT_armature_add); + WM_operatortype_append(OBJECT_OT_empty_add); WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_camera_add); WM_operatortype_append(OBJECT_OT_speaker_add); @@ -168,6 +169,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(CONSTRAINT_OT_childof_clear_inverse); WM_operatortype_append(CONSTRAINT_OT_objectsolver_set_inverse); WM_operatortype_append(CONSTRAINT_OT_objectsolver_clear_inverse); + WM_operatortype_append(CONSTRAINT_OT_followpath_path_animate); WM_operatortype_append(OBJECT_OT_vertex_group_add); WM_operatortype_append(OBJECT_OT_vertex_group_remove); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index ea6f9d4cebb..ee2b5e08520 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -398,41 +398,41 @@ static void PE_set_view3d_data(bContext *C, PEData *data) /*************************** selection utilities *******************************/ -static int key_test_depth(PEData *data, const float co[3]) +static int key_test_depth(PEData *data, const float co[3], const int screen_co[2]) { View3D *v3d= data->vc.v3d; double ux, uy, uz; float depth; - short wco[3], x, y; /* nothing to do */ if ((v3d->drawtype<=OB_WIRE) || (v3d->flag & V3D_ZBUF_SELECT)==0) return 1; - ED_view3d_project_short(data->vc.ar, co, wco); - - if (wco[0] == IS_CLIPPED) + /* 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) + { return 0; + } +#endif gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection, (GLint *)data->mats.viewport, &ux, &uy, &uz); - x=wco[0]; - y=wco[1]; - #if 0 /* works well but too slow on some systems [#23118] */ - x+= (short)data->vc.ar->winrct.xmin; - y+= (short)data->vc.ar->winrct.ymin; + screen_co[0] += (short)data->vc.ar->winrct.xmin; + screen_co[1] += (short)data->vc.ar->winrct.ymin; /* PE_set_view3d_data calls this. no need to call here */ /* view3d_validate_backbuf(&data->vc); */ - glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + glReadPixels(screen_co[0], screen_co[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); #else /* faster to use depths, these are calculated in PE_set_view3d_data */ { ViewDepths *vd = data->vc.rv3d->depths; assert(vd && vd->depths); /* we know its not clipped */ - depth= vd->depths[y * vd->w + x]; + depth = vd->depths[screen_co[1] * vd->w + screen_co[0]]; } #endif @@ -445,21 +445,21 @@ static int key_test_depth(PEData *data, const float co[3]) static int key_inside_circle(PEData *data, float rad, const float co[3], float *distance) { float dx, dy, dist; - int sco[2]; + int screen_co[2]; - ED_view3d_project_int(data->vc.ar, co, sco); - - if (sco[0] == IS_CLIPPED) + /* 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) { return 0; - - dx= data->mval[0] - sco[0]; - dy= data->mval[1] - sco[1]; + } + + dx= data->mval[0] - screen_co[0]; + dy= data->mval[1] - screen_co[1]; dist= sqrt(dx*dx + dy*dy); if (dist > rad) return 0; - if (key_test_depth(data, co)) { + if (key_test_depth(data, co, screen_co)) { if (distance) *distance=dist; @@ -471,17 +471,16 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float * static int key_inside_rect(PEData *data, const float co[3]) { - int sco[2]; + int screen_co[2]; - ED_view3d_project_int(data->vc.ar, co, sco); - - if (sco[0] == IS_CLIPPED) + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { return 0; + } - if (sco[0] > data->rect->xmin && sco[0] < data->rect->xmax && - sco[1] > data->rect->ymin && sco[1] < data->rect->ymax) + if (screen_co[0] > data->rect->xmin && screen_co[0] < data->rect->xmax && + screen_co[1] > data->rect->ymin && screen_co[1] < data->rect->ymax) { - return key_test_depth(data, co); + return key_test_depth(data, co, screen_co); } return 0; @@ -1634,7 +1633,7 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad) /************************ lasso select operator ************************/ -int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, short select) +int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short extend, short select) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); @@ -1645,7 +1644,7 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); POINT_P; KEY_K; float co[3], mat[4][4]= MAT4_UNITY; - int vertco[2]; + int screen_co[2]; PEData data; @@ -1666,9 +1665,9 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho LOOP_KEYS { copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - ED_view3d_project_int(ar, co, vertco); - if (BLI_lasso_is_point_inside(mcords, moves, vertco[0], vertco[1], IS_CLIPPED) && - key_test_depth(&data, co)) + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && + key_test_depth(&data, co, screen_co)) { if (select && !(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; @@ -1686,9 +1685,9 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - ED_view3d_project_int(ar, co, vertco); - if (BLI_lasso_is_point_inside(mcords, moves, vertco[0], vertco[1], IS_CLIPPED) && - key_test_depth(&data, co)) + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && + key_test_depth(&data, co, screen_co)) { if (select && !(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; @@ -2789,7 +2788,7 @@ static void brush_cut(PEData *data, int pa_index) float rad2, cut_time= 1.0; float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv; int k, cut, keys= (int)pow(2.0, (double)pset->draw_step); - int vertco[2]; + int screen_co[2]; /* blunt scissors */ if (BLI_frand() > data->cutfac) return; @@ -2798,13 +2797,15 @@ 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) + return; + rad2= data->rad * data->rad; cut=0; - ED_view3d_project_int_noclip(ar, key->co, vertco); - x0= (float)vertco[0]; - x1= (float)vertco[1]; + x0 = (float)screen_co[0]; + x1 = (float)screen_co[1]; o0= (float)data->mval[0]; o1= (float)data->mval[1]; @@ -2813,26 +2814,27 @@ static void brush_cut(PEData *data, int pa_index) xo1= x1 - o1; /* check if root is inside circle */ - if (xo0*xo0 + xo1*xo1 < rad2 && key_test_depth(data, key->co)) { + if (xo0*xo0 + xo1*xo1 < rad2 && key_test_depth(data, key->co, screen_co)) { cut_time= -1.0f; cut= 1; } else { /* calculate path time closest to root that was inside the circle */ for (k=1, key++; k<=keys; k++, key++) { - ED_view3d_project_int_noclip(ar, key->co, vertco); - if (key_test_depth(data, key->co) == 0) { - x0= (float)vertco[0]; - x1= (float)vertco[1]; + if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || + key_test_depth(data, key->co, screen_co) == 0) + { + x0 = (float)screen_co[0]; + x1 = (float)screen_co[1]; xo0= x0 - o0; xo1= x1 - o1; continue; } - v0= (float)vertco[0] - x0; - v1= (float)vertco[1] - x1; + v0 = (float)screen_co[0] - x0; + v1 = (float)screen_co[1] - x1; dv= v0*v0 + v1*v1; @@ -2857,8 +2859,8 @@ static void brush_cut(PEData *data, int pa_index) } } - x0= (float)vertco[0]; - x1= (float)vertco[1]; + x0 = (float)screen_co[0]; + x1 = (float)screen_co[1]; xo0= x0 - o0; xo1= x1 - o1; diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 099d868a0ad..315386a947e 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -695,21 +695,21 @@ static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetF outStringsChanged=1; } - // check if modified output dir is ok + /* check if modified output dir is ok */ #if 0 if (outStringsChanged) { char dispmsg[FILE_MAX+256]; int selection=0; BLI_strncpy(dispmsg, "Output settings set to: '", sizeof(dispmsg)); strcat(dispmsg, newSurfdataPath); - strcat(dispmsg, "'%t|Continue with changed settings%x1|Discard and abort%x0"); + strcat(dispmsg, "'%t|Continue with changed settings %x1|Discard and abort %x0"); - // ask user if thats what he/she wants... + /* ask user if thats what he/she wants... */ selection = pupmenu(dispmsg); - if (selection < 1) return 0; // 0 from menu, or -1 aborted + if (selection < 1) return 0; /* 0 from menu, or -1 aborted */ BLI_strncpy(targetDir, newSurfdataPath, sizeof(targetDir)); strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR); - BLI_path_abs(targetDir, G.main->name); // fixed #frame-no + BLI_path_abs(targetDir, G.main->name); /* fixed #frame-no */ } #endif return outStringsChanged; diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 6b6018e51d2..817067422af 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -271,9 +271,19 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre else sce->r.xparts = sce->r.yparts = 4; - /* exception: don't color manage texture previews or icons */ - if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) - BKE_scene_disable_color_management(sce); + /* 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)); + } if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO) sce->r.alphamode = R_ALPHAPREMUL; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index d14514546f5..01a5304451a 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1459,39 +1459,39 @@ void ED_area_prevspace(bContext *C, ScrArea *sa) static const char *editortype_pup(void) { const char *types = N_( - "Editor type:%t" + "Editor type: %t" "|3D View %x1" "|%l" - + "|Timeline %x15" "|Graph Editor %x2" "|DopeSheet %x12" "|NLA Editor %x13" - + "|%l" - + "|UV/Image Editor %x6" - + "|Video Sequence Editor %x8" "|Movie Clip Editor %x20" "|Text Editor %x9" "|Node Editor %x16" "|Logic Editor %x17" - + "|%l" - + "|Properties %x4" "|Outliner %x3" "|User Preferences %x19" - "|Info%x7" + "|Info %x7" "|%l" "|File Browser %x5" - + "|%l" - + "|Python Console %x18" ); @@ -1517,7 +1517,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_("Displays current editor type. Click for menu of available types")); + TIP_("Display current editor type (click for 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/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 043b7ecb5cb..ae72dce1415 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC ../include + ../uvedit ../../blenkernel ../../blenlib ../../blenloader @@ -28,7 +29,6 @@ set(INC ../../imbuf ../../makesdna ../../makesrna - ../uvedit ../../render/extern/include ../../windowmanager ../../../../intern/guardedalloc diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index e14266c83a7..6120229190d 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -322,11 +322,16 @@ 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 */ - ED_view3d_project_float(vc->ar, location, p1); - ED_view3d_project_float(vc->ar, offset, p2); - - /* the distance between these points is the size of the projected brush in pixels */ - return len_v2v2(p1, p2); + 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)) + { + /* the distance between these points is the size of the projected brush in pixels */ + return len_v2v2(p1, p2); + } + else { + BLI_assert(0); /* assert because the code that sets up the vectors should disallow this */ + return 0; + } } static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 2970bdfb5a4..bdd73cd6db3 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -197,7 +197,7 @@ static void partialvis_update_grids(Object *ob, for (x = 0; x < key.grid_size; x++) { CCGElem *elem = CCG_grid_elem(&key, grids[g], x, y); const float *co = CCG_elem_co(&key, elem); - float mask = *CCG_elem_mask(&key, elem); + float mask = key.has_mask ? *CCG_elem_mask(&key, elem) : 0.0f; /* skip grid element if not in the effected area */ if (is_effected(area, planes, co, mask)) { diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index e309bdb99cb..697d7c63d1f 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -54,6 +54,7 @@ #include "WM_types.h" #include "ED_screen.h" +#include "ED_sculpt.h" #include "paint_intern.h" #include "sculpt_intern.h" /* for undo push */ @@ -77,7 +78,9 @@ static void mask_flood_fill_set_elem(float *elem, static int mask_flood_fill_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); + struct Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + struct MultiresModifierData *mmd = sculpt_multires_active(scene, ob); PaintMaskFloodMode mode; float value; DerivedMesh *dm; @@ -88,7 +91,9 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) mode = RNA_enum_get(op->ptr, "mode"); value = RNA_float_get(op->ptr, "value"); - dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); + ED_sculpt_mask_layers_ensure(ob, mmd); + + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); pbvh = dm->getPBVH(ob, dm); ob->sculpt->pbvh = pbvh; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 29a59651cf7..b3679516fff 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -201,7 +201,7 @@ static void imapaint_project(Object *ob, float model[][4], float proj[][4], cons static void imapaint_tri_weights(Object *ob, const float v1[3], const float v2[3], const float v3[3], - const float co[3], float w[3]) + const float co[2], float w[3]) { float pv1[4], pv2[4], pv3[4], h[3], divw; float model[4][4], proj[4][4], wmat[3][3], invwmat[3][3]; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 8aed92df3af..5a79368ac49 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -846,20 +846,22 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_nor[3], const float mval[2], const float brush_size_pressure) { - Brush *brush = paint_brush(&vp->paint); - float dist_squared; - float vertco[2], delta[2]; + float vertco[2]; - ED_view3d_project_float_noclip(vc->ar, vert_nor, vertco); - sub_v2_v2v2(delta, mval, vertco); - dist_squared = dot_v2v2(delta, delta); /* len squared */ - if (dist_squared > brush_size_pressure * brush_size_pressure) { - return 0.0f; - } - else { - const float dist = sqrtf(dist_squared); - return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + float delta[2]; + float dist_squared; + + sub_v2_v2v2(delta, mval, vertco); + dist_squared = dot_v2v2(delta, delta); /* len squared */ + if (dist_squared <= brush_size_pressure * brush_size_pressure) { + Brush *brush = paint_brush(&vp->paint); + const float dist = sqrtf(dist_squared); + return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + } } + + return 0.0f; } static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, @@ -2370,7 +2372,8 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) { - + int retval; + op->customdata = paint_stroke_new(C, NULL, wpaint_stroke_test_start, wpaint_stroke_update_step, wpaint_stroke_done, event->type); @@ -2378,7 +2381,9 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) /* add modal handler */ WM_event_add_modal_handler(C, op); - op->type->modal(C, op, event); + retval = op->type->modal(C, op, event); + OPERATOR_RETVAL_CHECK(retval); + BLI_assert(retval == OPERATOR_RUNNING_MODAL); return OPERATOR_RUNNING_MODAL; } @@ -2814,7 +2819,8 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) { - + int retval; + op->customdata = paint_stroke_new(C, NULL, vpaint_stroke_test_start, vpaint_stroke_update_step, vpaint_stroke_done, event->type); @@ -2822,7 +2828,9 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) /* add modal handler */ WM_event_add_modal_handler(C, op); - op->type->modal(C, op, event); + retval = op->type->modal(C, op, event); + OPERATOR_RETVAL_CHECK(retval); + BLI_assert(retval == OPERATOR_RUNNING_MODAL); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 05b5b90344c..3d3e86d2acb 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1225,7 +1225,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->view_normal, vd.no, vd.fno, - smooth_mask ? 0 : *vd.mask); + smooth_mask ? 0 : (vd.mask ? *vd.mask : 0.0f)); if (smooth_mask) { float val = neighbor_average_mask(ss, vd.vert_indices[vd.i]) - *vd.mask; val *= fade * bstrength; @@ -1524,7 +1524,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /* offset vertex */ float fade = tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, vd.no, - vd.fno, *vd.mask); + vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -1580,7 +1580,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod /* offset vertex */ const float fade = tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); float val1[3]; float val2[3]; @@ -1623,7 +1623,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, vd.co)) { float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->view_normal, vd.no, - vd.fno, *vd.mask); + vd.fno, vd.mask ? *vd.mask : 0.0f); float val[3]; sub_v3_v3v3(val, test.location, vd.co); @@ -1677,7 +1677,8 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, - ss->cache->sculpt_normal_symm, origno[vd.i], NULL, *vd.mask); + ss->cache->sculpt_normal_symm, origno[vd.i], + NULL, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1718,7 +1719,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1767,7 +1768,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1815,7 +1816,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, ss->cache->sculpt_normal_symm, - origno[vd.i], NULL, *vd.mask); + origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1868,7 +1869,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, ss->cache->sculpt_normal_symm, - origno[vd.i], NULL, *vd.mask); + origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f); mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]); sub_v3_v3(proxy[vd.i], origco[vd.i]); @@ -1921,7 +1922,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); float *disp = &layer_disp[vd.i]; float val[3]; @@ -1974,7 +1975,8 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno { if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, - ss->cache->view_normal, vd.no, vd.fno, *vd.mask); + ss->cache->view_normal, + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); float val[3]; if (vd.fno) copy_v3_v3(val, vd.fno); @@ -2315,7 +2317,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist), - an, vd.no, vd.fno, *vd.mask); + an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2389,7 +2391,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist), - an, vd.no, vd.fno, *vd.mask); + an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2491,7 +2493,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, ss->cache->radius * test.dist, - an, vd.no, vd.fno, *vd.mask); + an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2555,7 +2557,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist), - an, vd.no, vd.fno, *vd.mask); + an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2619,7 +2621,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist), - an, vd.no, vd.fno, *vd.mask); + an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -3062,7 +3064,11 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) } } -void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_pmap) +/** + * \param need_mask So the DerivedMesh thats returned has mask data + */ +void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, + int need_pmap, int need_mask) { DerivedMesh *dm; SculptSession *ss = ob->sculpt; @@ -3071,6 +3077,27 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_ ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob); + if (need_mask) { + if (mmd == NULL) { + if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) { + ED_sculpt_mask_layers_ensure(ob, NULL); + } + } + else { + if (!CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) { +#if 1 + ED_sculpt_mask_layers_ensure(ob, mmd); +#else /* if we wanted to support adding mask data while multi-res painting, we would need to do this */ + if ((ED_sculpt_mask_layers_ensure(ob, mmd) & ED_SCULPT_MASK_LAYER_CALC_LOOP)) { + /* remake the derived mesh */ + ob->recalc |= OB_RECALC_DATA; + BKE_object_handle_update(scene, ob); + } +#endif + } + } + } + /* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */ BKE_mesh_tessface_ensure(me); @@ -3676,7 +3703,7 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) Brush *brush = paint_brush(&sd->paint); sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, - sculpt_any_smooth_mode(brush, ss->cache, 0)); + sculpt_any_smooth_mode(brush, ss->cache, 0), FALSE); } } @@ -3782,12 +3809,17 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op) Brush *brush = paint_brush(&sd->paint); int mode = RNA_enum_get(op->ptr, "mode"); int is_smooth = 0; + int need_mask = FALSE; + + if (brush->sculpt_tool == SCULPT_TOOL_MASK) { + need_mask = TRUE; + } view3d_operator_needs_opengl(C); sculpt_brush_init_tex(scene, sd, ss); is_smooth = sculpt_any_smooth_mode(brush, NULL, mode); - sculpt_update_mesh_elements(scene, sd, ob, is_smooth); + sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask); return 1; } @@ -3966,6 +3998,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even { struct PaintStroke *stroke; int ignore_background_click; + int retval; if (!sculpt_brush_stroke_init(C, op)) return OPERATOR_CANCELLED; @@ -3989,7 +4022,9 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even /* add modal handler */ WM_event_add_modal_handler(C, op); - op->type->modal(C, op, event); + retval = op->type->modal(C, op, event); + OPERATOR_RETVAL_CHECK(retval); + BLI_assert(retval == OPERATOR_RUNNING_MODAL); return OPERATOR_RUNNING_MODAL; } @@ -4103,13 +4138,14 @@ static void sculpt_init_session(Scene *scene, Object *ob) { ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); - sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0); + sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, FALSE); } -void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) +int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) { float *paint_mask; Mesh *me = ob->data; + int ret = 0; paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); @@ -4162,13 +4198,18 @@ void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) } } } + + ret |= ED_SCULPT_MASK_LAYER_CALC_LOOP; } /* create vertex paint mask layer if there isn't one already */ if (!paint_mask) { CustomData_add_layer(&me->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, me->totvert); + ret |= ED_SCULPT_MASK_LAYER_CALC_VERT; } + + return ret; } static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) @@ -4218,14 +4259,18 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) sculpt_init_session(scene, ob); /* Mask layer is required */ - ED_sculpt_mask_layers_ensure(ob, mmd); + if (mmd) { + /* XXX, we could attempt to support adding mask data mid-sculpt mode (with multi-res) + * but this ends up being quite tricky (and slow) */ + ED_sculpt_mask_layers_ensure(ob, mmd); + } BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); paint_cursor_start(C, sculpt_poll); } - WM_event_add_notifier(C, NC_SCENE | ND_MODE, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 5e79616b0b0..0852378974e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -58,7 +58,8 @@ void sculpt(struct Sculpt *sd); int sculpt_mode_poll(struct bContext *C); int sculpt_mode_poll_view3d(struct bContext *C); int sculpt_poll(struct bContext *C); -void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, int need_pmap); +void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, + int need_pmap, int need_mask); /* Deformed mesh sculpt */ void free_sculptsession_deformMats(struct SculptSession *ss); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 25555f2526f..b204fc75255 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -113,7 +113,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo if (kb) { ob->shapenr = BLI_findindex(&key->block, kb) + 1; - sculpt_update_mesh_elements(scene, sd, ob, 0); + sculpt_update_mesh_elements(scene, sd, ob, 0, FALSE); WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob); } else { @@ -271,8 +271,21 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) SculptUndoNode *unode; MultiresModifierData *mmd; int update = FALSE, rebuild = FALSE; + int need_mask = FALSE; + + for (unode = lb->first; unode; unode = unode->next) { + if (strcmp(unode->idname, ob->id.name) == 0) { + if (unode->type == SCULPT_UNDO_MASK) { + /* is possible that we can't do the mask undo (below) + * because of the vertex count */ + need_mask = TRUE; + break; + } + } + } + + sculpt_update_mesh_elements(scene, sd, ob, 0, need_mask); - sculpt_update_mesh_elements(scene, sd, ob, 0); /* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */ dm = mesh_get_derived_final(scene, ob, 0); diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 92b6517cbd9..2e92b1eea6f 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -357,8 +357,8 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) { + case NC_GPENCIL: + if (wmn->action == NA_EDITED) { /* only handle this event in GPencil mode for performance considerations */ if (saction->mode == SACTCONT_GPENCIL) ED_area_tag_redraw(sa); diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index ecc4dea8b05..75e3d8d5685 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -33,10 +33,10 @@ set(INC ../../windowmanager ../../gpu ../../../../intern/guardedalloc - ${GLEW_INCLUDE_PATH} ) set(INC_SYS + ${GLEW_INCLUDE_PATH} ) set(SRC diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index b22c9a60bdc..5e940df2a30 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1126,7 +1126,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, if (MARKER_VISIBLE(sc, track, marker)) { float npos[2]; - copy_v4_v4(vec, track->bundle_pos); + copy_v3_v3(vec, track->bundle_pos); vec[3] = 1; mul_v4_m4v4(pos, mat, vec); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 3f925df30c7..ffe4762ad15 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -407,8 +407,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) case NC_SCREEN: switch (wmn->data) { case ND_ANIMPLAY: - case ND_GPENCIL: - clip_scopes_check_gpencil_change(sa); ED_area_tag_redraw(sa); break; } @@ -420,6 +418,12 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) ED_area_tag_redraw(sa); } break; + case NC_GPENCIL: + if (wmn->action == NA_EDITED) { + clip_scopes_check_gpencil_change(sa); + ED_area_tag_redraw(sa); + } + break; } } @@ -1159,8 +1163,8 @@ static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) + case NC_GPENCIL: + if (wmn->action == NA_EDITED) ED_region_tag_redraw(ar); break; } @@ -1373,8 +1377,8 @@ static void clip_props_area_listener(ARegion *ar, wmNotifier *wmn) if (wmn->data == ND_SPACE_CLIP) ED_region_tag_redraw(ar); break; - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) + case NC_GPENCIL: + if (wmn->action == NA_EDITED) ED_region_tag_redraw(ar); break; } @@ -1406,8 +1410,8 @@ static void clip_properties_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) + case NC_GPENCIL: + if (wmn->data == ND_DATA) ED_region_tag_redraw(ar); break; case NC_BRUSH: diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 507e492497d..4f62d3fdc2f 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -413,7 +413,7 @@ void CLIP_OT_select_border(wmOperatorType *ot) /********************** lasso select operator *********************/ -static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, short select) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); @@ -469,7 +469,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho static int clip_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 0d40a6ae007..2f01483d23f 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -120,6 +120,8 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r) if (ibuf && (ibuf->rect || ibuf->rect_float)) return ibuf; } + else + *lock_r = NULL; return NULL; } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index dbad6e8bb24..31cb6d91889 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -708,8 +708,8 @@ static void image_main_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) + case NC_GPENCIL: + if (wmn->action == NA_EDITED) ED_region_tag_redraw(ar); break; } @@ -737,8 +737,8 @@ static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) + case NC_GPENCIL: + if (wmn->data == ND_DATA) ED_region_tag_redraw(ar); break; case NC_BRUSH: diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8ad02ad7d8b..470f82195a4 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1389,6 +1389,11 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE); } +static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "from_dupli", 0, NULL, 0); +} + static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); @@ -1470,6 +1475,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_TEX_VORONOI: ntype->uifunc = node_shader_buts_tex_voronoi; break; + case SH_NODE_TEX_COORD: + ntype->uifunc = node_shader_buts_tex_coord; + break; case SH_NODE_BSDF_GLOSSY: case SH_NODE_BSDF_GLASS: ntype->uifunc = node_shader_buts_glossy; @@ -2031,7 +2039,7 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C { PointerRNA imfptr = RNA_pointer_get(ptr, "format"); PointerRNA active_input_ptr, op_ptr; - uiLayout *row; + uiLayout *row, *col; int active_index; int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER); @@ -2042,32 +2050,34 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C uiItemO(layout, IFACE_("Add Input"), ICON_ZOOMIN, "NODE_OT_output_file_add_socket"); + row = uiLayoutRow(layout, FALSE); + col = uiLayoutColumn(row, TRUE); + active_index = RNA_int_get(ptr, "active_input_index"); /* using different collection properties if multilayer format is enabled */ if (multilayer) { - uiTemplateList(layout, C, ptr, "layer_slots", ptr, "active_input_index", NULL, 0, 0, 0); + uiTemplateList(col, C, ptr, "layer_slots", ptr, "active_input_index", NULL, 0, 0, 0); RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"), active_index, &active_input_ptr); } else { - uiTemplateList(layout, C, ptr, "file_slots", ptr, "active_input_index", NULL, 0, 0, 0); + uiTemplateList(col, C, ptr, "file_slots", ptr, "active_input_index", NULL, 0, 0, 0); RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"), active_index, &active_input_ptr); } /* XXX collection lookup does not return the ID part of the pointer, setting this manually here */ active_input_ptr.id.data = ptr->id.data; - row = uiLayoutRow(layout, TRUE); - op_ptr = uiItemFullO(row, "NODE_OT_output_file_move_active_socket", "", + col = uiLayoutColumn(row, TRUE); + op_ptr = uiItemFullO(col, "NODE_OT_output_file_move_active_socket", "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&op_ptr, "direction", 1); - op_ptr = uiItemFullO(row, "NODE_OT_output_file_move_active_socket", "", + op_ptr = uiItemFullO(col, "NODE_OT_output_file_move_active_socket", "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&op_ptr, "direction", 2); if (active_input_ptr.data) { if (multilayer) { - uiLayout *row, *col; col = uiLayoutColumn(layout, TRUE); uiItemL(col, IFACE_("Layer:"), ICON_NONE); @@ -2077,7 +2087,6 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY); } else { - uiLayout *row, *col; col = uiLayoutColumn(layout, TRUE); uiItemL(col, IFACE_("File Path:"), ICON_NONE); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index a5032fb6465..560ef9e8a29 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -167,7 +167,7 @@ void ED_operatormacros_node(void) ot = WM_operatortype_append_macro("NODE_OT_move_detach_links_release", "Detach", "Move a node to detach links", OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "NODE_OT_links_detach"); - mot = WM_operatortype_macro_define(ot, "NODE_OT_translate_attach"); + WM_operatortype_macro_define(ot, "NODE_OT_translate_attach"); } /* helper function for repetitive select operator keymap */ diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index f7757ce49b4..b0916a50c37 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -539,7 +539,7 @@ void NODE_OT_select_border(wmOperatorType *ot) /* ****** Lasso Select ****** */ -static int do_lasso_select_node(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_node(bContext *C, const int mcords[][2], short moves, short select) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; @@ -585,7 +585,7 @@ static int do_lasso_select_node(bContext *C, int mcords[][2], short moves, short static int node_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 0601d7c105f..b70d66f60b4 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -440,9 +440,6 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn) break; case NC_SCREEN: switch (wmn->data) { - case ND_GPENCIL: - ED_region_tag_redraw(ar); - break; case ND_SCREENCAST: case ND_ANIMPLAY: ED_region_tag_redraw(ar); @@ -463,6 +460,10 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn) if (wmn->action == NA_RENAME) ED_region_tag_redraw(ar); break; + case NC_GPENCIL: + if (wmn->action == NA_EDITED) + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 7b7170d99e0..ff895c06d57 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -242,7 +242,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) strip->us = 1; BLI_strncpy(seq->name + 2, sce_seq->id.name + 2, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); @@ -343,7 +343,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) strip->us = 1; BLI_strncpy(seq->name + 2, clip->id.name + 2, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); BKE_sequence_calc_disp(scene, seq); BKE_sequencer_sort(scene); @@ -439,7 +439,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) strip->us = 1; BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); BKE_sequence_calc_disp(scene, seq); BKE_sequencer_sort(scene); @@ -820,7 +820,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) seq->type = type; BLI_strncpy(seq->name + 2, BKE_sequence_give_name(seq), sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); sh = BKE_sequence_get_effect(seq); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index c72bff12056..7bec530fae9 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -747,7 +747,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glDisable(GL_BLEND); } - if (!BKE_seqence_is_valid_check(seq)) { + if (!BKE_sequence_is_valid_check(seq)) { glEnable(GL_POLYGON_STIPPLE); /* panic! */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index e7d964ba715..204930e82a6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1143,13 +1143,13 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op) if (selected) { /* mute unselected */ if (seq->flag & SELECT) { seq->flag |= SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } else { if ((seq->flag & SELECT) == 0) { seq->flag |= SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } } @@ -1194,13 +1194,13 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op) if (selected) { /* unmute unselected */ if (seq->flag & SELECT) { seq->flag &= ~SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } else { if ((seq->flag & SELECT) == 0) { seq->flag &= ~SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } } @@ -1573,7 +1573,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt) char name[sizeof(seq->name) - 2]; strcpy(name, seq->name + 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); BKE_sequencer_dupe_animdata(scene, name, seq->name + 2); return 1; @@ -1968,7 +1968,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) BKE_sequencer_update_muting(ed); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seqm); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 3d57f2f88ed..be33b782fdf 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -1109,7 +1109,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) actseq->tmp = SET_INT_IN_POINTER(TRUE); - for (BKE_seqence_iterator_begin(ed, &iter, TRUE); iter.valid; BKE_seqence_iterator_next(&iter)) { + for (BKE_sequence_iterator_begin(ed, &iter, TRUE); iter.valid; BKE_sequence_iterator_next(&iter)) { seq = iter.seq; /* Ignore all seqs already selected! */ @@ -1137,8 +1137,8 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) changed = TRUE; /* Unfortunately, we must restart checks from the beginning. */ - BKE_seqence_iterator_end(&iter); - BKE_seqence_iterator_begin(ed, &iter, TRUE); + BKE_sequence_iterator_end(&iter); + BKE_sequence_iterator_begin(ed, &iter, TRUE); } /* Video strips bellow active one, or any strip for audio (order do no matters here!). */ @@ -1147,7 +1147,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) changed = TRUE; } } - BKE_seqence_iterator_end(&iter); + BKE_sequence_iterator_end(&iter); return changed; } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 21c70a5b4a9..7bfe58cb50a 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -556,8 +556,8 @@ static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) { + case NC_GPENCIL: + if (wmn->action == NA_EDITED) { ED_region_tag_redraw(ar); } break; @@ -610,8 +610,8 @@ static void sequencer_buttons_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) { + case NC_GPENCIL: + if (wmn->data == ND_DATA) { ED_region_tag_redraw(ar); } break; diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index 5f312ff7fca..135e9b891bb 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -107,11 +107,6 @@ void draw_motion_path_instance(Scene *scene, * - abort if whole range is past ends of path * - otherwise clamp endpoints to extents of path */ - if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) { - /* whole path is out of bounds */ - return; - } - if (sfra < mpath->start_frame) { /* start clamp */ sfra = mpath->start_frame; @@ -121,9 +116,14 @@ void draw_motion_path_instance(Scene *scene, efra = mpath->end_frame; } + if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) { + /* whole path is out of bounds */ + return; + } + len = efra - sfra; - if (len <= 0) { + if ((len <= 0) || (mpath->points == NULL)) { return; } @@ -180,7 +180,7 @@ void draw_motion_path_instance(Scene *scene, UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10); } - /* draw a vertex with this color */ + /* draw a vertex with this color */ glVertex3fv(mpv->co); } @@ -230,7 +230,7 @@ void draw_motion_path_instance(Scene *scene, unsigned char col[4]; UI_GetThemeColor3ubv(TH_TEXT_HI, col); col[3] = 255; - + for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { char numstr[32]; float co[3]; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index f05c78e8512..e4c21a9c2c8 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -373,13 +373,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O Gtexdraw.ob = ob; Gtexdraw.is_tex = is_tex; - /* OCIO_TODO: for now assume OpenGL is always doing color management and working in sRGB space - * supporting for real display conversion could be nice here, but it's a bit challenging - * since all the shaders should be aware of such a transform - * perhaps this flag could be completely removed before release in separated commit and - * be re-implemented if real display transform would be needed - */ - Gtexdraw.color_profile = TRUE; + Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene); memcpy(Gtexdraw.obcol, obcol, sizeof(obcol)); set_draw_settings_cached(1, NULL, NULL, Gtexdraw); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5286718a587..df04cc33e71 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -101,6 +101,7 @@ #include "ED_sculpt.h" #include "ED_types.h" #include "ED_curve.h" /* for curve_editnurbs */ +#include "ED_armature.h" #include "UI_resources.h" @@ -239,107 +240,6 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return 1; } -/* ************* only use while object drawing ************** - * or after running ED_view3d_init_mats_rv3d - * */ -static void view3d_project_short_clip(ARegion *ar, const float vec[3], short adr[2], int is_local) -{ - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - adr[0] = IS_CLIPPED; - - /* clipplanes in eye space */ - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, vec, is_local)) - return; - } - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmatob, vec4); - - /* clipplanes in window space */ - if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > 0 && fx < ar->winx) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > 0.0f && fy < (float)ar->winy) { - adr[0] = (short)floorf(fx); - adr[1] = (short)floorf(fy); - } - } - } -} - -/* BMESH NOTE: this function is unused in bmesh only */ - -/* only use while object drawing */ -static void UNUSED_FUNCTION(view3d_project_short_noclip) (ARegion * ar, const float vec[3], short adr[2]) -{ - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - adr[0] = IS_CLIPPED; - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmatob, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > -32700 && fx < 32700) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > -32700.0f && fy < 32700.0f) { - adr[0] = (short)floorf(fx); - adr[1] = (short)floorf(fy); - } - } - } -} - -/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */ -static void view3d_project_short_clip_persmat(ARegion *ar, const float vec[3], short adr[2], int is_local) -{ - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - adr[0] = IS_CLIPPED; - - /* clipplanes in eye space */ - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, vec, is_local)) - return; - } - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmat, vec4); - - /* clipplanes in window space */ - if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > 0 && fx < ar->winx) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > 0.0f && fy < (float)ar->winy) { - adr[0] = (short)floorf(fx); - adr[1] = (short)floorf(fy); - } - } - } -} /* ************************ */ /* check for glsl drawing */ @@ -883,13 +783,17 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE)) mul_m4_v3(mat, vos->vec); - if (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) - view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0); - else - view3d_project_short_clip(ar, vos->vec, vos->sco, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0); - - if (vos->sco[0] != IS_CLIPPED) + 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) + { tot++; + } + else { + vos->sco[0] = IS_CLIPPED; + } } if (tot) { @@ -1974,15 +1878,17 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo 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; - short s[2] = {IS_CLIPPED, 0}; 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) { - view3d_project_short_clip(vc->ar, dl ? co : bp->vec, s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, bp, s[0], s[1]); + 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]); + } } } } @@ -2084,19 +1990,16 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo BMVert *eve = EDBM_vert_at_index(data->vc.em, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - short s[2] = {IS_CLIPPED, 0}; + 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 (data->clipVerts != V3D_CLIP_TEST_OFF) { - view3d_project_short_clip(data->vc.ar, co, s, TRUE); - } - else { - float co2[2]; - mul_v3_m4v3(co2, data->vc.obedit->obmat, co); - ED_view3d_project_short_noclip(data->vc.ar, co2, s); + if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) { + return; } - if (s[0] != IS_CLIPPED) - data->func(data->userData, eve, s[0], s[1], index); + data->func(data->userData, eve, screen_co[0], screen_co[1], index); } } @@ -2157,32 +2060,34 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - short s[2][2]; + 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) { - view3d_project_short_clip(data->vc.ar, v0co, s[0], TRUE); - view3d_project_short_clip(data->vc.ar, v1co, s[1], TRUE); + /* pass */ } else { - float v1_co[3], v2_co[3]; - - mul_v3_m4v3(v1_co, data->vc.obedit->obmat, v0co); - mul_v3_m4v3(v2_co, data->vc.obedit->obmat, v1co); - - ED_view3d_project_short_noclip(data->vc.ar, v1_co, s[0]); - ED_view3d_project_short_noclip(data->vc.ar, v2_co, s[1]); - if (data->clipVerts == V3D_CLIP_TEST_REGION) { - /* make an int copy */ - int s_int[2][2] = {{s[0][0], s[0][1]}, - {s[1][0], s[1][1]}}; - if (!BLI_rcti_isect_segment(&data->win_rect, s_int[0], s_int[1])) { + if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { return; } } } - data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index); + data->func(data->userData, eed, + screen_co_a[0], screen_co_a[1], + screen_co_b[0], screen_co_b[1], index); } } @@ -2221,14 +2126,11 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo BMFace *efa = EDBM_face_at_index(data->vc.em, index); if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - float cent2[3]; - short s[2]; - - mul_v3_m4v3(cent2, data->vc.obedit->obmat, cent); - ED_view3d_project_short(data->vc.ar, cent2, s); - - if (s[0] != IS_CLIPPED) { - data->func(data->userData, efa, s[0], s[1], index); + 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); } } } @@ -2245,8 +2147,7 @@ void mesh_foreachScreenFace( data.func = func; data.userData = userData; - //if (clipVerts) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + 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); @@ -2261,7 +2162,6 @@ void nurbs_foreachScreenVert( void *userData) { Curve *cu = vc->obedit->data; - short s[2] = {IS_CLIPPED, 0}; Nurb *nu; int i; ListBase *nurbs = BKE_curve_editNurbs_get(cu); @@ -2274,22 +2174,31 @@ void nurbs_foreachScreenVert( BezTriple *bezt = &nu->bezt[i]; if (bezt->hide == 0) { + int screen_co[2]; if (cu->drawflag & CU_HIDE_HANDLES) { - view3d_project_short_clip(vc->ar, bezt->vec[1], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 1, s[0], s[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]); + } } else { - view3d_project_short_clip(vc->ar, bezt->vec[0], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 0, s[0], s[1]); - view3d_project_short_clip(vc->ar, bezt->vec[1], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 1, s[0], s[1]); - view3d_project_short_clip(vc->ar, bezt->vec[2], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 2, s[0], s[1]); + 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]); + } } } } @@ -2299,15 +2208,129 @@ void nurbs_foreachScreenVert( BPoint *bp = &nu->bp[i]; if (bp->hide == 0) { - view3d_project_short_clip(vc->ar, bp->vec, s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, bp, NULL, -1, s[0], s[1]); + 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, @@ -3702,7 +3725,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } } - if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* GPU_begin_object_materials checked if this is needed */ if (do_alpha_after) { if (ob->dtx & OB_DRAWXRAY) { @@ -5952,8 +5975,8 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if (mb->editelems) { if ((G.f & G_PICKSEL) == 0) { - unsigned char wire_col[3]; - UI_GetThemeColor3ubv(TH_WIRE, wire_col); + unsigned char wire_col[4]; + UI_GetThemeColor4ubv(TH_WIRE, wire_col); glColor3ubv(wire_col); drawDispList(scene, v3d, rv3d, base, dt, dflag, wire_col); @@ -6611,7 +6634,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short return; /* xray delay? */ - if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* don't do xray in particle mode, need the z-buffer */ if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ @@ -6646,7 +6669,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* which wire color */ if ((dflag & DRAW_CONSTCOLOR) == 0) { - ED_view3d_project_short(ar, ob->obmat[3], &base->sx); + ED_view3d_project_base(ar, base); draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive); ob_wire_col = _ob_wire_col; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 1e371cb074d..236cbb86724 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -776,7 +776,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) break; case NC_SCREEN: switch (wmn->data) { - case ND_GPENCIL: case ND_ANIMPLAY: case ND_SKETCH: ED_region_tag_redraw(ar); @@ -793,6 +792,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) } break; + case NC_GPENCIL: + if (wmn->action == NA_EDITED) + ED_region_tag_redraw(ar); + break; } } @@ -941,8 +944,8 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) if (wmn->action == NA_RENAME) ED_region_tag_redraw(ar); break; - case NC_SCREEN: - if (wmn->data == ND_GPENCIL) + case NC_GPENCIL: + if (wmn->data == ND_DATA) ED_region_tag_redraw(ar); break; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 25ad85d3db8..ca768f2ef17 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -553,32 +553,23 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) { - int mx, my, co[2]; - int flag; - + int co[2]; + /* we don't want the clipping for cursor */ - flag = v3d->flag; - v3d->flag = 0; - ED_view3d_project_int(ar, give_cursor(scene, v3d), co); - v3d->flag = flag; - - mx = co[0]; - my = co[1]; - - if (mx != IS_CLIPPED) { + if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { setlinestyle(0); cpack(0xFF); - circ((float)mx, (float)my, 10.0); + circ((float)co[0], (float)co[1], 10.0); setlinestyle(4); cpack(0xFFFFFF); - circ((float)mx, (float)my, 10.0); + circ((float)co[0], (float)co[1], 10.0); setlinestyle(0); cpack(0x0); - sdrawline(mx - 20, my, mx - 5, my); - sdrawline(mx + 5, my, mx + 20, my); - sdrawline(mx, my - 20, mx, my - 5); - sdrawline(mx, my + 5, mx, my + 20); + sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]); + sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]); + sdrawline(co[0], co[1] - 20, co[0], co[1] - 5); + sdrawline(co[0], co[1] + 5, co[0], co[1] + 20); } } @@ -1927,7 +1918,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas if (base->object->restrictflag & OB_RESTRICT_VIEW) return; tbase.flag = OB_FROMDUPLI | base->flag; - lb = object_duplilist(scene, base->object); + lb = object_duplilist(scene, base->object, FALSE); // BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ dob = dupli_step(lb->first); @@ -2340,7 +2331,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) if (ob->transflag & OB_DUPLI) { DupliObject *dob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) if (dob->ob->type == OB_LAMP) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 744ce6f6209..735f7b5ea4a 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1235,8 +1235,8 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) /* -* this is basically just the pan only code + the rotate only code crammed into one function that does both -*/ + * this is basically just the pan only code + the rotate only code crammed into one function that does both + */ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (event->type != NDOF_MOTION) @@ -3514,57 +3514,49 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) /* ***************** 3d cursor cursor op ******************* */ /* mx my in region coords */ -static int set_3dcursor_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3]; - int mval[2]; -// short ctrl= 0; // XXX + float *fp = NULL; + float mval_fl[2]; int flip; fp = give_cursor(scene, v3d); -// if (obedit && ctrl) lr_click= 1; - copy_v3_v3(oldcurs, fp); - - ED_view3d_project_int_noclip(ar, fp, mval); flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); - /* reset the depth based on the view offset */ + /* reset the depth based on the view offset (we _know_ the offset is infront of us) */ if (flip) { negate_v3_v3(fp, rv3d->ofs); - - /* re initialize */ - ED_view3d_project_int_noclip(ar, fp, mval); - flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); - (void)flip; + /* re initialize, no need to check flip again */ + /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]); } - if (mval[0] != IS_CLIPPED) { - short depth_used = 0; + if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + short depth_used = FALSE; if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */ view3d_operator_needs_opengl(C); if (ED_view3d_autodist(scene, ar, v3d, event->mval, fp)) - depth_used = 1; + depth_used = TRUE; } - if (depth_used == 0) { - float mval_f[2]; - VECSUB2D(mval_f, mval, event->mval); - ED_view3d_win_to_delta(ar, mval_f, dvec); + if (depth_used == FALSE) { + float dvec[3]; + VECSUB2D(mval_fl, mval_fl, event->mval); + ED_view3d_win_to_delta(ar, mval_fl, dvec); sub_v3_v3(fp, dvec); } } else { - - dx = ((float)(event->mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2); - dy = ((float)(event->mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2); - - fz = rv3d->persmat[0][3] * fp[0] + rv3d->persmat[1][3] * fp[1] + rv3d->persmat[2][3] * fp[2] + rv3d->persmat[3][3]; - fz = fz / rv3d->zfac; + const float dx = ((float)(event->mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2); + const float dy = ((float)(event->mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2); + const float fz = (rv3d->persmat[0][3] * fp[0] + + rv3d->persmat[1][3] * fp[1] + + rv3d->persmat[2][3] * fp[2] + + rv3d->persmat[3][3]) / rv3d->zfac; fp[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy + rv3d->persinv[2][0] * fz) - rv3d->ofs[0]; fp[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy + rv3d->persinv[2][1] * fz) - rv3d->ofs[1]; @@ -3588,7 +3580,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot) ot->idname = "VIEW3D_OT_cursor3d"; /* api callbacks */ - ot->invoke = set_3dcursor_invoke; + ot->invoke = view3d_cursor3d_invoke; ot->poll = ED_operator_view3d_active; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index a2ad54cb92e..53f2c2e9f5e 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -61,13 +61,14 @@ #include "IMB_imbuf.h" #include "BKE_global.h" -#include "BKE_context.h" -#include "BKE_paint.h" #include "BKE_armature.h" +#include "BKE_context.h" #include "BKE_depsgraph.h" -#include "BKE_tessmesh.h" +#include "BKE_mball.h" #include "BKE_movieclip.h" #include "BKE_object.h" +#include "BKE_paint.h" +#include "BKE_tessmesh.h" #include "BKE_tracking.h" @@ -110,15 +111,16 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m { float dvec[3]; int mval_cpy[2]; + eV3DProjStatus ret; mval_cpy[0] = mval[0]; mval_cpy[1] = mval[1]; - ED_view3d_project_int_noclip(vc->ar, fp, mval_cpy); + ret = ED_view3d_project_int_global(vc->ar, fp, mval_cpy, V3D_PROJ_TEST_NOP); initgrabz(vc->rv3d, fp[0], fp[1], fp[2]); - if (mval_cpy[0] != IS_CLIPPED) { + if (ret == V3D_PROJ_RET_SUCCESS) { 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); @@ -255,10 +257,33 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) typedef struct LassoSelectUserData { ViewContext *vc; - rcti *rect; - int (*mcords)[2], moves, select, pass, done; + const rcti *rect; + const int (*mcords)[2]; + int moves; + int select; + + /* runtime */ + int pass; + int is_done; + int is_change; } LassoSelectUserData; +static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, + ViewContext *vc, const rcti *rect, const int (*mcords)[2], + const int moves, const int select) +{ + r_data->vc = vc; + r_data->rect = rect; + r_data->mcords = mcords; + r_data->moves = moves; + r_data->select = select; + + /* runtime */ + r_data->pass = 0; + r_data->is_done = FALSE; + r_data->is_change = FALSE; +} + static int view3d_selectable_data(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -289,12 +314,12 @@ static int view3d_selectable_data(bContext *C) /* helper also for borderselect */ -static int edge_fully_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) +static int edge_fully_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) { return BLI_rcti_isect_pt(rect, x1, y1) && BLI_rcti_isect_pt(rect, x2, y2); } -static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) +static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) { int d1, d2, d3, d4; @@ -319,35 +344,70 @@ static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) return 1; } -/* warning; lasso select with backbuffer-check draws in backbuf with persp(PERSP_WIN) - * and returns with persp(PERSP_VIEW). After lasso select backbuf is not OK - */ -static void do_lasso_select_pose(ViewContext *vc, Object *ob, int mcords[][2], short moves, short select) +static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) { - bPoseChannel *pchan; - float vec[3]; - int sco1[2], sco2[2]; - bArmature *arm = ob->data; - - if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) return; + LassoSelectUserData *data = userData; + bArmature *arm = data->vc->obact->data; - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (PBONE_VISIBLE(arm, pchan->bone) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) { - mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); - ED_view3d_project_int(vc->ar, vec, sco1); - mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); - ED_view3d_project_int(vc->ar, vec, sco2); - - if (BLI_lasso_is_edge_inside(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1], IS_CLIPPED)) { - if (select) pchan->bone->flag |= BONE_SELECTED; - else pchan->bone->flag &= ~BONE_SELECTED; + if (PBONE_SELECTABLE(arm, pchan->bone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x0, y0) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, INT_MAX)) + { + is_point_done = TRUE; + } + } + + /* project tail location to screenspace */ + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x1, y1) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, INT_MAX)) + { + is_point_done = TRUE; } } + + /* if one of points selected, we skip the bone itself */ + if ((is_point_done == TRUE) || + ((is_point_done == FALSE) && (points_proj_tot == 2) && + BLI_lasso_is_edge_inside(data->mcords, data->moves, x0, y0, x1, y1, INT_MAX))) + { + if (data->select) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_SELECTED; + data->is_change = TRUE; + } + data->is_change |= is_point_done; } +} +static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, short select) +{ + LassoSelectUserData data; + rcti rect; - if (arm->flag & ARM_HAS_VIZ_DEPS) { - /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) { + return; + } + + 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); + + if (data.is_change) { + bArmature *arm = ob->data; + if (arm->flag & ARM_HAS_VIZ_DEPS) { + /* mask modifier ('armature' mode), etc. */ + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } } } @@ -362,7 +422,7 @@ static void object_deselect_all_visible(Scene *scene, View3D *v3d) } } -static void do_lasso_select_objects(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], const short moves, short extend, short select) { Base *base; @@ -371,7 +431,7 @@ static void do_lasso_select_objects(ViewContext *vc, int mcords[][2], short move for (base = vc->scene->base.first; base; base = base->next) { if (BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */ - ED_view3d_project_short(vc->ar, base->object->obmat[3], &base->sx); + ED_view3d_project_base(vc->ar, base); if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) { if (select) ED_base_object_select(base, BA_SELECT); @@ -406,7 +466,7 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, IS_CLIPPED)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); - data->done = TRUE; + data->is_done = TRUE; } } else { @@ -427,7 +487,7 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int } } -static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; ToolSettings *ts = vc->scene->toolsettings; @@ -439,13 +499,7 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, /* set editmesh */ vc->em = BMEdit_FromObject(vc->obedit); - data.vc = vc; - data.rect = ▭ - data.mcords = mcords; - data.moves = moves; - data.select = select; - data.done = FALSE; - data.pass = 0; + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT); @@ -469,7 +523,7 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, data.pass = 0; mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); - if (data.done == 0) { + if (data.is_done == 0) { data.pass = 1; mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); } @@ -497,7 +551,7 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); - if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL; + if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; } else { if (cu->drawflag & CU_HIDE_HANDLES) { @@ -516,20 +570,16 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP } } - if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL; + if (bezt == cu->lastsel && !(bezt->f2 & SELECT)) cu->lastsel = NULL; } } } -static void do_lasso_select_curve(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; - /* set vc->editnurb */ - data.vc = vc; - data.mcords = mcords; - data.moves = moves; - data.select = select; + view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); @@ -546,14 +596,11 @@ static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } -static void do_lasso_select_lattice(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; - /* set editdata in vc */ - data.mcords = mcords; - data.moves = moves; - data.select = select; + view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); @@ -562,83 +609,104 @@ static void do_lasso_select_lattice(ViewContext *vc, int mcords[][2], short move lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); } -static void do_lasso_select_armature(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) { - bArmature *arm = vc->obedit->data; - EditBone *ebone; - float vec[3]; - short sco1[2], sco2[2], didpoint; - int change = FALSE; + LassoSelectUserData *data = userData; + bArmature *arm = data->vc->obedit->data; - if (extend == 0 && select) - ED_armature_deselect_all_visible(vc->obedit); + if (EBONE_SELECTABLE(arm, ebone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; - /* set editdata in vc */ - - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head); - ED_view3d_project_short(vc->ar, vec, sco1); - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail); - ED_view3d_project_short(vc->ar, vec, sco2); - - didpoint = 0; - if (BLI_lasso_is_point_inside(mcords, moves, sco1[0], sco1[1], IS_CLIPPED)) { - if (select) ebone->flag |= BONE_ROOTSEL; - else ebone->flag &= ~BONE_ROOTSEL; - didpoint = 1; - change = TRUE; - } - if (BLI_lasso_is_point_inside(mcords, moves, sco2[0], sco2[1], IS_CLIPPED)) { - if (select) ebone->flag |= BONE_TIPSEL; - else ebone->flag &= ~BONE_TIPSEL; - didpoint = 1; - change = TRUE; + /* project head location to screenspace */ + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x0, y0) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, INT_MAX)) + { + is_point_done = TRUE; + if (data->select) ebone->flag |= BONE_ROOTSEL; + else ebone->flag &= ~BONE_ROOTSEL; } - /* if one of points selected, we skip the bone itself */ - if (didpoint == 0 && - BLI_lasso_is_edge_inside(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1], IS_CLIPPED)) + } + + /* project tail location to screenspace */ + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x1, y1) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, INT_MAX)) { - if (select) ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED; - else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - change = TRUE; + is_point_done = TRUE; + if (data->select) ebone->flag |= BONE_TIPSEL; + else ebone->flag &= ~BONE_TIPSEL; } } + + /* if one of points selected, we skip the bone itself */ + if ((is_point_done == FALSE) && (points_proj_tot == 2) && + BLI_lasso_is_edge_inside(data->mcords, data->moves, x0, y0, x1, y1, INT_MAX)) + { + if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + data->is_change = TRUE; + } + + data->is_change |= is_point_done; } - - if (change) { +} + +static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) +{ + LassoSelectUserData data; + rcti rect; + + 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); + + if (data.is_change) { + bArmature *arm = vc->obedit->data; ED_armature_sync_selection(arm->edbo); ED_armature_validate_active(arm); WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit); } } +static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +{ + LassoSelectUserData *data = userData; - - -static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves, short extend, short select) + if (BLI_rcti_isect_pt(data->rect, x, y) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, INT_MAX)) { + if (data->select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + data->is_change = TRUE; + } +} +static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { + LassoSelectUserData data; + rcti rect; + MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; - float vec[3]; - short sco[2]; - if (extend == 0 && select) { - for (ml = mb->editelems->first; ml; ml = ml->next) { - ml->flag &= ~SELECT; - } - } + if (extend == 0 && select) + BKE_mball_deselect_all(mb); - for (ml = mb->editelems->first; ml; ml = ml->next) { - - mul_v3_m4v3(vec, vc->obedit->obmat, &ml->x); - ED_view3d_project_short(vc->ar, vec, sco); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); - if (BLI_lasso_is_point_inside(mcords, moves, sco[0], sco[1], IS_CLIPPED)) { - if (select) ml->flag |= SELECT; - else ml->flag &= ~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); } static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) @@ -700,7 +768,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int return OPERATOR_FINISHED; } -static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { Object *ob = vc->obact; Mesh *me = ob ? ob->data : NULL; @@ -722,7 +790,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short mo paintvert_flush_flags(ob); } -static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { Object *ob = vc->obact; Mesh *me = ob ? ob->data : NULL; @@ -777,7 +845,9 @@ static void do_lasso_select_node(int mcords[][2], short moves, short select) } #endif -static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void view3d_lasso_select(bContext *C, ViewContext *vc, + const int mcords[][2], short moves, + short extend, short select) { Object *ob = CTX_data_active_object(C); @@ -828,7 +898,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) { ViewContext vc; int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short extend, select; @@ -1059,8 +1129,7 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int } else { int temp, dist = 15; - - ED_view3d_project_short(vc->ar, base->object->obmat[3], &base->sx); + ED_view3d_project_base(vc->ar, base); temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]); if (temp < dist) @@ -1341,8 +1410,7 @@ 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_short(ar, base->object->obmat[3], &base->sx); - + 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) { @@ -1513,19 +1581,37 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese typedef struct BoxSelectUserData { ViewContext *vc; - rcti *rect; - int select, pass, done; + const rcti *rect; + int select; + + /* runtime */ + int pass; + int is_done; + int is_change; } BoxSelectUserData; -int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, int y2) +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->select = select; + + /* runtime */ + r_data->pass = 0; + r_data->is_done = FALSE; + r_data->is_change = FALSE; +} + +int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, int y2) { - int radsq = rad * rad; + int radius_squared = radius * radius; /* check points in circle itself */ - if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radsq) { + if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radius_squared) { return TRUE; } - else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radsq) { + else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radius_squared) { return TRUE; } else { @@ -1533,7 +1619,7 @@ int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, in const float v1[2] = {x1, y1}; const float v2[2] = {x2, y2}; /* pointdistline */ - if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radsq) { + if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radius_squared) { return TRUE; } } @@ -1550,7 +1636,7 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoi if (BLI_rcti_isect_pt(data->rect, x, y)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); - if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL; + if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; } else { if (cu->drawflag & CU_HIDE_HANDLES) { @@ -1569,7 +1655,7 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoi } } - if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL; + if (bezt == cu->lastsel && !(bezt->f2 & SELECT)) cu->lastsel = NULL; } } } @@ -1577,9 +1663,7 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte { BoxSelectUserData data; - data.vc = vc; - data.rect = rect; - data.select = select; + view3d_userdata_boxselect_init(&data, vc, rect, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); @@ -1602,9 +1686,7 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex { BoxSelectUserData data; - data.vc = vc; - data.rect = rect; - data.select = select; + view3d_userdata_boxselect_init(&data, vc, rect, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); @@ -1631,7 +1713,7 @@ static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0 if (data->pass == 0) { if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); - data->done = TRUE; + data->is_done = TRUE; } } else { @@ -1655,11 +1737,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten ToolSettings *ts = vc->scene->toolsettings; int bbsel; - data.vc = vc; - data.rect = rect; - data.select = select; - data.pass = 0; - data.done = FALSE; + view3d_userdata_boxselect_init(&data, vc, rect, select); if (extend == 0 && select) EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT); @@ -1684,7 +1762,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten data.pass = 0; mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); - if (data.done == 0) { + if (data.is_done == 0) { data.pass = 1; mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); } @@ -1717,11 +1795,8 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, int select, int exten hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect); - if (extend == 0 && select) { - for (ml = mb->editelems->first; ml; ml = ml->next) { - ml->flag &= ~SELECT; - } - } + if (extend == 0 && select) + BKE_mball_deselect_all(mb); for (ml = mb->editelems->first; ml; ml = ml->next) { for (a = 0; a < hits; a++) { @@ -2142,15 +2217,32 @@ typedef struct CircleSelectUserData { short select; int mval[2]; float radius; + float radius_squared; + + /* runtime */ + int is_change; } CircleSelectUserData; +static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, + ViewContext *vc, const int select, const int mval[2], const float rad) +{ + r_data->vc = vc; + r_data->select = select; + copy_v2_v2_int(r_data->mval, mval); + r_data->radius = rad; + r_data->radius_squared = rad * rad; + + /* runtime */ + r_data->is_change = FALSE; +} + static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; - if (r <= data->radius) { + if (len_squared_v2(delta) <= data->radius_squared) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } @@ -2165,10 +2257,10 @@ static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0 static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); - - if (r <= data->radius) { + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -2184,11 +2276,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f vc->em = BMEdit_FromObject(vc->obedit); - data.vc = vc; - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); if (ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { @@ -2259,16 +2347,17 @@ 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) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (r <= data->radius) { + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); - if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL; + if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; } else { if (cu->drawflag & CU_HIDE_HANDLES) { @@ -2287,7 +2376,7 @@ static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint } } - if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL; + if (bezt == cu->lastsel && !(bezt->f2 & SELECT)) cu->lastsel = NULL; } } } @@ -2295,13 +2384,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval { CircleSelectUserData data; - /* set vc-> edit data */ - - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; - data.vc = vc; + 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); @@ -2311,10 +2394,10 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; - if (r <= data->radius) { + if (len_squared_v2(delta) <= data->radius_squared) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -2322,12 +2405,7 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] { CircleSelectUserData data; - /* set vc-> edit data */ - - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + 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); @@ -2338,10 +2416,10 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); - - if (r <= data->radius) { + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else @@ -2350,63 +2428,78 @@ 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) +{ + CircleSelectUserData *data = userData; + bArmature *arm = data->vc->obact->data; + + if (PBONE_SELECTABLE(arm, pchan->bone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (pchan_circle_doSelectJoint(data, pchan, x0, y0)) { + is_point_done = TRUE; + } + } + + /* project tail location to screenspace */ + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (pchan_circle_doSelectJoint(data, pchan, x1, y1)) { + is_point_done = TRUE; + } + } + + /* check if the head and/or tail is in the circle + * - the call to check also does the selection already + */ + + /* only if the endpoints didn't get selected, deal with the middle of the bone too + * 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)) + { + if (data->select) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_SELECTED; + data->is_change = TRUE; + } + + data->is_change |= is_point_done; + } +} static void pose_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { CircleSelectUserData data; - bArmature *arm = vc->obact->data; - bPose *pose = vc->obact->pose; - bPoseChannel *pchan; - int change = FALSE; - /* set vc->edit data */ - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ - /* check each PoseChannel... */ - /* TODO: could be optimized at some point */ - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - short sco1[2], sco2[2], didpoint = 0; - float vec[3]; - - /* skip invisible bones */ - if (PBONE_VISIBLE(arm, pchan->bone) == 0) - continue; - - /* project head location to screenspace */ - mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head); - ED_view3d_project_short(vc->ar, vec, sco1); - - /* project tail location to screenspace */ - mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail); - ED_view3d_project_short(vc->ar, vec, sco2); - - /* check if the head and/or tail is in the circle - * - the call to check also does the selection already - */ - if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1])) - didpoint = 1; - if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1])) - didpoint = 1; - - change |= didpoint; - } + pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data); + + if (data.is_change) { + bArmature *arm = vc->obact->data; - if (change) { WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obact); + + if (arm->flag & ARM_HAS_VIZ_DEPS) { + /* mask modifier ('armature' mode), etc. */ + DAG_id_tag_update(&vc->obact->id, OB_RECALC_DATA); + } } } static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; - if (r <= data->radius) { + if (len_squared_v2(delta) <= data->radius_squared) { if (head) { if (data->select) ebone->flag |= BONE_ROOTSEL; @@ -2423,63 +2516,90 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int } return 0; } -static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) { - CircleSelectUserData data; - bArmature *arm = vc->obedit->data; - EditBone *ebone; - int change = FALSE; - - /* set vc->edit data */ - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + CircleSelectUserData *data = userData; + bArmature *arm = data->vc->obedit->data; + + if (EBONE_SELECTABLE(arm, ebone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - - /* check each EditBone... */ - /* TODO: could be optimized at some point */ - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - short sco1[2], sco2[2], didpoint = 0; - float vec[3]; - /* project head location to screenspace */ - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head); - ED_view3d_project_short(vc->ar, vec, sco1); - + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) { + is_point_done = TRUE; + } + } + /* project tail location to screenspace */ - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail); - ED_view3d_project_short(vc->ar, vec, sco2); - - /* check if the head and/or tail is in the circle - * - the call to check also does the selection already + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (armature_circle_doSelectJoint(data, ebone, x1, y1, FALSE)) { + is_point_done = TRUE; + } + } + + /* check if the head and/or tail is in the circle + * - the call to check also does the selection already */ - if (armature_circle_doSelectJoint(&data, ebone, sco1[0], sco1[1], 1)) - didpoint = 1; - if (armature_circle_doSelectJoint(&data, ebone, sco2[0], sco2[1], 0)) - didpoint = 1; - - /* only if the endpoints didn't get selected, deal with the middle of the bone too */ - /* XXX should we just do this always? */ - if ((didpoint == 0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1])) { - if (select) - ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED; - else - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - change = TRUE; + + /* only if the endpoints didn't get selected, deal with the middle of the bone too + * 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)) + { + if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + data->is_change = TRUE; } - - change |= didpoint; + + data->is_change |= is_point_done; } +} +static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +{ + CircleSelectUserData data; + bArmature *arm = vc->obedit->data; - if (change) { + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data); + + if (data.is_change) { ED_armature_sync_selection(arm->edbo); ED_armature_validate_active(arm); WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit); } } +static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +{ + 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 (data->select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + data->is_change = TRUE; + } +} +static void mball_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +{ + CircleSelectUserData data; + + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data); +} + /** Callbacks for circle selection in Editmode */ static void obedit_circle_select(ViewContext *vc, short select, const int mval[2], float rad) @@ -2498,24 +2618,50 @@ static void obedit_circle_select(ViewContext *vc, short select, const int mval[2 case OB_ARMATURE: armature_circle_select(vc, select, mval, rad); break; + case OB_MBALL: + mball_circle_select(vc, select, mval, rad); + break; default: return; } } +static int object_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +{ + Scene *scene = vc->scene; + const float radius_squared = rad * rad; + const float mval_fl[2] = {mval[0], mval[1]}; + int is_change = FALSE; + + 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)) { + 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) + { + if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { + ED_base_object_select(base, select); + is_change = TRUE; + } + } + } + } + + return is_change; +} + /* not a real operator, only for circle test */ static int view3d_circle_select_exec(bContext *C, wmOperator *op) { - ScrArea *sa = CTX_wm_area(C); - ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); - View3D *v3d = sa->spacedata.first; - int x = RNA_int_get(op->ptr, "x"); - int y = RNA_int_get(op->ptr, "y"); int radius = RNA_int_get(op->ptr, "radius"); int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); int select; + const int mval[2] = {RNA_int_get(op->ptr, "x"), + RNA_int_get(op->ptr, "y")}; select = (gesture_mode == GESTURE_MODAL_SELECT); @@ -2523,13 +2669,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) { ViewContext vc; - int mval[2]; view3d_operator_needs_opengl(C); view3d_set_viewcontext(C, &vc); - mval[0] = x; - mval[1] = y; if (CTX_data_edit_object(C)) { obedit_circle_select(&vc, select, mval, (float)radius); @@ -2552,21 +2695,12 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - Base *base; - select = select ? BA_SELECT : BA_DESELECT; - for (base = FIRSTBASE; base; base = base->next) { - if (BASE_SELECTABLE(v3d, base)) { - ED_view3d_project_short(ar, base->object->obmat[3], &base->sx); - if (base->sx != IS_CLIPPED) { - int dx = base->sx - x; - int dy = base->sy - y; - if (dx * dx + dy * dy < radius * radius) - ED_base_object_select(base, select); - } - } + ViewContext vc; + view3d_set_viewcontext(C, &vc); + + if (object_circle_select(&vc, select, mval, (float)radius)) { + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } - - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ff518e6ce5b..f138a95b0ef 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -858,6 +858,19 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3 } } +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 */ @@ -893,148 +906,145 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) return 0; } -void ED_view3d_project_short(ARegion *ar, const float co[3], short r_co[2]) /* clips */ +/* 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) { - RegionView3D *rv3d = ar->regiondata; float fx, fy, vec4[4]; - - r_co[0] = IS_CLIPPED; - - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, co, FALSE)) { - return; + + 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(rv3d->persmat, vec4); - + mul_m4_v4(perspmat, vec4); + if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > 0 && fx < ar->winx) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > 0.0f && fy < (float)ar->winy) { + 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; } -void ED_view3d_project_int(ARegion *ar, const float co[3], int r_co[2]) +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) { - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - r_co[0] = (int)2140000000.0f; - - mul_m4_v4(rv3d->persmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > -2140000000.0f && fx < 2140000000.0f) { - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > -2140000000.0f && fy < 2140000000.0f) { - r_co[0] = (int)floor(fx); - r_co[1] = (int)floor(fy); - } + 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; } -void ED_view3d_project_int_noclip(ARegion *ar, const float co[3], int r_co[2]) +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) { - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmat, vec4); - - if (fabs(vec4[3]) > BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - r_co[0] = (int)floor(fx); - r_co[1] = (int)floor(fy); - } - else { - r_co[0] = ar->winx / 2; - r_co[1] = ar->winy / 2; + 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; } -void ED_view3d_project_short_noclip(ARegion *ar, const float co[3], short r_co[2]) +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) { - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - r_co[0] = IS_CLIPPED; - - mul_m4_v4(rv3d->persmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > -32700 && fx < 32700) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > -32700.0f && fy < 32700.0f) { - r_co[0] = (short)floor(fx); - r_co[1] = (short)floor(fy); - } + 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; } -void ED_view3d_project_float(ARegion *ar, const float co[3], float r_co[2]) +/* --- 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) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - r_co[0] = IS_CLIPPED; - - mul_m4_v4(rv3d->persmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - 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]; - } +/* --- 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); } -void ED_view3d_project_float_noclip(ARegion *ar, const float co[3], float r_co[2]) +/* --- float --- */ +eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmat, vec4); - - if (fabs(vec4[3]) > BL_NEAR_CLIP) { - 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 { - r_co[0] = ar->winx / 2.0f; - r_co[1] = ar->winy / 2.0f; - } + 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) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* copies logic of get_view3d_viewplane(), keep in sync */ @@ -1309,7 +1319,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b Base tbase; tbase.flag = OB_FROMDUPLI; - lb = object_duplilist(scene, base->object); + lb = object_duplilist(scene, base->object, FALSE); for (dob = lb->first; dob; dob = dob->next) { tbase.object = dob->ob; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 822ab0b9e70..d2354a4a7ad 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -57,6 +57,8 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "BLF_api.h" + #include "BKE_nla.h" #include "BKE_bmesh.h" #include "BKE_context.h" @@ -88,12 +90,14 @@ #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> +#include <stdio.h> // XXX: duplicated??? static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); @@ -225,8 +229,12 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { if (t->spacetype == SPACE_VIEW3D) { - if (t->ar->regiontype == RGN_TYPE_WINDOW) - ED_view3d_project_int_noclip(t->ar, vec, adr); + 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) { + adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */ + adr[1] = (int)2140000000.0f; + } + } } else if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = t->sa->spacedata.first; @@ -347,7 +355,11 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) case SPACE_VIEW3D: { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - ED_view3d_project_float_noclip(t->ar, vec, adr); + if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + /* XXX, 2.64 and prior did this, weak! */ + adr[0] = t->ar->winx / 2.0f; + adr[1] = t->ar->winy / 2.0f; + } return; } break; @@ -819,7 +831,7 @@ int transformEvent(TransInfo *t, wmEvent *event) float mati[3][3] = MAT3_UNITY; char cmode = constraintModeToChar(t); int handled = 1; - + t->redraw |= handleMouseInput(t, &t->mouse, event); if (event->type == MOUSEMOVE) { @@ -1260,10 +1272,13 @@ int transformEvent(TransInfo *t, wmEvent *event) if (t->handleEvent) t->redraw |= t->handleEvent(t, event); - if (handled || t->redraw) + if (handled || t->redraw) { + t->last_update = PIL_check_seconds_timer(); return 0; - else + } + else { return OPERATOR_PASS_THROUGH; + } } int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2]) @@ -1546,14 +1561,63 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi drawNonPropEdge(C, t); } -#if 0 -static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) +/* 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) { -// TransInfo *t = arg; -// -// drawHelpline(C, t->mval[0], t->mval[1], t); + int show_warning; + + /* red border around the viewport */ + UI_ThemeColor(TH_REDALERT); + + 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(); + + /* 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 + */ + show_warning = (int)(t->last_update * 2.0) & 1; + + 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); + } +} + +static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) +{ + TransInfo *t = arg; + 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); + } } -#endif void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { @@ -1723,7 +1787,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW); t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL); + t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL); t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t); } else if (t->spacetype == SPACE_IMAGE) { @@ -4789,12 +4853,12 @@ 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); - ED_view3d_project_float_noclip(t->ar, v_proj, v_proj); - - dist = len_squared_v2v2(mval, v_proj); - if (dist < min_dist) { - min_dist = dist; - sld->curr_sv_index = i; + if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + dist = len_squared_v2v2(mval, v_proj); + if (dist < min_dist) { + min_dist = dist; + sld->curr_sv_index = i; + } } } } @@ -5529,42 +5593,42 @@ static int doEdgeSlide(TransInfo *t, float perc) int i; sld->perc = perc; - sv = svlist; - for (i = 0; i < sld->totsv; i++, sv++) { - if (sld->is_proportional == FALSE) { - TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; - float cur_sel = curr_sv->edge_len; - float cur_sv = sv->edge_len; - float extd = 0.0f; - float recip_cur_sv = 0.0f; - - if (cur_sel == 0.0f) cur_sel = 1.0f; - if (cur_sv == 0.0f) cur_sv = 1.0f; - - recip_cur_sv = 1.0f / cur_sv; - if (!sld->flipped_vtx) { - extd = (cur_sv - cur_sel) * recip_cur_sv; + if (sld->is_proportional == TRUE) { + for (i = 0; i < sld->totsv; i++, sv++) { + if (perc > 0.0f) { + copy_v3_v3(vec, sv->upvec); + mul_v3_fl(vec, perc); + add_v3_v3v3(sv->v->co, sv->origvert.co, vec); } else { - extd = (cur_sel - cur_sv) * recip_cur_sv; + copy_v3_v3(vec, sv->downvec); + mul_v3_fl(vec, -perc); + add_v3_v3v3(sv->v->co, sv->origvert.co, vec); } - - extd += (sld->perc * cur_sel) * recip_cur_sv; - CLAMP(extd, -1.0f, 1.0f); - perc = extd; } + } + else { + /** + * Implementation note, non proportional mode ignores the starting positions and uses only the + * up/down verts, this could be changed/improved so the distance is still met but the verts are moved along + * their original path (which may not be straight), however how it works now is OK and matches 2.4x - Campbell + */ + TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; + const float curr_length_perc = len_v3v3(curr_sv->up->co, curr_sv->down->co) * + (((sld->flipped_vtx ? perc : -perc) + 1.0f) / 2.0f); - if (perc > 0.0f) { - copy_v3_v3(vec, sv->upvec); - mul_v3_fl(vec, perc); - add_v3_v3v3(sv->v->co, sv->origvert.co, vec); - } - else { - copy_v3_v3(vec, sv->downvec); - mul_v3_fl(vec, -perc); - add_v3_v3v3(sv->v->co, sv->origvert.co, vec); + for (i = 0; i < sld->totsv; i++, sv++) { + const float sv_length = len_v3v3(sv->up->co, sv->down->co); + const float fac = minf(sv_length, curr_length_perc) / sv_length; + + if (sld->flipped_vtx) { + interp_v3_v3v3(sv->v->co, sv->down->co, sv->up->co, fac); + } + else { + interp_v3_v3v3(sv->v->co, sv->up->co, sv->down->co, fac); + } } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index e645cb2fed6..40f53423d37 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -322,6 +322,8 @@ typedef struct TransInfo { float auto_values[4]; 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. */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 540cbb97609..39a5da94798 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1489,6 +1489,8 @@ static void createTransCurveVerts(TransInfo *t) count++; tail++; } + + (void)hdata; /* quiet warning */ } else if (propmode && head != tail) { calc_distanceCurveVerts(head, tail - 1); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index b8db0b575cf..a9d9ec7b010 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -895,16 +895,20 @@ static void recalcData_view3d(TransInfo *t) /* helper for recalcData() - for sequencer transforms */ static void recalcData_sequencer(TransInfo *t) { - Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE); - Sequence *seq; + TransData *td; + int a; + Sequence *seq_prev = NULL; - SEQ_BEGIN(ed, seq) - { - if (seq->flag & SELECT) { - BKE_sequence_invalidate_deendent(t->scene, seq); + for (a = 0, td = t->data; a < t->total; a++, td++) { + TransDataSeq *tdsq = (TransDataSeq *) td->extra; + Sequence *seq = tdsq->seq; + + if (seq != seq_prev) { + BKE_sequence_invalidate_dependent(t->scene, seq); } + + seq_prev = seq; } - SEQ_END BKE_sequencer_preprocessed_cache_cleanup(); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index a155ff7786a..0e25739c34a 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -402,7 +402,7 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) const char *BIF_menustringTransformOrientation(const bContext *C, const char *title) { - const char *menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); + const char *menu = IFACE_("%t|Global %x0|Local %x1|Gimbal %x4|Normal %x2|View %x3"); ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int i = V3D_MANIP_CUSTOM; @@ -411,14 +411,14 @@ const char *BIF_menustringTransformOrientation(const bContext *C, const char *ti title = IFACE_(title); - str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix")); + str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), "UserTransSpace from matrix"); p = str_menu; p += sprintf(str_menu, "%s", title); p += sprintf(p, "%s", menu); for (ts = transform_spaces->first; ts; ts = ts->next) { - p += sprintf(p, "|%s%%x%d", ts->name, i++); + p += sprintf(p, "|%s %%x%d", ts->name, i++); } return str_menu; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 1d75be05534..2f2b31de89d 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -80,6 +80,8 @@ #define USE_BVH_FACE_SNAP +#define TRANSFORM_DIST_MAX_PX 1000 + /********************* PROTOTYPES ***********************/ static void setSnappingCallback(TransInfo *t); @@ -296,7 +298,7 @@ void applyProject(TransInfo *t) for (i = 0; i < t->total; i++, td++) { float iloc[3], loc[3], no[3]; float mval[2]; - int dist = 1000; + int dist = TRANSFORM_DIST_MAX_PX; if (td->flag & TD_NOACTION) break; @@ -315,18 +317,18 @@ void applyProject(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - ED_view3d_project_float(t->ar, iloc, mval); - - if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { -// if (t->flag & (T_EDIT|T_POSE)) { -// mul_m4_v3(imat, loc); -// } -// - sub_v3_v3v3(tvec, loc, iloc); - - mul_m3_v3(td->smtx, tvec); - - add_v3_v3(td->loc, tvec); + if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { +// if (t->flag & (T_EDIT|T_POSE)) { +// mul_m4_v3(imat, loc); +// } + + sub_v3_v3v3(tvec, loc, iloc); + + mul_m3_v3(td->smtx, tvec); + + add_v3_v3(td->loc, tvec); + } } //XXX constraintTransLim(t, td); @@ -601,7 +603,9 @@ int updateSelectedSnapPoint(TransInfo *t) int dx, dy; int dist; - ED_view3d_project_int(t->ar, p->co, screen_loc); + if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + continue; + } dx = t->mval[0] - screen_loc[0]; dy = t->mval[1] - screen_loc[1]; @@ -1232,8 +1236,12 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh new_depth = len_v3v3(location, ray_start); - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + } + else { + new_dist = TRANSFORM_DIST_MAX_PX; + } /* 10% threshold if edge is closer but a bit further * this takes care of series of connected edges a bit slanted w.r.t the viewport @@ -1289,8 +1297,13 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], new_depth = len_v3v3(location, ray_start); - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + } + else { + new_dist = TRANSFORM_DIST_MAX_PX; + } + if (new_dist <= *r_dist && new_depth < *r_depth) { *r_depth = new_depth; @@ -1697,7 +1710,7 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { Object *dob = dupli_ob->ob; @@ -1903,7 +1916,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { Object *dob = dupli_ob->ob; diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 281b682465d..b73f5fa0869 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -279,7 +279,9 @@ char handleNumInput(NumInput *n, wmEvent *event) if (!n->ctrl[idx]) n->ctrl[idx] = 1; - if (fabsf(n->val[idx]) > 9999999.0f) ; + if (fabsf(n->val[idx]) > 9999999.0f) { + /* pass */ + } else if (n->ctrl[idx] == 1) { n->val[idx] *= 10; n->val[idx] += Val; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 06da1c8bfea..6e655faf35f 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -759,14 +759,13 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i BMLoop *l; MLoopUV *luv; BMIter iter; - float m[3], v1[3], v2[3], c1, c2, *uv1 = NULL, /* *uv2, */ /* UNUSED */ *uv3 = NULL; + float m[2], v1[2], v2[2], c1, c2, *uv1 = NULL, /* *uv2, */ /* UNUSED */ *uv3 = NULL; int id1, id2, i; id1 = (id + efa->len - 1) % efa->len; id2 = (id + efa->len + 1) % efa->len; - m[0] = co[0] - uv[0]; - m[1] = co[1] - uv[1]; + sub_v2_v2v2(m, co, uv); i = 0; BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { @@ -782,8 +781,8 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i i++; } - sub_v3_v3v3(v1, uv1, uv); - sub_v3_v3v3(v2, uv3, uv); + sub_v2_v2v2(v1, uv1, uv); + sub_v2_v2v2(v2, uv3, uv); /* m and v2 on same side of v-v1? */ c1 = v1[0] * m[1] - v1[1] * m[0]; @@ -1744,7 +1743,7 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop) * the selection rather than de-selecting the closest. */ uvedit_pixel_to_float(sima, limit, 0.05f); - uvedit_pixel_to_float(sima, penalty, 5.0f / sima->zoom); + uvedit_pixel_to_float(sima, penalty, 5.0f / (sima ? sima->zoom : 1.0f)); /* retrieve operation mode */ if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -2745,7 +2744,7 @@ static void UV_OT_circle_select(wmOperatorType *ot) /* ******************** lasso select operator **************** */ -static int do_lasso_select_mesh_uv(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short moves, short select) { Image *ima = CTX_data_edit_image(C); ARegion *ar = CTX_wm_region(C); @@ -2819,7 +2818,7 @@ static int do_lasso_select_mesh_uv(bContext *C, int mcords[][2], short moves, sh static int uv_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 745ca1ef2ac..1729ac06f5a 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -162,9 +162,8 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], struct MFace *mface, struct MVert *mvert, int *face_indices, int totface); -void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MFace *mface, int *face_indices, int totface, - struct MVert *mvert, int *vert_indices, int totvert, - int (*face_vert_indices)[4], const float *vmask); +void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert, + int *vert_indices, int totvert, const float *vmask); GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid, unsigned int **grid_hidden, int gridsize); diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 7d829bd57bf..285acb6bdde 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -75,8 +75,6 @@ void GPU_end_object_materials(void); int GPU_enable_material(int nr, void *attribs); void GPU_disable_material(void); -void GPU_material_diffuse_get(int nr, float diff[4]); - void GPU_set_material_alpha_blend(int alphablend); int GPU_get_material_alpha_blend(void); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 659cd4e944c..201162262b2 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -54,7 +54,6 @@ #include "DNA_userdef_types.h" #include "GPU_buffers.h" -#include "GPU_draw.h" typedef enum { GPU_BUFFER_VERTEX_STATE = 1, @@ -1270,6 +1269,14 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, /* XXX: the rest of the code in this file is used for optimized PBVH * drawing and doesn't interact at all with the buffer code above */ +/* Return false if VBO is either unavailable or disabled by the user, + true otherwise */ +static int gpu_vbo_enabled(void) +{ + return (GLEW_ARB_vertex_buffer_object && + !(U.gameflags & USER_DISABLE_VBO)); +} + /* Convenience struct for building the VBO. */ typedef struct { float co[3]; @@ -1281,8 +1288,6 @@ typedef struct { char pad[2]; unsigned char color[3]; - float accum_color[3]; - int tot_color; } VertexBufferFormat; struct GPU_Buffers { @@ -1307,6 +1312,10 @@ struct GPU_Buffers { int has_hidden; unsigned int tot_tri, tot_quad; + + /* The PBVH ensures that either all faces in the node are + smooth-shaded or all faces are flat-shaded */ + int smooth; }; typedef enum { VBO_ENABLED, @@ -1330,24 +1339,24 @@ static void gpu_colors_disable(VBO_State vbo_state) static float gpu_color_from_mask(float mask) { - return 1.0f - mask * 0.75f; + return (1.0f - mask) * 0.5f + 0.25f; } -static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3]) +static void gpu_color_from_mask_copy(float mask, unsigned char out[3]) { - float mask_color; - - mask_color = gpu_color_from_mask(mask) * 255.0f; + unsigned char color; + + color = gpu_color_from_mask(mask) * 255.0f; - out[0] = diffuse_color[0] * mask_color; - out[1] = diffuse_color[1] * mask_color; - out[2] = diffuse_color[2] * mask_color; + out[0] = color; + out[1] = color; + out[2] = color; } -static void gpu_color_from_mask_set(float mask, float diffuse_color[4]) +static void gpu_color_from_mask_set(float mask) { float color = gpu_color_from_mask(mask); - glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color); + glColor3f(color, color, color); } static float gpu_color_from_mask_quad(const CCGKey *key, @@ -1363,86 +1372,113 @@ static float gpu_color_from_mask_quad(const CCGKey *key, static void gpu_color_from_mask_quad_copy(const CCGKey *key, CCGElem *a, CCGElem *b, CCGElem *c, CCGElem *d, - const float *diffuse_color, unsigned char out[3]) { - float mask_color = + unsigned char color = gpu_color_from_mask((*CCG_elem_mask(key, a) + *CCG_elem_mask(key, b) + *CCG_elem_mask(key, c) + *CCG_elem_mask(key, d)) * 0.25f) * 255.0f; - out[0] = diffuse_color[0] * mask_color; - out[1] = diffuse_color[1] * mask_color; - out[2] = diffuse_color[2] * mask_color; + out[0] = color; + out[1] = color; + out[2] = color; } static void gpu_color_from_mask_quad_set(const CCGKey *key, CCGElem *a, CCGElem *b, - CCGElem *c, CCGElem *d, - float diffuse_color[4]) + CCGElem *c, CCGElem *d) { float color = gpu_color_from_mask_quad(key, a, b, c, d); - glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color); + glColor3f(color, color, color); } -void GPU_update_mesh_buffers(GPU_Buffers *buffers, MFace *mface, int *face_indices, int totface, - MVert *mvert, int *vert_indices, int totvert, - int (*face_vert_indices)[4], const float *vmask) +void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert, + int *vert_indices, int totvert, const float *vmask) { VertexBufferFormat *vert_data; - int i; + int i, j, k; buffers->vmask = vmask; if (buffers->vert_buf) { + int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); + /* Build VBO */ glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf); glBufferDataARB(GL_ARRAY_BUFFER_ARB, - sizeof(VertexBufferFormat) * totvert, - NULL, GL_STATIC_DRAW_ARB); + sizeof(VertexBufferFormat) * totelem, + NULL, GL_STATIC_DRAW_ARB); + vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); if (vert_data) { - for (i = 0; i < totvert; ++i) { - MVert *v = mvert + vert_indices[i]; - VertexBufferFormat *out = vert_data + i; - - copy_v3_v3(out->co, v->co); - memcpy(out->no, v->no, sizeof(short) * 3); - zero_v3(out->accum_color); - out->tot_color = 0; + /* Vertex data is shared if smooth-shaded, but seperate + copies are made for flat shading because normals + shouldn't be shared. */ + if (buffers->smooth) { + for (i = 0; i < totvert; ++i) { + MVert *v = mvert + vert_indices[i]; + VertexBufferFormat *out = vert_data + i; + + copy_v3_v3(out->co, v->co); + memcpy(out->no, v->no, sizeof(short) * 3); + if (vmask) { + gpu_color_from_mask_copy(vmask[vert_indices[i]], + out->color); + } + } } + else { + for (i = 0; i < buffers->totface; ++i) { + const MFace *f = &buffers->mface[buffers->face_indices[i]]; + const unsigned int *fv = &f->v1; + const int vi[2][3] = {{0, 1, 2}, {3, 0, 2}}; + float fno[3]; + short no[3]; -#define UPDATE_VERTEX(face, vertex, index, diffuse_color) \ - { \ - VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \ - add_v3_v3(out->accum_color, diffuse_color); \ - out->tot_color++; \ - } (void)0 - - for (i = 0; i < totface; ++i) { - MFace *f = mface + face_indices[i]; - float diffuse_color[4]; - - GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color); + float fmask; - UPDATE_VERTEX(i, f->v1, 0, diffuse_color); - UPDATE_VERTEX(i, f->v2, 1, diffuse_color); - UPDATE_VERTEX(i, f->v3, 2, diffuse_color); - if (f->v4) - UPDATE_VERTEX(i, f->v4, 3, diffuse_color); - } -#undef UPDATE_VERTEX + /* Face normal and mask */ + if (f->v4) { + normal_quad_v3(fno, + mvert[fv[0]].co, + mvert[fv[1]].co, + mvert[fv[2]].co, + mvert[fv[3]].co); + if (vmask) { + fmask = (vmask[fv[0]] + + vmask[fv[1]] + + vmask[fv[2]] + + vmask[fv[3]]) * 0.25; + } + } + else { + normal_tri_v3(fno, + mvert[fv[0]].co, + mvert[fv[1]].co, + mvert[fv[2]].co); + if (vmask) { + fmask = (vmask[fv[0]] + + vmask[fv[1]] + + vmask[fv[2]]) / 3.0f; + } + } + normal_float_to_short_v3(no, fno); - for (i = 0; i < totvert; ++i) { - VertexBufferFormat *out = vert_data + i; - if (out->tot_color) { - float diffuse_color[4]; + for (j = 0; j < (f->v4 ? 2 : 1); j++) { + for (k = 0; k < 3; k++) { + const MVert *v = &mvert[fv[vi[j][k]]]; + VertexBufferFormat *out = vert_data; - mul_v3_v3fl(diffuse_color, out->accum_color, 1.0f / out->tot_color); + copy_v3_v3(out->co, v->co); + memcpy(out->no, no, sizeof(short) * 3); + if (vmask) + gpu_color_from_mask_copy(fmask, out->color); - gpu_color_from_mask_copy(vmask[vert_indices[i]], diffuse_color, out->color); + vert_data++; + } + } } } @@ -1470,6 +1506,7 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers"); buffers->index_type = GL_UNSIGNED_SHORT; + buffers->smooth = mface[face_indices[0]].flag & ME_SMOOTH; /* Count the number of visible triangles */ for (i = 0, tottri = 0; i < totface; ++i) { @@ -1477,8 +1514,11 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], if (!paint_is_face_hidden(f, mvert)) tottri += f->v4 ? 2 : 1; } - - if (GLEW_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO)) + + /* An element index buffer is used for smooth shading, but flat + shading requires separate vertex normals so an index buffer is + can't be used there. */ + if (gpu_vbo_enabled() && buffers->smooth) glGenBuffersARB(1, &buffers->index_buf); if (buffers->index_buf) { @@ -1522,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) + if (buffers->index_buf || !buffers->smooth) glGenBuffersARB(1, &buffers->vert_buf); buffers->tot_tri = tottri; @@ -1545,6 +1585,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, if (buffers->vert_buf) { int totvert = key->grid_area * totgrid; int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; + const int has_mask = key->has_mask; glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf); glBufferDataARB(GL_ARRAY_BUFFER_ARB, @@ -1555,10 +1596,6 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, for (i = 0; i < totgrid; ++i) { VertexBufferFormat *vd = vert_data; CCGElem *grid = grids[grid_indices[i]]; - const DMFlagMat *flags = &grid_flag_mats[grid_indices[i]]; - float diffuse_color[4]; - - GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color); for (y = 0; y < key->grid_size; y++) { for (x = 0; x < key->grid_size; x++) { @@ -1566,9 +1603,13 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, copy_v3_v3(vd->co, CCG_elem_co(key, elem)); if (smooth) { - normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem)); + normal_float_to_short_v3(vd->no, + CCG_elem_no(key, elem)); - gpu_color_from_mask_copy(*CCG_elem_mask(key, elem), diffuse_color, vd->color); + if (has_mask) { + gpu_color_from_mask_copy(*CCG_elem_mask(key, elem), + vd->color); + } } vd++; } @@ -1596,13 +1637,15 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, vd = vert_data + (j + 1) * key->grid_size + (k + 1); normal_float_to_short_v3(vd->no, fno); - gpu_color_from_mask_quad_copy(key, - elems[0], - elems[1], - elems[2], - elems[3], - diffuse_color, - vd->color); + + if (has_mask) { + gpu_color_from_mask_quad_copy(key, + elems[0], + elems[1], + elems[2], + elems[3], + vd->color); + } } } } @@ -1624,6 +1667,8 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, buffers->grid_flag_mats = grid_flag_mats; buffers->gridkey = *key; + buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; + //printf("node updated %p\n", buffers); } @@ -1718,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 (!GLEW_ARB_vertex_buffer_object || (U.gameflags & USER_DISABLE_VBO)) { + if (gpu_vbo_enabled()) { if (buffer) glDeleteBuffersARB(1, &buffer); return 0; @@ -1806,15 +1851,15 @@ GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid, #undef FILL_QUAD_BUFFER -static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) +static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers) { const MVert *mvert = buffers->mvert; int i, j; - float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f}; - - glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_color); + const int has_mask = (buffers->vmask != NULL); - gpu_colors_enable(VBO_DISABLED); + if (has_mask) { + gpu_colors_enable(VBO_DISABLED); + } for (i = 0; i < buffers->totface; ++i) { MFace *f = buffers->mface + buffers->face_indices[i]; @@ -1826,15 +1871,17 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) glBegin((f->v4) ? GL_QUADS : GL_TRIANGLES); - if (smooth) { + if (buffers->smooth) { for (j = 0; j < S; j++) { - gpu_color_from_mask_set(buffers->vmask[fv[j]], diffuse_color); + if (has_mask) { + gpu_color_from_mask_set(buffers->vmask[fv[j]]); + } glNormal3sv(mvert[fv[j]].no); glVertex3fv(mvert[fv[j]].co); } } else { - float fmask, fno[3]; + float fno[3]; /* calculate face normal */ if (f->v4) { @@ -1845,15 +1892,19 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) normal_tri_v3(fno, mvert[fv[0]].co, mvert[fv[1]].co, mvert[fv[2]].co); glNormal3fv(fno); - /* calculate face mask color */ - fmask = (buffers->vmask[fv[0]] + - buffers->vmask[fv[1]] + - buffers->vmask[fv[2]]); - if (f->v4) - fmask = (fmask + buffers->vmask[fv[3]]) * 0.25; - else - fmask /= 3.0f; - gpu_color_from_mask_set(fmask, diffuse_color); + if (has_mask) { + float fmask; + + /* calculate face mask color */ + fmask = (buffers->vmask[fv[0]] + + buffers->vmask[fv[1]] + + buffers->vmask[fv[2]]); + if (f->v4) + fmask = (fmask + buffers->vmask[fv[3]]) * 0.25; + else + fmask /= 3.0f; + gpu_color_from_mask_set(fmask); + } for (j = 0; j < S; j++) glVertex3fv(mvert[fv[j]].co); @@ -1862,18 +1913,20 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) glEnd(); } - gpu_colors_disable(VBO_DISABLED); + if (has_mask) { + gpu_colors_disable(VBO_DISABLED); + } } -static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) +static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers) { const CCGKey *key = &buffers->gridkey; int i, j, x, y, gridsize = buffers->gridkey.grid_size; - float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f}; - - glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_color); + const int has_mask = key->has_mask; - gpu_colors_enable(VBO_DISABLED); + if (has_mask) { + gpu_colors_enable(VBO_DISABLED); + } for (i = 0; i < buffers->totgrid; ++i) { int g = buffers->grid_indices[i]; @@ -1898,9 +1951,11 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) if (paint_is_grid_face_hidden(gh, gridsize, x, y)) continue; - if (smooth) { + if (buffers->smooth) { for (j = 0; j < 4; j++) { - gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]), diffuse_color); + if (has_mask) { + gpu_color_from_mask_set(*CCG_elem_mask(key, e[j])); + } glNormal3fv(CCG_elem_no(key, e[j])); glVertex3fv(CCG_elem_co(key, e[j])); } @@ -1913,7 +1968,10 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) CCG_elem_co(key, e[2]), CCG_elem_co(key, e[3])); glNormal3fv(fno); - gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3], diffuse_color); + + if (has_mask) { + gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3]); + } for (j = 0; j < 4; j++) glVertex3fv(CCG_elem_co(key, e[j])); @@ -1923,17 +1981,21 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) glEnd(); } - else if (smooth) { + else if (buffers->smooth) { for (y = 0; y < gridsize - 1; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridsize; x++) { CCGElem *a = CCG_grid_elem(key, grid, x, y); CCGElem *b = CCG_grid_elem(key, grid, x, y + 1); - gpu_color_from_mask_set(*CCG_elem_mask(key, a), diffuse_color); + if (has_mask) { + gpu_color_from_mask_set(*CCG_elem_mask(key, a)); + } glNormal3fv(CCG_elem_no(key, a)); glVertex3fv(CCG_elem_co(key, a)); - gpu_color_from_mask_set(*CCG_elem_mask(key, b), diffuse_color); + if (has_mask) { + gpu_color_from_mask_set(*CCG_elem_mask(key, b)); + } glNormal3fv(CCG_elem_no(key, b)); glVertex3fv(CCG_elem_co(key, b)); } @@ -1959,7 +2021,9 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) CCG_elem_co(key, c)); glNormal3fv(fno); - gpu_color_from_mask_quad_set(key, a, b, c, d, diffuse_color); + if (has_mask) { + gpu_color_from_mask_quad_set(key, a, b, c, d); + } } glVertex3fv(CCG_elem_co(key, a)); @@ -1970,37 +2034,43 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) } } - gpu_colors_disable(VBO_DISABLED); + if (has_mask) { + gpu_colors_disable(VBO_DISABLED); + } } void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial) { - int smooth = 0; + const int has_mask = (buffers->vmask || buffers->gridkey.has_mask); if (buffers->totface) { const MFace *f = &buffers->mface[buffers->face_indices[0]]; if (!setMaterial(f->mat_nr + 1, NULL)) return; - - smooth = f->flag & ME_SMOOTH; - glShadeModel(smooth ? GL_SMOOTH : GL_FLAT); } else if (buffers->totgrid) { const DMFlagMat *f = &buffers->grid_flag_mats[buffers->grid_indices[0]]; if (!setMaterial(f->mat_nr + 1, NULL)) return; - - smooth = f->flag & ME_SMOOTH; - glShadeModel(smooth ? GL_SMOOTH : GL_FLAT); } - if (buffers->vert_buf && buffers->index_buf) { + glShadeModel((buffers->smooth || buffers->totface) ? GL_SMOOTH : GL_FLAT); + + if (buffers->vert_buf) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - gpu_colors_enable(VBO_ENABLED); + if (has_mask) { + gpu_colors_enable(VBO_ENABLED); + } + else { + gpu_colors_enable(VBO_DISABLED); + glColor4ub(0xff, 0xff, 0xff, 0xff); + } glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf); + + if (buffers->index_buf) + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf); if (buffers->tot_quad) { char *offset = 0; @@ -2010,8 +2080,10 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial) offset + offsetof(VertexBufferFormat, co)); glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat), offset + offsetof(VertexBufferFormat, no)); - glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), - offset + offsetof(VertexBufferFormat, color)); + if (has_mask) { + glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), + offset + offsetof(VertexBufferFormat, color)); + } glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0); @@ -2019,29 +2091,42 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial) } } else { + int totelem = buffers->tot_tri * 3; + glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat), (void *)offsetof(VertexBufferFormat, co)); glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat), (void *)offsetof(VertexBufferFormat, no)); - glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), - (void *)offsetof(VertexBufferFormat, color)); + if (has_mask) { + glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), + (void *)offsetof(VertexBufferFormat, color)); + } - glDrawElements(GL_TRIANGLES, buffers->tot_tri * 3, buffers->index_type, 0); + if (buffers->index_buf) + glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, 0); + else + glDrawArrays(GL_TRIANGLES, 0, totelem); } glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + if (buffers->index_buf) + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); - gpu_colors_disable(VBO_ENABLED); + if (has_mask) { + gpu_colors_disable(VBO_ENABLED); + } + else { + gpu_colors_disable(VBO_DISABLED); + } } /* fallbacks if we are out of memory or VBO is disabled */ else if (buffers->totface) { - gpu_draw_buffers_legacy_mesh(buffers, smooth); + gpu_draw_buffers_legacy_mesh(buffers); } else if (buffers->totgrid) { - gpu_draw_buffers_legacy_grids(buffers, smooth); + gpu_draw_buffers_legacy_grids(buffers); } } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 60e3c19a419..956c76aec20 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1209,10 +1209,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GPUBlendMode alphablend; int a; - /* OCIO_TODO: assume color management is always enabled. could be nice to support real display transform here, - * but that's not so important and could be done later - */ - int gamma = TRUE; + int gamma = BKE_scene_check_color_management_enabled(scene); int new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); @@ -1440,21 +1437,6 @@ void GPU_disable_material(void) GPU_set_material_alpha_blend(GPU_BLEND_SOLID); } -void GPU_material_diffuse_get(int nr, float diff[4]) -{ - /* prevent index to use un-initialized array items */ - if (nr >= GMS.totmat) - nr = 0; - - /* no GPU_begin_object_materials, use default material */ - if (!GMS.matbuf) { - mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit); - } - else { - copy_v4_v4(diff, GMS.matbuf[nr].diff); - } -} - void GPU_end_object_materials(void) { GPU_disable_material(); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index dd92b561235..e035f1c3f5a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -389,10 +389,8 @@ void gpu_material_add_node(GPUMaterial *material, GPUNode *node) int GPU_material_do_color_management(GPUMaterial *mat) { - /* OCIO_TODO: for now assume scene always does color management. probably could be - * improved in the future to support real display transform - * also probably we'll need to get rid ofgame engine's color management flag - */ + if (!BKE_scene_check_color_management_enabled(mat->scene)) + return FALSE; return !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT)); } @@ -843,7 +841,7 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) if (ob->transflag & OB_DUPLI) { DupliObject *dob; - ListBase *lb = object_duplilist(shi->gpumat->scene, ob); + ListBase *lb = object_duplilist(shi->gpumat->scene, ob, FALSE); for (dob=lb->first; dob; dob=dob->next) { Object *ob_iter = dob->ob; diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index d88f954345f..c929c97a040 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -1172,10 +1172,8 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) switch (ikchan->jointType & ~IK_TRANSY) { case 0: // fixed bone - if (!(ikchan->jointType & IK_TRANSY)) { - joint += ":F"; - ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, tip); - } + joint += ":F"; + ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, tip); break; case IK_XDOF: // RX only, get the X rotation diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 1503b9f6f67..28dbe110528 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -410,10 +410,10 @@ void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); -void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); -void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); -void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); -void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); +void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void neareast_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); /** * diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h index 35a6ea9b207..ba9e20ac411 100644 --- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h +++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h @@ -35,7 +35,7 @@ #define BCM_CONFIG_FILE "config.ocio" -struct ConstProcessorRcPtr; +struct OCIO_ConstProcessorRcPtr; struct ImBuf; typedef struct ColorSpace { @@ -44,8 +44,8 @@ typedef struct ColorSpace { char name[64]; char description[64]; - struct ConstProcessorRcPtr *to_scene_linear; - struct ConstProcessorRcPtr *from_scene_linear; + struct OCIO_ConstProcessorRcPtr *to_scene_linear; + struct OCIO_ConstProcessorRcPtr *from_scene_linear; int is_invertible; int is_data; @@ -57,8 +57,8 @@ typedef struct ColorManagedDisplay { char name[64]; ListBase views; - struct ConstProcessorRcPtr *to_scene_linear; - struct ConstProcessorRcPtr *from_scene_linear; + struct OCIO_ConstProcessorRcPtr *to_scene_linear; + struct OCIO_ConstProcessorRcPtr *from_scene_linear; } ColorManagedDisplay; typedef struct ColorManagedView { diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 02d84819924..37510c10e9a 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -51,6 +51,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_fileops.h" #include "BLI_math.h" #include "BLI_math_color.h" #include "BLI_path_util.h" @@ -88,8 +89,15 @@ static int global_tot_colorspace = 0; static int global_tot_display = 0; static int global_tot_view = 0; +/* lock used by pre-cached processors getters, so processor wouldn't + * be created several times + * LOCK_COLORMANAGE can not be used since this mutex could be needed to + * be locked before pre-cached processor are creating + */ +static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; + typedef struct ColormanageProcessor { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; CurveMapping *curve_mapping; } ColormanageProcessor; @@ -412,9 +420,9 @@ static void colormanage_cache_handle_release(void *cache_handle) /*********************** Initialization / De-initialization *************************/ -static void colormanage_role_color_space_name_get(ConstConfigRcPtr *config, char *colorspace_name, const char *role, const char *backup_role) +static void colormanage_role_color_space_name_get(OCIO_ConstConfigRcPtr *config, char *colorspace_name, const char *role, const char *backup_role) { - ConstColorSpaceRcPtr *ociocs; + OCIO_ConstColorSpaceRcPtr *ociocs; ociocs = OCIO_configGetColorSpace(config, role); @@ -433,7 +441,7 @@ static void colormanage_role_color_space_name_get(ConstConfigRcPtr *config, char } } -static void colormanage_load_config(ConstConfigRcPtr *config) +static void colormanage_load_config(OCIO_ConstConfigRcPtr *config) { int tot_colorspace, tot_display, tot_display_view, index, viewindex, viewindex2; const char *name; @@ -449,7 +457,7 @@ static void colormanage_load_config(ConstConfigRcPtr *config) /* load colorspaces */ tot_colorspace = OCIO_configGetNumColorSpaces(config); for (index = 0 ; index < tot_colorspace; index++) { - ConstColorSpaceRcPtr *ocio_colorspace; + OCIO_ConstColorSpaceRcPtr *ocio_colorspace; const char *description; int is_invertible, is_data; @@ -514,10 +522,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (colorspace->to_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) colorspace->to_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) colorspace->to_scene_linear); if (colorspace->from_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) colorspace->from_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) colorspace->from_scene_linear); /* free color space itself */ MEM_freeN(colorspace); @@ -532,10 +540,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (display->to_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) display->to_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) display->to_scene_linear); if (display->from_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) display->from_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) display->from_scene_linear); /* free list of views */ BLI_freelistN(&display->views); @@ -546,6 +554,8 @@ static void colormanage_free_config(void) /* free views */ BLI_freelistN(&global_views); + + OCIO_exit(); } void colormanagement_init(void) @@ -553,7 +563,9 @@ void colormanagement_init(void) const char *ocio_env; const char *configdir; char configfile[FILE_MAX]; - ConstConfigRcPtr *config = NULL; + OCIO_ConstConfigRcPtr *config = NULL; + + OCIO_init(); ocio_env = getenv("OCIO"); @@ -563,15 +575,27 @@ void colormanagement_init(void) if (config == NULL) { configdir = BLI_get_folder(BLENDER_DATAFILES, "colormanagement"); - if (configdir) { + if (configdir) { BLI_join_dirfile(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE); +#ifdef WIN32 + { + /* quite a hack to support loading configuration from path with non-acii symbols */ + + char short_name[256]; + BLI_get_short_name(short_name, configfile); + config = OCIO_configCreateFromFile(short_name); + } +#else config = OCIO_configCreateFromFile(configfile); +#endif } } if (config == NULL) { - config = OCIO_getDefaultConfig(); + printf("Color management: using fallback mode for management\n"); + + config = OCIO_configCreateFallback(); } if (config) { @@ -636,21 +660,17 @@ static void display_transform_get_from_ctx(const bContext *C, ColorManagedViewSe static const char *display_transform_get_colorspace_name(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - if (config) { - const char *display = display_settings->display_device; - const char *view = view_settings->view_transform; - const char *colorspace_name; + const char *display = display_settings->display_device; + const char *view = view_settings->view_transform; + const char *colorspace_name; - colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view); - - OCIO_configRelease(config); + colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view); - return colorspace_name; - } + OCIO_configRelease(config); - return NULL; + return colorspace_name; } static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettings *view_settings, @@ -664,18 +684,12 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin return NULL; } -static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display, +static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display, float exposure, float gamma) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - DisplayTransformRcPtr *dt; - ConstProcessorRcPtr *processor; - - if (!config) { - /* there's no valid OCIO configuration, can't create processor */ - - return NULL; - } + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_DisplayTransformRcPtr *dt; + OCIO_ConstProcessorRcPtr *processor; dt = OCIO_createDisplayTransform(); @@ -686,7 +700,7 @@ static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_tra /* fstop exposure control */ if (exposure != 0.0f) { - MatrixTransformRcPtr *mt; + OCIO_MatrixTransformRcPtr *mt; float gain = powf(2.0f, exposure); const float scale4f[] = {gain, gain, gain, gain}; float m44[16], offset4[4]; @@ -694,25 +708,25 @@ static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_tra OCIO_matrixTransformScale(m44, offset4, scale4f); mt = OCIO_createMatrixTransform(); OCIO_matrixTransformSetValue(mt, m44, offset4); - OCIO_displayTransformSetLinearCC(dt, (ConstTransformRcPtr *) mt); + OCIO_displayTransformSetLinearCC(dt, (OCIO_ConstTransformRcPtr *) mt); OCIO_matrixTransformRelease(mt); } /* post-display gamma transform */ if (gamma != 1.0f) { - ExponentTransformRcPtr *et; + OCIO_ExponentTransformRcPtr *et; float exponent = 1.0f / MAX2(FLT_EPSILON, gamma); const float exponent4f[] = {exponent, exponent, exponent, exponent}; et = OCIO_createExponentTransform(); OCIO_exponentTransformSetValue(et, exponent4f); - OCIO_displayTransformSetDisplayCC(dt, (ConstTransformRcPtr *) et); + OCIO_displayTransformSetDisplayCC(dt, (OCIO_ConstTransformRcPtr *) et); OCIO_exponentTransformRelease(et); } - processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr *) dt); + processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *) dt); OCIO_displayTransformRelease(dt); OCIO_configRelease(config); @@ -720,17 +734,11 @@ static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_tra return processor; } -static ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, +static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, const char *to_colorspace) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - ConstProcessorRcPtr *processor; - - if (!config) { - /* there's no valid OCIO configuration, can't create processor */ - - return NULL; - } + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor; processor = OCIO_configGetProcessorWithNames(config, from_colorspace, to_colorspace); @@ -739,49 +747,49 @@ static ConstProcessorRcPtr *create_colorspace_transform_processor(const char *fr return processor; } -static ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace) { if (colorspace->to_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (colorspace->to_scene_linear == NULL) { - ConstProcessorRcPtr *to_scene_linear; + OCIO_ConstProcessorRcPtr *to_scene_linear; to_scene_linear = create_colorspace_transform_processor(colorspace->name, global_role_scene_linear); - colorspace->to_scene_linear = (struct ConstProcessorRcPtr *) to_scene_linear; + colorspace->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *) to_scene_linear; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) colorspace->to_scene_linear; + return (OCIO_ConstProcessorRcPtr *) colorspace->to_scene_linear; } -static ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace) { if (colorspace->from_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (colorspace->from_scene_linear == NULL) { - ConstProcessorRcPtr *from_scene_linear; + OCIO_ConstProcessorRcPtr *from_scene_linear; from_scene_linear = create_colorspace_transform_processor(global_role_scene_linear, colorspace->name); - colorspace->from_scene_linear = (struct ConstProcessorRcPtr *) from_scene_linear; + colorspace->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *) from_scene_linear; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) colorspace->from_scene_linear; + return (OCIO_ConstProcessorRcPtr *) colorspace->from_scene_linear; } -static ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display) { if (display->from_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (display->from_scene_linear == NULL) { const char *view_name = colormanage_view_get_default_name(display); - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - ConstProcessorRcPtr *processor = NULL; + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor = NULL; if (view_name && config) { const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(config, display->name, view_name); @@ -790,24 +798,24 @@ static ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisp OCIO_configRelease(config); } - display->from_scene_linear = (struct ConstProcessorRcPtr *) processor; + display->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *) processor; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) display->from_scene_linear; + return (OCIO_ConstProcessorRcPtr *) display->from_scene_linear; } -static ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) { if (display->to_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (display->to_scene_linear == NULL) { const char *view_name = colormanage_view_get_default_name(display); - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - ConstProcessorRcPtr *processor = NULL; + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor = NULL; if (view_name && config) { const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(config, display->name, view_name); @@ -816,13 +824,13 @@ static ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDispla OCIO_configRelease(config); } - display->to_scene_linear = (struct ConstProcessorRcPtr *) processor; + display->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *) processor; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) display->to_scene_linear; + return (OCIO_ConstProcessorRcPtr *) display->to_scene_linear; } static void init_default_view_settings(const ColorManagedDisplaySettings *display_settings, @@ -1273,7 +1281,7 @@ static void *do_display_buffer_apply_thread(void *handle_v) if (cm_processor == NULL) { if (display_buffer_byte) { IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB, - FALSE, width, height, width, width); + FALSE, width, height, width, width); } if (display_buffer) { @@ -1536,7 +1544,7 @@ void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspac */ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpace *colorspace) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -1553,7 +1561,7 @@ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpac /* same as above, but converts colors in opposite direction */ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpace *colorspace) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -1569,7 +1577,7 @@ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpac void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, int height, int channels, struct ColorSpace *colorspace, int predivide) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -1580,9 +1588,9 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in processor = colorspace_to_scene_linear_processor(colorspace); if (processor) { - PackedImageDesc *img; + OCIO_PackedImageDesc *img; - img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float), + img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), channels * sizeof(float), channels * sizeof(float) * width); if (predivide) @@ -1590,7 +1598,7 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in else OCIO_processorApply(processor, img); - OCIO_packedImageDescRelease(img); + OCIO_OCIO_PackedImageDescRelease(img); } } @@ -1600,7 +1608,7 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in */ void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManagedDisplay *display) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; processor = display_from_scene_linear_processor(display); @@ -1611,7 +1619,7 @@ void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManaged /* same as above, but converts color in opposite direction */ void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], ColorManagedDisplay *display) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; processor = display_to_scene_linear_processor(display); @@ -1895,15 +1903,9 @@ void IMB_display_buffer_release(void *cache_handle) const char *colormanage_display_get_default_name(void) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); const char *display_name; - if (!config) { - /* no valid OCIO configuration, can't get default display */ - - return NULL; - } - display_name = OCIO_configGetDefaultDisplay(config); OCIO_configRelease(config); @@ -2012,15 +2014,9 @@ const char *IMB_colormanagement_display_get_none_name(void) const char *colormanage_view_get_default_name(const ColorManagedDisplay *display) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); const char *name; - if (!config) { - /* no valid OCIO configuration, can't get default view */ - - return NULL; - } - name = OCIO_configGetDefaultView(config, display->name); OCIO_configRelease(config); @@ -2526,10 +2522,10 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo } if (cm_processor->processor && channels >= 3) { - PackedImageDesc *img; + OCIO_PackedImageDesc *img; /* apply OCIO processor */ - img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float), + img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), channels * sizeof(float), channels * sizeof(float) * width); if (predivide) @@ -2537,7 +2533,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo else OCIO_processorApply(cm_processor->processor, img); - OCIO_packedImageDescRelease(img); + OCIO_OCIO_PackedImageDescRelease(img); } } diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 9ce5d0e30da..aa236af3507 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -43,6 +43,8 @@ #include "IMB_colormanagement.h" #include "IMB_colormanagement_intern.h" +#include "BLI_threads.h" + #include "MEM_guardedalloc.h" /**************************** Interlace/Deinterlace **************************/ @@ -599,9 +601,18 @@ void IMB_float_from_rect(ImBuf *ibuf) if (ibuf->rect == NULL) return; + /* lock the color management thread + * need this because allocated but not filled float buffer will confuse + * display transform which lead to black areas across the frame + */ + BLI_lock_thread(LOCK_COLORMANAGE); + if (ibuf->rect_float == NULL) { - if (imb_addrectfloatImBuf(ibuf) == 0) + if (imb_addrectfloatImBuf(ibuf) == 0) { + BLI_unlock_thread(LOCK_COLORMANAGE); + return; + } } /* first, create float buffer in non-linear space */ @@ -611,6 +622,8 @@ void IMB_float_from_rect(ImBuf *ibuf) /* then make float be in linear space */ IMB_colormanagement_colorspace_to_scene_linear(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, ibuf->rect_colorspace, predivide); + + BLI_unlock_thread(LOCK_COLORMANAGE); } /* no profile conversion */ diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 3fd06a7c34d..863b8424cc2 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -125,15 +125,16 @@ static float P(float k) } #endif -void bicubic_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) +void bicubic_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { int i, j, n, m, x1, y1; unsigned char *dataI; float a, b, w, wx, wy[4], outR, outG, outB, outA, *dataF; /* sample area entirely outside image? */ - if (ceil(u) < 0 || floor(u) > in->x - 1 || ceil(v) < 0 || floor(v) > in->y - 1) + if (ceil(u) < 0 || floor(u) > in->x - 1 || ceil(v) < 0 || floor(v) > in->y - 1) { return; + } /* ImBuf in must have a valid rect or rect_float, assume this is already checked */ @@ -226,11 +227,12 @@ void bicubic_interpolation_color(struct ImBuf *in, unsigned char *outI, float *o void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) { - unsigned char *outI = NULL; float *outF = NULL; - if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return; + if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) { + return; + } pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ @@ -239,7 +241,7 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in /* function assumes out to be zero'ed, only does RGBA */ /* BILINEAR INTERPOLATION */ -void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) +void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { float *row1, *row2, *row3, *row4, a, b; unsigned char *row1I, *row2I, *row3I, *row4I; @@ -257,7 +259,9 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float * y2 = (int)ceil(v); /* sample area entirely outside image? */ - if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) return; + if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) { + return; + } if (outF) { /* sample including outside of edges of image */ @@ -315,7 +319,7 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float * /* Note about wrapping, the u/v still needs to be within the image bounds, * just the interpolation is wrapped. * This the same as bilinear_interpolation_color except it wraps rather than using empty and emptyI */ -void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) +void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { float *row1, *row2, *row3, *row4, a, b; unsigned char *row1I, *row2I, *row3I, *row4I; @@ -331,7 +335,9 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, fl y2 = (int)ceil(v); /* sample area entirely outside image? */ - if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) return; + if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) { + return; + } /* wrap interpolation pixels - main difference from bilinear_interpolation_color */ if (x1 < 0) x1 = in->x + x1; @@ -378,11 +384,12 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, fl void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) { - unsigned char *outI = NULL; float *outF = NULL; - if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return; + if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) { + return; + } pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ @@ -391,7 +398,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i /* function assumes out to be zero'ed, only does RGBA */ /* NEAREST INTERPOLATION */ -void neareast_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) +void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { float *dataF; unsigned char *dataI; @@ -403,7 +410,9 @@ void neareast_interpolation_color(struct ImBuf *in, unsigned char *outI, float * y1 = (int)(v); /* sample area entirely outside image? */ - if (x1 < 0 || x1 > in->x - 1 || y1 < 0 || y1 > in->y - 1) return; + if (x1 < 0 || x1 > in->x - 1 || y1 < 0 || y1 > in->y - 1) { + return; + } /* sample including outside of edges of image */ if (x1 < 0 || y1 < 0) { @@ -440,11 +449,12 @@ void neareast_interpolation_color(struct ImBuf *in, unsigned char *outI, float * void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) { - unsigned char *outI = NULL; float *outF = NULL; - if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return; + if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) { + return; + } pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 97316c48621..f35a4345366 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -955,9 +955,9 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, } /* process pictures still stuck in decoder engine after EOF - according to ffmpeg docs using 0-size packets. - - At least, if we haven't already stopped... */ + * according to ffmpeg docs using 0-size packets. + * + * At least, if we haven't already stopped... */ if (!*stop) { int frame_finished; diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 13078921d1c..066d07a36c5 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -372,10 +372,10 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags for (int j = ibuf->x; j > 0; j--) { to->r = from[0]; - to->g = from[1]; - to->b = from[2]; + to->g = (channels >= 2) ? from[1] : from[0]; + to->b = (channels >= 3) ? from[2] : from[0]; to->a = (channels >= 4) ? from[3] : 1.0f; - to++; from += 4; + to++; from += channels; } } } @@ -383,7 +383,7 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags unsigned char *from; for (int i = ibuf->y - 1; i >= 0; i--) { - from = (unsigned char *)ibuf->rect + channels * i * width; + from = (unsigned char *)ibuf->rect + 4 * i * width; for (int j = ibuf->x; j > 0; j--) { to->r = srgb_to_linearrgb((float)from[0] / 255.0f); @@ -448,8 +448,8 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag /* last scanline, stride negative */ rect[0] = ibuf->rect_float + channels * (height - 1) * width; - rect[1] = rect[0] + 1; - rect[2] = rect[0] + 2; + rect[1] = (channels >= 2) ? rect[0] + 1 : rect[0]; + rect[2] = (channels >= 3) ? rect[0] + 2 : rect[0]; rect[3] = (channels >= 4) ? rect[0] + 3 : rect[0]; /* red as alpha, is this needed since alpha isn't written? */ frameBuffer.insert("R", Slice(Imf::FLOAT, (char *)rect[0], xstride, ystride)); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 284694f2b48..9fbe045226e 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -74,7 +74,7 @@ typedef struct Path { typedef struct BevList { struct BevList *next, *prev; int nr, dupe_nr; - short poly, hole; + int poly, hole; } BevList; /* These two Lines with # tell makesdna this struct can be excluded. */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index c22de3cb7eb..9d40af92638 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -36,8 +36,6 @@ extern "C" { #endif -#include "DNA_defs.h" /* USE_BMESH_FORWARD_COMPAT */ - /** descriptor and storage for a custom data layer */ typedef struct CustomDataLayer { int type; /* type of data in layer */ diff --git a/source/blender/makesdna/DNA_defs.h b/source/blender/makesdna/DNA_defs.h index 762e027f934..774fbcf081a 100644 --- a/source/blender/makesdna/DNA_defs.h +++ b/source/blender/makesdna/DNA_defs.h @@ -45,9 +45,6 @@ /* hrmf, we need a better include then this */ #include "../blenloader/BLO_sys_types.h" /* needed for int64_t only! */ -/* Must not be defined for BMesh, as this guards code for pre-BMesh code to load BMesh .blend files */ -/* #define USE_BMESH_FORWARD_COMPAT */ - /* non-id name variables should use this length */ #define MAX_NAME 64 diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 1196ce20a6b..058be2e2046 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -37,8 +37,6 @@ #include "DNA_ID.h" #include "DNA_customdata_types.h" -#include "DNA_defs.h" /* USE_BMESH_FORWARD_COMPAT */ - struct AnimData; struct DerivedMesh; struct Ipo; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index b40af805f77..99df51e9ec4 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -28,9 +28,6 @@ #include "DNA_defs.h" #include "DNA_listBase.h" - -#define MODSTACK_DEBUG 1 - /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! * (ONLY ADD NEW ITEMS AT THE END) */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a1534c7b9d3..4b8fc9c7ed6 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -264,8 +264,8 @@ typedef enum eSpaceOutliner_Mode { SO_SAME_TYPE = 5, SO_GROUPS = 6, SO_LIBRARIES = 7, - SO_VERSE_SESSION = 8, - SO_VERSE_MS = 9, + /* SO_VERSE_SESSION = 8, */ /* deprecated! */ + /* SO_VERSE_MS = 9, */ /* deprecated!*/ SO_SEQUENCE = 10, SO_DATABLOCKS = 11, SO_USERDEF = 12, diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index d55810deeac..2041ee01d6e 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -1188,7 +1188,19 @@ int main(int argc, char **argv) return(return_status); } +/* handy but fails on struct bounds which makesdna doesnt care about + * unless structs are nested */ +#if 0 /* include files for automatic dependencies */ + +/* extra safety check that we are aligned, + * warnings here are easier to fix the makesdna's */ +#ifdef __GNUC__ +# pragma GCC diagnostic error "-Wpadded" +#endif + +#endif /* if 0 */ + #include "DNA_listBase.h" #include "DNA_vec_types.h" #include "DNA_ID.h" diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 1c41c67b39c..071c1fae4ef 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -38,6 +38,7 @@ extern EnumPropertyItem DummyRNA_NULL_items[]; extern EnumPropertyItem DummyRNA_DEFAULT_items[]; extern EnumPropertyItem object_mode_items[]; +extern EnumPropertyItem object_empty_drawtype_items[]; extern EnumPropertyItem metaelem_type_items[]; extern EnumPropertyItem proportional_falloff_items[]; diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 12a41f213b7..b1fdfccd0be 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -41,6 +41,8 @@ #include "BLI_utildefines.h" +#include "BLF_translation.h" + /* Always keep in alphabetical order */ EnumPropertyItem actuator_type_items[] = { {ACT_ACTION, "ACTION", 0, "Action", ""}, @@ -971,11 +973,13 @@ static void rna_def_sound_actuator(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 2); RNA_def_property_range(prop, 0.0, 2.0); RNA_def_property_ui_text(prop, "Volume", "Initial volume of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_update(prop, NC_LOGIC, NULL); prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_range(prop, -12.0, 12.0, 1, 2); RNA_def_property_ui_text(prop, "Pitch", "Pitch of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_update(prop, NC_LOGIC, NULL); /* floats - 3D Parameters */ diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 770bdb68e38..f2454a2dcfb 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1243,7 +1243,7 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) prop = RNA_def_property(srna, "offset_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "offset_fac"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Offset Factor", "Percentage value defining target position along length of bone"); + RNA_def_property_ui_text(prop, "Offset Factor", "Percentage value defining target position along length of curve"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "forward_axis", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 131611d3002..bf7f4984ea1 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -40,6 +40,15 @@ #ifdef RNA_RUNTIME +#include "WM_api.h" + +#include "BKE_gpencil.h" + +static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +{ + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr) { bGPDlayer *gpl = (bGPDlayer *)ptr->data; @@ -53,6 +62,7 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr) static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr) { + bGPdata *gpd = ptr->id.data; if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */ @@ -101,6 +111,34 @@ 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 bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int setactive) +{ + bGPDlayer *gl = gpencil_layer_addnew(gpd, name, setactive); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return gl; +} + +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) { + BKE_reportf(reports, RPT_ERROR, "Layer not found in grease pencil data"); + return; + } + + gpencil_layer_delete(gpd, layer); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + #else static void rna_def_gpencil_stroke_point(BlenderRNA *brna) @@ -116,13 +154,13 @@ 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_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); 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_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); } static void rna_def_gpencil_stroke(BlenderRNA *brna) @@ -189,7 +227,8 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Info", "Layer name"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilLayer_info_set"); RNA_def_struct_name_property(srna, prop); - + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + /* Frames */ prop = RNA_def_property(srna, "frames", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "frames", NULL); @@ -201,32 +240,33 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "actframe"); RNA_def_property_ui_text(prop, "Active Frame", "Frame currently being displayed for this layer"); RNA_def_property_editable_func(prop, "rna_GPencilLayer_active_frame_editable"); - + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + /* Drawing Color */ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Color", "Color for all strokes in this layer"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "color[3]"); RNA_def_property_range(prop, 0.3, 1.0f); RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Line Thickness */ prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "thickness"); RNA_def_property_range(prop, 1, 10); RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Onion-Skinning */ prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ONIONSKIN); RNA_def_property_ui_text(prop, "Onion Skinning", "Ghost frames on either side of frame"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "ghost_range_max", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gstep"); @@ -234,23 +274,23 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Max Ghost Range", "Maximum number of frames on either side of the active frame to show " "(0 = show the 'first' available sketch on either side)"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Flags */ prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE); RNA_def_property_ui_text(prop, "Hide", "Set layer Visibility"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED); RNA_def_property_ui_text(prop, "Locked", "Protect layer from further editing and/or frame changes"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); prop = RNA_def_property(srna, "lock_frame", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_FRAMELOCK); RNA_def_property_ui_text(prop, "Frame Locked", "Lock current frame displayed by layer"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); /* expose as layers.active */ #if 0 @@ -258,25 +298,25 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ACTIVE); RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencilLayer_active_set"); RNA_def_property_ui_text(prop, "Active", "Set active layer for editing"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); #endif prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT); RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the DopeSheet"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); /* XXX keep this option? */ prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_DRAWDEBUG); RNA_def_property_ui_text(prop, "Show Points", "Draw the points which make up the strokes (for debugging purposes)"); - RNA_def_property_update(prop, NC_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update_runtime(prop, "rna_GPencil_update"); /* X-Ray */ prop = RNA_def_property(srna, "show_x_ray", PROP_BOOLEAN, PROP_NONE); 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_SCREEN | ND_GPENCIL, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); } static void rna_def_gpencil_layers(BlenderRNA *brna, PropertyRNA *cprop) @@ -284,28 +324,27 @@ static void rna_def_gpencil_layers(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; PropertyRNA *prop; -/* FunctionRNA *func; */ -/* PropertyRNA *parm; */ + FunctionRNA *func; + PropertyRNA *parm; RNA_def_property_srna(cprop, "GreasePencilLayers"); srna = RNA_def_struct(brna, "GreasePencilLayers", NULL); RNA_def_struct_sdna(srna, "bGPdata"); RNA_def_struct_ui_text(srna, "Grease Pencil Layers", "Collection of grease pencil layers"); -#if 0 func = RNA_def_function(srna, "new", "rna_GPencil_layer_new"); - RNA_def_function_ui_description(func, "Add a new spline to the curve"); - parm = RNA_def_enum(func, "type", curve_type_items, CU_POLY, "", "type for the new spline"); + RNA_def_function_ui_description(func, "Add a new grease pencil layer"); + parm = RNA_def_string(func, "name", "GPencilLayer", MAX_NAME, "Name", "Name of the layer"); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_pointer(func, "spline", "Spline", "", "The newly created spline"); + RNA_def_boolean(func, "set_active", 0, "Set Active", "Set the newly created layer to the active layer"); + parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The newly created layer"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_GPencil_layer_remove"); - RNA_def_function_ui_description(func, "Remove a spline from a curve"); + RNA_def_function_ui_description(func, "Remove a grease pencil layer"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_pointer(func, "spline", "Spline", "", "The spline to remove"); + parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The layer to remove"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); -#endif prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "GreasePencil"); @@ -344,11 +383,12 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, draw_mode_items); RNA_def_property_ui_text(prop, "Draw Mode", ""); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); prop = RNA_def_property(srna, "use_stroke_endpoints", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_DEPTH_STROKE_ENDPOINTS); 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); } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index f75862af61d..e3ab7d25d79 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -411,7 +411,7 @@ int rna_IDMaterials_assign_int(struct PointerRNA *ptr, int key, const struct Poi /* Internal functions that cycles uses so we need to declare (tsk tsk) */ struct Mesh *rna_Object_to_mesh(struct Object *ob, struct ReportList *reports, struct Scene *sce, int apply_modifiers, int settings); void rna_Main_meshes_remove(struct Main *bmain, struct ReportList *reports, struct Mesh *mesh); -void rna_Object_create_duplilist(struct Object *ob, struct ReportList *reports, struct Scene *sce); +void rna_Object_create_duplilist(struct Object *ob, struct ReportList *reports, struct Scene *sce, int settings); void rna_Object_free_duplilist(struct Object *ob); void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values); void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index eb4660c18e8..1b26c0447ff 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3007,7 +3007,7 @@ static void rna_def_modifier_remesh(BlenderRNA *brna) prop = RNA_def_property(srna, "octree_depth", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "depth"); - RNA_def_property_range(prop, 1, 10); + RNA_def_property_range(prop, 1, 12); RNA_def_property_ui_text(prop, "Octree Depth", "Resolution of the octree; higher values give finer details"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 3239e8ac596..d650c8dbf69 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1720,6 +1720,16 @@ static void def_sh_tex_wave(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Node_update"); } +static void def_sh_tex_coord(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); + RNA_def_property_ui_text(prop, "From Dupli", "Use the parent of the dupli object if possible"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_glossy(StructRNA *srna) { PropertyRNA *prop; @@ -2195,14 +2205,14 @@ static void def_cmp_inpaint(StructRNA *srna) { PropertyRNA *prop; -/* +#if 0 prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, type_items); RNA_def_property_ui_text(prop, "Type", "Type of inpaint algorithm"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); -*/ +#endif prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); @@ -4315,7 +4325,7 @@ static void rna_def_node(BlenderRNA *brna) prop = RNA_def_property(srna, "label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "label"); RNA_def_property_ui_text(prop, "Label", "Optional custom node label"); - RNA_def_property_update(prop, NC_NODE, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); prop = RNA_def_property(srna, "inputs", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "inputs", NULL); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 0baa4cc0838..db1e1e16adf 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -92,7 +92,7 @@ DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TE 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_COORD, 0, "TEX_COORD", TexCoord, "Texture Coordinate","" ) +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", "" ) DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index a10c153515a..0b8afef0364 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -69,6 +69,19 @@ EnumPropertyItem object_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem object_empty_drawtype_items[] = { + {OB_PLAINAXES, "PLAIN_AXES", 0, "Plain Axes", ""}, + {OB_ARROWS, "ARROWS", 0, "Arrows", ""}, + {OB_SINGLE_ARROW, "SINGLE_ARROW", 0, "Single Arrow", ""}, + {OB_CIRCLE, "CIRCLE", 0, "Circle", ""}, + {OB_CUBE, "CUBE", 0, "Cube", ""}, + {OB_EMPTY_SPHERE, "SPHERE", 0, "Sphere", ""}, + {OB_EMPTY_CONE, "CONE", 0, "Cone", ""}, + {OB_EMPTY_IMAGE, "IMAGE", 0, "Image", ""}, + {0, NULL, 0, NULL, NULL} +}; + + static EnumPropertyItem parent_type_items[] = { {PAROBJECT, "OBJECT", 0, "Object", "The object is parented to an object"}, {PARCURVE, "CURVE", 0, "Curve", "The object is parented to a curve"}, @@ -80,7 +93,7 @@ static EnumPropertyItem parent_type_items[] = { {PARBONE, "BONE", 0, "Bone", "The object is parented to a bone"}, {0, NULL, 0, NULL, NULL} }; - + static EnumPropertyItem collision_bounds_items[] = { {OB_BOUND_BOX, "BOX", 0, "Box", ""}, {OB_BOUND_SPHERE, "SPHERE", 0, "Sphere", ""}, @@ -1874,18 +1887,6 @@ static void rna_def_object(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - - static EnumPropertyItem empty_drawtype_items[] = { - {OB_PLAINAXES, "PLAIN_AXES", 0, "Plain Axes", ""}, - {OB_ARROWS, "ARROWS", 0, "Arrows", ""}, - {OB_SINGLE_ARROW, "SINGLE_ARROW", 0, "Single Arrow", ""}, - {OB_CIRCLE, "CIRCLE", 0, "Circle", ""}, - {OB_CUBE, "CUBE", 0, "Cube", ""}, - {OB_EMPTY_SPHERE, "SPHERE", 0, "Sphere", ""}, - {OB_EMPTY_CONE, "CONE", 0, "Cone", ""}, - {OB_EMPTY_IMAGE, "IMAGE", 0, "Image", ""}, - {0, NULL, 0, NULL, NULL} - }; static EnumPropertyItem track_items[] = { {OB_POSX, "POS_X", 0, "+X", ""}, @@ -2267,7 +2268,7 @@ static void rna_def_object(BlenderRNA *brna) /* empty */ prop = RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype"); - RNA_def_property_enum_items(prop, empty_drawtype_items); + RNA_def_property_enum_items(prop, object_empty_drawtype_items); RNA_def_property_ui_text(prop, "Empty Display Type", "Viewport display style for empties"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); @@ -2572,7 +2573,16 @@ static void rna_def_dupli_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text(prop, "Particle Index", "Index in the lowest-level particle dupli list"); - /* TODO: DupliObject has more properties that can be wrapped */ + prop = RNA_def_property(srna, "orco", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "orco"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Generated Coordinates", "Generated coordinates in parent object space"); + + prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "uv"); + RNA_def_property_array(prop, 2); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_ui_text(prop, "UV Coordinates", "UV coordinates in parent object space"); } static void rna_def_object_base(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index a6f49d80b25..879a77527cd 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -177,6 +177,8 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ return NULL; /* only do basis metaball */ tmpmesh = BKE_mesh_add("Mesh"); + /* BKE_mesh_add gives us a user count we don't need */ + tmpmesh->id.us--; if (render) { ListBase disp = {NULL, NULL}; @@ -186,6 +188,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ } else BKE_mesh_from_metaball(&ob->disp, tmpmesh); + break; } @@ -214,6 +217,9 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ dm->release(dm); } + /* BKE_mesh_add/copy gives us a user count we don't need */ + tmpmesh->id.us--; + break; default: BKE_report(reports, RPT_ERROR, "Object does not have geometry data"); @@ -283,9 +289,6 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ /* cycles and exporters rely on this still */ BKE_mesh_tessface_ensure(tmpmesh); - /* we don't assign it to anything */ - tmpmesh->id.us--; - /* make sure materials get updated in objects */ test_object_materials(&tmpmesh->id); @@ -337,8 +340,10 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e dupli_render_particle_set(scene, go->ob, level + 1, enable); } /* When no longer needed, duplilist should be freed with Object.free_duplilist */ -void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce) +void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, int settings) { + int for_render = settings == eModifierMode_Render; + if (!(ob->transflag & OB_DUPLI)) { BKE_report(reports, RPT_ERROR, "Object does not have duplis"); return; @@ -353,7 +358,7 @@ void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce) } if (G.is_rendering) dupli_render_particle_set(sce, ob, 0, 1); - ob->duplilist = object_duplilist(sce, ob); + ob->duplilist = object_duplilist(sce, ob, for_render); if (G.is_rendering) dupli_render_particle_set(sce, ob, 0, 0); /* ob->duplilist should now be freed with Object.free_duplilist */ @@ -608,6 +613,7 @@ void RNA_api_object(StructRNA *srna) "objects real matrix and layers"); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate duplis"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Generate texture coordinates for rendering"); RNA_def_function_flag(func, FUNC_USE_REPORTS); func = RNA_def_function(srna, "dupli_list_clear", "rna_Object_free_duplilist"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 1c7f0b00caf..62ba3a7e663 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3538,6 +3538,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_translation_context(prop, "Audio"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); #endif @@ -4970,6 +4971,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "audio.volume"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_update(prop, NC_SCENE, NULL); RNA_def_property_float_funcs(prop, NULL, "rna_Scene_volume_set", NULL); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index d83debd3266..d8ca1aea5dd 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -50,6 +50,8 @@ #include "WM_types.h" #include "BLI_math.h" +#include "BLF_translation.h" + typedef struct EffectInfo { const char *struct_name; const char *ui_name; @@ -405,7 +407,7 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value) BLI_strncpy_utf8(seq->name + 2, value, sizeof(seq->name) - 2); /* make sure the name is unique */ - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* fix all the animation data which may link to this */ @@ -1673,14 +1675,14 @@ static void rna_def_effect_inputs(StructRNA *srna, int count) RNA_def_property_ui_text(prop, "Input 2", "Second input for the effect strip"); } - /* +#if 0 if (count == 3) { // not used by any effects (perhaps one day plugins?) prop = RNA_def_property(srna, "input_3", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "seq3"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL); RNA_def_property_ui_text(prop, "Input 3", "Third input for the effect strip"); } - */ +#endif } static void rna_def_image(BlenderRNA *brna) @@ -1858,6 +1860,7 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "volume"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_volume_set", NULL); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); @@ -1865,6 +1868,7 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "pitch"); RNA_def_property_range(prop, 0.1f, 10.0f); RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_pitch_set", NULL); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index c7c4b0817f6..f63ef6c8d76 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -81,7 +81,7 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start seq->type = type; BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); seq->strip->us = 1; diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c index 1e3c8df9273..a160aaf94e2 100644 --- a/source/blender/makesrna/intern/rna_speaker.c +++ b/source/blender/makesrna/intern/rna_speaker.c @@ -35,6 +35,8 @@ #include "DNA_speaker_types.h" #include "DNA_sound_types.h" +#include "BLF_translation.h" + #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -45,7 +47,6 @@ #include "WM_api.h" #include "WM_types.h" - #else static void rna_def_speaker(BlenderRNA *brna) @@ -151,6 +152,7 @@ static void rna_def_speaker(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "volume"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Volume", "How loud the sound is"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); /* RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_set", NULL); */ /* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */ @@ -158,6 +160,7 @@ static void rna_def_speaker(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "pitch"); RNA_def_property_range(prop, 0.1f, 10.0f); RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); /* RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_pitch_set", NULL); */ /* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */ diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 483e3ab7f8a..45e3d15b9be 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1733,6 +1733,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) prop = RNA_def_property(srna, "turbulence_strength", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "noise_fac"); RNA_def_property_range(prop, 0.01, FLT_MAX); + RNA_def_property_ui_text(prop, "Turbulence Strength", "Strength of the added turbulent noise"); RNA_def_property_update(prop, 0, "rna_Texture_update"); prop = RNA_def_property(srna, "turbulence_depth", PROP_INT, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index afc85a8144e..4292246d8cc 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -80,6 +80,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, Mesh *me = (Mesh *)ob->data; const int useRenderParams = flag & MOD_APPLY_RENDER; MultiresFlags flags = 0; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); if (mmd->totlvl) { if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) { @@ -88,7 +89,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, } } - flags = MULTIRES_ALLOC_PAINT_MASK; + if (has_mask) + flags |= MULTIRES_ALLOC_PAINT_MASK; + if (useRenderParams) flags |= MULTIRES_USE_RENDER_PARAMS; diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 68bafd94ce4..0d86ada8026 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -515,9 +515,9 @@ static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd) static void freeExecutableNode(bNodeTreeExec *exec) { /* node outputs can be freed when: - - not a render result or image node - - when node outputs go to nodes all being set NODE_FINISHED - */ + * - not a render result or image node + * - when node outputs go to nodes all being set NODE_FINISHED + */ bNodeTree *ntree = exec->nodetree; bNodeExec *nodeexec; bNode *node; diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index a61cf00d81c..301dea22c17 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -650,3 +650,15 @@ void ntree_update_reroute_nodes(bNodeTree *ntree) if (node->type == NODE_REROUTE && !node->done) node_reroute_inherit_type_recursive(ntree, node); } + +void BKE_node_tree_unlink_id_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree) +{ + ID *id = (ID *)calldata; + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id == id) { + node->id = NULL; + } + } +} diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c index 86f71f6f05b..62b1cabd491 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c @@ -57,7 +57,7 @@ void register_node_type_sh_tex_coord(bNodeTreeType *ttype) { static bNodeType ntype; - node_type_base(ttype, &ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, 0); + node_type_base(ttype, &ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, NODE_OPTIONS); node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_tex_coord_out); node_type_size(&ntype, 150, 60, 200); diff --git a/source/blender/opencl/intern/OCL_opencl.c b/source/blender/opencl/intern/OCL_opencl.c index fa22acbc1a2..e3130e16bde 100644 --- a/source/blender/opencl/intern/OCL_opencl.c +++ b/source/blender/opencl/intern/OCL_opencl.c @@ -22,14 +22,14 @@ #include "OCL_opencl.h" -void OCL_init() +void OCL_init(void) { #ifdef _WIN32 - const char *path = "OpenCL.dll"; + const char *path = "OpenCL.dll"; #elif defined(__APPLE__) - const char *path = "/Library/Frameworks/OpenCL.framework/OpenCL"; + const char *path = "/Library/Frameworks/OpenCL.framework/OpenCL"; #else - const char *path = "libOpenCL.so"; + const char *path = "libOpenCL.so"; #endif clewInit(path); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index fefccceeb6e..fd5fa63647b 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1808,7 +1808,7 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args) f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, FALSE); - if (f_new == NULL) { + if (UNLIKELY(f_new == NULL)) { PyErr_SetString(PyExc_ValueError, "faces.new(verts): couldn't create the new face, internal error"); goto cleanup; diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 2a9592d21e2..0391839c763 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -1079,7 +1079,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj ret = -1; } else { - BLI_strncpy(mstring->s, tmp_val, sizeof(mstring->s)); + BLI_strncpy(mstring->s, tmp_val, MIN2(PyBytes_Size(py_value), sizeof(mstring->s))); } break; } diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index a2521484c88..9492c8384dc 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -760,7 +760,6 @@ int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int *valu return 0; } -/* 'value' _must_ be a set type, error check before calling */ int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix) { /* set of enum items, concatenate all values with OR */ @@ -771,6 +770,13 @@ int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, co Py_ssize_t hash = 0; PyObject *key; + if (!PySet_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s expected a set, not %.200s", + error_prefix, Py_TYPE(value)->tp_name); + return -1; + } + *r_value = 0; while (_PySet_NextEntry(value, &pos, &key, &hash)) { @@ -778,7 +784,7 @@ int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, co if (param == NULL) { PyErr_Format(PyExc_TypeError, - "%.200s expected a string, not %.200s", + "%.200s set must contain strings, not %.200s", error_prefix, Py_TYPE(key)->tp_name); return -1; } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 85f6163c721..b628f42e759 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -251,6 +251,10 @@ void BPY_python_start(int argc, const char **argv) * an error, this is highly annoying, another stumbling block for devs, * so use a more relaxed error handler and enforce utf-8 since the rest of * blender is utf-8 too - campbell */ + + /* XXX, update: this is unreliable! 'PYTHONIOENCODING' is ignored in MS-Windows + * when dynamically linked, see: [#31555] for details. + * Python doesn't expose a good way to set this. */ BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape"); /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to @@ -264,15 +268,6 @@ void BPY_python_start(int argc, const char **argv) Py_Initialize(); -#ifdef WIN32 - /* this is disappointing, its likely a bug in python? - * for some reason 'PYTHONIOENCODING' is ignored in windows - * see: [#31555] for details. */ - PyRun_SimpleString("import sys, io\n" - "sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='surrogateescape', line_buffering=True)\n" - "sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='surrogateescape', line_buffering=True)\n"); -#endif /* WIN32 */ - // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal /* sigh, why do python guys not have a (char **) version anymore? */ { @@ -678,6 +673,11 @@ void BPY_modules_load_user(bContext *C) else { Py_DECREF(module); } + + /* check if the script loaded a new file */ + if (bmain != CTX_data_main(C)) { + break; + } } } } diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index e8f171fe383..4b9fa2d2042 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -76,7 +76,7 @@ void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); /* imagetexture.h */ -int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[3], const float dyt[3], struct TexResult *texres); +int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[2], const float dyt[2], struct TexResult *texres); int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres); void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float result[4]); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 2e3468862d9..e3db4b7c266 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4955,7 +4955,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* create list of duplis generated by this object, particle * system need to have render settings set for dupli particles */ dupli_render_particle_set(re, ob, timeoffset, 0, 1); - lb= object_duplilist(re->scene, ob); + lb= object_duplilist(re->scene, ob, TRUE); dupli_render_particle_set(re, ob, timeoffset, 0, 0); for (dob= lb->first; dob; dob= dob->next) { diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index f62ed909094..6c86f2a2999 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -1018,7 +1018,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf) } -static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[3], float dyt[3], TexResult *texres) +static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres) { TexResult texr; float fx, fy, minx, maxx, miny, maxy; @@ -1412,17 +1412,17 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex } -int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[3], const float DYT[3], TexResult *texres) +int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], TexResult *texres) { TexResult texr; - float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[3], dyt[3]; + float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2]; float maxd, pixsize, val1, val2, val3; int curmap, retval, imaprepeat, imapextend; /* TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call, * make a local copy here so that original vecs remain untouched */ - copy_v3_v3(dxt, DXT); - copy_v3_v3(dyt, DYT); + copy_v2_v2(dxt, DXT); + copy_v2_v2(dyt, DYT); /* anisotropic filtering */ if (tex->texfilter != TXF_BOX) diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index c8aad21b322..af774c5be73 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -232,9 +232,9 @@ static void occ_build_shade(Render *re, OcclusionTree *tree) /* ------------------------- Spherical Harmonics --------------------------- */ /* Use 2nd order SH => 9 coefficients, stored in this order: -* 0 = (0,0), -* 1 = (1,-1), 2 = (1,0), 3 = (1,1), -* 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */ + * 0 = (0,0), + * 1 = (1,-1), 2 = (1,0), 3 = (1,1), + * 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */ static void sh_copy(float *shresult, float *sh) { @@ -1056,8 +1056,8 @@ static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, floa static __m128 sse_approx_acos(__m128 x) { /* needs a better approximation than taylor expansion of acos, since that - * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work - * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */ + * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work + * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */ return _mm_set_ps1(1.0f); } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 35ab06cc564..ff543b8ce06 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -44,6 +44,7 @@ #include "DNA_material_types.h" #include "BKE_colortools.h" +#include "BKE_scene.h" #include "BKE_node.h" @@ -1321,12 +1322,7 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in shi->thread = pa->thread; shi->do_preview = (R.r.scemode & R_MATNODE_PREVIEW) != 0; - /* OCIO_TODO: for now assume color management is always enabled and vertes colors are in sRGB space - * probably would be nice to have this things configurable, but for now it should work - * also probably this flag could be removed (in separated commit) before the release - * since it's not actually meaningful anymore - */ - shi->do_manage = TRUE; + shi->do_manage = BKE_scene_check_color_management_enabled(R.scene); shi->lay = rl->lay; shi->layflag = rl->layflag; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ac05331095b..e7b7f679ce3 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -273,7 +273,7 @@ int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op); int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op); -int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2]; +const int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2]; int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 4ec3d8ea755..82bd37eb6cc 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -238,7 +238,8 @@ typedef struct wmNotifier { #define NC_LOGIC (19<<24) #define NC_MOVIECLIP (20<<24) #define NC_MASK (21<<24) -#define NC_LINESTYLE (22<<24) +#define NC_GPENCIL (22<<24) +#define NC_LINESTYLE (23<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 @@ -509,7 +510,11 @@ typedef struct wmOperatorType { * parameters may be provided through operator properties. cannot use * any interface code or input device state. * - see defines below for return values */ - int (*exec)(struct bContext *, struct wmOperator *); + int (*exec)(struct bContext *, struct wmOperator *) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* this callback executes on a running operator whenever as property * is changed. It can correct its own properties or report errors for @@ -521,9 +526,17 @@ typedef struct wmOperatorType { * any further events are handled in modal. if the operation is * canceled due to some external reason, cancel is called * - see defines below for return values */ - int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *); + int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; int (*cancel)(struct bContext *, struct wmOperator *); - int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *); + int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* 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 */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 594804d10f6..aab20e5849b 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -56,6 +56,7 @@ #include "BLI_blenlib.h" #include "BLI_linklist.h" #include "BLI_utildefines.h" +#include "BLI_threads.h" #include "BLI_callbacks.h" #include "BLF_translation.h" @@ -797,7 +798,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ - if (U.flag & USER_SAVE_PREVIEWS) { + if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 313fc0a819e..e4d6b3dd465 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2289,6 +2289,8 @@ static int border_apply_rect(wmOperator *op) static int border_apply(bContext *C, wmOperator *op, int gesture_mode) { + int retval; + if (!border_apply_rect(op)) return 0; @@ -2296,7 +2298,9 @@ static int border_apply(bContext *C, wmOperator *op, int gesture_mode) if (RNA_struct_find_property(op->ptr, "gesture_mode") ) RNA_int_set(op->ptr, "gesture_mode", gesture_mode); - op->type->exec(C, op); + retval = op->type->exec(C, op); + OPERATOR_RETVAL_CHECK(retval); + return 1; } @@ -2422,8 +2426,11 @@ static void gesture_circle_apply(bContext *C, wmOperator *op) RNA_int_set(op->ptr, "y", rect->ymin); RNA_int_set(op->ptr, "radius", rect->xmax); - if (op->type->exec) - op->type->exec(C, op); + if (op->type->exec) { + int retval; + retval = op->type->exec(C, op); + OPERATOR_RETVAL_CHECK(retval); + } #ifdef GESTURE_MEMORY circle_select_size = rect->xmax; #endif @@ -2643,8 +2650,10 @@ static void gesture_lasso_apply(bContext *C, wmOperator *op) wm_gesture_end(C, op); - if (op->type->exec) - op->type->exec(C, op); + if (op->type->exec) { + int retval = op->type->exec(C, op); + OPERATOR_RETVAL_CHECK(retval); + } } int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event) @@ -2727,7 +2736,7 @@ int WM_gesture_lines_cancel(bContext *C, wmOperator *op) * * caller must free. */ -int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2] +const int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2] { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "path"); int (*mcords)[2] = NULL; @@ -2757,7 +2766,8 @@ int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *m *mcords_tot = 0; } - return mcords; + /* cast for 'const' */ + return (const int (*)[2])mcords; } #if 0 @@ -2812,8 +2822,10 @@ static int straightline_apply(bContext *C, wmOperator *op) RNA_int_set(op->ptr, "xend", rect->xmax); RNA_int_set(op->ptr, "yend", rect->ymax); - if (op->type->exec) - op->type->exec(C, op); + if (op->type->exec) { + int retval = op->type->exec(C, op); + OPERATOR_RETVAL_CHECK(retval); + } return 1; } diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 96b56768b8f..fa0994d788a 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -28,11 +28,11 @@ set(INC ../../../intern/guardedalloc ../../../intern/moto/include ../../../intern/string - ${GLEW_INCLUDE_PATH} ) set(INC_SYS ${PTHREADS_INCLUDE_DIRS} + ${GLEW_INCLUDE_PATH} ) set(SRC |