diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e5f62355af..fe1a6d03335 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -502,20 +502,6 @@ set(PLATFORM_LINKFLAGS_DEBUG "") #Platform specifics if(UNIX AND NOT APPLE) - - # set lib directory if it exists - if(CMAKE_SYSTEM_NAME MATCHES "Linux") - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/linux64) - else() - set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/linux) - endif() - - if(NOT EXISTS ${LIBDIR}) - unset(LIBDIR) - endif() - endif() - find_package(JPEG REQUIRED) find_package(PNG REQUIRED) find_package(ZLIB REQUIRED) @@ -590,15 +576,8 @@ if(UNIX AND NOT APPLE) endif() if(WITH_CODEC_FFMPEG) - # use lib dir if available and nothing else specified - if(LIBDIR AND NOT FFMPEG) - set(FFMPEG ${LIBDIR}/ffmpeg CACHE PATH "FFMPEG Directory") - # XXX, some distros might need 'theoraenc theoradec' too - set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale dirac_encoder mp3lame ogg orc-0.4 schroedinger-1.0 theora vorbis vorbisenc vpx x264 xvidcore faad asound CACHE STRING "FFMPEG Libraries") - else() - set(FFMPEG /usr CACHE PATH "FFMPEG Directory") - set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries") - endif() + set(FFMPEG /usr CACHE PATH "FFMPEG Directory") + set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries") mark_as_advanced(FFMPEG) @@ -654,14 +633,13 @@ if(UNIX AND NOT APPLE) if(WITH_BOOST) # uses in build instructions to override include and library variables if(NOT BOOST_CUSTOM) - # use lib dir if available and nothing else specified - if(LIBDIR AND NOT BOOST_ROOT) - set(BOOST_ROOT ${LIBDIR}/boost) + # XXX No more lib dir, is this multithread stuff still needed? + if(NOT BOOST_ROOT) set(Boost_USE_MULTITHREADED OFF) else() set(Boost_USE_MULTITHREADED ON) endif() - set(__boost_packages filesystem regex system thread) + set(__boost_packages filesystem regex system thread date_time) if (WITH_INTERNATIONAL) list(APPEND __boost_packages locale) endif() @@ -676,11 +654,6 @@ if(UNIX AND NOT APPLE) endif() if(WITH_OPENIMAGEIO) - # use lib dir if available and nothing else specified - if(LIBDIR AND NOT OPENIMAGEIO_ROOT_DIR) - set(OPENIMAGEIO_ROOT_DIR ${LIBDIR}/oiio) - endif() - find_package(OpenImageIO) set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${ZLIB_LIBRARIES} ${BOOST_LIBRARIES}) @@ -701,11 +674,6 @@ if(UNIX AND NOT APPLE) endif() if(WITH_OPENCOLORIO) - # use lib dir if available and nothing else specified - if(LIBDIR AND NOT OPENCOLORIO_ROOT_DIR) - set(OPENCOLORIO_ROOT_DIR ${LIBDIR}/ocio) - endif() - find_package(OpenColorIO) set(OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARIES}) @@ -718,14 +686,16 @@ if(UNIX AND NOT APPLE) endif() endif() + # XXX Maybe most of this section should go into an llvm module? 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 version if not specified + if(NOT LLVM_VERSION) + set(LLVM_VERSION "3.0") + endif() set(LLVM_STATIC YES) - if(EXISTS "${LLVM_DIRECTORY}/bin/llvm-config") - set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config") - else() - set(LLVM_CONFIG llvm-config) + FIND_PROGRAM(LLVM_CONFIG llvm-config-${LLVM_VERSION} HINTS ${LLVM_DIRECTORY}) + if(NOT LLVM_CONFIG) + FIND_PROGRAM(LLVM_CONFIG llvm-config HINTS ${LLVM_DIRECTORY}) endif() execute_process(COMMAND ${LLVM_CONFIG} --version OUTPUT_VARIABLE LLVM_VERSION @@ -742,6 +712,8 @@ if(UNIX AND NOT APPLE) message(STATUS "LLVM version = ${LLVM_VERSION}") message(STATUS "LLVM dir = ${LLVM_DIRECTORY}") message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") + set(LLVM_VERSION ${LLVM_VERSION} CACHE STRING "Version of LLVM to use") + set(LLVM_DIRECTORY ${LLVM_DIRECTORY} CACHE PATH "Path to the LLVM installation") if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR) if(LLVM_STATIC) @@ -928,7 +900,6 @@ elseif(WIN32) find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib) - # WARNING! depends on correct order of OSL libs linking list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} ${OSL_LIB_EXEC} ${OSL_LIB_QUERY}) find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include) find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin) @@ -943,8 +914,15 @@ elseif(WIN32) endif() endif() + if(WITH_LLVM) + set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation") + file(GLOB LLVM_LIBRARY ${LLVM_DIRECTORY}/lib/*.lib) + set(LLVM_STATIC YES) + endif() + + if(MSVC) - set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid) + set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid psapi) add_definitions(/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB) @@ -1113,23 +1091,23 @@ elseif(WIN32) if(MSVC10) set(BOOST_LIBPATH ${BOOST}/vc2010/lib) set(BOOST_POSTFIX "vc100-mt-s-1_49.lib") - set(BOOST_DEBUG_POSTFIX "vc100-mt-sgd-1_49.lib") + #set(BOOST_DEBUG_POSTFIX "vc100-mt-sgd-1_49.lib") else() set(BOOST_LIBPATH ${BOOST}/lib) set(BOOST_POSTFIX "vc90-mt-s-1_49.lib") - set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_49.lib") + #set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_49.lib") endif() set(BOOST_LIBRARIES optimized libboost_date_time-${BOOST_POSTFIX} optimized libboost_filesystem-${BOOST_POSTFIX} optimized libboost_regex-${BOOST_POSTFIX} - optimized libboost_system-${BOOST_POSTFIX} optimized libboost_thread-${BOOST_POSTFIX} - debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX} - debug libboost_regex-${BOOST_DEBUG_POSTFIX} - debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX}) + optimized libboost_system-${BOOST_POSTFIX} optimized libboost_thread-${BOOST_POSTFIX}) + #debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX} + #debug libboost_regex-${BOOST_DEBUG_POSTFIX} + #debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX} if(WITH_INTERNATIONAL) set(BOOST_LIBRARIES ${BOOST_LIBRARIES} - optimized libboost_locale-${BOOST_POSTFIX} - debug libboost_locale-${BOOST_DEBUG_POSTFIX}) + optimized libboost_locale-${BOOST_POSTFIX}) + #debug libboost_locale-${BOOST_DEBUG_POSTFIX} endif(WITH_INTERNATIONAL) set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") endif() @@ -1139,7 +1117,7 @@ elseif(WIN32) set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) set(OPENIMAGEIO_LIBRARIES OpenImageIO) set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) - set(OPENIMAGEIO_DEFINITIONS) + set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0") endif() if(WITH_OPENCOLORIO) @@ -1150,6 +1128,7 @@ elseif(WIN32) set(OPENCOLORIO_DEFINITIONS) endif() + set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib") # MSVC only, Mingw doesnt need diff --git a/SConstruct b/SConstruct index 4af85f51a4b..a765488d3f1 100644 --- a/SConstruct +++ b/SConstruct @@ -306,6 +306,11 @@ if env['OURPLATFORM']=='darwin': else: env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','Jackmp']) + if env['WITH_BF_CYCLES_OSL'] == 1: + # this is kinda hardcoded atm due not understood path issues, also look that we need 2 variants of passing the oslexec with the force_load option, why ? + env.Append(LINKFLAGS=['-L../lib/darwin-9.x.universal/osl/lib','-loslcomp','-force_load ../lib/darwin-9.x.universal/osl/lib/liboslexec.a','-loslquery']) + env.Append(BF_PROGRAM_LINKFLAGS=['-Xlinker','-force_load','-Xlinker','../lib/darwin-9.x.universal/osl/lib/liboslexec.a']) + if env['WITH_BF_OPENMP'] == 1: if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env['CCFLAGS'].append('/openmp') @@ -577,11 +582,11 @@ B.init_lib_dict() Export('env') -BuildDir(B.root_build_dir+'/source', 'source', duplicate=0) +VariantDir(B.root_build_dir+'/source', 'source', duplicate=0) SConscript(B.root_build_dir+'/source/SConscript') -BuildDir(B.root_build_dir+'/intern', 'intern', duplicate=0) +VariantDir(B.root_build_dir+'/intern', 'intern', duplicate=0) SConscript(B.root_build_dir+'/intern/SConscript') -BuildDir(B.root_build_dir+'/extern', 'extern', duplicate=0) +VariantDir(B.root_build_dir+'/extern', 'extern', duplicate=0) SConscript(B.root_build_dir+'/extern/SConscript') # now that we have read all SConscripts, we know what @@ -725,6 +730,22 @@ if env['OURPLATFORM']!='darwin': cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch) scriptinstall.append(env.Install(dir=dir,source=cubin_file)) + # osl shaders + if env['WITH_BF_CYCLES_OSL']: + dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader') + + osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path + oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders') + + headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split() + source=['intern/cycles/kernel/shaders/'+s for s in headers] + scriptinstall.append(env.Install(dir=dir,source=source)) + + for f in os.listdir(osl_source_dir): + if f.endswith('.osl'): + oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso')) + scriptinstall.append(env.Install(dir=dir,source=oso_file)) + if env['WITH_BF_OCIO']: colormanagement = os.path.join('release', 'datafiles', 'colormanagement') @@ -870,9 +891,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'): dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb.dll') dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb64.dll') - if env['WITH_BF_OIIO'] and env['OURPLATFORM'] != 'win32-mingw': - dllsources.append('${LCGDIR}/openimageio/bin/OpenImageIO.dll') - if env['WITH_BF_OCIO']: if not env['OURPLATFORM'] in ('win32-mingw', 'linuxcross'): dllsources.append('${LCGDIR}/opencolorio/bin/OpenColorIO.dll') diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 853f38610c2..7077b66fc5e 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -2,24 +2,68 @@ DISTRO="" SRC="$HOME/src/blender-deps" +INST="/opt/lib" CWD=$PWD +# OSL is horror for manual building even +# i would want it to be setteled for manual build first, +# and only then do it automatically +BUILD_OSL=false + THREADS=`cat /proc/cpuinfo | grep cores | uniq | sed -e "s/.*: *\(.*\)/\\1/"` +if [ -z "$THREADS" ]; then + THREADS=1 +fi PYTHON_VERSION="3.3.0" -BOOST_VERSION="1_51_0" -OIIO_VERSION="1.1.0" +PYTHON_VERSION_MIN="3.3" +PYTHON_SOURCE="http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.bz2" + +BOOST_VERSION="1.51.0" +_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'` +BOOST_SOURCE="http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download" +BOOST_VERSION_MIN="1.49" + OCIO_VERSION="1.0.7" +OCIO_SOURCE="https://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION" +OCIO_VERSION_MIN="1.0" + +OIIO_VERSION="1.1.1" +OIIO_SOURCE="https://github.com/OpenImageIO/oiio/tarball/Release-$OIIO_VERSION" +OIIO_VERSION_MIN="1.1" + +LLVM_VERSION="3.1" +LLVM_VERSION_MIN="3.0" +LLVM_VERSION_FOUND="" + +# OSL needs to be compiled for now! +OSL_VERSION="1.2.0" +OSL_SOURCE="https://github.com/mont29/OpenShadingLanguage/archive/blender-fixes.tar.gz" + FFMPEG_VERSION="1.0" +FFMPEG_SOURCE="http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" +FFMPEG_VERSION_MIN="0.7.6" _ffmpeg_list_sep=";" -HASXVID=false -XVIDDEV="" -HASVPX=false -HASMP3LAME=false -HASX264=false -HASOPENJPEG=false -HASSCHRO=false +# FFMPEG optional libs. +VORBIS_USE=false +VORBIS_DEV="" +SCHRO_USE=false +SCRHO_DEV="" +THEORA_USE=false +THEORA_DEV="" +XVID_USE=false +XVID_DEV="" +X264_USE=false +X264_DEV="" +X264_VERSION_MIN=0.118 +VPX_USE=false +VPX_VERSION_MIN=0.9.7 +VPX_DEV="" +MP3LAME_USE=false +MP3LAME_DEV="" +OPENJPEG_USE=false +OPENJPEG_DEV="" # Switch to english language, else some things (like check_package_DEB()) won't work! LANG_BACK=$LANG @@ -34,6 +78,48 @@ INFO() { echo "${@}" } +# Return 0 if $1 >= $2, else 1. +# $1 and $2 should be version numbers made of numbers only. +version_ge() { + # XXX Not yet perfect, won't always work as expected with e.g. 1.0.0 and 1.0... :/ + if [ "$1" != "$2" ] && + [ $(echo -e "$1\n$2" | sort --version-sort | head --lines=1) = "$1" ]; then + return 1 + else + return 0 + fi +} + +# Return 0 if $1 is into $2 (e.g. 3.3.2 is into 3.3, but not 3.3.0 or 3.3.5), else 1. +# $1 and $2 should be version numbers made of numbers only. +# $1 should be at least as long as $2! +version_match() { + backIFS=$IFS + IFS='.' + + # Split both version numbers into their numeric elements. + arr1=( $1 ) + arr2=( $2 ) + + ret=1 + + count1=${#arr1[@]} + count2=${#arr2[@]} + if [ $count1 -ge $count2 ]; then + ret=0 + for (( i=0; $i < $count2; i++ )) + do + if [ $(( 10#${arr1[$i]} )) -ne $(( 10#${arr2[$i]} )) ]; then + ret=1 + break + fi + done + fi + + IFS=$backIFS + return $ret +} + detect_distro() { if [ -f /etc/debian_version ]; then DISTRO="DEB" @@ -45,91 +131,161 @@ detect_distro() { } prepare_opt() { - INFO "Ensuring /opt/lib exists and writable by us" - sudo mkdir -p /opt/lib - sudo chown $USER /opt/lib - sudo chmod 775 /opt/lib + INFO "Ensuring $INST exists and is writable by us" + sudo mkdir -p $INST + sudo chown $USER $INST + sudo chmod 775 $INST +} + +# Check whether the current package needs to be recompiled, based on a dummy file containing a magic number in its name... +magic_compile_check() { + if [ -f $INST/.$1-magiccheck-$2 ]; then + return 0 + else + return 1 + fi +} + +magic_compile_set() { + rm -f $INST/.$1-magiccheck-* + touch $INST/.$1-magiccheck-$2 } compile_Python() { - if [ ! -d /opt/lib/python-$PYTHON_VERSION ]; then + # To be changed each time we make edits that would modify the compiled result! + py_magic=0 + + _src=$SRC/Python-$PYTHON_VERSION + _inst=$INST/python-$PYTHON_VERSION + + # Clean install if needed! + magic_compile_check python-$PYTHON_VERSION $py_magic + if [ $? -eq 1 ]; then + rm -rf $_inst + fi + + if [ ! -d $_inst ]; then INFO "Building Python-$PYTHON_VERSION" prepare_opt - if [ ! -d $SRC/Python-$PYTHON_VERSION ]; then + if [ ! -d $_src ]; then mkdir -p $SRC - wget -c http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.bz2 -P $SRC + wget -c $PYTHON_SOURCE -O $_src.tar.bz2 INFO "Unpacking Python-$PYTHON_VERSION" - tar -C $SRC -xf $SRC/Python-$PYTHON_VERSION.tar.bz2 + tar -C $SRC -xf $_src.tar.bz2 fi - cd $SRC/Python-$PYTHON_VERSION + cd $_src - ./configure --prefix=/opt/lib/python-$PYTHON_VERSION --enable-ipv6 \ + ./configure --prefix=$_inst --enable-ipv6 \ --enable-loadable-sqlite-extensions --with-dbmliborder=bdb \ --with-computed-gotos --with-pymalloc - make -j$THREADS - make install + make -j$THREADS && make install make clean - rm -f /opt/lib/python-3.3 - ln -s python-$PYTHON_VERSION /opt/lib/python-3.3 + if [ -d $_inst ]; then + rm -f $INST/python-3.3 + ln -s python-$PYTHON_VERSION $INST/python-3.3 + else + ERROR "Python--$PYTHON_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set python-$PYTHON_VERSION $py_magic cd $CWD + else + INFO "Own Python-$PYTHON_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories." fi } compile_Boost() { - INFO "Building boost" + # To be changed each time we make edits that would modify the compiled result! + boost_magic=7 - version_dots=`echo "$BOOST_VERSION" | sed -r 's/_/./g'` + _src=$SRC/boost-$BOOST_VERSION + _inst=$INST/boost-$BOOST_VERSION - if [ ! -d /opt/lib/boost-$version_dots ]; then - INFO "Building Boost-$version_dots" + # Clean install if needed! + magic_compile_check boost-$BOOST_VERSION $boost_magic + if [ $? -eq 1 ]; then + rm -rf $_inst + fi + + if [ ! -d $_inst ]; then + INFO "Building Boost-$BOOST_VERSION" prepare_opt - if [ ! -d $SRC/boost_$BOOST_VERSION ]; then - INFO "Downloading Boost-$version_dots" + if [ ! -d $_src ]; then + INFO "Downloading Boost-$BOOST_VERSION" mkdir -p $SRC - wget -c http://sourceforge.net/projects/boost/files/boost/$version_dots/boost_$BOOST_VERSION.tar.bz2/download \ - -O $SRC/boost_$BOOST_VERSION.tar.bz2 - tar -C $SRC -xf $SRC/boost_$BOOST_VERSION.tar.bz2 + wget -c $BOOST_SOURCE -O $_src.tar.bz2 + tar -C $SRC --transform "s,(.*/?)boost_1_[^/]+(.*),\1boost-$BOOST_VERSION\2,x" -xf $_src.tar.bz2 fi - cd $SRC/boost_$BOOST_VERSION - ./bootstrap.sh --with-libraries=system,filesystem,thread,regex,locale --prefix=/opt/lib/boost-$version_dots - ./b2 install + cd $_src + if [ ! -f $_src/b2 ]; then + ./bootstrap.sh + fi + ./b2 -j$THREADS -a --with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time \ + --prefix=$_inst --disable-icu boost.locale.icu=off install ./b2 --clean - rm -f /opt/lib/boost - ln -s boost-$version_dots /opt/lib/boost + if [ -d $_inst ]; then + rm -f $INST/boost + ln -s boost-$BOOST_VERSION $INST/boost + else + ERROR "Boost-$BOOST_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set boost-$BOOST_VERSION $boost_magic cd $CWD + else + INFO "Own Boost-$BOOST_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories." fi } compile_OCIO() { - if [ ! -d /opt/lib/ocio-$OCIO_VERSION ]; then + # To be changed each time we make edits that would modify the compiled result! + ocio_magic=1 + + _src=$SRC/OpenColorIO-$OCIO_VERSION + _inst=$INST/ocio-$OCIO_VERSION + + # Clean install if needed! + magic_compile_check ocio-$OCIO_VERSION $ocio_magic + if [ $? -eq 1 ]; then + rm -rf $_inst + fi + + if [ ! -d $_inst ]; then INFO "Building OpenColorIO-$OCIO_VERSION" prepare_opt - if [ ! -d $SRC/OpenColorIO-$OCIO_VERSION ]; then - INFO "Downloading OpenColorIO-$OCIO_VERSION" - mkdir -p $SRC - wget -c http://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION \ - -O $SRC/OpenColorIO-$OCIO_VERSION.tar.gz + if [ ! -d $_src ]; then + INFO "Downloading OpenColorIO-$OCIO_VERSION" + mkdir -p $SRC + wget -c $OCIO_SOURCE -O $_src.tar.gz - INFO "Unpacking OpenColorIO-$OCIO_VERSION" - tar -C "$SRC" -xf $SRC/OpenColorIO-$OCIO_VERSION.tar.gz - mv $SRC/imageworks-OpenColorIO* $SRC/OpenColorIO-$OCIO_VERSION + INFO "Unpacking OpenColorIO-$OCIO_VERSION" + tar -C $SRC --transform "s,(.*/?)imageworks-OpenColorIO[^/]*(.*),\1OpenColorIO-$OCIO_VERSION\2,x" \ + -xf $_src.tar.gz fi - cd $SRC/OpenColorIO-$OCIO_VERSION + cd $_src + # Always refresh the whole build! + if [ -d build ]; then + rm -rf build + fi mkdir build cd build @@ -140,147 +296,313 @@ compile_OCIO() { fi cmake -D CMAKE_BUILD_TYPE=Release \ - -D CMAKE_PREFIX_PATH=/opt/lib/ocio-$OCIO_VERSION \ - -D CMAKE_INSTALL_PREFIX=/opt/lib/ocio-$OCIO_VERSION \ - -D CMAKE_CXX_FLAGS="$cflags" \ - -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" \ - .. + -D CMAKE_PREFIX_PATH=$_inst \ + -D CMAKE_INSTALL_PREFIX=$_inst \ + -D CMAKE_CXX_FLAGS="$cflags" \ + -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" \ + .. - make -j$THREADS - make install + make -j$THREADS && make install - # Force linking against sttaic libs - rm -f /opt/lib/ocio-$OCIO_VERSION/lib/*.so* + # Force linking against static libs + rm -f $_inst/lib/*.so* # Additional depencencies - cp ext/dist/lib/libtinyxml.a /opt/lib/ocio-$OCIO_VERSION/lib - cp ext/dist/lib/libyaml-cpp.a /opt/lib/ocio-$OCIO_VERSION/lib + cp ext/dist/lib/libtinyxml.a $_inst/lib + cp ext/dist/lib/libyaml-cpp.a $_inst/lib make clean - rm -f /opt/lib/ocio - ln -s ocio-$OCIO_VERSION /opt/lib/ocio + if [ -d $_inst ]; then + rm -f $INST/ocio + ln -s ocio-$OCIO_VERSION $INST/ocio + else + ERROR "OpenColorIO-$OCIO_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set ocio-$OCIO_VERSION $ocio_magic cd $CWD + else + INFO "Own OpenColorIO-$OCIO_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories." fi } compile_OIIO() { - if [ ! -d /opt/lib/oiio-$OIIO_VERSION ]; then + # To be changed each time we make edits that would modify the compiled result! + oiio_magic=5 + + _src=$SRC/OpenImageIO-$OIIO_VERSION + _inst=$INST/oiio-$OIIO_VERSION + + # Clean install if needed! + magic_compile_check oiio-$OIIO_VERSION $oiio_magic + if [ $? -eq 1 ]; then + rm -rf $_inst + fi + + if [ ! -d $_inst ]; then INFO "Building OpenImageIO-$OIIO_VERSION" prepare_opt - if [ ! -d $SRC/OpenImageIO-$OIIO_VERSION ]; then - wget -c https://github.com/OpenImageIO/oiio/tarball/Release-$OIIO_VERSION \ - -O "$SRC/OpenImageIO-$OIIO_VERSION.tar.gz" + if [ ! -d $_src ]; then + wget -c $OIIO_SOURCE -O "$_src.tar.gz" INFO "Unpacking OpenImageIO-$OIIO_VERSION" - tar -C $SRC -xf $SRC/OpenImageIO-$OIIO_VERSION.tar.gz - mv $SRC/OpenImageIO-oiio* $SRC/OpenImageIO-$OIIO_VERSION + tar -C $SRC --transform "s,(.*/?)OpenImageIO-oiio[^/]*(.*),\1OpenImageIO-$OIIO_VERSION\2,x" \ + -xf $_src.tar.gz + + cd $_src + + # XXX Ugly patching hack! + cat << EOF | patch -p1 +diff --git a/src/libutil/SHA1.cpp b/src/libutil/SHA1.cpp +index b9e6c8b..c761185 100644 +--- a/src/libutil/SHA1.cpp ++++ b/src/libutil/SHA1.cpp +@@ -8,9 +8,9 @@ + + // If compiling with MFC, you might want to add #include "StdAfx.h" + ++#include "SHA1.h" + #include "hash.h" + #include "dassert.h" +-#include "SHA1.h" + + #ifdef SHA1_UTILITY_FUNCTIONS + #define SHA1_MAX_FILE_BUFFER 8000 +EOF + fi - cd $SRC/OpenImageIO-$OIIO_VERSION + cd $_src + # Always refresh the whole build! + if [ -d build ]; then + rm -rf build + fi mkdir build cd build - if [ -d /opt/lib/boost ]; then - boost_root="/opt/lib/boost" - else - boost_root="/usr" + cmake_d="-D CMAKE_BUILD_TYPE=Release \ + -D CMAKE_PREFIX_PATH=$_inst \ + -D CMAKE_INSTALL_PREFIX=$_inst \ + -D BUILDSTATIC=ON" + + if [ -d $INST/boost ]; then + cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON" fi + # Looks like we do not need ocio in oiio for now... +# if [ -d $INST/ocio ]; then +# cmake_d="$cmake_d -D OCIO_PATH=$INST/ocio" +# fi + if file /bin/cp | grep -q '32-bit'; then cflags="-fPIC -m32 -march=i686" else cflags="-fPIC" fi - cmake -D CMAKE_BUILD_TYPE=Release \ - -D CMAKE_PREFIX_PATH=/opt/lib/oiio-$OIIO_VERSION \ - -D CMAKE_INSTALL_PREFIX=/opt/lib/oiio-$OIIO_VERSION \ - -D BUILDSTATIC=ON \ - -D CMAKE_CXX_FLAGS="$cflags" \ - -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" \ - -D BOOST_ROOT="$boost_root" \ - ../src + cmake $cmake_d -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" ../src - make -j$THREADS - make install + make -j$THREADS && make install make clean - rm -f /opt/lib/oiio - ln -s oiio-$OIIO_VERSION /opt/lib/oiio + if [ -d $_inst ]; then + rm -f $INST/oiio + ln -s oiio-$OIIO_VERSION $INST/oiio + else + ERROR "OpenImageIO-$OIIO_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set oiio-$OIIO_VERSION $oiio_magic cd $CWD + else + INFO "Own OpenImageIO-$OIIO_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories." + fi +} + +compile_OSL() { + # To be changed each time we make edits that would modify the compiled result! + osl_magic=5 + + _src=$SRC/OpenShadingLanguage-$OSL_VERSION + _inst=$INST/osl-$OSL_VERSION + + # Clean install if needed! + magic_compile_check osl-$OSL_VERSION $osl_magic + if [ $? -eq 1 ]; then + rm -rf $_inst + fi + + if [ ! -d $_inst ]; then + INFO "Building OpenShadingLanguage-$OSL_VERSION" + + prepare_opt + + if [ ! -d $_src ]; then + # XXX Using git on my own repo for now, looks like archives are not updated immediately... :/ +# wget -c $OSL_SOURCE -O "$_src.tar.gz" + +# INFO "Unpacking OpenShadingLanguage-$OSL_VERSION" +# tar -C $SRC --transform "s,(.*/?)OpenShadingLanguage-[^/]*(.*),\1OpenShadingLanguage-$OSL_VERSION\2,x" \ +# -xf $_src.tar.gz + git clone https://github.com/mont29/OpenShadingLanguage.git $_src + cd $_src + git checkout blender-fixes + cd $CWD + fi + + cd $_src + # XXX For now, always update from latest repo... + git checkout . + + # Always refresh the whole build! + if [ -d build ]; then + rm -rf build + fi + mkdir build + cd build + + cmake_d="-D CMAKE_BUILD_TYPE=Release" + cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" + cmake_d="$cmake_d -D BUILDSTATIC=ON" + cmake_d="$cmake_d -D BUILD_TESTING=OFF" + + if [ -d $INST/boost ]; then + cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost" + fi + + if [ -d $INST/oiio ]; then + cmake_d="$cmake_d -D OPENIMAGEIOHOME=$INST/oiio" + fi + + if [ ! -z $LLVM_VERSION_FOUND ]; then + cmake_d="$cmake_d -D LLVM_VERSION=$LLVM_VERSION_FOUND" + fi + + cmake $cmake_d ../src + + make -j$THREADS && make install + make clean + + if [ -d $_inst ]; then + rm -f $INST/osl + ln -s osl-$OSL_VERSION $INST/osl + else + ERROR "OpenShadingLanguage-$OSL_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set osl-$OSL_VERSION $osl_magic + + cd $CWD + else + INFO "Own OpenShadingLanguage-$OSL_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories." fi } compile_FFmpeg() { - if [ ! -d /opt/lib/ffmpeg-$FFMPEG_VERSION ]; then - INFO "Building FFmpeg-$FFMPEG_VERSION" + # To be changed each time we make edits that would modify the compiled result! + ffmpeg_magic=0 + + _src=$SRC/ffmpeg-$FFMPEG_VERSION + _inst=$INST/ffmpeg-$FFMPEG_VERSION + + # Clean install if needed! + magic_compile_check ffmpeg-$FFMPEG_VERSION $ffmpeg_magic + if [ $? -eq 1 ]; then + rm -rf $_inst + fi + + if [ ! -d $_inst ]; then + INFO "Building ffmpeg-$FFMPEG_VERSION" prepare_opt - if [ ! -d $SRC/ffmpeg-$FFMPEG_VERSION ]; then - INFO "Downloading FFmpeg-$FFMPEG_VERSION" - wget -c http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2 -P $SRC + if [ ! -d $_src ]; then + INFO "Downloading ffmpeg-$FFMPEG_VERSION" + wget -c $FFMPEG_SOURCE -O "$_src.tar.bz2" - INFO "Unpacking FFmpeg-$FFMPEG_VERSION" - tar -C $SRC -xf $SRC/ffmpeg-$FFMPEG_VERSION.tar.bz2 + INFO "Unpacking ffmpeg-$FFMPEG_VERSION" + tar -C $SRC -xf $_src.tar.bz2 fi - cd $SRC/ffmpeg-$FFMPEG_VERSION + cd $_src extra="" - if $HASXVID; then - extra="$extra --enable-libxvid" + if $VORBIS_USE; then + extra="$extra --enable-libvorbis" fi - if $HASVPX; then - extra="$extra --enable-libvpx" + if $THEORA_USE; then + extra="$extra --enable-libtheora" fi - if $HASMP3LAME; then - extra="$extra --enable-libmp3lame" - fi - - if $HASX264; then - extra="$extra --enable-libx264" - fi - - if $HASOPENJPEG; then - extra="$extra --enable-libopenjpeg" - fi - - if $HASSCHRO; then + if $SCHRO_USE; then extra="$extra --enable-libschroedinger" fi + if $XVID_USE; then + extra="$extra --enable-libxvid" + fi + + if $X264_USE; then + extra="$extra --enable-libx264" + fi + + if $VPX_USE; then + extra="$extra --enable-libvpx" + fi + + if $MP3LAME_USE; then + extra="$extra --enable-libmp3lame" + fi + + if $OPENJPEG_USE; then + extra="$extra --enable-libopenjpeg" + fi + ./configure --cc="gcc -Wl,--as-needed" --extra-ldflags="-pthread -static-libgcc" \ - --prefix=/opt/lib/ffmpeg-$FFMPEG_VERSION --enable-static --enable-avfilter --disable-vdpau \ - --disable-bzlib --disable-libgsm --disable-libspeex --enable-libtheora \ - --enable-libvorbis --enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \ + --prefix=$_inst --enable-static --enable-avfilter --disable-vdpau \ + --disable-bzlib --disable-libgsm --disable-libspeex \ + --enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \ --disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \ --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \ --disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \ --disable-outdev=alsa --disable-indev=sdl --disable-indev=alsa --disable-indev=jack \ --disable-indev=lavfi $extra - make -j$THREADS - make install + make -j$THREADS && make install make clean - rm -f /opt/lib/ffmpeg - ln -s ffmpeg-$FFMPEG_VERSION /opt/lib/ffmpeg + if [ -d $_inst ]; then + rm -f $INST/ffmpeg + ln -s ffmpeg-$FFMPEG_VERSION $INST/ffmpeg + else + ERROR "FFmpeg-$FFMPEG_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set ffmpeg-$FFMPEG_VERSION $ffmpeg_magic cd $CWD + else + INFO "Own ffmpeg-$FFMPEG_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories." fi } -deb_version() { - dpkg-query -W -f '${Version}' $1 | sed -r 's/^([0-9]\.[0-9]+).*/\1/' +get_package_version_DEB() { + dpkg-query -W -f '${Version}' $1 | sed -r 's/.*:\s*([0-9]+:)(([0-9]+\.?)+).*/\2/' } check_package_DEB() { @@ -293,58 +615,93 @@ check_package_DEB() { fi } +check_package_version_match_DEB() { + v=`apt-cache policy $1 | grep 'Candidate:' | sed -r 's/.*:\s*([0-9]+:)(([0-9]+\.?)+).*/\2/'` + + if [ -z "$v" ]; then + return 1 + fi + + version_match $v $2 + return $? +} + +check_package_version_ge_DEB() { + v=`apt-cache policy $1 | grep 'Candidate:' | sed -r 's/.*:\s*([0-9]+:)?(([0-9]+\.?)+).*/\2/'` + + if [ -z "$v" ]; then + return 1 + fi + + version_ge $v $2 + return $? +} + install_DEB() { - INFO "Installing dependencies for DEB-based distributive" + INFO "" + INFO "Installing dependencies for DEB-based distribution" + INFO "Source code of dependencies needed to be compiled will be downloaded and extracted into $SRC" + INFO "Built libs of dependencies needed to be compiled will be installed into $INST" + INFO "Please edit \$SRC and/or \$INST variables at the begining of this script if you want to use other paths!" + INFO "" sudo apt-get update - sudo apt-get -y upgrade +# XXX Why in hell? Let's let this stuff to the user's responsability!!! +# sudo apt-get -y upgrade - sudo apt-get install -y cmake scons gcc g++ libjpeg-dev libpng-dev libtiff-dev \ + # These libs should always be available in debian/ubuntu official repository... + OPENJPEG_DEV="libopenjpeg-dev" + SCHRO_DEV="libschroedinger-dev" + VORBIS_DEV="libvorbis-dev" + THEORA_DEV="libtheora-dev" + + sudo apt-get install -y gawk cmake scons gcc g++ libjpeg-dev libpng-dev libtiff-dev \ libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev libncurses5-dev \ - libssl-dev liblzma-dev libreadline-dev libopenjpeg-dev libopenexr-dev libopenal-dev \ - libglew-dev yasm libschroedinger-dev libtheora-dev libvorbis-dev libsdl1.2-dev \ + libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV libopenexr-dev libopenal-dev \ + libglew-dev yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV libsdl1.2-dev \ libfftw3-dev libjack-dev python-dev patch - HASOPENJPEG=true - HASSCHRO=true + OPENJPEG_USE=true + SCHRO_USE=true + VORBIS_USE=true + THEORA_USE=true - check_package_DEB libxvidcore-dev + # Grmpf, debian is libxvidcore-dev and ubuntu libxvidcore4-dev! + XVID_DEV="libxvidcore-dev" + check_package_DEB $XVID_DEV if [ $? -eq 0 ]; then - sudo apt-get install -y libxvidcore-dev - HASXVID=true - XVIDDEV="libxvidcore-dev" - fi - - check_package_DEB libxvidcore4-dev - if [ $? -eq 0 ]; then - sudo apt-get install -y libxvidcore4-dev - HASXVID=true - XVIDDEV="libxvidcore4-dev" - fi - - check_package_DEB libmp3lame-dev - if [ $? -eq 0 ]; then - sudo apt-get install -y libmp3lame-dev - HASMP3LAME=true - fi - - check_package_DEB libx264-dev - if [ $? -eq 0 ]; then - sudo apt-get install -y libx264-dev - HASX264=true - fi - - check_package_DEB libvpx-dev - if [ $? -eq 0 ]; then - sudo apt-get install -y libvpx-dev - vpx_version=`deb_version libvpx-dev` - if [ ! -z "$vpx_version" ]; then - if dpkg --compare-versions $vpx_version gt 0.9.7; then - HASVPX=true - fi + sudo apt-get install -y $XVID_DEV + XVID_USE=true + else + XVID_DEV="libxvidcore4-dev" + check_package_DEB $XVID_DEV + if [ $? -eq 0 ]; then + sudo apt-get install -y $XVID_DEV + XVID_USE=true fi fi + MP3LAME_DEV="libmp3lame-dev" + check_package_DEB $MP3LAME_DEV + if [ $? -eq 0 ]; then + sudo apt-get install -y $MP3LAME_DEV + MP3LAME_USE=true + fi + + X264_DEV="libx264-dev" + check_package_version_ge_DEB $X264_DEV $X264_VERSION_MIN + if [ $? -eq 0 ]; then + sudo apt-get install -y $X264_DEV + X264_USE=true + fi + + VPX_DEV="libvpx-dev" + check_package_version_ge_DEB $VPX_DEV $VPX_VERSION_MIN + if [ $? -eq 0 ]; then + sudo apt-get install -y $VPX_DEV + VPX_USE=true + fi + check_package_DEB libspnav-dev if [ $? -eq 0 ]; then sudo apt-get install -y libspnav-dev @@ -357,16 +714,17 @@ install_DEB() { compile_Python fi - check_package_DEB libboost-dev + check_package_version_ge_DEB libboost-dev $BOOST_VERSION_MIN if [ $? -eq 0 ]; then sudo apt-get install -y libboost-dev - boost_version=`deb_version libboost-dev` + boost_version=`get_package_version_DEB libboost-dev` check_package_DEB libboost-locale$boost_version-dev if [ $? -eq 0 ]; then sudo apt-get install -y libboost-locale$boost_version-dev libboost-filesystem$boost_version-dev \ - libboost-regex$boost_version-dev libboost-system$boost_version-dev libboost-thread$boost_version-dev + libboost-regex$boost_version-dev libboost-system$boost_version-dev \ + libboost-thread$boost_version-dev else compile_Boost fi @@ -374,26 +732,50 @@ install_DEB() { compile_Boost fi - check_package_DEB libopencolorio-dev + check_package_version_ge_DEB libopencolorio-dev $OCIO_VERSION_MIN if [ $? -eq 0 ]; then sudo apt-get install -y libopencolorio-dev else compile_OCIO fi - check_package_DEB libopenimageio-dev + check_package_version_ge_DEB libopenimageio-dev $OIIO_VERSION_MIN if [ $? -eq 0 ]; then sudo apt-get install -y libopenimageio-dev else compile_OIIO fi + if $BUILD_OSL; then + have_llvm=false + + check_package_DEB llvm-$LLVM_VERSION-dev + if [ $? -eq 0 ]; then + sudo apt-get install -y llvm-$LLVM_VERSION-dev + have_llvm=true + LLVM_VERSION_FOUND=$LLVM_VERSION + else + check_package_DEB llvm-$LLVM_VERSION_MIN-dev + if [ $? -eq 0 ]; then + sudo apt-get install -y llvm-$LLVM_VERSION_MIN-dev + have_llvm=true + LLVM_VERSION_FOUND=$LLVM_VERSION_MIN + fi + fi + + if $have_llvm; then + sudo apt-get install -y clang flex bison libtbb-dev git + # No package currently! + compile_OSL + fi + fi + # XXX Debian features libav packages as ffmpeg, those are not really compatible with blender code currently :/ # So for now, always build our own ffmpeg. # check_package_DEB ffmpeg # if [ $? -eq 0 ]; then # sudo apt-get install -y ffmpeg -# ffmpeg_version=`deb_version ffmpeg` +# ffmpeg_version=`get_package_version_DEB ffmpeg` # INFO "ffmpeg version: $ffmpeg_version" # if [ ! -z "$ffmpeg_version" ]; then # if dpkg --compare-versions $ffmpeg_version gt 0.7.2; then @@ -406,6 +788,10 @@ install_DEB() { compile_FFmpeg } +get_package_version_RPM() { + yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/' +} + check_package_RPM() { r=`yum info $1 | grep -c 'Summary'` @@ -416,62 +802,143 @@ check_package_RPM() { fi } -check_package_version_RPM() { +check_package_version_match_RPM() { v=`yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'` - # for now major and minor versions only (as if x.y, not x.y.z) - r=`echo $v | grep -c $2` - - if [ $r -ge 1 ]; then - return 0 - else + if [ -z "$v" ]; then return 1 fi + + version_match $v $2 + return $? +} + +check_package_version_ge_RPM() { + v=`yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'` + + if [ -z "$v" ]; then + return 1 + fi + + version_ge $v $2 + return $? } install_RPM() { - INFO "Installing dependencies for RPM-based distributive" + INFO "" + INFO "Installing dependencies for RPM-based distribution" + INFO "Source code of dependencies needed to be compiled will be downloaded and extracted into $SRC" + INFO "Built libs of dependencies needed to be compiled will be installed into $INST" + INFO "Please edit \$SRC and/or \$INST variables at the begining of this script if you want to use other paths!" + INFO "" sudo yum -y update - sudo yum -y install gcc gcc-c++ cmake scons libpng-devel libtiff-devel \ + # These libs should always be available in debian/ubuntu official repository... + OPENJPEG_DEV="openjpeg-devel" + SCHRO_DEV="schroedinger-devel" + VORBIS_DEV="libvorbis-devel" + THEORA_DEV="libtheora-devel" + + sudo yum -y install gawk gcc gcc-c++ cmake scons libpng-devel libtiff-devel \ freetype-devel libX11-devel libXi-devel wget libsqlite3x-devel ncurses-devel \ - readline-devel openjpeg-devel openexr-devel openal-soft-devel \ - glew-devel yasm schroedinger-devel libtheora-devel libvorbis-devel SDL-devel \ - fftw-devel lame-libs jack-audio-connection-kit-devel x264-devel libspnav-devel \ + readline-devel $OPENJPEG_DEV openexr-devel openal-soft-devel \ + glew-devel yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV SDL-devel \ + fftw-devel lame-libs jack-audio-connection-kit-devel libspnav-devel \ libjpeg-devel patch python-devel - HASOPENJPEG=true - HASSCHRO=true + OPENJPEG_USE=true + SCHRO_USE=true + VORBIS_USE=true + THEORA_USE=true - check_package_version_RPM python-devel 3.3. + X264_DEV="x264-devel" + check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN if [ $? -eq 0 ]; then - sudo yum install -y python-devel + sudo yum install -y $X264_DEV + X264_USE=true + fi + + XVID_DEV="xvidcore-devel" + check_package_RPM $XVID_DEV + if [ $? -eq 0 ]; then + sudo yum install -y $XVID_DEV + XVID_USE=true + fi + + VPX_DEV="libvpx-devel" + check_package_version_ge_RPM $VPX_DEV $VPX_VERSION_MIN + if [ $? -eq 0 ]; then + sudo yum install -y $VPX_DEV + VPX_USE=true + fi + + MP3LAME_DEV="lame-devel" + check_package_RPM $MP3LAME_DEV + if [ $? -eq 0 ]; then + sudo yum install -y $MP3LAME_DEV + MP3LAME_USE=true + fi + + check_package_version_match_RPM python3-devel $PYTHON_VERSION_MIN + if [ $? -eq 0 ]; then + sudo yum install -y python3-devel else compile_Python fi - check_package_RPM boost-devel + check_package_version_ge_RPM boost-devel $BOOST_VERSION_MIN if [ $? -eq 0 ]; then sudo yum install -y boost-devel else compile_Boost fi - check_package_RPM OpenColorIO-devel + check_package_version_ge_RPM OpenColorIO-devel $OCIO_VERSION_MIN if [ $? -eq 0 ]; then sudo yum install -y OpenColorIO-devel else compile_OCIO fi - check_package_RPM OpenImageIO-devel + check_package_version_ge_RPM OpenImageIO-devel $OIIO_VERSION_MIN if [ $? -eq 0 ]; then sudo yum install -y OpenImageIO-devel else compile_OIIO fi + if $BUILD_OSL; then + have_llvm=false + + check_package_RPM llvm-$LLVM_VERSION-devel + if [ $? -eq 0 ]; then + sudo yum install -y llvm-$LLVM_VERSION-devel + have_llvm=true + LLVM_VERSION_FOUND=$LLVM_VERSION + else + check_package_RPM llvm-$LLVM_VERSION_MIN-devel + if [ $? -eq 0 ]; then + sudo yum install -y llvm-$LLVM_VERSION_MIN-devel + have_llvm=true + LLVM_VERSION_FOUND=$LLVM_VERSION_MIN + else + check_package_version_ge_RPM llvm-devel $LLVM_VERSION_MIN + if [ $? -eq 0 ]; then + sudo yum install -y llvm-devel + have_llvm=true + LLVM_VERSION_FOUND=`get_package_version_RPM llvm-devel` + fi + fi + fi + + if $have_llvm; then + sudo yum install -y flex bison clang tbb-devel git + # No package currently! + compile_OSL + fi + fi + # Always for now, not sure which packages should be installed compile_FFmpeg } @@ -500,7 +967,12 @@ check_package_version_SUSE() { } install_SUSE() { - INFO "Installing dependencies for SuSE-based distributive" + INFO "" + INFO "Installing dependencies for SuSE-based distribution" + INFO "Source code of dependencies needed to be compiled will be downloaded and extracted into $SRC" + INFO "Built libs of dependencies needed to be compiled will be installed into $INST" + INFO "Please edit \$SRC and/or \$INST variables at the begining of this script if you want to use other paths!" + INFO "" sudo zypper --non-interactive update --auto-agree-with-licenses @@ -526,33 +998,11 @@ install_SUSE() { } print_info_ffmpeglink_DEB() { - _packages="libtheora-dev" + dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }' +} - if $HASXVID; then - _packages="$_packages $XVIDDEV" - fi - - if $HASVPX; then - _packages="$_packages libvpx-dev" - fi - - if $HASMP3LAME; then - _packages="$_packages libmp3lame-dev" - fi - - if $HASX264; then - _packages="$_packages libx264-dev" - fi - - if $HASOPENJPEG; then - _packages="$_packages libopenjpeg-dev" - fi - - if $HASSCHRO; then - _packages="$_packages libschroedinger-dev" - fi - - dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.so" | awk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }' +print_info_ffmpeglink_RPM() { + rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }' } print_info_ffmpeglink() { @@ -560,12 +1010,49 @@ print_info_ffmpeglink() { if [ -z "$DISTRO" ]; then ERROR "Failed to detect distribution type" exit 1 - elif [ "$DISTRO" = "DEB" ]; then + fi + + # Create list of packages from which to get libs names... + _packages="" + + if $THEORA_USE; then + _packages="$_packages $THEORA_DEV" + fi + + if $VORBIS_USE; then + _packages="$_packages $VORBIS_DEV" + fi + + if $XVID_USE; then + _packages="$_packages $XVID_DEV" + fi + + if $VPX_USE; then + _packages="$_packages $VPX_DEV" + fi + + if $MP3LAME_USE; then + _packages="$_packages $MP3LAME_DEV" + fi + + if $X264_USE; then + _packages="$_packages $X264_DEV" + fi + + if $OPENJPEG_USE; then + _packages="$_packages $OPENJPEG_DEV" + fi + + if $SCHRO_USE; then + _packages="$_packages $SCHRO_DEV" + fi + + if [ "$DISTRO" = "DEB" ]; then print_info_ffmpeglink_DEB + elif [ "$DISTRO" = "RPM" ]; then + print_info_ffmpeglink_RPM # XXX TODO! else INFO "" -# elif [ "$DISTRO" = "RPM" ]; then -# print_info_ffmpeglink_RPM # elif [ "$DISTRO" = "SUSE" ]; then # print_info_ffmpeglink_SUSE fi @@ -575,42 +1062,57 @@ print_info() { INFO "" INFO "If you're using CMake add this to your configuration flags:" - if [ -d /opt/lib/boost ]; then - INFO " -D BOOST_ROOT=/opt/lib/boost" + if [ -d $INST/boost ]; then + INFO " -D BOOST_ROOT=$INST/boost" INFO " -D Boost_NO_SYSTEM_PATHS=ON" fi - if [ -d /opt/lib/ffmpeg ]; then + if [ -d $INST/osl ]; then + INFO " -D CYCLES_OSL=$INST/osl" + INFO " -D WITH_CYCLES_OSL=ON" + INFO " -D LLVM_VERSION=$LLVM_VERSION_FOUND" + fi + + if [ -d $INST/ffmpeg ]; then INFO " -D WITH_CODEC_FFMPEG=ON" - INFO " -D FFMPEG=/opt/lib/ffmpeg" - INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;`print_info_ffmpeglink`'" + INFO " -D FFMPEG=$INST/ffmpeg" + INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'" fi INFO "" INFO "If you're using SCons add this to your user-config:" - if [ -d /opt/lib/python-3.3 ]; then - INFO "BF_PYTHON='/opt/lib/python-3.3'" - INFO "BF_PYTHON_ABI_FLAGS='m'" + if [ -d $INST/python-3.3 ]; then + INFO "BF_PYTHON = '$INST/python-3.3'" + INFO "BF_PYTHON_ABI_FLAGS = 'm'" fi - if [ -d /opt/lib/ocio ]; then - INFO "BF_OCIO='/opt/lib/ocio'" + if [ -d $INST/ocio ]; then + INFO "BF_OCIO = '$INST/ocio'" fi - if [ -d /opt/lib/oiio ]; then - INFO "BF_OIIO='/opt/lib/oiio'" + if [ -d $INST/oiio ]; then + INFO "BF_OIIO = '$INST/oiio'" fi - if [ -d /opt/lib/boost ]; then - INFO "BF_BOOST='/opt/lib/boost'" + if [ -d $INST/boost ]; then + INFO "BF_BOOST = '$INST/boost'" fi - if [ -d /opt/lib/ffmpeg ]; then - INFO "BF_FFMPEG='/opt/lib/ffmpeg'" + if [ -d $INST/ffmpeg ]; then + INFO "BF_FFMPEG = '$INST/ffmpeg'" _ffmpeg_list_sep=" " - INFO "BF_FFMPEG_LIB='avformat avcodec swscale avutil avdevice `print_info_ffmpeglink`'" + INFO "BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice `print_info_ffmpeglink`'" fi + + INFO "" + INFO "" + INFO "WARNING: If this script had to build boost into $INST, and you are dynamically linking " + INFO " blender against it, you will have to run those commands as root user:" + INFO "" + INFO " echo \"$INST/boost/lib\" > /etc/ld.so.conf.d/boost.conf" + INFO " ldconfig" + INFO "" } # Detect distributive type used on this machine diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index e0e55909138..2b1af356773 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -120,6 +120,24 @@ BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' +WITH_BF_CYCLES_OSL = True +WITH_BF_STATICOSL = False +BF_OSL = '/opt/lib/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +BF_OSL_LIB = 'oslcomp oslexec oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + +WITH_BF_LLVM = True +WITH_BF_STATICLLVM = False +BF_LLVM = '/opt/lib/llvm-3.1' +BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ + 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ + 'LLVMTarget LLVMMC LLVMCore LLVMSupport' +BF_LLVM_LIBPATH = '${BF_LLVM}/lib' + # Color management WITH_BF_OCIO = True WITH_BF_STATICOCIO = True @@ -144,3 +162,4 @@ WITH_BF_OCEANSIM = True BF_DEBUG = False REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-lrt'] +BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive'] diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py index afff0451d5b..dbae44af66f 100644 --- a/build_files/buildbot/config/user-config-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py @@ -119,6 +119,24 @@ BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' +WITH_BF_CYCLES_OSL = True +WITH_BF_STATICOSL = False +BF_OSL = '/opt/lib/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +BF_OSL_LIB = 'oslcomp oslexec oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + +WITH_BF_LLVM = True +WITH_BF_STATICLLVM = False +BF_LLVM = '/opt/lib/llvm-3.1' +BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ + 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ + 'LLVMTarget LLVMMC LLVMCore LLVMSupport' +BF_LLVM_LIBPATH = '${BF_LLVM}/lib' + # Color management WITH_BF_OCIO = True WITH_BF_STATICOCIO = True @@ -143,3 +161,4 @@ WITH_BF_OCEANSIM = True BF_DEBUG = False REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-lrt'] +BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive'] diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py index ec04533ecb3..c8e144e8a7f 100644 --- a/build_files/buildbot/config/user-config-glibc27-i686.py +++ b/build_files/buildbot/config/user-config-glibc27-i686.py @@ -107,6 +107,24 @@ BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' +WITH_BF_CYCLES_OSL = True +WITH_BF_STATICOSL = False +BF_OSL = '/opt/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +BF_OSL_LIB = 'oslcomp oslexec oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + +WITH_BF_LLVM = True +WITH_BF_STATICLLVM = False +BF_LLVM = '/opt/llvm-3.1' +BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ + 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ + 'LLVMTarget LLVMMC LLVMCore LLVMSupport' +BF_LLVM_LIBPATH = '${BF_LLVM}/lib' + # Color management WITH_BF_OCIO = True WITH_BF_STATICOCIO = True @@ -129,3 +147,4 @@ WITH_BF_OCEANSIM = True BF_DEBUG = False REL_CCFLAGS = ['-O2'] # C & C++ PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] +BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive'] diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py index 37bc946918b..9541908d4ed 100644 --- a/build_files/buildbot/config/user-config-glibc27-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc27-x86_64.py @@ -106,6 +106,24 @@ BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' +WITH_BF_CYCLES_OSL = True +WITH_BF_STATICOSL = False +BF_OSL = '/opt/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +BF_OSL_LIB = 'oslcomp oslexec oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + +WITH_BF_LLVM = True +WITH_BF_STATICLLVM = False +BF_LLVM = '/opt/llvm-3.1' +BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ + 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ + 'LLVMTarget LLVMMC LLVMCore LLVMSupport' +BF_LLVM_LIBPATH = '${BF_LLVM}/lib' + # Color management WITH_BF_OCIO = True WITH_BF_STATICOCIO = True @@ -128,3 +146,4 @@ WITH_BF_OCEANSIM = True BF_DEBUG = False REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] +BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive'] diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index e9deade6e99..90f0c805f58 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -77,17 +77,18 @@ def svn_step(branch=''): def lib_svn_step(dir): return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, mode='update', defaultBranch='trunk', workdir='lib/' + dir) -def rsync_step(file_from, file_to): - return ShellCommand(name='rsync', command=['rsync', '-v', '-P', file_from, 'brecht@builder.blender.org:/data/buildbot-master/' + file_to], haltOnFailure=True, description=['rsync']) +def rsync_step(id, branch, rsync_script): + return ShellCommand(name='rsync', command=['python', rsync_script, id, branch], description='uploading', descriptionDone='uploaded', workdir='install') # generic builder def generic_builder(id, libdir='', branch='', rsync=False): - filename = 'buildbot_upload_' + id + '.zip' + filename = 'uploaded/buildbot_upload_' + id + '.zip' compile_script = '../blender/build_files/buildbot/slave_compile.py' test_script = '../blender/build_files/buildbot/slave_test.py' pack_script = '../blender/build_files/buildbot/slave_pack.py' + rsync_script = '../blender/build_files/buildbot/slave_rsync.py' unpack_script = 'master_unpack.py' f = BuildFactory() @@ -95,11 +96,11 @@ def generic_builder(id, libdir='', branch='', rsync=False): if libdir != '': f.addStep(lib_svn_step(libdir)) - f.addStep(Compile(command=['python', compile_script, id])) + f.addStep(Compile(command=['python', compile_script, id], timeout=3600)) f.addStep(Test(command=['python', test_script, id])) f.addStep(ShellCommand(name='package', command=['python', pack_script, id, branch], description='packaging', descriptionDone='packaged')) if rsync: - f.addStep(rsync_step('../install/buildbot_upload.zip', filename)) + f.addStep(rsync_step(id, branch, rsync_script)) elif id.find('cmake') != -1: f.addStep(FileUpload(name='upload', slavesrc='buildbot_upload.zip', masterdest=filename, maxsize=100 * 1024 * 1024)) else: @@ -109,7 +110,8 @@ def generic_builder(id, libdir='', branch='', rsync=False): # builders -add_builder(c, 'mac_x86_64_scons', '', generic_builder) +add_builder(c, 'mac_x86_64_10_6_scons', 'darwin-9.x.universal', generic_builder, '', True) +add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True) #add_builder(c, 'salad_mac_x86_64_scons', 'darwin-9.x.universal', generic_builder, 'soc-2011-salad') add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder) add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder) diff --git a/build_files/buildbot/slave_rsync.py b/build_files/buildbot/slave_rsync.py new file mode 100644 index 00000000000..aea1b65e333 --- /dev/null +++ b/build_files/buildbot/slave_rsync.py @@ -0,0 +1,45 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +# Runs on buildbot slave, rsync zip directly to buildbot server rather +# than using upload which is much slower + +import os +import sys + +# get builder name +if len(sys.argv) < 2: + sys.stderr.write("Not enough arguments, expecting builder name\n") + sys.exit(1) + +builder = sys.argv[1] + +# rsync, this assumes ssh keys are setup so no password is needed +local_zip = "buildbot_upload.zip" +remote_folder = "builder.blender.org:/data/buildbot-master/uploaded/" +remote_zip = remote_folder + "buildbot_upload_" + builder + ".zip" +command = "rsync -avz %s %s" % (local_zip, remote_zip) + +print(command) + +ret = os.system(command) +sys.exit(ret) + + diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py index 072bbb12fb3..83ebf927b3c 100755 --- a/build_files/cmake/cmake_consistency_check.py +++ b/build_files/cmake/cmake_consistency_check.py @@ -222,8 +222,8 @@ def cmake_get_src(f): ''' # reset - sources_h[:] = [] - sources_c[:] = [] + del sources_h[:] + del sources_c[:] filen.close() diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 2d9de5a5792..4f1d34f993c 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -700,7 +700,11 @@ macro(delayed_install destination) foreach(f ${files}) - set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f}) + if(IS_ABSOLUTE ${f}) + set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${f}) + else() + set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f}) + endif() set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination}) endforeach() endmacro() diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index b89f3f92cfe..3c051dbe242 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -276,24 +276,42 @@ BF_PCRE_LIBPATH = '${BF_PCRE}/lib' # Cycles WITH_BF_CYCLES = True +#OSL + +WITH_BF_CYCLES_OSL = True +BF_OSL = LIBDIR + '/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +#BF_OSL_LIB = 'oslcomp oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + +WITH_BF_LLVM = True +BF_LLVM = LIBDIR + '/llvm' +BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ + 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ + 'LLVMTarget LLVMMC LLVMCore LLVMSupport' +BF_LLVM_LIBPATH = '${BF_LLVM}/lib' + WITH_BF_OIIO = True BF_OIIO = LIBDIR + '/openimageio' -BF_OIIO_INC = BF_OIIO + '/include' +BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB = 'OpenImageIO' -BF_OIIO_LIBPATH = BF_OIIO + '/lib' +BF_OIIO_LIBPATH = '${BF_OIIO}/lib' WITH_BF_OCIO = True BF_OCIO = LIBDIR + '/opencolorio' -BF_OCIO_INC = BF_OCIO + '/include' +BF_OCIO_INC = '${BF_OCIO}/include' BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp' -BF_OCIO_LIBPATH = BF_OCIO + '/lib' +BF_OCIO_LIBPATH = '${BF_OCIO}/lib' WITH_BF_BOOST = True BF_BOOST = LIBDIR + '/boost' -BF_BOOST_INC = BF_BOOST + '/include' +BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt' BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt' -BF_BOOST_LIBPATH = BF_BOOST + '/lib' +BF_BOOST_LIBPATH = '${BF_BOOST}/lib' WITH_BF_CYCLES_CUDA_BINARIES = False BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc' diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py index 9ffe67e6b48..0ffd9ca9cc6 100644 --- a/build_files/scons/config/linux-config.py +++ b/build_files/scons/config/linux-config.py @@ -204,9 +204,9 @@ BF_OIIO = LIBDIR + '/oiio' if not os.path.exists(LCGDIR + '/oiio'): WITH_BF_OIIO = False BF_OIIO = '/usr' -BF_OIIO_INC = BF_OIIO + '/include' +BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB = 'OpenImageIO' -BF_OIIO_LIBPATH = BF_OIIO + '/lib' +BF_OIIO_LIBPATH = '${BF_OIIO}/lib' WITH_BF_OCIO = True WITH_BF_STATICOCIO = False @@ -214,9 +214,9 @@ BF_OCIO = LIBDIR + '/ocio' if not os.path.exists(LCGDIR + '/ocio'): WITH_BF_OCIO = False BF_OCIO = '/usr' -BF_OCIO_INC = BF_OCIO + '/include' +BF_OCIO_INC = '${BF_OCIO}/include' BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml' -BF_OCIO_LIBPATH = BF_OCIO + '/lib' +BF_OCIO_LIBPATH = '${BF_OCIO}/lib' WITH_BF_BOOST = True WITH_BF_STATICBOOST = False @@ -224,10 +224,10 @@ BF_BOOST = LIBDIR + '/boost' if not os.path.exists(LCGDIR + '/boost'): WITH_BF_BOOST = False BF_BOOST = '/usr' -BF_BOOST_INC = BF_BOOST + '/include' +BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread' BF_BOOST_LIB_INTERNATIONAL = 'boost_locale' -BF_BOOST_LIBPATH = BF_BOOST + '/lib' +BF_BOOST_LIBPATH = '${BF_BOOST}/lib' WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py index 77641f8c842..80e3592c71e 100644 --- a/build_files/scons/config/win32-mingw-config.py +++ b/build_files/scons/config/win32-mingw-config.py @@ -150,22 +150,22 @@ WITH_BF_CYCLES = True WITH_BF_OIIO = True BF_OIIO = LIBDIR + '/openimageio' -BF_OIIO_INC = BF_OIIO + '/include' +BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB = 'OpenImageIO' -BF_OIIO_LIBPATH = BF_OIIO + '/lib' +BF_OIIO_LIBPATH = '${BF_OIIO}/lib' WITH_BF_OCIO = True BF_OCIO = LIBDIR + '/opencolorio' -BF_OCIO_INC = BF_OCIO + '/include' +BF_OCIO_INC = '${BF_OCIO}/include' BF_OCIO_LIB = 'OpenColorIO' -BF_OCIO_LIBPATH = BF_OCIO + '/lib' +BF_OCIO_LIBPATH = '${BF_OCIO}/lib' WITH_BF_BOOST = True BF_BOOST = LIBDIR + '/boost' -BF_BOOST_INC = BF_BOOST + '/include' +BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_49 boost_filesystem-mgw46-mt-s-1_49 boost_regex-mgw46-mt-s-1_49 boost_system-mgw46-mt-s-1_49 boost_thread-mgw46-mt-s-1_49' BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mgw46-mt-s-1_49' -BF_BOOST_LIBPATH = BF_BOOST + '/lib' +BF_BOOST_LIBPATH = '${BF_BOOST}/lib' #Ray trace optimization WITH_BF_RAYOPTIMIZATION = True diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py index a2b76bbed88..39031ef27ca 100644 --- a/build_files/scons/config/win32-vc-config.py +++ b/build_files/scons/config/win32-vc-config.py @@ -150,6 +150,17 @@ WITH_BF_OPENMP = True #Cycles WITH_BF_CYCLES = True +#OSL +WITH_BF_CYCLES_OSL = False +WITH_BF_STATICOSL = True +BF_OSL = LIBDIR + '/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +BF_OSL_LIB = 'oslcomp oslexec oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + WITH_BF_OIIO = True BF_OIIO = '${LIBDIR}/openimageio' BF_OIIO_INC = '${BF_OIIO}/include' @@ -204,7 +215,7 @@ C_WARN = [] CC_WARN = [] CXX_WARN = [] -LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid'] +LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi'] PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/INCREMENTAL:NO', '/LARGEADDRESSAWARE', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib'] diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py index 0840c6fd7e3..b4e06655c7e 100644 --- a/build_files/scons/config/win64-mingw-config.py +++ b/build_files/scons/config/win64-mingw-config.py @@ -162,10 +162,10 @@ BF_OCIO_LIBPATH = '${BF_OCIO}/lib' WITH_BF_BOOST = True BF_BOOST = LIBDIR + '/boost' -BF_BOOST_INC = BF_BOOST + '/include' +BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_LIB = 'boost_date_time-mgw47-mt-s-1_49 boost_date_time-mgw47-mt-sd-1_49 boost_filesystem-mgw47-mt-s-1_49 boost_filesystem-mgw47-mt-sd-1_49 boost_regex-mgw47-mt-s-1_49 boost_regex-mgw47-mt-sd-1_49 boost_system-mgw47-mt-s-1_49 boost_system-mgw47-mt-sd-1_49 boost_thread-mgw47-mt-s-1_49 boost_thread-mgw47-mt-sd-1_49' BF_BOOST_LIB_INTERNATIONAL = ' boost_locale-mgw47-mt-s-1_49 boost_locale-mgw47-mt-sd-1_49' -BF_BOOST_LIBPATH = BF_BOOST + '/lib' +BF_BOOST_LIBPATH = '${BF_BOOST}/lib' #Ray trace optimization WITH_BF_RAYOPTIMIZATION = True diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py index a0c37f0b73f..2434cb0c63a 100644 --- a/build_files/scons/config/win64-vc-config.py +++ b/build_files/scons/config/win64-vc-config.py @@ -146,19 +146,28 @@ WITH_BF_OPENMP = True #Cycles WITH_BF_CYCLES = True +#OSL +WITH_BF_CYCLES_OSL = False +WITH_BF_STATICOSL = True +BF_OSL = LIBDIR + '/osl' +BF_OSL_INC = '${BF_OSL}/include' +# note oslexec would passed via program linkflags, which is needed to +# make llvm happy with osl_allocate_closure_component +BF_OSL_LIB = 'oslcomp oslexec oslquery' +BF_OSL_LIBPATH = '${BF_OSL}/lib' +BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' + WITH_BF_OIIO = True BF_OIIO = '${LIBDIR}/openimageio' BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB = 'OpenImageIO' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' -BF_OIIO_LIBPATH = '${BF_OIIO}/lib' WITH_BF_OCIO = True BF_OCIO = '${LIBDIR}/opencolorio' BF_OCIO_INC = '${BF_OCIO}/include' BF_OCIO_LIB = 'OpenColorIO' BF_OCIO_LIBPATH = '${BF_OCIO}/lib' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' WITH_BF_BOOST = True BF_BOOST = '${LIBDIR}/boost' @@ -203,7 +212,7 @@ C_WARN = [] CC_WARN = [] CXX_WARN = [] -LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid'] +LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi'] PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib'] diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py index 199357d4c3a..2e0c81126b4 100644 --- a/build_files/scons/tools/Blender.py +++ b/build_files/scons/tools/Blender.py @@ -222,6 +222,16 @@ def setup_staticlibs(lenv): if lenv['WITH_BF_STATICBOOST']: statlibs += Split(lenv['BF_BOOST_LIB_STATIC']) + if lenv['WITH_BF_CYCLES_OSL']: + libincs += Split(lenv['BF_OSL_LIBPATH']) + if lenv['WITH_BF_STATICOSL']: + statlibs += Split(lenv['BF_OSL_LIB_STATIC']) + + if lenv['WITH_BF_LLVM']: + libincs += Split(lenv['BF_LLVM_LIBPATH']) + if lenv['WITH_BF_STATICLLVM']: + statlibs += Split(lenv['BF_LLVM_LIB_STATIC']) + # setting this last so any overriding of manually libs could be handled if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross', 'win64-mingw'): libincs.append('/usr/lib') @@ -314,6 +324,12 @@ def setup_syslibs(lenv): if lenv['WITH_BF_INTERNATIONAL']: syslibs += Split(lenv['BF_BOOST_LIB_INTERNATIONAL']) + if lenv['WITH_BF_CYCLES_OSL'] and not lenv['WITH_BF_STATICOSL']: + syslibs += Split(lenv['BF_OSL_LIB']) + + if lenv['WITH_BF_LLVM'] and not lenv['WITH_BF_STATICLLVM']: + syslibs += Split(lenv['BF_LLVM_LIB']) + if not lenv['WITH_BF_STATICJPEG']: syslibs += Split(lenv['BF_JPEG_LIB']) @@ -580,8 +596,8 @@ def AppIt(target=None, source=None, env=None): bldroot = env.Dir('.').abspath binary = env['BINARYKIND'] - sourcedir = bldroot + '/source/darwin/%s.app'%binary - sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary + sourcedir = bldroot + '/release/darwin/%s.app' % binary + sourceinfo = bldroot + "/release/darwin/%s.app/Contents/Info.plist"%binary targetinfo = installdir +'/' + "%s.app/Contents/Info.plist"%binary cmd = installdir + '/' +'%s.app'%binary @@ -636,6 +652,14 @@ def AppIt(target=None, source=None, env=None): cmd = 'cp -R %s/../intern/cycles/kernel/*.cubin %s/lib/' % (builddir, cinstalldir) commands.getoutput(cmd) + if env['WITH_BF_CYCLES_OSL']: + cmd = 'mkdir %s/shader' % (cinstalldir) + commands.getoutput(cmd) + cmd = 'cp -R %s/kernel/shaders/*.h %s/shader' % (croot, cinstalldir) + commands.getoutput(cmd) + cmd = 'cp -R %s/../intern/cycles/kernel/shaders/*.oso %s/shader' % (builddir, cinstalldir) + commands.getoutput(cmd) + if env['WITH_OSX_STATICPYTHON']: cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION) commands.getoutput(cmd) @@ -662,7 +686,7 @@ def AppIt(target=None, source=None, env=None): commands.getoutput(cmd) cmd = 'rm -rf %s/set_simulation_threads.app'%(installdir) # first clear omp_num_threads applescript commands.getoutput(cmd) - cmd = 'cp -R %s/source/darwin/set_simulation_threads.app %s/'%(bldroot, installdir) # copy the omp_num_threads applescript + cmd = 'cp -R %s/release/darwin/set_simulation_threads.app %s/'%(bldroot, installdir) # copy the omp_num_threads applescript commands.getoutput(cmd) # extract copy system python, be sure to update other build systems @@ -790,6 +814,20 @@ class BlenderEnvironment(SConsEnvironment): def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None, cc_compilerchange=None, cxx_compilerchange=None): global vcp + + # sanity check + # run once in a while to check we dont have duplicates + if 0: + for name, dirs in (("source", sources), ("include", includes)): + files_clean = [os.path.normpath(f) for f in dirs] + files_clean_set = set(files_clean) + if len(files_clean) != len(files_clean_set): + for f in sorted(files_clean_set): + if f != '.' and files_clean.count(f) > 1: + raise Exception("Found duplicate %s %r" % (name, f)) + del name, dirs, files_clean, files_clean_set, f + # end sanity check + if not self or not libname or not sources: print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC self.Exit() @@ -869,6 +907,7 @@ class BlenderEnvironment(SConsEnvironment): print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC lenv = self.Clone() lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS']) + lenv.Append(LINKFLAGS = lenv['BF_PROGRAM_LINKFLAGS']) if lenv['OURPLATFORM'] in ('win32-mingw', 'win64-mingw', 'linuxcross', 'cygwin', 'linux'): lenv.Replace(LINK = '$CXX') if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'): diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index 4e50f0dc313..ab963d4543c 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -164,7 +164,9 @@ def validate_arguments(args, bc): 'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH', 'WITH_BF_OCIO', 'WITH_BF_STATICOCIO', 'BF_OCIO', 'BF_OCIO_INC', 'BF_OCIO_LIB', 'BF_OCIO_LIB_STATIC', 'BF_OCIO_LIBPATH', 'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_INTERNATIONAL', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH', - 'WITH_BF_LIBMV' + 'WITH_BF_LIBMV', + 'WITH_BF_CYCLES_OSL', 'WITH_BF_STATICOSL', 'BF_OSL', 'BF_OSL_INC', 'BF_OSL_LIB', 'BF_OSL_LIBPATH', 'BF_OSL_LIB_STATIC', 'BF_OSL_COMPILER', + 'WITH_BF_LLVM', 'WITH_BF_STATICLLVM', 'BF_LLVM', 'BF_LLVM_LIB', 'BF_LLVM_LIBPATH', 'BF_LLVM_LIB_STATIC', 'BF_PROGRAM_LINKFLAGS' ] # Have options here that scons expects to be lists @@ -178,7 +180,7 @@ def validate_arguments(args, bc): 'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS', 'C_WARN', 'CC_WARN', 'CXX_WARN', 'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE', 'MACOSX_SDK_CHECK', 'XCODE_CUR_VER', - 'BF_CYCLES_CUDA_BINARIES_ARCH', + 'BF_CYCLES_CUDA_BINARIES_ARCH', 'BF_PROGRAM_LINKFLAGS', 'MACOSX_DEPLOYMENT_TARGET' ] @@ -500,8 +502,9 @@ def read_opts(env, cfg, args): ('LLIBS', 'Platform libs', []), ('PLATFORM_LINKFLAGS', 'Platform linkflags', []), ('MACOSX_ARCHITECTURE', 'python_arch.zip select', ''), - ('MACOSX_SDK_CHECK', 'detect available OSX sdk`s', ''), - ('XCODE_CUR_VER', 'detect XCode version', ''), + ('MACOSX_SDK_CHECK', 'Detect available OS X SDK`s', ''), + ('XCODE_CUR_VER', 'Detect XCode version', ''), + ('MACOSX_DEPLOYMENT_TARGET', 'Detect OS X target version', ''), (BoolVariable('BF_PROFILE', 'Add profiling information if true', False)), ('BF_PROFILE_CFLAGS', 'C only profiling flags', []), @@ -595,7 +598,25 @@ def read_opts(env, cfg, args): ('BF_BOOST_LIB_STATIC', 'Boost static library', ''), (BoolVariable('WITH_GHOST_XDND', 'Build with drag-n-drop support on Linux platforms using XDND protocol', True)), - (BoolVariable('WITH_BF_COMPOSITOR_LEGACY', 'Enable the legacy compositor', False)) + (BoolVariable('WITH_BF_COMPOSITOR_LEGACY', 'Enable the legacy compositor', False)), + + (BoolVariable('WITH_BF_CYCLES_OSL', 'Build with OSL sypport in Cycles', False)), + (BoolVariable('WITH_BF_STATICOSL', 'Staticly link to OSL', False)), + ('BF_OSL', 'OSL root path', ''), + ('BF_OSL_INC', 'OSL include path', ''), + ('BF_OSL_LIB', 'OSL library', ''), + ('BF_OSL_LIBPATH', 'OSL library path', ''), + ('BF_OSL_LIB_STATIC', 'OSL static library', ''), + ('BF_OSL_COMPILER', 'OSL compiler', ''), + + (BoolVariable('WITH_BF_LLVM', 'Build with LLVM sypport (required for OSL)', False)), + (BoolVariable('WITH_BF_STATICLLVM', 'Staticly link to LLVM', False)), + ('BF_LLVM', 'LLVM root path', ''), + ('BF_LLVM_LIB', 'LLVM library', ''), + ('BF_LLVM_LIBPATH', 'LLVM library path', ''), + ('BF_LLVM_LIB_STATIC', 'LLVM static library', ''), + + ('BF_PROGRAM_LINKFLAGS', 'Link flags applied only to final binaries (blender and blenderplayer, not makesrna/makesdna)', '') ) # end of opts.AddOptions() return localopts @@ -666,7 +687,7 @@ def buildslave(target=None, source=None, env=None): elif bitness == '32bit': platform = 'linux-' + glibc + '-i686' if platform == 'darwin': - platform = 'OSX-' + env['MACOSX_ARCHITECTURE'] + platform = 'OSX-' + env['MACOSX_DEPLOYMENT_TARGET'] + '-' + env['MACOSX_ARCHITECTURE'] branch = env['BUILDBOT_BRANCH'] diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index a8e2275e1ae..782e0c6daaa 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -1259,7 +1259,7 @@ def pyrna2sphinx(basepath): bases = list(reversed(struct.get_bases())) # props - lines[:] = [] + del lines[:] if _BPY_STRUCT_FAKE: descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")] @@ -1290,7 +1290,7 @@ def pyrna2sphinx(basepath): fw("\n") # funcs - lines[:] = [] + del lines[:] if _BPY_STRUCT_FAKE: for key, descr in descr_items: @@ -1313,7 +1313,7 @@ def pyrna2sphinx(basepath): fw(line) fw("\n") - lines[:] = [] + del lines[:] if struct.references: # use this otherwise it gets in the index for a normal heading. diff --git a/extern/xdnd/xdnd.c b/extern/xdnd/xdnd.c index 9bdee89c1ce..50d1fec4969 100644 --- a/extern/xdnd/xdnd.c +++ b/extern/xdnd/xdnd.c @@ -347,7 +347,7 @@ void xdnd_set_dnd_aware (DndClass * dnd, Window window, Atom * typelist) &nchildren_return); if (children_return) XFree (children_return); - if (r) + if (r && parent != root_return) xdnd_set_dnd_aware (dnd, parent, typelist); } diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript index c7d7720e0fe..1a127e364fe 100644 --- a/intern/cycles/SConscript +++ b/intern/cycles/SConscript @@ -23,6 +23,10 @@ defs.append('WITH_OPENCL') defs.append('WITH_MULTI') defs.append('WITH_CUDA') +if env['WITH_BF_CYCLES_OSL']: + defs.append('WITH_OSL') + incs.append(cycles['BF_OSL_INC']) + if env['WITH_BF_CYCLES_CUDA_BINARIES']: defs.append('WITH_CUDA_BINARIES') @@ -32,6 +36,7 @@ incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.sp incs.extend('#extern/glew/include #intern/mikktspace'.split()) incs.append(cycles['BF_OIIO_INC']) incs.append(cycles['BF_BOOST_INC']) +incs.append(cycles['BF_OPENEXR_INC'].split()) incs.extend(cycles['BF_PYTHON_INC'].split()) if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): @@ -62,6 +67,12 @@ if env['WITH_BF_RAYOPTIMIZATION']: cycles.BlenderLib('bf_intern_cycles', sources, incs, defs, libtype=['intern'], priority=[0], cxx_compileflags=cxxflags) +if env['WITH_BF_CYCLES_OSL']: + oso_files = SConscript(['kernel/shaders/SConscript']) + cycles.Depends("kernel/osl/osl_shader.o", oso_files) + + SConscript(['kernel/osl/SConscript']) + # cuda kernel binaries if env['WITH_BF_CYCLES_CUDA_BINARIES']: kernel_binaries = SConscript(['kernel/SConscript']) diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py index aac1e2422b9..79ce3df20c3 100644 --- a/intern/cycles/blender/addon/osl.py +++ b/intern/cycles/blender/addon/osl.py @@ -79,12 +79,13 @@ def update_script_node(node, report): if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path): # write text datablock contents to temporary file - osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=True) + osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=False) osl_file.write(script.as_string()) - osl_file.flush() + osl_file.close() + ok, oso_path = osl_compile(osl_file.name, report) oso_file_remove = False - osl_file.close() + os.remove(osl_file.name) else: # compile text datablock from disk directly ok, oso_path = osl_compile(osl_path, report) diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 9ebdcfd04bd..d0e8b508df6 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -179,12 +179,14 @@ void BlenderSync::sync_integrator() integrator->sample_clamp = get_float(cscene, "sample_clamp"); #ifdef __CAMERA_MOTION__ - if(integrator->motion_blur != r.use_motion_blur()) { - scene->object_manager->tag_update(scene); - scene->camera->tag_update(); - } + if(!preview) { + if(integrator->motion_blur != r.use_motion_blur()) { + scene->object_manager->tag_update(scene); + scene->camera->tag_update(); + } - integrator->motion_blur = (!preview && r.use_motion_blur()); + integrator->motion_blur = r.use_motion_blur(); + } #endif integrator->diffuse_samples = get_int(cscene, "diffuse_samples"); diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 2f2314c9a8b..d99beb8905a 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -301,10 +301,6 @@ __device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) __device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float clamp) { - #ifdef __OSL__ - using std::isfinite; - #endif - float sum = fabsf((*L_sum).x) + fabsf((*L_sum).y) + fabsf((*L_sum).z); if(!isfinite(sum)) { diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 585068ce8e2..70a9b372ebc 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -331,10 +331,13 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U); float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V); + float ao_factor = kernel_data.background.ao_factor; + float3 ao_N; + float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); float3 ao_D; float ao_pdf; - sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); + sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { Ray light_ray; @@ -347,11 +350,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, light_ray.time = sd.time; #endif - if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) { - float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor; - ao_bsdf += shader_bsdf_ao(kg, &sd); + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce); - } } } #endif @@ -509,10 +509,13 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U); float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V); + float ao_factor = kernel_data.background.ao_factor; + float3 ao_N; + float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); float3 ao_D; float ao_pdf; - sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); + sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { Ray light_ray; @@ -525,11 +528,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray light_ray.time = sd.time; #endif - if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) { - float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor; - ao_bsdf += shader_bsdf_ao(kg, &sd); + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce); - } } } #endif @@ -712,6 +712,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam int num_samples = kernel_data.integrator.ao_samples; float num_samples_inv = 1.0f/num_samples; float ao_factor = kernel_data.background.ao_factor; + float3 ao_N; + float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); for(int j = 0; j < num_samples; j++) { /* todo: solve correlation */ @@ -721,7 +723,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam float3 ao_D; float ao_pdf; - sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); + sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { Ray light_ray; @@ -734,11 +736,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam light_ray.time = sd.time; #endif - if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) { - float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor; - ao_bsdf += shader_bsdf_ao(kg, &sd); + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce); - } } } } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 1af5e048ad9..f935858f8ba 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -599,21 +599,35 @@ __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd) #endif } -__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd) +__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N) { #ifdef __MULTI_CLOSURE__ float3 eval = make_float3(0.0f, 0.0f, 0.0f); + *N = make_float3(0.0f, 0.0f, 0.0f); + for(int i = 0; i< sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) + if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) { + eval += sc->weight*ao_factor; + *N += sc->N*average(sc->weight); + } + if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) { eval += sc->weight; + *N += sd->N*average(sc->weight); + } } + *N = normalize(*N); + return eval; #else - if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type)) + *N = sd->N; + + if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type)) + return sd->closure.weight*ao_factor; + else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type)) return sd->closure.weight; else return make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript new file mode 100644 index 00000000000..d4b42d2becb --- /dev/null +++ b/intern/cycles/kernel/osl/SConscript @@ -0,0 +1,27 @@ +#!/usr/bin/python + +Import('env') + +defs = [] +incs = [] +cxxflags = Split(env['CXXFLAGS']) + +sources = env.Glob('*.cpp') + +incs.extend('. .. ../svm ../../render ../../util ../../device'.split()) +incs.append(env['BF_OIIO_INC']) +incs.append(env['BF_BOOST_INC']) +incs.append(env['BF_OSL_INC']) +incs.append(env['BF_OPENEXR_INC'].split()) + +defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {') +defs.append('CCL_NAMESPACE_END=}') +defs.append('WITH_OSL') + +if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + cxxflags.append('-DBOOST_NO_RTTI -DBOOST_NO_TYPEID'.split()) + incs.append(env['BF_PTHREADS_INC']) +else: + cxxflags.append('-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID'.split()) + +env.BlenderLib ('cycles_kernel_osl', sources, incs, defs, libtype=['intern'], priority=[10], cxx_compileflags=cxxflags) diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h index 80ced9dfd62..003e39ca3c3 100644 --- a/intern/cycles/kernel/osl/osl_globals.h +++ b/intern/cycles/kernel/osl/osl_globals.h @@ -22,12 +22,17 @@ #ifdef WITH_OSL #include +#include #include "util_map.h" #include "util_param.h" #include "util_thread.h" #include "util_vector.h" +#ifndef WIN32 +using std::isfinite; +#endif + CCL_NAMESPACE_BEGIN class OSLRenderServices; diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index 4f5a97c1bb6..f7fec62fd6d 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -89,7 +89,7 @@ foreach(_file ${SRC_OSL}) list(APPEND SRC_OSO ${_OSO_FILE} ) - + unset(_OSL_FILE) unset(_OSO_FILE) endforeach() diff --git a/intern/cycles/kernel/shaders/SConscript b/intern/cycles/kernel/shaders/SConscript new file mode 100644 index 00000000000..1d446205d92 --- /dev/null +++ b/intern/cycles/kernel/shaders/SConscript @@ -0,0 +1,45 @@ +#!/usr/bin/python +import sys +import os +import Blender as B + +def normpath(path): + return os.path.abspath(os.path.normpath(path)) + +Import ('env') + +oso_files = [] + +if env['WITH_BF_CYCLES_OSL']: + shaders = env.Clone() + + # osl compiler info + if env['OURPLATFORM']=='darwin': + osl_compiler = '../lib/darwin-9.x.universal/osl/bin/oslc' # temporary hack to get the leading "#" away that breaks shadercompile + else: + osl_compiler = env['BF_OSL_COMPILER'] + + # build directory + root_build_dir = normpath(env['BF_BUILDDIR']) + build_dir = os.path.join(root_build_dir, 'intern/cycles/kernel/shaders') + + # source directories and files + source_dir = Dir('.').srcnode().path + + # dependencies + dependencies = shaders.Glob('*.h') + + for f in os.listdir(source_dir): + if f.endswith('.osl'): + osl_file = os.path.join(source_dir, f) + oso_file = os.path.join(build_dir, f.replace('.osl', '.oso')) + + command = "%s -O2 -I%s -o %s %s" % (osl_compiler, source_dir, oso_file, osl_file) + + shaders.Command(oso_file, f, command) + shaders.Depends(oso_file, [f] + dependencies) + + oso_files.append(oso_file) + + +Return('oso_files') diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl index 57a06f35461..b9423344e73 100644 --- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl +++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl @@ -19,6 +19,7 @@ #include "stdosl.h" shader node_ambient_occlusion( + normal NormalIn = N, color Color = color(0.8, 0.8, 0.8), output closure color AO = ambient_occlusion()) { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 82afab4dc1a..cdc3b555a51 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1578,6 +1578,8 @@ void HoldoutNode::compile(OSLCompiler& compiler) AmbientOcclusionNode::AmbientOcclusionNode() : ShaderNode("ambient_occlusion") { + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); add_output("AO", SHADER_SOCKET_CLOSURE); } diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 843764ca9d6..751d22b2f63 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -75,7 +75,7 @@ protected: * Boost implementation is a bit slow, and Mac OS X __thread is not supported * but the pthreads implementation is optimized, so we use these macros. */ -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(_WIN32) #define tls_ptr(type, name) \ pthread_key_t name @@ -90,10 +90,6 @@ protected: #else -#ifdef __WIN32 -#define __thread __declspec(thread) -#endif - #define tls_ptr(type, name) \ __thread type *name #define tls_set(name, value) \ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 475ad2bdcb3..628b0d038f9 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1591,13 +1591,17 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) if ((dx == 0) && (dy == 0)) break; /* Quadratic acceleration */ - dx = dx*(fabs(dx)+0.5); - if (dx<0.0) dx-=0.5; else dx+=0.5; - if (dx< -deltaMax) dx= -deltaMax; else if (dx>deltaMax) dx=deltaMax; + dx = dx*(fabs(dx) + 0.5); + if (dx < 0.0) dx -= 0.5; + else dx += 0.5; + if (dx < -deltaMax) dx = -deltaMax; + else if (dx > deltaMax) dx = deltaMax; - dy = dy*(fabs(dy)+0.5); - if (dy<0.0) dy-=0.5; else dy+=0.5; - if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax; + dy = dy*(fabs(dy) + 0.5); + if (dy < 0.0) dy -= 0.5; + else dy += 0.5; + if (dy < -deltaMax) dy= -deltaMax; + else if (dy > deltaMax) dy= deltaMax; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); dy = -dy; diff --git a/source/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist similarity index 100% rename from source/darwin/blender.app/Contents/Info.plist rename to release/darwin/blender.app/Contents/Info.plist diff --git a/source/darwin/blender.app/Contents/MacOS/blender b/release/darwin/blender.app/Contents/MacOS/blender similarity index 100% rename from source/darwin/blender.app/Contents/MacOS/blender rename to release/darwin/blender.app/Contents/MacOS/blender diff --git a/source/darwin/blender.app/Contents/PkgInfo b/release/darwin/blender.app/Contents/PkgInfo similarity index 100% rename from source/darwin/blender.app/Contents/PkgInfo rename to release/darwin/blender.app/Contents/PkgInfo diff --git a/source/darwin/blender.app/Contents/Resources/blender file icon.icns b/release/darwin/blender.app/Contents/Resources/blender file icon.icns similarity index 100% rename from source/darwin/blender.app/Contents/Resources/blender file icon.icns rename to release/darwin/blender.app/Contents/Resources/blender file icon.icns diff --git a/source/darwin/blender.app/Contents/Resources/blender icon.icns b/release/darwin/blender.app/Contents/Resources/blender icon.icns similarity index 100% rename from source/darwin/blender.app/Contents/Resources/blender icon.icns rename to release/darwin/blender.app/Contents/Resources/blender icon.icns diff --git a/source/darwin/blenderplayer.app/Contents/Info.plist b/release/darwin/blenderplayer.app/Contents/Info.plist similarity index 100% rename from source/darwin/blenderplayer.app/Contents/Info.plist rename to release/darwin/blenderplayer.app/Contents/Info.plist diff --git a/source/darwin/blenderplayer.app/Contents/MacOS/blenderplayer b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer similarity index 100% rename from source/darwin/blenderplayer.app/Contents/MacOS/blenderplayer rename to release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer diff --git a/source/darwin/blenderplayer.app/Contents/PkgInfo b/release/darwin/blenderplayer.app/Contents/PkgInfo similarity index 100% rename from source/darwin/blenderplayer.app/Contents/PkgInfo rename to release/darwin/blenderplayer.app/Contents/PkgInfo diff --git a/source/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns b/release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns similarity index 100% rename from source/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns rename to release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns diff --git a/source/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns b/release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns similarity index 100% rename from source/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns rename to release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns diff --git a/source/darwin/set_simulation_threads.app/Contents/Info.plist b/release/darwin/set_simulation_threads.app/Contents/Info.plist similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/Info.plist rename to release/darwin/set_simulation_threads.app/Contents/Info.plist diff --git a/source/darwin/set_simulation_threads.app/Contents/MacOS/applet b/release/darwin/set_simulation_threads.app/Contents/MacOS/applet similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/MacOS/applet rename to release/darwin/set_simulation_threads.app/Contents/MacOS/applet diff --git a/source/darwin/set_simulation_threads.app/Contents/PkgInfo b/release/darwin/set_simulation_threads.app/Contents/PkgInfo similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/PkgInfo rename to release/darwin/set_simulation_threads.app/Contents/PkgInfo diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt b/release/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt rename to release/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/applet.icns b/release/darwin/set_simulation_threads.app/Contents/Resources/applet.icns similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/Resources/applet.icns rename to release/darwin/set_simulation_threads.app/Contents/Resources/applet.icns diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc b/release/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc rename to release/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf b/release/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf similarity index 100% rename from source/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf rename to release/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 7e604c5de4c..6bf81d73f8b 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -232,7 +232,6 @@ def enable(module_name, default_set=True, persistent=False): import os import sys - import imp def handle_error(): import traceback @@ -246,6 +245,7 @@ def enable(module_name, default_set=True, persistent=False): mtime_orig = getattr(mod, "__time__", 0) mtime_new = os.path.getmtime(mod.__file__) if mtime_orig != mtime_new: + import imp print("module changed on disk:", mod.__file__, "reloading...") try: diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index 573694ff08e..4ad00eb267e 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -216,7 +216,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): for mod in _global_loaded_modules: test_reload(mod) - _global_loaded_modules[:] = [] + del _global_loaded_modules[:] for base_path in script_paths(): for path_subdir in _script_module_dirs: diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py index ad3cf8c08ec..2042cc1c8a1 100644 --- a/release/scripts/modules/bpy_extras/mesh_utils.py +++ b/release/scripts/modules/bpy_extras/mesh_utils.py @@ -223,7 +223,7 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()): else: other_dir = None - ed_adj[:] = [] + del ed_adj[:] flipped = False @@ -235,22 +235,22 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()): if other_dir and flipped is False: flipped = True # only flip the list once context_loop.reverse() - ed_adj[:] = [] + del ed_adj[:] context_loop.append(other_dir) # save 1 look-up ed_adj = edges[context_loop[-1]] if len(ed_adj) != 2: - ed_adj[:] = [] + del ed_adj[:] break else: - ed_adj[:] = [] + del ed_adj[:] break i = ed_adj.index(context_loop[-2]) context_loop.append(ed_adj[not i]) # Dont look at this again - ed_adj[:] = [] + del ed_adj[:] return edge_loops @@ -436,7 +436,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True): if s1[0][1] == s1[-1][1]: # remove endpoints double s1.pop() - s2[:] = [] # Empty this segment s2 so we don't use it again. + del s2[:] # Empty this segment s2 so we don't use it again. return True joining_segments = True diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 4e7003fd453..ee9769d8b43 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -558,7 +558,7 @@ class WM_MT_operator_presets(Menu): # dummy 'default' menu item layout = self.layout layout.operator("wm.operator_defaults") - layout.seperator() + layout.separator() Menu.draw_preset(self, context) diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index 694412e51d7..6d1f35fe937 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -116,8 +116,12 @@ class PlayRenderedAnim(Operator): cmd = [player_path] # extra options, fps controls etc. if preset in {'BLENDER24', 'INTERNAL'}: - opts = ["-a", "-f", str(rd.fps), str(rd.fps_base), - "-j", str(scene.frame_step), file] + opts = ["-a", + "-f", str(rd.fps), str(rd.fps_base), + "-s", str(scene.frame_start), + "-e", str(scene.frame_end), + "-j", str(scene.frame_step), + file] cmd.extend(opts) elif preset == 'DJV': opts = [file, "-playback_speed", "%d" % int(rd.fps / rd.fps_base)] diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 9fa44cac812..eb05057de3d 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -517,7 +517,7 @@ def mergeUvIslands(islandList): for uv in f.uv: uv+= offset - sourceIsland[0][:] = [] # Empty + del sourceIsland[0][:] # Empty # Move edge loop into new and offset. @@ -527,7 +527,7 @@ def mergeUvIslands(islandList): (e[0]+offset, e[1]+offset, e[2])\ ) for e in sourceIsland[6] ] ) - sourceIsland[6][:] = [] # Empty + del sourceIsland[6][:] # Empty # Sort by edge length, reverse so biggest are first. @@ -540,7 +540,7 @@ def mergeUvIslands(islandList): for p in sourceIsland[7]: p+= offset - sourceIsland[7][:] = [] + del sourceIsland[7][:] # Decrement the efficiency diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 2bff11a686d..0945098bd1e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -41,12 +41,17 @@ class MESH_OT_delete_edgeloop(Operator): return bpy.ops.transform.edge_slide.poll() def execute(self, context): + mesh = context.object.data + use_mirror_x = mesh.use_mirror_x + mesh.use_mirror_x = False if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0): bpy.ops.mesh.select_more() bpy.ops.mesh.remove_doubles() - return {'FINISHED'} - - return {'CANCELLED'} + ret = {'FINISHED'} + else: + ret = {'CANCELLED'} + mesh.use_mirror_x = use_mirror_x + return ret rna_path_prop = StringProperty( name="Context Attributes", diff --git a/source/blender/avi/intern/avi_rgb.c b/source/blender/avi/intern/avi_rgb.c index 11d9bdf8612..c6a78eccce2 100644 --- a/source/blender/avi/intern/avi_rgb.c +++ b/source/blender/avi/intern/avi_rgb.c @@ -98,7 +98,7 @@ void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buf buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "fromavirgbbuf"); rowstride = movie->header->Width * 3; - if (bits != 16) if (movie->header->Width % 2) rowstride++; + if ((bits != 16) && (movie->header->Width % 2)) rowstride++; for (y = 0; y < movie->header->Height; y++) { memcpy(&buf[y * movie->header->Width * 3], &buffer[((movie->header->Height - 1) - y) * rowstride], movie->header->Width * 3); diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 1875fd66628..1f9630d9fce 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -48,6 +48,9 @@ struct Main; #define IMA_MAX_SPACE 64 +void BKE_images_init(void); +void BKE_images_exit(void); + /* call from library */ void BKE_image_free(struct Image *me); @@ -133,14 +136,13 @@ enum { #define IMA_CHAN_FLAG_RGB 2 #define IMA_CHAN_FLAG_ALPHA 4 -/* depending Image type, and (optional) ImageUser setting it returns ibuf */ -/* always call to make signals work */ -struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser); +/* checks whether there's an image buffer for given image and user */ +int BKE_image_has_ibuf(struct Image *ima, struct ImageUser *iuser); /* same as above, but can be used to retrieve images being rendered in * a thread safe way, always call both acquire and release */ struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r); -void BKE_image_release_ibuf(struct Image *ima, void *lock); +void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock); /* returns a new image or NULL if it can't load */ struct Image *BKE_image_load(const char *filepath); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b365d93b246..65610b5c989 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -706,6 +706,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria #define CMP_NODE_SWITCH 317 #define CMP_NODE_PIXELATE 318 +#define CMP_NODE_MAP_RANGE 319 + /* channel toggles */ #define CMP_CHAN_RGB 1 #define CMP_CHAN_A 2 diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index 875903f2e20..aaf88e4924d 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -83,7 +83,7 @@ void txt_sel_line (struct Text *text); char* txt_sel_to_buf (struct Text *text); void txt_insert_buf (struct Text *text, const char *in_buffer); void txt_print_undo (struct Text *text); -void txt_undo_add_toop (struct Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc); +void txt_undo_add_op (struct Text *text, int op); void txt_do_undo (struct Text *text); void txt_do_redo (struct Text *text); void txt_split_curline (struct Text *text); @@ -123,24 +123,6 @@ enum { /* Undo opcodes */ -/* Simple main cursor movement */ -#define UNDO_CLEFT 001 -#define UNDO_CRIGHT 002 -#define UNDO_CUP 003 -#define UNDO_CDOWN 004 - -/* Simple selection cursor movement */ -#define UNDO_SLEFT 005 -#define UNDO_SRIGHT 006 -#define UNDO_SUP 007 -#define UNDO_SDOWN 010 - -/* Complex movement (opcode is followed - * by 4 character line ID + a 2 character - * position ID and opcode (repeat)) */ -#define UNDO_CTO 011 -#define UNDO_STO 012 - /* Complex editing */ /* 1 - opcode is followed by 1 byte for ascii character and opcode (repeat)) */ /* 2 - opcode is followed by 2 bytes for utf-8 character and opcode (repeat)) */ @@ -169,8 +151,6 @@ enum { #define UNDO_IBLOCK 030 /* Insert block */ /* Misc */ -#define UNDO_SWAP 031 /* Swap cursors */ - #define UNDO_INDENT 032 #define UNDO_UNINDENT 033 #define UNDO_COMMENT 034 diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index e1e868b234e..40cd5b3d403 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -70,6 +70,7 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_idprop.h" +#include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_library.h" #include "BKE_main.h" @@ -113,6 +114,7 @@ void free_blender(void) BKE_spacetypes_free(); /* after free main, it uses space callbacks */ IMB_exit(); + BKE_images_exit(); BLI_callback_global_finalize(); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 98b206712d6..f310895f590 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1287,8 +1287,6 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side) texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache"); - BKE_image_get_ibuf(mtex->tex->ima, NULL); - /*do normalized cannonical view coords for texture*/ for (y = -1.0, iy = 0; iy < side; iy++, y += step) { for (x = -1.0, ix = 0; ix < side; ix++, x += step) { diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 719ae7357b4..ffb93139358 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -44,6 +44,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "BLI_threads.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -245,6 +246,10 @@ static void *ctx_wm_python_context_get(const bContext *C, const char *member, vo (void)C, (void)member; #endif + /* don't allow UI context access from non-main threads */ + if (!BLI_thread_is_main()) + return NULL; + return fall_through; } @@ -264,6 +269,11 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res // return 1; } #endif + + /* don't allow UI context access from non-main threads */ + if (!BLI_thread_is_main()) + return done; + /* we check recursion to ensure that we do not get infinite * loops requesting data from ourselfs in a context callback */ diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index f2cd695d64a..754a4fbc0c8 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1116,7 +1116,7 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float * *fp = basisu[i] * bp->vec[3]; sumdiv += *fp; } - if (sumdiv != 0.0f) if (sumdiv < 0.999f || sumdiv > 1.001f) { + if ((sumdiv != 0.0f) && (sumdiv < 0.999f || sumdiv > 1.001f)) { /* is normalizing needed? */ fp = sum; for (i = istart; i <= iend; i++, fp++) { diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 93c776ae30e..b2f8db0dcce 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -761,7 +761,7 @@ static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax) { MLoopUV *min = vmin, *max = vmax, *luv = data; - DO_MINMAX2(luv->uv, min->uv, max->uv); + minmax_v2v2_v2(min->uv, max->uv, luv->uv); } static void layerAdd_mloopuv(void *data1, void *data2) @@ -833,7 +833,7 @@ static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax) { OrigSpaceLoop *min = vmin, *max = vmax, *luv = data; - DO_MINMAX2(luv->uv, min->uv, max->uv); + minmax_v2v2_v2(min->uv, max->uv, luv->uv); } static void layerAdd_mloop_origspace(void *data1, void *data2) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 55d37c91859..d98c2bc2f8b 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -100,6 +100,8 @@ #include "WM_api.h" +static SpinLock image_spin; + /* max int, to indicate we don't store sequences in ibuf */ #define IMA_NO_INDEX 0x7FEFEFEF @@ -108,6 +110,16 @@ #define IMA_INDEX_FRAME(index) (index >> 10) #define IMA_INDEX_PASS(index) (index & ~1023) +void BKE_images_init(void) +{ + BLI_spin_init(&image_spin); +} + +void BKE_images_exit(void) +{ + BLI_spin_end(&image_spin); +} + /* ******** IMAGE PROCESSING ************* */ static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */ @@ -168,13 +180,14 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */ void BKE_image_de_interlace(Image *ima, int odd) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ibuf) { if (odd) de_interlace_st(ibuf); else de_interlace_ng(ibuf); } + BKE_image_release_ibuf(ima, ibuf, NULL); } /* ***************** ALLOC & FREE, DATA MANAGING *************** */ @@ -260,8 +273,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame) /* this function is intended to be thread safe. with IMA_NO_INDEX this * should be OK, but when iterating over the list this is more tricky * */ - if (index == IMA_NO_INDEX) + if (index == IMA_NO_INDEX) { return ima->ibufs.first; + } else { ImBuf *ibuf; @@ -269,9 +283,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame) for (ibuf = ima->ibufs.first; ibuf; ibuf = ibuf->next) if (ibuf->index == index) return ibuf; - - return NULL; } + + return NULL; } /* no ima->ibuf anymore, but listbase */ @@ -534,7 +548,7 @@ int BKE_image_scale(Image *image, int width, int height) ibuf->userflags |= IB_BITMAPDIRTY; } - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); return (ibuf != NULL); } @@ -2081,6 +2095,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) if (ima == NULL) return; + BLI_spin_lock(&image_spin); + switch (signal) { case IMA_SIGNAL_FREE: image_free_buffers(ima); @@ -2157,6 +2173,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) break; } + BLI_spin_unlock(&image_spin); + /* don't use notifiers because they are not 100% sure to succeeded * this also makes sure all scenes are accounted for. */ { @@ -2320,7 +2338,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) if (ibuf) { #ifdef WITH_OPENEXR - /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */ + /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */ if (ibuf->ftype == OPENEXR && ibuf->userdata) { image_create_multilayer(ima, ibuf, frame); ima->type = IMA_TYPE_MULTILAYER; @@ -2482,7 +2500,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) } if (ibuf) { - /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */ + /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */ if (ibuf->ftype == OPENEXR && ibuf->userdata) { image_create_multilayer(ima, ibuf, cfra); ima->type = IMA_TYPE_MULTILAYER; @@ -2751,38 +2769,32 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame * a big bottleneck */ } - *frame_r = frame; - *index_r = index; + if (frame_r) + *frame_r = frame; + + if (index_r) + *index_r = index; return ibuf; } -/* Checks optional ImageUser and verifies/creates ImBuf. */ -/* use this one if you want to get a render result in progress, - * if not, use BKE_image_get_ibuf which doesn't require a release */ -ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) +/* Checks optional ImageUser and verifies/creates ImBuf. + * + * not thread-safe, so callee should worry about thread locks + */ +static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) { ImBuf *ibuf = NULL; float color[] = {0, 0, 0, 1}; int frame = 0, index = 0; - /* This function is intended to be thread-safe. It postpones the mutex lock - * until it needs to load the image, if the image is already there it - * should just get the pointer and return. The reason is that a lot of mutex - * locks appears to be very slow on certain multicore macs, causing a render - * with image textures to actually slow down as more threads are used. - * - * Note that all the image loading functions should also make sure they do - * things in a threadsafe way for image_get_ibuf_threadsafe to work correct. - * That means, the last two steps must be, 1) add the ibuf to the list and - * 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */ - if (lock_r) *lock_r = NULL; /* quick reject tests */ if (ima == NULL) return NULL; + if (iuser) { if (iuser->ok == 0) return NULL; @@ -2790,95 +2802,71 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) else if (ima->ok == 0) return NULL; - /* try to get the ibuf without locking */ ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index); if (ibuf == NULL) { - /* couldn't get ibuf and image is not ok, so let's lock and try to - * load the image */ - BLI_lock_thread(LOCK_IMAGE); - - /* need to check ok flag and loading ibuf again, because the situation - * might have changed in the meantime */ - if (iuser) { - if (iuser->ok == 0) { - BLI_unlock_thread(LOCK_IMAGE); - return NULL; + /* we are sure we have to load the ibuf, using source and type */ + if (ima->source == IMA_SRC_MOVIE) { + /* source is from single file, use flipbook to store ibuf */ + ibuf = image_load_movie_file(ima, iuser, frame); + } + else if (ima->source == IMA_SRC_SEQUENCE) { + if (ima->type == IMA_TYPE_IMAGE) { + /* regular files, ibufs in flipbook, allows saving */ + ibuf = image_load_sequence_file(ima, iuser, frame); + } + /* no else; on load the ima type can change */ + if (ima->type == IMA_TYPE_MULTILAYER) { + /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */ + ibuf = image_load_sequence_multilayer(ima, iuser, frame); } } - else if (ima->ok == 0) { - BLI_unlock_thread(LOCK_IMAGE); - return NULL; + else if (ima->source == IMA_SRC_FILE) { + + if (ima->type == IMA_TYPE_IMAGE) + ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */ + /* no else; on load the ima type can change */ + if (ima->type == IMA_TYPE_MULTILAYER) + /* keeps render result, stores ibufs in listbase, allows saving */ + ibuf = image_get_ibuf_multilayer(ima, iuser); + } - - ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index); - - if (ibuf == NULL) { - /* we are sure we have to load the ibuf, using source and type */ - if (ima->source == IMA_SRC_MOVIE) { - /* source is from single file, use flipbook to store ibuf */ - ibuf = image_load_movie_file(ima, iuser, frame); + else if (ima->source == IMA_SRC_GENERATED) { + /* generated is: ibuf is allocated dynamically */ + /* UV testgrid or black or solid etc */ + if (ima->gen_x == 0) ima->gen_x = 1024; + if (ima->gen_y == 0) ima->gen_y = 1024; + ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type, + color, &ima->colorspace_settings); + image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + ima->ok = IMA_OK_LOADED; + } + else if (ima->source == IMA_SRC_VIEWER) { + if (ima->type == IMA_TYPE_R_RESULT) { + /* always verify entirely, and potentially + * returns pointer to release later */ + ibuf = image_get_render_result(ima, iuser, lock_r); } - else if (ima->source == IMA_SRC_SEQUENCE) { - if (ima->type == IMA_TYPE_IMAGE) { - /* regular files, ibufs in flipbook, allows saving */ - ibuf = image_load_sequence_file(ima, iuser, frame); - } - /* no else; on load the ima type can change */ - if (ima->type == IMA_TYPE_MULTILAYER) { - /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */ - ibuf = image_load_sequence_multilayer(ima, iuser, frame); - } - } - else if (ima->source == IMA_SRC_FILE) { + else if (ima->type == IMA_TYPE_COMPOSITE) { + /* requires lock/unlock, otherwise don't return image */ + if (lock_r) { + /* unlock in BKE_image_release_ibuf */ + BLI_lock_thread(LOCK_VIEWER); + *lock_r = ima; - if (ima->type == IMA_TYPE_IMAGE) - ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */ - /* no else; on load the ima type can change */ - if (ima->type == IMA_TYPE_MULTILAYER) - /* keeps render result, stores ibufs in listbase, allows saving */ - ibuf = image_get_ibuf_multilayer(ima, iuser); + /* XXX anim play for viewer nodes not yet supported */ + frame = 0; // XXX iuser?iuser->framenr:0; + ibuf = image_get_ibuf(ima, 0, frame); - } - else if (ima->source == IMA_SRC_GENERATED) { - /* generated is: ibuf is allocated dynamically */ - /* UV testgrid or black or solid etc */ - if (ima->gen_x == 0) ima->gen_x = 1024; - if (ima->gen_y == 0) ima->gen_y = 1024; - ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type, - color, &ima->colorspace_settings); - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); - ima->ok = IMA_OK_LOADED; - } - else if (ima->source == IMA_SRC_VIEWER) { - if (ima->type == IMA_TYPE_R_RESULT) { - /* always verify entirely, and potentially - * returns pointer to release later */ - ibuf = image_get_render_result(ima, iuser, lock_r); - } - else if (ima->type == IMA_TYPE_COMPOSITE) { - /* requires lock/unlock, otherwise don't return image */ - if (lock_r) { - /* unlock in BKE_image_release_ibuf */ - BLI_lock_thread(LOCK_VIEWER); - *lock_r = ima; - - /* XXX anim play for viewer nodes not yet supported */ - frame = 0; // XXX iuser?iuser->framenr:0; - ibuf = image_get_ibuf(ima, 0, frame); - - if (!ibuf) { - /* Composite Viewer, all handled in compositor */ - /* fake ibuf, will be filled in compositor */ - ibuf = IMB_allocImBuf(256, 256, 32, IB_rect); - image_assign_ibuf(ima, ibuf, 0, frame); - } + if (!ibuf) { + /* Composite Viewer, all handled in compositor */ + /* fake ibuf, will be filled in compositor */ + ibuf = IMB_allocImBuf(256, 256, 32, IB_rect); + image_assign_ibuf(ima, ibuf, 0, frame); } } } } - - BLI_unlock_thread(LOCK_IMAGE); } BKE_image_tag_time(ima); @@ -2886,23 +2874,66 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) return ibuf; } -void BKE_image_release_ibuf(Image *ima, void *lock) +/* return image buffer for given image and user + * + * - will lock render result if image type is render result and lock is not NULL + * - will return NULL if image type if render or composite result and lock is NULL + * + * references the result, BKE_image_release_ibuf should be used to de-reference + */ +ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) { - /* for getting image during threaded render / compositing, need to release */ - if (lock == ima) { - BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ + ImBuf *ibuf; + + BLI_spin_lock(&image_spin); + + ibuf = image_acquire_ibuf(ima, iuser, lock_r); + + if (ibuf) + IMB_refImBuf(ibuf); + + BLI_spin_unlock(&image_spin); + + return ibuf; +} + +void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock) +{ + if (lock) { + /* for getting image during threaded render / compositing, need to release */ + if (lock == ima) { + BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ + } + else if (lock) { + RE_ReleaseResultImage(lock); /* render result */ + BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */ + } } - else if (lock) { - RE_ReleaseResultImage(lock); /* render result */ - BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */ + + if (ibuf) { + BLI_spin_lock(&image_spin); + IMB_freeImBuf(ibuf); + BLI_spin_unlock(&image_spin); } } -/* warning, this can allocate generated images */ -ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) +/* checks whether there's an image buffer for given image and user */ +int BKE_image_has_ibuf(Image *ima, ImageUser *iuser) { - /* here (+fie_ima/2-1) makes sure that division happens correctly */ - return BKE_image_acquire_ibuf(ima, iuser, NULL); + ImBuf *ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL); + + if (!ibuf) { + BLI_spin_lock(&image_spin); + + ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL); + + if (!ibuf) + ibuf = image_acquire_ibuf(ima, iuser, NULL); + + BLI_spin_unlock(&image_spin); + } + + return ibuf != NULL; } int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range) @@ -3020,7 +3051,7 @@ int BKE_image_has_alpha(struct Image *image) ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); planes = (ibuf ? ibuf->planes : 0); - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); if (planes == 32) return 1; @@ -3044,7 +3075,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height) *height = IMG_SIZE_FALLBACK; } - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); } void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2]) diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 5b54154a489..db96567a4da 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1535,7 +1535,9 @@ void test_idbutton(char *name) /* search for id */ idtest = BLI_findstring(lb, name, offsetof(ID, name) + 2); - if (idtest) if (new_id(lb, idtest, name) == 0) id_sort_by_name(lb, idtest); + if (idtest && (new_id(lb, idtest, name) == 0)) { + id_sort_by_name(lb, idtest); + } } void text_idbutton(struct ID *id, char *text) diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index 7d89678d36f..a2f6b3c1929 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -289,10 +289,10 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f /* collapse loop with smaller AABB */ for (k = 0; k < tot_feather_point; k++) { if (k >= check_b && k <= cur_a) { - DO_MINMAX2(feather_points[k], min_a, max_a); + minmax_v2v2_v2(min_a, max_a, feather_points[k]); } else { - DO_MINMAX2(feather_points[k], min_b, max_b); + minmax_v2v2_v2(min_b, max_b, feather_points[k]); } } @@ -379,7 +379,7 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*fe int next = i + 1; float delta; - DO_MINMAX2(feather_points[i], min, max); + minmax_v2v2_v2(min, max, feather_points[i]); if (next == tot_feather_point) { if (spline->flag & MASK_SPLINE_CYCLIC) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 2d76484b60a..06b846a6df9 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2184,6 +2184,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_normal(ttype); register_node_type_cmp_curve_vec(ttype); register_node_type_cmp_map_value(ttype); + register_node_type_cmp_map_range(ttype); register_node_type_cmp_normalize(ttype); register_node_type_cmp_filter(ttype); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index d645204d29c..93bf5a5c0b4 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3786,14 +3786,22 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co return 1; } -#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \ - if ((event & mtex->mapto) & type) { pvalue = texture_value_blend(def, pvalue, value, texfac, blend); } (void)0 +#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \ + if ((event & mtex->mapto) & type) { \ + pvalue = texture_value_blend(def, pvalue, value, texfac, blend); \ + } (void)0 -#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \ - if (event & type) { if (pvalue < 0.0f) pvalue = 1.0f + pvalue; CLAMP(pvalue, 0.0f, 1.0f); } (void)0 +#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \ + if (event & type) { \ + if (pvalue < 0.0f) \ + pvalue = 1.0f + pvalue; \ + CLAMP(pvalue, 0.0f, 1.0f); \ + } (void)0 -#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \ - if (event & type) { CLAMP(pvalue, -1.0f, 1.0f); } (void)0 +#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \ + if (event & type) { \ + CLAMP(pvalue, -1.0f, 1.0f); \ + } (void)0 static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra) { @@ -3802,8 +3810,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti float value, rgba[4], texvec[3]; ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp = - ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink = - ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f; + ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink = + ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f; ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26); ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index f195b3d71b0..3f2eb32f61c 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2568,10 +2568,12 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) sbFreeSimulation(pid->calldata); else if (pid->type == PTCACHE_TYPE_PARTICLES) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); - /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) +#if 0 + else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset_turbulence(pid->calldata);*/ + smokeModifier_reset_turbulence(pid->calldata); +#endif else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 3ce66f23d81..2e57df844c8 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1052,7 +1052,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* always update layer, so that animating layers works (joshua july 2010) */ /* XXX commented out, this has depsgraph issues anyway - and this breaks setting scenes - (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */ + * (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */ // base->lay = ob->lay; } diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c index 99e33594a3e..ff9774f85af 100644 --- a/source/blender/blenkernel/intern/suggestions.c +++ b/source/blender/blenkernel/intern/suggestions.c @@ -47,6 +47,7 @@ static SuggList suggestions = {NULL, NULL, NULL, NULL, NULL}; static char *documentation = NULL; //static int doc_lines = 0; +/* TODO, replace with BLI_strncasecmp() */ static int txttl_cmp(const char *first, const char *second, int len) { int cmp, i; @@ -113,19 +114,18 @@ short texttool_text_is_active(Text *text) void texttool_suggest_add(const char *name, char type) { + const int len = strlen(name); + int cmp; SuggItem *newitem, *item; - int len, cmp; - newitem = MEM_mallocN(sizeof(SuggItem) + strlen(name) + 1, "SuggestionItem"); + newitem = MEM_mallocN(sizeof(SuggItem) + len + 1, "SuggItem"); if (!newitem) { printf("Failed to allocate memory for suggestion.\n"); return; } newitem->name = (char *) (newitem + 1); - len = strlen(name); - strncpy(newitem->name, name, len); - newitem->name[len] = '\0'; + memcpy(newitem->name, name, len + 1); newitem->type = type; newitem->prev = newitem->next = NULL; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index d230cf8f1fe..d166592424d 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -136,8 +136,7 @@ static void txt_pop_first(Text *text); static void txt_pop_last(Text *text); -static void txt_undo_add_op(Text *text, int op); -static void txt_undo_add_block(Text *text, int op, const char *buf); +static void txt_undo_add_blockop(Text *text, int op, const char *buf); static void txt_delete_line(Text *text, TextLine *line); static void txt_delete_sel(Text *text); static void txt_make_dirty(Text *text); @@ -785,23 +784,6 @@ static void txt_curs_sel(Text *text, TextLine ***linep, int **charp) *linep = &text->sell; *charp = &text->selc; } -static void txt_curs_first(Text *text, TextLine **linep, int *charp) -{ - if (text->curl == text->sell) { - *linep = text->curl; - if (text->curc < text->selc) *charp = text->curc; - else *charp = text->selc; - } - else if (txt_get_span(text->lines.first, text->curl) < txt_get_span(text->lines.first, text->sell)) { - *linep = text->curl; - *charp = text->curc; - } - else { - *linep = text->sell; - *charp = text->selc; - } -} - /*****************************/ /* Cursor movement functions */ /*****************************/ @@ -843,13 +825,11 @@ void txt_move_up(Text *text, short sel) { TextLine **linep; int *charp; - /* int old; */ /* UNUSED */ if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - /* old = *charp; */ /* UNUSED */ if ((*linep)->prev) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); @@ -857,8 +837,6 @@ void txt_move_up(Text *text, short sel) if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len; else *charp = txt_utf8_index_to_offset((*linep)->line, index); - if (!undoing) - txt_undo_add_op(text, sel ? UNDO_SUP : UNDO_CUP); } else { txt_move_bol(text, sel); @@ -871,22 +849,17 @@ void txt_move_down(Text *text, short sel) { TextLine **linep; int *charp; - /* int old; */ /* UNUSED */ if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - /* old = *charp; */ /* UNUSED */ if ((*linep)->next) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); *linep = (*linep)->next; if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len; else *charp = txt_utf8_index_to_offset((*linep)->line, index); - - if (!undoing) - txt_undo_add_op(text, sel ? UNDO_SDOWN : UNDO_CDOWN); } else { txt_move_eol(text, sel); @@ -898,7 +871,7 @@ void txt_move_down(Text *text, short sel) void txt_move_left(Text *text, short sel) { TextLine **linep; - int *charp, oundoing = undoing; + int *charp; int tabsize = 0, i = 0; if (!text) return; @@ -906,8 +879,6 @@ void txt_move_left(Text *text, short sel) else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - undoing = 1; - if (*charp == 0) { if ((*linep)->prev) { txt_move_up(text, sel); @@ -939,24 +910,19 @@ void txt_move_left(Text *text, short sel) } } - undoing = oundoing; - if (!undoing) txt_undo_add_op(text, sel ? UNDO_SLEFT : UNDO_CLEFT); - if (!sel) txt_pop_sel(text); } void txt_move_right(Text *text, short sel) { TextLine **linep; - int *charp, oundoing = undoing, do_tab = FALSE, i; + int *charp, do_tab = FALSE, i; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - undoing = 1; - if (*charp == (*linep)->len) { if ((*linep)->next) { txt_move_down(text, sel); @@ -984,124 +950,103 @@ void txt_move_right(Text *text, short sel) else (*charp) += BLI_str_utf8_size((*linep)->line + *charp); } - undoing = oundoing; - if (!undoing) txt_undo_add_op(text, sel ? UNDO_SRIGHT : UNDO_CRIGHT); - if (!sel) txt_pop_sel(text); } void txt_jump_left(Text *text, short sel) { TextLine **linep; - int *charp, oldc; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - oldc = *charp; BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, charp, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM); if (!sel) txt_pop_sel(text); - if (!undoing) { - int span = txt_get_span(text->lines.first, *linep); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp); - } } void txt_jump_right(Text *text, short sel) { TextLine **linep; - int *charp, oldc; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - oldc = *charp; BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, charp, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM); if (!sel) txt_pop_sel(text); - if (!undoing) { - int span = txt_get_span(text->lines.first, *linep); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp); - } } void txt_move_bol(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; *charp = 0; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_eol(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; - + *charp = (*linep)->len; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_bof(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; *linep = text->lines.first; *charp = 0; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_eof(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; *linep = text->lines.last; *charp = (*linep)->len; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_toline(Text *text, unsigned int line, short sel) @@ -1112,16 +1057,14 @@ void txt_move_toline(Text *text, unsigned int line, short sel) /* Moves to a certain byte in a line, not a certain utf8-character! */ void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel) { - TextLine **linep, *oldl; - int *charp, oldc; + TextLine **linep; + int *charp; unsigned int i; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - oldc = *charp; - oldl = *linep; *linep = text->lines.first; for (i = 0; i < line; i++) { @@ -1133,7 +1076,6 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel) *charp = ch; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } /****************************/ @@ -1152,8 +1094,6 @@ static void txt_curs_swap(Text *text) tmpc = text->curc; text->curc = text->selc; text->selc = tmpc; - - if (!undoing) txt_undo_add_op(text, UNDO_SWAP); } static void txt_pop_first(Text *text) @@ -1164,12 +1104,6 @@ static void txt_pop_first(Text *text) { txt_curs_swap(text); } - - if (!undoing) txt_undo_add_toop(text, UNDO_STO, - txt_get_span(text->lines.first, text->sell), - text->selc, - txt_get_span(text->lines.first, text->curl), - text->curc); txt_pop_sel(text); } @@ -1181,12 +1115,6 @@ static void txt_pop_last(Text *text) { txt_curs_swap(text); } - - if (!undoing) txt_undo_add_toop(text, UNDO_STO, - txt_get_span(text->lines.first, text->sell), - text->selc, - txt_get_span(text->lines.first, text->curl), - text->curc); txt_pop_sel(text); } @@ -1236,7 +1164,7 @@ static void txt_delete_sel(Text *text) if (!undoing) { buf = txt_sel_to_buf(text); - txt_undo_add_block(text, UNDO_DBLOCK, buf); + txt_undo_add_blockop(text, UNDO_DBLOCK, buf); MEM_freeN(buf); } @@ -1517,7 +1445,7 @@ void txt_insert_buf(Text *text, const char *in_buffer) buffer = BLI_strdupn(in_buffer, len); len += txt_extended_ascii_as_utf8(&buffer); - if (!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer); + if (!undoing) txt_undo_add_blockop(text, UNDO_IBLOCK, buffer); u = undoing; undoing = 1; @@ -1599,6 +1527,7 @@ static void dump_buffer(Text *text) while (i++ < text->undo_pos) printf("%d: %d %c\n", i, text->undo_buf[i], text->undo_buf[i]); } +/* Note: this function is outdated and must be updated if needed for future use */ void txt_print_undo(Text *text) { int i = 0; @@ -1615,37 +1544,7 @@ void txt_print_undo(Text *text) while (i <= text->undo_pos) { op = text->undo_buf[i]; - if (op == UNDO_CLEFT) { - ops = "Cursor left"; - } - else if (op == UNDO_CRIGHT) { - ops = "Cursor right"; - } - else if (op == UNDO_CUP) { - ops = "Cursor up"; - } - else if (op == UNDO_CDOWN) { - ops = "Cursor down"; - } - else if (op == UNDO_SLEFT) { - ops = "Selection left"; - } - else if (op == UNDO_SRIGHT) { - ops = "Selection right"; - } - else if (op == UNDO_SUP) { - ops = "Selection up"; - } - else if (op == UNDO_SDOWN) { - ops = "Selection down"; - } - else if (op == UNDO_STO) { - ops = "Selection "; - } - else if (op == UNDO_CTO) { - ops = "Cursor "; - } - else if (op == UNDO_INSERT_1) { + if (op == UNDO_INSERT_1) { ops = "Insert ascii "; } else if (op == UNDO_INSERT_2) { @@ -1681,9 +1580,6 @@ void txt_print_undo(Text *text) else if (op == UNDO_DEL_4) { ops = "Delete unicode "; } - else if (op == UNDO_SWAP) { - ops = "Cursor swap"; - } else if (op == UNDO_DBLOCK) { ops = "Delete text block"; } @@ -1738,29 +1634,6 @@ void txt_print_undo(Text *text) } } } - else if (op == UNDO_STO || op == UNDO_CTO) { - i++; - - charp = text->undo_buf[i]; i++; - charp = charp + (text->undo_buf[i] << 8); i++; - - linep = text->undo_buf[i]; i++; - linep = linep + (text->undo_buf[i] << 8); i++; - linep = linep + (text->undo_buf[i] << 16); i++; - linep = linep + (text->undo_buf[i] << 24); i++; - - printf("to <%d, %d> ", linep, charp); - - charp = text->undo_buf[i]; i++; - charp = charp + (text->undo_buf[i] << 8); i++; - - linep = text->undo_buf[i]; i++; - linep = linep + (text->undo_buf[i] << 8); i++; - linep = linep + (text->undo_buf[i] << 16); i++; - linep = linep + (text->undo_buf[i] << 24); i++; - - printf("from <%d, %d>", linep, charp); - } else if (op == UNDO_DBLOCK || op == UNDO_IBLOCK) { i++; @@ -1811,16 +1684,6 @@ void txt_print_undo(Text *text) } } -static void txt_undo_add_op(Text *text, int op) -{ - if (!max_undo_test(text, 2)) - return; - - text->undo_pos++; - text->undo_buf[text->undo_pos] = op; - text->undo_buf[text->undo_pos + 1] = 0; -} - static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value) { undo_buf[*undo_pos] = (value) & 0xff; @@ -1841,17 +1704,41 @@ static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int va (*undo_pos)++; } -static void txt_undo_add_block(Text *text, int op, const char *buf) +/* store the cur cursor to the undo buffer */ +static void txt_undo_store_cur(Text *text) +{ + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->curc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->curl)); +} + +/* store the sel cursor to the undo buffer */ +static void txt_undo_store_sel(Text *text) +{ + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->selc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->sell)); +} + +/* store both cursors to the undo buffer */ +static void txt_undo_store_cursors(Text *text) +{ + txt_undo_store_cur(text); + txt_undo_store_sel(text); +} + +/* store an operator along with a block of data */ +static void txt_undo_add_blockop(Text *text, int op, const char *buf) { unsigned int length = strlen(buf); - if (!max_undo_test(text, length + 11)) + if (!max_undo_test(text, length + 11 + 12)) return; text->undo_pos++; text->undo_buf[text->undo_pos] = op; text->undo_pos++; + txt_undo_store_cursors(text); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length); strncpy(text->undo_buf + text->undo_pos, buf, length); @@ -1863,34 +1750,30 @@ static void txt_undo_add_block(Text *text, int op, const char *buf) text->undo_buf[text->undo_pos + 1] = 0; } -void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc) +/* store a regular operator */ +void txt_undo_add_op(Text *text, int op) { if (!max_undo_test(text, 15)) return; - if (froml == tol && fromc == toc) return; - text->undo_pos++; text->undo_buf[text->undo_pos] = op; text->undo_pos++; - txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc); - txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml); - txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc); - txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol); + txt_undo_store_cursors(text); text->undo_buf[text->undo_pos] = op; - text->undo_buf[text->undo_pos + 1] = 0; } +/* store an operator for a single character */ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) { char utf8[BLI_UTF8_MAX]; size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8); - if (!max_undo_test(text, 3 + utf8_size)) + if (!max_undo_test(text, 3 + utf8_size + 12)) return; text->undo_pos++; @@ -1899,6 +1782,8 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) text->undo_buf[text->undo_pos] = op_start + utf8_size - 1; text->undo_pos++; + txt_undo_store_cur(text); + for (i = 0; i < utf8_size; i++) { text->undo_buf[text->undo_pos] = utf8[i]; text->undo_pos++; @@ -1909,6 +1794,9 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) else { text->undo_buf[text->undo_pos] = op_start + 3; text->undo_pos++; + + txt_undo_store_cursors(text); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c); text->undo_buf[text->undo_pos] = op_start + 3; } @@ -1934,6 +1822,29 @@ static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos) return val; } +/* read the cur cursor from the undo buffer */ +static void txt_undo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc) +{ + *curln = txt_undo_read_uint32(undo_buf, undo_pos); + *curc = txt_undo_read_uint16(undo_buf, undo_pos); +} + +/* read the sel cursor from the undo buffer */ +static void txt_undo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc) +{ + *selln = txt_undo_read_uint32(undo_buf, undo_pos); + *selc = txt_undo_read_uint16(undo_buf, undo_pos); +} + +/* read both cursors from the undo buffer */ +static void txt_undo_read_cursors(const char *undo_buf, int *undo_pos, + unsigned int *curln, unsigned short *curc, + unsigned int *selln, unsigned short *selc) +{ + txt_undo_read_sel(undo_buf, undo_pos, selln, selc); + txt_undo_read_cur(undo_buf, undo_pos, curln, curc); +} + static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) { unsigned int unicode; @@ -1986,6 +1897,29 @@ static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos) return val; } +/* redo read cur cursor from the undo buffer */ +static void txt_redo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc) +{ + *curc = txt_redo_read_uint16(undo_buf, undo_pos); + *curln = txt_redo_read_uint32(undo_buf, undo_pos); +} + +/* redo read sel cursor from the undo buffer */ +static void txt_redo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc) +{ + *selc = txt_redo_read_uint16(undo_buf, undo_pos); + *selln = txt_redo_read_uint32(undo_buf, undo_pos); +} + +/* redo read both cursors from the undo buffer */ +static void txt_redo_read_cursors(const char *undo_buf, int *undo_pos, + unsigned int *curln, unsigned short *curc, + unsigned int *selln, unsigned short *selc) +{ + txt_redo_read_cur(undo_buf, undo_pos, curln, curc); + txt_redo_read_sel(undo_buf, undo_pos, selln, selc); +} + static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) { unsigned int unicode; @@ -2024,9 +1958,10 @@ void txt_do_undo(Text *text) { int op = text->undo_buf[text->undo_pos]; unsigned int linep, i; + unsigned int uchar; + unsigned int curln, selln; + unsigned short curc, selc; unsigned short charp; - TextLine *holdl; - int holdc, holdln; char *buf; if (text->undo_pos < 0) { @@ -2038,88 +1973,60 @@ void txt_do_undo(Text *text) undoing = 1; switch (op) { - case UNDO_CLEFT: - txt_move_right(text, 0); - break; - - case UNDO_CRIGHT: - txt_move_left(text, 0); - break; - - case UNDO_CUP: - txt_move_down(text, 0); - break; - - case UNDO_CDOWN: - txt_move_up(text, 0); - break; - - case UNDO_SLEFT: - txt_move_right(text, 1); - break; - - case UNDO_SRIGHT: - txt_move_left(text, 1); - break; - - case UNDO_SUP: - txt_move_down(text, 1); - break; - - case UNDO_SDOWN: - txt_move_up(text, 1); - break; - - case UNDO_CTO: - case UNDO_STO: - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - - text->undo_pos--; - text->undo_pos--; - - linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - - if (op == UNDO_CTO) { - txt_move_toline(text, linep, 0); - text->curc = charp; - txt_pop_sel(text); - } - else { - txt_move_toline(text, linep, 1); - text->selc = charp; - } - - text->undo_pos--; - break; - - case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: - txt_backspace_char(text); + case UNDO_INSERT_1: + case UNDO_INSERT_2: + case UNDO_INSERT_3: + case UNDO_INSERT_4: text->undo_pos -= op - UNDO_INSERT_1 + 1; - text->undo_pos--; - break; - - case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: - charp = op - UNDO_BS_1 + 1; - txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); - text->undo_pos--; - break; - case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: - charp = op - UNDO_DEL_1 + 1; - txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); - txt_move_left(text, 0); + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + txt_delete_char(text); + text->undo_pos--; break; - case UNDO_SWAP: - txt_curs_swap(text); + case UNDO_BS_1: + case UNDO_BS_2: + case UNDO_BS_3: + case UNDO_BS_4: + charp = op - UNDO_BS_1 + 1; + uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp); + + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + txt_add_char(text, uchar); + + text->undo_pos--; + break; + + case UNDO_DEL_1: + case UNDO_DEL_2: + case UNDO_DEL_3: + case UNDO_DEL_4: + charp = op - UNDO_DEL_1 + 1; + uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp); + + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + txt_add_char(text, uchar); + + txt_move_left(text, 0); + + text->undo_pos--; break; case UNDO_DBLOCK: + /* length of the string in the buffer */ linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); buf = MEM_mallocN(linep + 1, "dblock buffer"); @@ -2128,34 +2035,33 @@ void txt_do_undo(Text *text) text->undo_pos--; } buf[i] = 0; - - txt_curs_first(text, &holdl, &holdc); - holdln = txt_get_span(text->lines.first, holdl); - - txt_insert_buf(text, buf); - MEM_freeN(buf); - - text->curl = text->lines.first; - while (holdln > 0) { - if (text->curl->next) - text->curl = text->curl->next; - - holdln--; - } - text->curc = holdc; + /* skip over the length that was stored again */ text->undo_pos--; text->undo_pos--; text->undo_pos--; text->undo_pos--; + /* Get the cursor positions */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + + /* move cur to location that needs buff inserted */ + txt_move_to(text, curln, curc, 0); + + txt_insert_buf(text, buf); + MEM_freeN(buf); + + /* restore the cursors */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + text->undo_pos--; break; case UNDO_IBLOCK: + /* length of the string in the buffer */ linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - txt_delete_sel(text); /* txt_backspace_char removes utf8-characters, not bytes */ buf = MEM_mallocN(linep + 1, "iblock buffer"); @@ -2167,47 +2073,32 @@ void txt_do_undo(Text *text) linep = txt_utf8_len(buf); MEM_freeN(buf); - while (linep > 0) { - txt_backspace_char(text); - linep--; - } + /* skip over the length that was stored again */ + text->undo_pos--; + text->undo_pos--; + text->undo_pos--; + text->undo_pos--; + + /* get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc + linep, 1); + + txt_delete_selected(text); text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - - text->undo_pos--; - break; case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: - linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the end line of the selection - - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - //charp is the last char selected or text->line->len - - //set the selection for this now - text->selc = charp; - text->sell = text->lines.first; - for (i = 0; i < linep; i++) { - text->sell = text->sell->next; - } - - linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - //first line to be selected - - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - //first postion to be selected - text->curc = charp; - text->curl = text->lines.first; - for (i = 0; i < linep; i++) { - text->curl = text->curl->next; - } - + case UNDO_DUPLICATE: + case UNDO_MOVE_LINES_UP: + case UNDO_MOVE_LINES_DOWN: + /* get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); if (op == UNDO_INDENT) { txt_unindent(text); @@ -2221,37 +2112,24 @@ void txt_do_undo(Text *text) else if (op == UNDO_UNCOMMENT) { txt_comment(text); } + else if (op == UNDO_DUPLICATE) { + txt_delete_line(text, text->curl->next); + } + else if (op == UNDO_MOVE_LINES_UP) { + txt_move_lines(text, TXT_MOVE_LINE_DOWN); + } + else if (op == UNDO_MOVE_LINES_DOWN) { + txt_move_lines(text, TXT_MOVE_LINE_UP); + } text->undo_pos--; break; - case UNDO_DUPLICATE: - txt_delete_line(text, text->curl->next); - break; - case UNDO_MOVE_LINES_UP: - txt_move_lines(text, TXT_MOVE_LINE_DOWN); - break; - case UNDO_MOVE_LINES_DOWN: - txt_move_lines(text, TXT_MOVE_LINE_UP); - break; default: //XXX error("Undo buffer error - resetting"); text->undo_pos = -1; break; } - - /* next undo step may need evaluating */ - if (text->undo_pos >= 0) { - switch (text->undo_buf[text->undo_pos]) { - case UNDO_STO: - txt_do_undo(text); - txt_do_redo(text); /* selections need restoring */ - break; - case UNDO_SWAP: - txt_do_undo(text); /* swaps should appear transparent */ - break; - } - } undoing = 0; } @@ -2259,9 +2137,12 @@ void txt_do_undo(Text *text) void txt_do_redo(Text *text) { char op; - unsigned int linep, i; - unsigned short charp; char *buf; + unsigned int linep; + unsigned short charp; + unsigned int uchar; + unsigned int curln, selln; + unsigned short curc, selc; text->undo_pos++; op = text->undo_buf[text->undo_pos]; @@ -2274,104 +2155,91 @@ void txt_do_redo(Text *text) undoing = 1; switch (op) { - case UNDO_CLEFT: - txt_move_left(text, 0); - break; - - case UNDO_CRIGHT: - txt_move_right(text, 0); - break; - - case UNDO_CUP: - txt_move_up(text, 0); - break; - - case UNDO_CDOWN: - txt_move_down(text, 0); - break; - - case UNDO_SLEFT: - txt_move_left(text, 1); - break; - - case UNDO_SRIGHT: - txt_move_right(text, 1); - break; - - case UNDO_SUP: - txt_move_up(text, 1); - break; - - case UNDO_SDOWN: - txt_move_down(text, 1); - break; - - case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: + case UNDO_INSERT_1: + case UNDO_INSERT_2: + case UNDO_INSERT_3: + case UNDO_INSERT_4: text->undo_pos++; + + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + charp = op - UNDO_INSERT_1 + 1; - txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp)); + uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp); + + txt_add_char(text, uchar); break; - case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: + case UNDO_BS_1: + case UNDO_BS_2: + case UNDO_BS_3: + case UNDO_BS_4: text->undo_pos++; - txt_backspace_char(text); + + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + text->undo_pos += op - UNDO_BS_1 + 1; + + /* move right so we backspace the correct char */ + txt_move_right(text, 0); + txt_backspace_char(text); + break; - case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: + case UNDO_DEL_1: + case UNDO_DEL_2: + case UNDO_DEL_3: + case UNDO_DEL_4: text->undo_pos++; - txt_delete_char(text); + + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + text->undo_pos += op - UNDO_DEL_1 + 1; - break; - case UNDO_SWAP: - txt_curs_swap(text); - txt_do_redo(text); /* swaps should appear transparent a*/ - break; - - case UNDO_CTO: - case UNDO_STO: - text->undo_pos++; - text->undo_pos++; - - text->undo_pos++; - text->undo_pos++; - text->undo_pos++; - text->undo_pos++; - - text->undo_pos++; - - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - - if (op == UNDO_CTO) { - txt_move_toline(text, linep, 0); - text->curc = charp; - txt_pop_sel(text); - } - else { - txt_move_toline(text, linep, 1); - text->selc = charp; - } + txt_delete_char(text); break; case UNDO_DBLOCK: text->undo_pos++; + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + + /* length of the block */ linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - txt_delete_sel(text); text->undo_pos += linep; + /* skip over the length that was stored again */ text->undo_pos++; text->undo_pos++; text->undo_pos++; text->undo_pos++; + txt_delete_sel(text); + break; case UNDO_IBLOCK: text->undo_pos++; + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + /* length of the block */ linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); buf = MEM_mallocN(linep + 1, "iblock buffer"); @@ -2382,40 +2250,27 @@ void txt_do_redo(Text *text) txt_insert_buf(text, buf); MEM_freeN(buf); + /* skip over the length that was stored again */ text->undo_pos++; text->undo_pos++; text->undo_pos++; text->undo_pos++; + break; case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: + case UNDO_DUPLICATE: + case UNDO_MOVE_LINES_UP: + case UNDO_MOVE_LINES_DOWN: text->undo_pos++; - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - //charp is the first char selected or 0 - - linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the first line of the selection - //set the selcetion for this now - text->curc = charp; - text->curl = text->lines.first; - for (i = 0; i < linep; i++) { - text->curl = text->curl->next; - } - - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - //last postion to be selected - - linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //Last line to be selected - - text->selc = charp; - text->sell = text->lines.first; - for (i = 0; i < linep; i++) { - text->sell = text->sell->next; - } + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); if (op == UNDO_INDENT) { txt_indent(text); @@ -2429,15 +2284,28 @@ void txt_do_redo(Text *text) else if (op == UNDO_UNCOMMENT) { txt_uncomment(text); } - break; - case UNDO_DUPLICATE: - txt_duplicate_line(text); - break; - case UNDO_MOVE_LINES_UP: - txt_move_lines(text, TXT_MOVE_LINE_UP); - break; - case UNDO_MOVE_LINES_DOWN: - txt_move_lines(text, TXT_MOVE_LINE_DOWN); + else if (op == UNDO_DUPLICATE) { + txt_duplicate_line(text); + } + else if (op == UNDO_MOVE_LINES_UP) { + /* offset the cursor by + 1 */ + txt_move_to(text, curln + 1, curc, 0); + txt_move_to(text, selln + 1, selc, 1); + + txt_move_lines(text, TXT_MOVE_LINE_UP); + } + else if (op == UNDO_MOVE_LINES_DOWN) { + /* offset the cursor by - 1 */ + txt_move_to(text, curln - 1, curc, 0); + txt_move_to(text, selln - 1, selc, 1); + + txt_move_lines(text, TXT_MOVE_LINE_DOWN); + } + + /* re-restore the cursors since they got moved when redoing */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + break; default: //XXX error("Undo buffer error - resetting"); @@ -2518,20 +2386,22 @@ void txt_split_curline(Text *text) static void txt_delete_line(Text *text, TextLine *line) { TextMarker *mrk = NULL, *nxt; - int lineno = -1; if (!text) return; if (!text->curl) return; - lineno = txt_get_span(text->lines.first, line); - mrk = text->markers.first; - while (mrk) { - nxt = mrk->next; - if (mrk->lineno == lineno) - BLI_freelinkN(&text->markers, mrk); - else if (mrk->lineno > lineno) - mrk->lineno--; - mrk = nxt; + /* warning, this can be _slow_ when deleting many lines! */ + if ((mrk = text->markers.first)) { + int lineno = txt_get_span(text->lines.first, line); + mrk = text->markers.first; + while (mrk) { + nxt = mrk->next; + if (mrk->lineno == lineno) + BLI_freelinkN(&text->markers, mrk); + else if (mrk->lineno > lineno) + mrk->lineno--; + mrk = nxt; + } } BLI_remlink(&text->lines, line); @@ -2549,14 +2419,14 @@ static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb) { char *tmp; TextMarker *mrk = NULL; - int lineno = -1; - + if (!text) return; if (!linea || !lineb) return; mrk = txt_find_marker_region(text, lineb, 0, lineb->len, 0, 0); if (mrk) { + int lineno; lineno = mrk->lineno; do { mrk->lineno--; @@ -2565,8 +2435,11 @@ static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb) mrk = mrk->next; } while (mrk && mrk->lineno == lineno); } - if (lineno == -1) lineno = txt_get_span(text->lines.first, lineb); - +#if 0 /* UNUSED */ + if (lineno == -1) + lineno = txt_get_span(text->lines.first, lineb); +#endif + tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string"); strcpy(tmp, linea->line); @@ -2767,6 +2640,8 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs) txt_delete_sel(text); + if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); + add_len = BLI_str_utf8_from_unicode(add, ch); mrk = txt_find_marker_region(text, text->curl, text->curc - 1, text->curl->len, 0, 0); if (mrk) { @@ -2793,7 +2668,6 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs) txt_make_dirty(text); txt_clean_text(text); - if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); return 1; } @@ -2854,8 +2728,8 @@ int txt_replace_char(Text *text, unsigned int add) /* Should probably create a new op for this */ if (!undoing) { - txt_undo_add_charop(text, UNDO_DEL_1, del); txt_undo_add_charop(text, UNDO_INSERT_1, add); + txt_undo_add_charop(text, UNDO_DEL_1, del); } return 1; } @@ -2924,7 +2798,7 @@ void txt_indent(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_INDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_INDENT); } } @@ -2982,7 +2856,7 @@ void txt_unindent(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_UNINDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_UNINDENT); } } @@ -3031,7 +2905,7 @@ void txt_comment(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_COMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_COMMENT); } } @@ -3076,7 +2950,7 @@ void txt_uncomment(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_UNCOMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_UNCOMMENT); } } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index b174f27b7e1..30b48401046 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1124,10 +1124,10 @@ void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float { INIT_MINMAX2(min, max); - DO_MINMAX2(marker->pattern_corners[0], min, max); - DO_MINMAX2(marker->pattern_corners[1], min, max); - DO_MINMAX2(marker->pattern_corners[2], min, max); - DO_MINMAX2(marker->pattern_corners[3], min, max); + minmax_v2v2_v2(min, max, marker->pattern_corners[0]); + minmax_v2v2_v2(min, max, marker->pattern_corners[1]); + minmax_v2v2_v2(min, max, marker->pattern_corners[2]); + minmax_v2v2_v2(min, max, marker->pattern_corners[3]); } void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2]) @@ -3161,7 +3161,7 @@ static int stabilization_median_point_get(MovieTracking *tracking, int framenr, if (track->flag & TRACK_USE_2D_STAB) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - DO_MINMAX2(marker->pos, min, max); + minmax_v2v2_v2(min, max, marker->pos); ok = TRUE; } diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 80169e952bf..509927e589c 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -187,6 +187,10 @@ int barycentric_inside_triangle_v2(const float w[3]); void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]); void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]); +/* use to find the point of a UV on a face */ +void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]); +void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]); + /***************************** View & Projection *****************************/ void lookat_m4(float mat[4][4], float vx, float vy, diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 77c0ec0a88f..5f80d1e52d7 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -169,6 +169,7 @@ void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const void mid_v3_v3v3(float r[3], const float a[3], const float b[3]); void mid_v2_v2v2(float r[2], const float a[2], const float b[2]); +void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]); /********************************* Comparison ********************************/ diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 9cd801f819d..ec8e567c0ef 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -37,6 +37,10 @@ extern "C" { #include +#ifdef __APPLE__ +#include +#endif + /* for tables, button in UI, etc */ #define BLENDER_MAX_THREADS 64 @@ -92,6 +96,19 @@ void BLI_mutex_lock(ThreadMutex *mutex); void BLI_mutex_unlock(ThreadMutex *mutex); void BLI_mutex_end(ThreadMutex *mutex); +/* Spin Lock */ + +#ifdef __APPLE__ +typedef OSSpinLock SpinLock; +#else +typedef pthread_spinlock_t SpinLock; +#endif + +void BLI_spin_init(SpinLock *spin); +void BLI_spin_lock(SpinLock *spin); +void BLI_spin_unlock(SpinLock *spin); +void BLI_spin_end(SpinLock *spin); + /* Read/Write Mutex Lock */ #define THREAD_LOCK_READ 1 diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 056fa916da1..a22aa0c13d7 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -257,6 +257,15 @@ #define IN_RANGE(a, b, c) ((b < c) ? ((b < a && a < c) ? 1 : 0) : ((c < a && a < b) ? 1 : 0)) #define IN_RANGE_INCL(a, b, c) ((b < c) ? ((b <= a && a <= c) ? 1 : 0) : ((c <= a && a <= b) ? 1 : 0)) +/* unpack vector for args */ +#define UNPACK2(a) ((a)[0]), ((a)[1]) +#define UNPACK3(a) ((a)[0]), ((a)[1]), ((a)[2]) +#define UNPACK4(a) ((a)[0]), ((a)[1]), ((a)[2]), ((a)[3]) +/* op may be '&' or '*' */ +#define UNPACK2OP(a, op) op((a)[0]), op((a)[1]) +#define UNPACK3OP(a, op) op((a)[0]), op((a)[1]), op((a)[2]) +#define UNPACK4OP(a, op) op((a)[0]), op((a)[1]), op((a)[2]), op((a)[3]) + /* array helpers */ #define ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot) \ (arr_dtype *)((char *)arr_start + (elem_size * (tot - 1))) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 7968fcabda6..6cf167b8823 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1410,7 +1410,7 @@ static float ray_nearest_hit(BVHRayCastData *data, const float bv[6]) * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] * - * TODO this doens't has data->ray.radius in consideration */ + * TODO this doesn't take data->ray.radius into consideration */ static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *node) { const float *bv = node->bv; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index e10229f11da..cd726179f56 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2399,6 +2399,33 @@ void resolve_quad_uv(float r_uv[2], const float st[2], const float st0[2], const #undef IS_ZERO +/* reverse of the functions above */ +void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]) +{ + float vec[3]; + + copy_v3_v3(res, data[0]); + mul_v3_fl(res, (1 - u) * (1 - v)); + copy_v3_v3(vec, data[1]); + mul_v3_fl(vec, u * (1 - v)); add_v3_v3(res, vec); + copy_v3_v3(vec, data[2]); + mul_v3_fl(vec, u * v); add_v3_v3(res, vec); + copy_v3_v3(vec, data[3]); + mul_v3_fl(vec, (1 - u) * v); add_v3_v3(res, vec); +} + +void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]) +{ + float vec[3]; + + copy_v3_v3(res, data[0]); + mul_v3_fl(res, u); + copy_v3_v3(vec, data[1]); + mul_v3_fl(vec, v); add_v3_v3(res, vec); + copy_v3_v3(vec, data[2]); + mul_v3_fl(vec, 1.0f - u - v); add_v3_v3(res, vec); +} + /***************************** View & Projection *****************************/ void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 59a1c1f649c..5a9e8244a46 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -134,12 +134,12 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const fl w = wx * wy[m + 1]; if (float_output) { - const float *float_data = float_buffer + width * y1 * 4 + 4 * x1; + const float *float_data = float_buffer + width * y1 * components + components * x1; vector_from_float(float_data, data, components); } else { - const unsigned char *byte_data = byte_buffer + width * y1 * 4 + 4 * x1; + const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1; vector_from_byte(byte_data, data, components); } @@ -173,12 +173,12 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const fl float data[4]; if (float_output) { - const float *float_data = float_buffer + width * y1 * 4 + 4 * x1; + const float *float_data = float_buffer + width * y1 * components + components * x1; vector_from_float(float_data, data, components); } else { - const unsigned char *byte_data = byte_buffer + width * y1 * 4 + 4 * x1; + const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1; vector_from_byte(byte_data, data, components); } @@ -270,16 +270,16 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f /* sample including outside of edges of image */ if (x1 < 0 || y1 < 0) row1 = empty; - else row1 = float_buffer + width * y1 * 4 + 4 * x1; + else row1 = float_buffer + width * y1 * components + components * x1; if (x1 < 0 || y2 > height - 1) row2 = empty; - else row2 = float_buffer + width * y2 * 4 + 4 * x1; + else row2 = float_buffer + width * y2 * components + components * x1; if (x2 > width - 1 || y1 < 0) row3 = empty; - else row3 = float_buffer + width * y1 * 4 + 4 * x2; + else row3 = float_buffer + width * y1 * components + components * x2; if (x2 > width - 1 || y2 > height - 1) row4 = empty; - else row4 = float_buffer + width * y2 * 4 + 4 * x2; + else row4 = float_buffer + width * y2 * components + components * x2; a = u - floorf(u); b = v - floorf(v); @@ -306,16 +306,16 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f /* sample including outside of edges of image */ if (x1 < 0 || y1 < 0) row1 = empty; - else row1 = byte_buffer + width * y1 * 4 + 4 * x1; + else row1 = byte_buffer + width * y1 * components + components * x1; if (x1 < 0 || y2 > height - 1) row2 = empty; - else row2 = byte_buffer + width * y2 * 4 + 4 * x1; + else row2 = byte_buffer + width * y2 * components + components * x1; if (x2 > width - 1 || y1 < 0) row3 = empty; - else row3 = byte_buffer + width * y1 * 4 + 4 * x2; + else row3 = byte_buffer + width * y1 * components + components * x2; if (x2 > width - 1 || y2 > height - 1) row4 = empty; - else row4 = byte_buffer + width * y2 * 4 + 4 * x2; + else row4 = byte_buffer + width * y2 * components + components * x2; a = u - floorf(u); b = v - floorf(v); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index b0c4724e1ec..3069542107e 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -84,7 +84,7 @@ void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4]) * \note: * Assumes a unit quaternion? * - * in fact not, but you may wan't to use a unit quat, read on... + * in fact not, but you may want to use a unit quat, read on... * * Shortcut for 'q v q*' when \a v is actually a quaternion. * This removes the need for converting a vector to a quaternion, diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 976895fe6fc..812e2b3e63d 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -115,6 +115,13 @@ void mid_v2_v2v2(float v[2], const float v1[2], const float v2[2]) v[1] = 0.5f * (v1[1] + v2[1]); } +void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]) +{ + v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f; + v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f; + v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f; +} + /********************************** Angles ***********************************/ /* Return the angle in radians between vecs 1-2 and 2-3 in radians @@ -201,6 +208,13 @@ float angle_signed_v2v2(const float v1[2], const float v2[2]) float angle_normalized_v3v3(const float v1[3], const float v2[3]) { + /* double check they are normalized */ +#ifdef DEBUG + float test; + BLI_assert(fabsf((test = len_squared_v3(v1)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f); + BLI_assert(fabsf((test = len_squared_v3(v2)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f); +#endif + /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ if (dot_v3v3(v1, v2) < 0.0f) { float vec[3]; @@ -217,6 +231,13 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3]) float angle_normalized_v2v2(const float v1[2], const float v2[2]) { + /* double check they are normalized */ +#ifdef DEBUG + float test; + BLI_assert(fabsf((test = len_squared_v2(v1)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f); + BLI_assert(fabsf((test = len_squared_v2(v2)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f); +#endif + /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */ if (dot_v2v2(v1, v2) < 0.0f) { float vec[2]; @@ -401,6 +422,12 @@ void rotate_normalized_v3_v3v3fl(float r[3], const float p[3], const float axis[ const float costheta = cos(angle); const float sintheta = sin(angle); + /* double check they are normalized */ +#ifdef DEBUG + float test; + BLI_assert(fabsf((test = len_squared_v3(axis)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f); +#endif + r[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) + (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) + (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]); diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 6bb59e1e195..f37e1e03f39 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -398,7 +398,8 @@ static float orgBlenderNoise(float x, float y, float z) h = hashvectf + 3 * hash[b21 + b11]; n += i * (h[0] * jx + h[1] * jy + h[2] * jz); - if (n < 0.0f) n = 0.0f; else if (n > 1.0f) n = 1.0f; + if (n < 0.0f) n = 0.0f; + else if (n > 1.0f) n = 1.0f; return n; } @@ -1890,7 +1891,8 @@ float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity y *= lacunarity; z *= lacunarity; weight = signal * gain; - if (weight > 1.0f) weight = 1.0f; else if (weight < 0.0f) weight = 0.0f; + if (weight > 1.0f) weight = 1.0f; + else if (weight < 0.0f) weight = 0.0f; signal = offset - fabsf(noisefunc(x, y, z)); signal *= signal; signal *= weight; diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index e21ce0716d2..6fa6d86589f 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -1715,11 +1715,14 @@ void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, bvh->grids = grids; bvh->gridadj = gridadj; bvh->gridfaces = gridfaces; - bvh->grid_flag_mats = flagmats; - bvh->grid_hidden = grid_hidden; - for (a = 0; a < bvh->totnode; ++a) - BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]); + if (flagmats != bvh->grid_flag_mats || bvh->grid_hidden != grid_hidden) { + bvh->grid_flag_mats = flagmats; + bvh->grid_hidden = grid_hidden; + + for (a = 0; a < bvh->totnode; ++a) + BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]); + } } float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3] diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 362a87782c6..1b7858f7f88 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -985,7 +985,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu /* CURRENT STATUS: - * - eve->f :1 = availalble in edges + * - eve->f :1 = available in edges * - eve->xs :polynumber * - eve->h :amount of edges connected to vertex * - eve->tmp.v :store! original vertex number diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 66527b9b92a..146e1d531f1 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -400,6 +400,42 @@ void BLI_mutex_end(ThreadMutex *mutex) pthread_mutex_destroy(mutex); } +/* Spin Locks */ + +void BLI_spin_init(SpinLock *spin) +{ +#ifdef __APPLE__ + *spin = OS_SPINLOCK_INIT; +#else + pthread_spin_init(spin, 0); +#endif +} + +void BLI_spin_lock(SpinLock *spin) +{ +#ifdef __APPLE__ + OSSpinLockLock(spin); +#else + pthread_spin_lock(spin); +#endif +} + +void BLI_spin_unlock(SpinLock *spin) +{ +#ifdef __APPLE__ + OSSpinLockUnlock(spin); +#else + pthread_spin_unlock(spin); +#endif +} + +void BLI_spin_end(SpinLock *spin) +{ +#ifndef __APPLE__ + pthread_spin_destroy(spin); +#endif +} + /* Read/Write Mutex Lock */ void BLI_rw_mutex_init(ThreadRWMutex *mutex) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1a16615616d..90fd6cad93c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8553,6 +8553,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + if (ob->step_height == 0.0) { + ob->step_height = 0.150; + ob->jump_speed = 10.0; + ob->fall_speed = 55.0; + } + } + } + /* default values in Freestyle settings */ { Scene *sce; diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index d7858ebbc0d..2a23658f5d0 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -68,10 +68,6 @@ set(SRC intern/bmesh_construct.h intern/bmesh_core.c intern/bmesh_core.h - intern/bmesh_decimate_collapse.c - intern/bmesh_decimate_dissolve.c - intern/bmesh_decimate_unsubdivide.c - intern/bmesh_decimate.h intern/bmesh_inline.h intern/bmesh_interp.c intern/bmesh_interp.h @@ -109,6 +105,12 @@ set(SRC intern/bmesh_error.h tools/BME_bevel.c + tools/bmesh_bevel.c + tools/bmesh_bevel.h + tools/bmesh_decimate_collapse.c + tools/bmesh_decimate_dissolve.c + tools/bmesh_decimate_unsubdivide.c + tools/bmesh_decimate.h bmesh.h bmesh_class.h diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index a672ec0b6a7..6257aa4bf3e 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -252,7 +252,6 @@ extern "C" { #include "intern/bmesh_construct.h" #include "intern/bmesh_core.h" -#include "intern/bmesh_decimate.h" #include "intern/bmesh_interp.h" #include "intern/bmesh_iterators.h" #include "intern/bmesh_marking.h" @@ -267,6 +266,9 @@ extern "C" { #include "intern/bmesh_inline.h" +#include "tools/bmesh_decimate.h" +#include "tools/bmesh_bevel.h" + #ifdef __cplusplus } #endif diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index af5a5719866..f686e96cb7d 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -48,6 +48,8 @@ struct Object; * hrm. it doesn't but stull works ok, remove the comment above? - campbell. */ +// #pragma GCC diagnostic error "-Wpadded" + /** * BMHeader * @@ -69,10 +71,19 @@ typedef struct BMHeader { * this is abused by various tools which set it dirty. * - For loops this is used for sorting during tessellation. */ - char htype; /* element geometric type (verts/edges/loops/faces) */ - char hflag; /* this would be a CD layer, see below */ + char htype; /* element geometric type (verts/edges/loops/faces) */ + char hflag; /* this would be a CD layer, see below */ + + /* internal use only! + * note,.we are very picky about not bloating this struct + * but in this case its padded up to 16 bytes anyway, + * so adding a flag here gives no increase in size */ + char api_flag; +// char _pad; } BMHeader; +BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!"); + /* note: need some way to specify custom locations for custom data layers. so we can * make them point directly into structs. and some way to make it only happen to the * active layer, and properly update when switching active layers.*/ @@ -122,7 +133,10 @@ typedef struct BMLoop { /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */ typedef struct BMElemF { BMHeader head; - struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */ + + /* keep directly after header, + * optional array of flags, only used by the operator stack */ + struct BMFlagLayer *oflags; } BMElemF; /* can cast anything to this, including BMLoop */ @@ -142,21 +156,24 @@ typedef struct BMFace { BMHeader head; struct BMFlagLayer *oflags; /* an array of flags, mostly used by the operator stack */ - int len; /*includes all boundary loops*/ #ifdef USE_BMESH_HOLES int totbounds; /*total boundaries, is one plus the number of holes in the face*/ ListBase loops; #else BMLoop *l_first; #endif - float no[3]; /*yes, we do store this here*/ + int len; /* includes all boundary loops */ + float no[3]; /* yes, we do store this here */ short mat_nr; +// short _pad[3]; } BMFace; typedef struct BMFlagLayer { - short f, pflag; /* flags */ + short f; /* flags */ } BMFlagLayer; +// #pragma GCC diagnostic ignored "-Wpadded" + typedef struct BMesh { int totvert, totedge, totloop, totface; int totvertsel, totedgesel, totfacesel; @@ -166,7 +183,7 @@ typedef struct BMesh { * valid flags are - BM_VERT | BM_EDGE | BM_FACE. * BM_LOOP isn't handled so far. */ char elem_index_dirty; - + /*element pools*/ struct BLI_mempool *vpool, *epool, *lpool, *fpool; @@ -192,7 +209,7 @@ typedef struct BMesh { int walkers, totflags; ListBase selected, error_stack; - + BMFace *act_face; ListBase errorstack; diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 5dd090c523d..ba600cfe6bd 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -187,8 +187,10 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i * _and_ the old bmesh_mf functions, so its kindof smashed together * - joeedh */ - if (!len || !v1 || !v2 || !edges || !bm) + if (!len || !v1 || !v2 || !edges || !bm) { + BLI_assert(0); return NULL; + } /* put edges in correct order */ for (i = 0; i < len; i++) { diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index c427734f58d..d4539050147 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -76,7 +76,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) } /* allocate flag */ - v->oflags = BLI_mempool_calloc(bm->toolflagpool); + if (bm->toolflagpool) { + v->oflags = BLI_mempool_calloc(bm->toolflagpool); + } CustomData_bmesh_set_default(&bm->vdata, &v->head.data); @@ -125,7 +127,9 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, e->head.htype = BM_EDGE; /* allocate flag */ - e->oflags = BLI_mempool_calloc(bm->toolflagpool); + if (bm->toolflagpool) { + e->oflags = BLI_mempool_calloc(bm->toolflagpool); + } e->v1 = v1; e->v2 = v2; @@ -278,7 +282,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm) f->head.htype = BM_FACE; /* allocate flag */ - f->oflags = BLI_mempool_calloc(bm->toolflagpool); + if (bm->toolflagpool) { + f->oflags = BLI_mempool_calloc(bm->toolflagpool); + } CustomData_bmesh_set_default(&bm->pdata, &f->head.data); @@ -495,7 +501,9 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v) if (v->head.data) CustomData_bmesh_free_block(&bm->vdata, &v->head.data); - BLI_mempool_free(bm->toolflagpool, v->oflags); + if (bm->toolflagpool) { + BLI_mempool_free(bm->toolflagpool, v->oflags); + } BLI_mempool_free(bm->vpool, v); } @@ -513,7 +521,9 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e) if (e->head.data) CustomData_bmesh_free_block(&bm->edata, &e->head.data); - BLI_mempool_free(bm->toolflagpool, e->oflags); + if (bm->toolflagpool) { + BLI_mempool_free(bm->toolflagpool, e->oflags); + } BLI_mempool_free(bm->epool, e); } @@ -534,7 +544,9 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f) if (f->head.data) CustomData_bmesh_free_block(&bm->pdata, &f->head.data); - BLI_mempool_free(bm->toolflagpool, f->oflags); + if (bm->toolflagpool) { + BLI_mempool_free(bm->toolflagpool, f->oflags); + } BLI_mempool_free(bm->fpool, f); } @@ -1773,14 +1785,18 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2); /* deallocate edge and its two loops as well as f2 */ - BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags); + if (bm->toolflagpool) { + BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags); + } BLI_mempool_free(bm->epool, f1loop->e); bm->totedge--; BLI_mempool_free(bm->lpool, f1loop); bm->totloop--; BLI_mempool_free(bm->lpool, f2loop); bm->totloop--; - BLI_mempool_free(bm->toolflagpool, f2->oflags); + if (bm->toolflagpool) { + BLI_mempool_free(bm->toolflagpool, f2->oflags); + } BLI_mempool_free(bm->fpool, f2); bm->totface--; /* account for both above */ diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index c0eefc2a3aa..7291bca6356 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -107,14 +107,14 @@ typedef struct BMIter { BMesh *bm; void (*begin)(struct BMIter *iter); void *(*step)(struct BMIter *iter); - /* +#if 0 union { void *p; int i; long l; float f; } filter; - */ +#endif int count; /* note, only some iterators set this, don't rely on it */ char itype; } BMIter; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index d3e3bcd3556..062c47dc686 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -59,9 +59,37 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) #ifdef USE_BMESH_HOLES bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0); #endif +} - /* allocate one flag pool that we don't get rid of. */ - bm->toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), 512, 512, 0); +void BM_mesh_elem_toolflags_ensure(BMesh *bm) +{ + if (bm->toolflagpool == NULL) { + const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface); + BLI_mempool *toolflagpool; + + BMIter iter; + BMElemF *ele; + const char iter_types[3] = {BM_VERTS_OF_MESH, + BM_EDGES_OF_MESH, + BM_FACES_OF_MESH}; + + int i; + + BLI_assert(bm->totflags == 0); + + /* allocate one flag pool that we don't get rid of. */ + toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0); + + + for (i = 0; i < 3; i++) { + BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { + ele->oflags = BLI_mempool_calloc(toolflagpool); + } + } + + bm->toolflagpool = toolflagpool; + bm->totflags = 1; + } } /** @@ -83,7 +111,7 @@ BMesh *BM_mesh_create(BMAllocTemplate *allocsize) /* allocate one flag pool that we don't get rid of. */ bm->stackdepth = 1; - bm->totflags = 1; + bm->totflags = 0; CustomData_reset(&bm->vdata); CustomData_reset(&bm->edata); @@ -143,7 +171,9 @@ void BM_mesh_data_free(BMesh *bm) BLI_mempool_destroy(bm->fpool); /* destroy flag pool */ - BLI_mempool_destroy(bm->toolflagpool); + if (bm->toolflagpool) { + BLI_mempool_destroy(bm->toolflagpool); + } #ifdef USE_BMESH_HOLES BLI_mempool_destroy(bm->looplistpool); diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index 8b6ef9aa3e0..0dcd3fc2f01 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -29,6 +29,7 @@ struct BMAllocTemplate; +void BM_mesh_elem_toolflags_ensure(BMesh *bm); BMesh *BM_mesh_create(struct BMAllocTemplate *allocsize); void BM_mesh_free(BMesh *bm); @@ -58,4 +59,8 @@ typedef struct BMAllocTemplate { extern BMAllocTemplate bm_mesh_allocsize_default; extern BMAllocTemplate bm_mesh_chunksize_default; +enum { + BM_MESH_CREATE_USE_TOOLFLAGS = (1 << 0) +}; + #endif /* __BMESH_MESH_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 398e6bbedcf..c5941a6c637 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -117,7 +117,7 @@ static BMOpDefine bmo_smooth_vert_def = { * Vertext Smooth Laplacian * Smooths vertices by using Laplacian smoothing propose by. * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow -*/ + */ static BMOpDefine bmo_smooth_laplacian_vert_def = { "smooth_laplacian_vert", {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 9d1054dc042..8f38e1c9ba2 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -101,6 +101,8 @@ void BMO_push(BMesh *bm, BMOperator *UNUSED(op)) { bm->stackdepth++; + BLI_assert(bm->totflags > 0); + /* add flag layer, if appropriate */ if (bm->stackdepth > 1) bmo_flag_layer_alloc(bm); @@ -172,7 +174,9 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname) */ void BMO_op_exec(BMesh *bm, BMOperator *op) { - + /* allocate tool flags on demand */ + BM_mesh_elem_toolflags_ensure(bm); + BMO_push(bm, op); if (bm->stackdepth == 2) @@ -1056,7 +1060,9 @@ static void bmo_flag_layer_alloc(BMesh *bm) /* store memcpy size for reuse */ const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer)); - + + BLI_assert(oldpool != NULL); + bm->totflags++; /* allocate new flag poo */ @@ -1068,18 +1074,21 @@ static void bmo_flag_layer_alloc(BMesh *bm) ele->oflags = BLI_mempool_calloc(newpool); memcpy(ele->oflags, oldflags, old_totflags_size); BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); } BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { oldflags = ele->oflags; ele->oflags = BLI_mempool_calloc(newpool); memcpy(ele->oflags, oldflags, old_totflags_size); BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); } BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { oldflags = ele->oflags; ele->oflags = BLI_mempool_calloc(newpool); memcpy(ele->oflags, oldflags, old_totflags_size); BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); } bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); @@ -1113,18 +1122,21 @@ static void bmo_flag_layer_free(BMesh *bm) ele->oflags = BLI_mempool_calloc(newpool); memcpy(ele->oflags, oldflags, new_totflags_size); BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); } BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { oldflags = ele->oflags; ele->oflags = BLI_mempool_calloc(newpool); memcpy(ele->oflags, oldflags, new_totflags_size); BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); } BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { oldflags = ele->oflags; ele->oflags = BLI_mempool_calloc(newpool); memcpy(ele->oflags, oldflags, new_totflags_size); BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); } bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index b3fe3676ab8..a5eb7e63505 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -62,9 +62,10 @@ int bmesh_disk_count(BMVert *v); #define _FLAG_MF 2 /* make face */ #define _FLAG_MV 2 /* make face, vertex */ -#define BM_ELEM_API_FLAG_ENABLE(element, f) ((element)->oflags[0].pflag |= (f)) -#define BM_ELEM_API_FLAG_DISABLE(element, f) ((element)->oflags[0].pflag &= ~(f)) -#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->oflags[0].pflag & (f)) +#define BM_ELEM_API_FLAG_ENABLE(element, f) ((element)->head.api_flag |= (f)) +#define BM_ELEM_API_FLAG_DISABLE(element, f) ((element)->head.api_flag &= ~(f)) +#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->head.api_flag & (f)) +#define BM_ELEM_API_FLAG_CLEAR(element) ((element)->head.api_flag = 0) void calc_poly_plane(float (*verts)[3], const int nverts); void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nverts); diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index db5b769d078..049b923315b 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -15,2339 +15,44 @@ * 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): Joseph Eagar, Aleksandr Mokhov, Howard Trickey + * Contributor(s): * * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/operators/bmo_bevel.c +/** \file blender/bmesh/operators/bmesh_bevel.c * \ingroup bmesh */ -#include "MEM_guardedalloc.h" - -#include "BLI_listbase.h" -#include "BLI_array.h" -#include "BLI_math.h" -#include "BLI_smallhash.h" - -#include "BKE_customdata.h" +#include "BLI_utildefines.h" #include "bmesh.h" #include "intern/bmesh_operators_private.h" /* own include */ -#define NEW_BEVEL 1 - -#ifdef NEW_BEVEL -#define BEVEL_FLAG 1 -#define EDGE_SELECTED 2 - -#define BEVEL_EPSILON 1e-6 - -/* Constructed vertex, sometimes later instantiated as BMVert */ -typedef struct NewVert { - float co[3]; - BMVert *v; -} NewVert; - -struct BoundVert; - -/* Data for one end of an edge involved in a bevel */ -typedef struct EdgeHalf { - struct EdgeHalf *next, *prev; /* in CCW order */ - BMEdge *e; /* original mesh edge */ - int isbev; /* is this edge beveled? */ - int isrev; /* is e->v2 the vertex at this end? */ - int seg; /* how many segments for the bevel */ - float offset; /* offset for this edge */ - BMFace *fprev; /* face between this edge and previous, if any */ - BMFace *fnext; /* face between this edge and next, if any */ - struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */ - struct BoundVert *rightv; /* right boundary vert, if beveled */ -} EdgeHalf; - -/* An element in a cyclic boundary of a Vertex Mesh (VMesh) */ -typedef struct BoundVert { - struct BoundVert *next, *prev; /* in CCW order */ - int index; /* used for vmesh indexing */ - NewVert nv; - EdgeHalf *efirst; /* first of edges attached here: in CCW order */ - EdgeHalf *elast; - EdgeHalf *ebev; /* beveled edge whose left side is attached here, if any */ -} BoundVert; - -/* Mesh structure replacing a vertex */ -typedef struct VMesh { - enum { - M_NONE, /* no polygon mesh needed */ - M_POLY, /* a simple polygon */ - M_ADJ, /* "adjacent edges" mesh pattern */ - M_CROSS, /* "cross edges" mesh pattern */ - M_TRI_FAN, /* a simple polygon - fan filled */ - M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */ - } mesh_kind; - int count; /* number of vertices in the boundary */ - int seg; /* common # of segments for segmented edges */ - BoundVert *boundstart; /* start of boundary double-linked list */ - NewVert *mesh; /* allocated array - size and structure depends on kind */ -} VMesh; - -/* Data for a vertex involved in a bevel */ -typedef struct BevVert { - struct BevVert *next, *prev; - BMVert *v; /* original mesh vertex */ - int edgecount; /* total number of edges around the vertex */ - int selcount; /* number of selected edges around the vertex */ - EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */ - VMesh *vmesh; /* mesh structure for replacing vertex */ -} BevVert; - -/* - * Bevel parameters and state - */ -typedef struct BevelParams { - ListBase vertList; /* list of BevVert for each vertex involved in bevel */ - float offset; /* blender units to offset each side of a beveled edge */ - int seg; /* number of segments in beveled edge profile */ - - BMOperator *op; -} BevelParams; - -/* Make a new BoundVert of the given kind, insert it at the end of the circular linked - * list with entry point bv->boundstart, and return it. */ -static BoundVert *add_new_bound_vert(VMesh *vm, float co[3]) +void bmo_bevel_exec(BMesh *bm, BMOperator *op) { - BoundVert *ans = (BoundVert *) MEM_callocN(sizeof(BoundVert), "BoundVert"); - copy_v3_v3(ans->nv.co, co); - if (!vm->boundstart) { - ans->index = 0; - vm->boundstart = ans; - ans->next = ans->prev = ans; - } - else { - BoundVert *tail = vm->boundstart->prev; - ans->index = tail->index + 1; - ans->prev = tail; - ans->next = vm->boundstart; - tail->next = ans; - vm->boundstart->prev = ans; - } - vm->count++; - return ans; -} + const float offset = BMO_slot_float_get(op, "offset"); + const int seg = BMO_slot_int_get(op, "segments"); -/* Mesh verts are indexed (i, j, k) where - * i = boundvert index (0 <= i < nv) - * j = ring index (0 <= j <= ns2) - * k = segment index (0 <= k <= ns) - * Not all of these are used, and some will share BMVerts */ -static NewVert *mesh_vert(VMesh *vm, int i, int j, int k) -{ - int nj = (vm->seg / 2) + 1; - int nk = vm->seg + 1; - - return &vm->mesh[i * nk * nj + j * nk + k]; -} - -static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg) -{ - NewVert *nv = mesh_vert(vm, i, j, k); - nv->v = BM_vert_create(bm, nv->co, eg); -} - -static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto, - int ifrom, int jfrom, int kfrom) -{ - NewVert *nvto, *nvfrom; - - nvto = mesh_vert(vm, ito, jto, kto); - nvfrom = mesh_vert(vm, ifrom, jfrom, kfrom); - nvto->v = nvfrom->v; - copy_v3_v3(nvto->co, nvfrom->co); -} - -/* find the EdgeHalf in bv's array that has edge bme */ -static EdgeHalf *find_edge_half(BevVert *bv, BMEdge *bme) -{ - int i; - - for (i = 0; i < bv->edgecount; i++) { - if (bv->edges[i].e == bme) - return &bv->edges[i]; - } - return NULL; -} - -/* Return the next EdgeHalf after from_e that is beveled. - * If from_e is NULL, find the first beveled edge. */ -static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e) -{ - EdgeHalf *e; - - if (from_e == NULL) - from_e = &bv->edges[bv->edgecount - 1]; - e = from_e; - do { - if (e->isbev) { - return e; - } - } while ((e = e->next) != from_e); - return NULL; -} - -/* find the BevVert corresponding to BMVert bmv */ -static BevVert *find_bevvert(BevelParams *bp, BMVert *bmv) -{ - BevVert *bv; - - for (bv = bp->vertList.first; bv; bv = bv->next) { - if (bv->v == bmv) - return bv; - } - return NULL; -} - -/* Return a good respresentative face (for materials, etc.) for faces - * created around/near BoundVert v */ -static BMFace *boundvert_rep_face(BoundVert *v) -{ - BMFace *fans = NULL; - BMFace *firstf = NULL; - BMEdge *e1, *e2; - BMFace *f1, *f2; - BMIter iter1, iter2; - - BLI_assert(v->efirst != NULL && v->elast != NULL); - e1 = v->efirst->e; - e2 = v->elast->e; - BM_ITER_ELEM (f1, &iter1, e1, BM_FACES_OF_EDGE) { - if (!firstf) - firstf = f1; - BM_ITER_ELEM (f2, &iter2, e2, BM_FACES_OF_EDGE) { - if (f1 == f2) { - fans = f1; - break; - } - } - } - if (!fans) - fans = firstf; - - return fans; -} - -/* Make ngon from verts alone. - * Make sure to properly copy face attributes and do custom data interpolation from - * example face, facerep. */ -static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, int totv, BMFace *facerep) -{ - BMIter iter; - BMLoop *l; - BMFace *f; - - if (totv == 3) { - f = BM_face_create_quad_tri(bm, - vert_arr[0], vert_arr[1], vert_arr[2], NULL, facerep, 0); - } - else if (totv == 4) { - f = BM_face_create_quad_tri(bm, - vert_arr[0], vert_arr[1], vert_arr[2], vert_arr[3], facerep, 0); - } - else { - int i; + if (offset > 0) { + BMOIter siter; BMEdge *e; - BMEdge **ee = NULL; - BLI_array_staticdeclare(ee, 30); + BMVert *v; - for (i = 0; i < totv; i++) { - e = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE); - BLI_array_append(ee, e); - } - f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE); - BLI_array_free(ee); - } - if (facerep && f) { - int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS); - BM_elem_attrs_copy(bm, bm, facerep, f); - BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { - BM_loop_interp_from_face(bm, l, facerep, TRUE, TRUE); - if (has_mdisps) - BM_loop_interp_multires(bm, l, facerep); - } - } - return f; -} + /* first flush 'geom' into flags, this makes it possible to check connected data */ + BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE, BM_ELEM_TAG, FALSE); -static BMFace *bev_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4, - BMFace *facerep) -{ - BMVert *varr[4]; - - varr[0] = v1; - varr[1] = v2; - varr[2] = v3; - varr[3] = v4; - return bev_create_ngon(bm, varr, v4 ? 4 : 3, facerep); -} - -/* - * Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco. - * e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of - * the bevel vertex, e1 precedes e2 in CCW order. - * If on_right is true, offset edge is on right of both edges, where e1 enters v and - * e2 leave it. If on_right is false, then the offset edge is on the left. - * When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2), - * but if the offsets are not equal (allowing for this, as bevel modifier has edge weights that may - * lead to different offsets) then meeting point can be found be intersecting offset lines. - */ -static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, - int on_right, float meetco[3]) -{ - float dir1[3], dir2[3], norm_v[3], norm_perp1[3], norm_perp2[3], - off1a[3], off1b[3], off2a[3], off2b[3], isect2[3]; - - /* get direction vectors for two offset lines */ - sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co); - sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co); - - /* get normal to plane where meet point should be */ - cross_v3_v3v3(norm_v, dir2, dir1); - normalize_v3(norm_v); - if (!on_right) - negate_v3(norm_v); - if (is_zero_v3(norm_v)) { - /* special case: e1 and e2 are parallel; put offset point perp to both, from v. - * need to find a suitable plane. - * if offsets are different, we're out of luck: just use e1->offset */ - if (f) - copy_v3_v3(norm_v, f->no); - else - copy_v3_v3(norm_v, v->no); - cross_v3_v3v3(norm_perp1, dir1, norm_v); - normalize_v3(norm_perp1); - copy_v3_v3(off1a, v->co); - madd_v3_v3fl(off1a, norm_perp1, e1->offset); - copy_v3_v3(meetco, off1a); - } - else { - /* get vectors perp to each edge, perp to norm_v, and pointing into face */ - if (f) { - copy_v3_v3(norm_v, f->no); - normalize_v3(norm_v); - } - cross_v3_v3v3(norm_perp1, dir1, norm_v); - cross_v3_v3v3(norm_perp2, dir2, norm_v); - normalize_v3(norm_perp1); - normalize_v3(norm_perp2); - - /* get points that are offset distances from each line, then another point on each line */ - copy_v3_v3(off1a, v->co); - madd_v3_v3fl(off1a, norm_perp1, e1->offset); - add_v3_v3v3(off1b, off1a, dir1); - copy_v3_v3(off2a, v->co); - madd_v3_v3fl(off2a, norm_perp2, e2->offset); - add_v3_v3v3(off2b, off2a, dir2); - - /* intersect the lines; by construction they should be on the same plane and not parallel */ - if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) { - BLI_assert(!"offset_meet failure"); - copy_v3_v3(meetco, off1a); /* just to do something */ - } - } -} - -/* Like offset_meet, but here f1 and f2 must not be NULL and give the - * planes in which to run the offset lines. They may not meet exactly, - * but the line intersection routine will find the closest approach point. */ -static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, - BMFace *f1, BMFace *f2, float meetco[3]) -{ - float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3], - off1a[3], off1b[3], off2a[3], off2b[3], isect2[3]; - - BLI_assert(f1 != NULL && f2 != NULL); - - /* get direction vectors for two offset lines */ - sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co); - sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co); - - /* get directions into offset planes */ - cross_v3_v3v3(norm_perp1, dir1, f1->no); - normalize_v3(norm_perp1); - cross_v3_v3v3(norm_perp2, dir2, f2->no); - normalize_v3(norm_perp2); - - /* get points that are offset distances from each line, then another point on each line */ - copy_v3_v3(off1a, v->co); - madd_v3_v3fl(off1a, norm_perp1, e1->offset); - add_v3_v3v3(off1b, off1a, dir1); - copy_v3_v3(off2a, v->co); - madd_v3_v3fl(off2a, norm_perp2, e2->offset); - add_v3_v3v3(off2b, off2a, dir2); - - if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) { - /* lines are parallel; off1a is a good meet point */ - copy_v3_v3(meetco, off1a); - } -} - -/* Offset by e->offset in plane with normal plane_no, on left if left==TRUE, - * else on right. If no is NULL, choose an arbitrary plane different - * from eh's direction. */ -static void offset_in_plane(EdgeHalf *e, float plane_no[3], int left, float r[3]) -{ - float dir[3], no[3]; - BMVert *v; - - v = e->isrev ? e->e->v1 : e->e->v2; - - sub_v3_v3v3(dir, BM_edge_other_vert(e->e, v)->co, v->co); - normalize_v3(dir); - if (plane_no) { - copy_v3_v3(no, plane_no); - } - else { - zero_v3(no); - if (fabs(dir[0]) < fabs(dir[1])) - no[0] = 1.0f; - else - no[1] = 1.0f; - } - if (left) - cross_v3_v3v3(r, no, dir); - else - cross_v3_v3v3(r, dir, no); - normalize_v3(r); - mul_v3_fl(r, e->offset); -} - -/* Calculate coordinates of a point a distance d from v on e->e and return it in slideco */ -static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3]) -{ - float dir[3], len; - - sub_v3_v3v3(dir, v->co, BM_edge_other_vert(e->e, v)->co); - len = len_v3(dir); - normalize_v3(dir); - if (d > len) - d = len - (float)(50 * BEVEL_EPSILON); - copy_v3_v3(slideco, v->co); - madd_v3_v3fl(slideco, dir, -d); -} - -/* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */ -static void project_to_edge(BMEdge *e, float co_a[3], float co_b[3], float projco[3]) -{ - float otherco[3]; - - if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b, projco, otherco)) { - BLI_assert(!"project meet failure"); - copy_v3_v3(projco, e->v1->co); - } -} - - -/* return 1 if a and b are in CCW order on the normal side of f, - * and -1 if they are reversed, and 0 if there is no shared face f */ -static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f) -{ - BMLoop *la, *lb; - - if (!f) - return 0; - la = BM_face_edge_share_loop(f, a); - lb = BM_face_edge_share_loop(f, b); - if (!la || !lb) - return 0; - return lb->next == la ? 1 : -1; -} - -/* - * calculation of points on the round profile - * r - result, coordinate of point on round profile - * method: - * Inscribe a circle in angle va - v -vb - * such that it touches the arms at offset from v. - * Rotate the center-va segment by (i/n) of the - * angle va - center -vb, and put the endpoint - * of that segment in r. - */ -static void get_point_on_round_profile(float r[3], float offset, int i, int count, - float va[3], float v[3], float vb[3]) -{ - float vva[3], vvb[3], angle, center[3], rv[3], axis[3], co[3]; - - sub_v3_v3v3(vva, va, v); - sub_v3_v3v3(vvb, vb, v); - normalize_v3(vva); - normalize_v3(vvb); - angle = angle_v3v3(vva, vvb); - - add_v3_v3v3(center, vva, vvb); - normalize_v3(center); - mul_v3_fl(center, offset * (1.0f / cosf(0.5f * angle))); - add_v3_v3(center, v); /* coordinates of the center of the inscribed circle */ - - - sub_v3_v3v3(rv, va, center); /* radius vector */ - - - sub_v3_v3v3(co, v, center); - cross_v3_v3v3(axis, rv, co); /* calculate axis */ - - sub_v3_v3v3(vva, va, center); - sub_v3_v3v3(vvb, vb, center); - angle = angle_v3v3(vva, vvb); - - rotate_v3_v3v3fl(co, rv, axis, angle * (float)(i) / (float)(count)); - - add_v3_v3(co, center); - copy_v3_v3(r, co); -} - -/* - * Find the point (i/n) of the way around the round profile for e, - * where start point is va, midarc point is vmid, and end point is vb. - * Return the answer in profileco. - * Method: - * Adjust va and vb (along edge direction) so that they are perpendicular - * to edge at v, then use get_point_on_round_profile, then project - * back onto original va - vmid - vb plane. - * If va, vmid, and vb are all on the same plane, just interpolate between va and vb. - */ -static void get_point_on_round_edge(EdgeHalf *e, int i, - float va[3], float vmid[3], float vb[3], float profileco[3]) -{ - float vva[3], vvb[3], point[3], dir[3], vaadj[3], vbadj[3], p2[3], pn[3]; - int n = e->seg; - - sub_v3_v3v3(vva, va, vmid); - sub_v3_v3v3(vvb, vb, vmid); - if (e->isrev) - sub_v3_v3v3(dir, e->e->v1->co, e->e->v2->co); - else - sub_v3_v3v3(dir, e->e->v2->co, e->e->v1->co); - normalize_v3(dir); - if (fabsf(angle_v3v3(vva, vvb) - (float)M_PI) > (float)BEVEL_EPSILON) { - copy_v3_v3(vaadj, va); - madd_v3_v3fl(vaadj, dir, -len_v3(vva) * cosf(angle_v3v3(vva, dir))); - copy_v3_v3(vbadj, vb); - madd_v3_v3fl(vbadj, dir, -len_v3(vvb) * cosf(angle_v3v3(vvb, dir))); - - get_point_on_round_profile(point, e->offset, i, n, vaadj, vmid, vbadj); - - add_v3_v3v3(p2, point, dir); - cross_v3_v3v3(pn, vva, vvb); - if (!isect_line_plane_v3(profileco, point, p2, vmid, pn, 0)) { - /* TODO: track down why this sometimes fails */ - copy_v3_v3(profileco, point); - } - } - else { - /* planar case */ - interp_v3_v3v3(profileco, va, vb, (float) i / (float) n); - } -} - -static void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]) -{ - v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f; - v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f; - v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f; -} - -/* Make a circular list of BoundVerts for bv, each of which has the coordinates - * of a vertex on the the boundary of the beveled vertex bv->v. - * Also decide on the mesh pattern that will be used inside the boundary. - * Doesn't make the actual BMVerts */ -static void build_boundary(BevVert *bv) -{ - EdgeHalf *efirst, *e; - BoundVert *v; - VMesh *vm; - float co[3], *no; - float lastd; - - e = efirst = next_bev(bv, NULL); - vm = bv->vmesh; - - BLI_assert(bv->edgecount >= 2); /* since bevel edges incident to 2 faces */ - - if (bv->edgecount == 2 && bv->selcount == 1) { - /* special case: beveled edge meets non-beveled one at valence 2 vert */ - no = e->fprev ? e->fprev->no : (e->fnext ? e->fnext->no : NULL); - offset_in_plane(e, no, TRUE, co); - v = add_new_bound_vert(vm, co); - v->efirst = v->elast = v->ebev = e; - e->leftv = v; - no = e->fnext ? e->fnext->no : (e->fprev ? e->fprev->no : NULL); - offset_in_plane(e, no, FALSE, co); - v = add_new_bound_vert(vm, co); - v->efirst = v->elast = e; - e->rightv = v; - /* make artifical extra point along unbeveled edge, and form triangle */ - slide_dist(e->next, bv->v, e->offset, co); - v = add_new_bound_vert(vm, co); - v->efirst = v->elast = e->next; - vm->mesh_kind = M_POLY; - return; - } - - lastd = e->offset; - vm->boundstart = NULL; - do { - if (e->isbev) { - /* handle only left side of beveled edge e here: next iteration should do right side */ - if (e->prev->isbev) { - BLI_assert(e->prev != e); /* see: wire edge special case */ - offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); - v = add_new_bound_vert(vm, co); - v->efirst = e->prev; - v->elast = v->ebev = e; - e->leftv = v; - e->prev->rightv = v; - } - else { - /* e->prev is not beveled */ - if (e->prev->prev->isbev) { - BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */ - /* find meet point between e->prev->prev and e and attach e->prev there */ - /* TODO: fix case when one or both faces in following are NULL */ - offset_in_two_planes(e->prev->prev, e, bv->v, - e->prev->prev->fnext, e->fprev, co); - v = add_new_bound_vert(vm, co); - v->efirst = e->prev->prev; - v->elast = v->ebev = e; - e->leftv = v; - e->prev->leftv = v; - e->prev->prev->rightv = v; - } - else { - /* neither e->prev nor e->prev->prev are beveled: make on-edge on e->prev */ - offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); - v = add_new_bound_vert(vm, co); - v->efirst = e->prev; - v->elast = v->ebev = e; - e->leftv = v; - e->prev->leftv = v; - } - } - lastd = len_v3v3(bv->v->co, v->nv.co); - } - else { - /* e is not beveled */ - if (e->next->isbev) { - /* next iteration will place e between beveled previous and next edges */ - /* do nothing... */ - } - else if (e->prev->isbev) { - /* on-edge meet between e->prev and e */ - offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); - v = add_new_bound_vert(vm, co); - v->efirst = e->prev; - v->elast = e; - e->leftv = v; - e->prev->rightv = v; - } - else { - /* None of e->prev, e, e->next are beveled. - * could either leave alone or add slide points to make - * one polygon around bv->v. For now, we choose latter. - * Could slide to make an even bevel plane but for now will - * just use last distance a meet point moved from bv->v. */ - slide_dist(e, bv->v, lastd, co); - v = add_new_bound_vert(vm, co); - v->efirst = v->elast = e; - e->leftv = v; - } - } - } while ((e = e->next) != efirst); - - BLI_assert(vm->count >= 2); - if (vm->count == 2 && bv->edgecount == 3) { - vm->mesh_kind = M_NONE; - } - else if (efirst->seg == 1 || bv->selcount == 1) { - if (vm->count == 3 && bv->selcount == 1) { - vm->mesh_kind = M_TRI_FAN; - } - else { - vm->mesh_kind = M_POLY; - } - } - else { - if (bv->selcount == 2) { - vm->mesh_kind = M_QUAD_STRIP; - } - else { - vm->mesh_kind = M_ADJ; - } - } - /* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */ -} - -/* - * Given that the boundary is built and the boundary BMVerts have been made, - * calculate the positions of the interior mesh points for the M_ADJ pattern, - * then make the BMVerts and the new faces. */ -static void bevel_build_rings(BMesh *bm, BevVert *bv) -{ - int k, ring, i, n, ns, ns2, nn; - VMesh *vm = bv->vmesh; - BoundVert *v, *vprev, *vnext; - NewVert *nv, *nvprev, *nvnext; - BMVert *bmv, *bmv1, *bmv2, *bmv3, *bmv4; - BMFace *f; - float co[3], coa[3], cob[3], midco[3]; - - n = vm->count; - ns = vm->seg; - ns2 = ns / 2; - BLI_assert(n > 2 && ns > 1); - /* Make initial rings, going between points on neighbors. - * After this loop, will have coords for all (i, r, k) where - * BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */ - for (ring = 1; ring <= ns2; ring++) { - v = vm->boundstart; - do { - i = v->index; - if (v->ebev) { - /* get points coords of points a and b, on outer rings - * of prev and next edges, k away from this edge */ - vprev = v->prev; - vnext = v->next; - - if (vprev->ebev) - nvprev = mesh_vert(vm, vprev->index, 0, ns - ring); - else - nvprev = mesh_vert(vm, vprev->index, 0, ns); - copy_v3_v3(coa, nvprev->co); - nv = mesh_vert(vm, i, ring, 0); - copy_v3_v3(nv->co, coa); - nv->v = nvprev->v; - - if (vnext->ebev) - nvnext = mesh_vert(vm, vnext->index, 0, ring); - else - nvnext = mesh_vert(vm, vnext->index, 0, 0); - copy_v3_v3(cob, nvnext->co); - nv = mesh_vert(vm, i, ring, ns); - copy_v3_v3(nv->co, cob); - nv->v = nvnext->v; - - /* TODO: better calculation of new midarc point? */ - project_to_edge(v->ebev->e, coa, cob, midco); - - for (k = 1; k < ns; k++) { - get_point_on_round_edge(v->ebev, k, coa, midco, cob, co); - copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co); - } - } - } while ((v = v->next) != vm->boundstart); - } - - /* Now make sure cross points of rings share coordinates and vertices. - * After this loop, will have BMVerts for all (i, r, k) where - * i is for a BoundVert that is beveled and has either a predecessor or - * successor BoundVert beveled too, and - * for odd ns: 0 <= r <= ns2, 0 <= k <= ns - * for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */ - v = vm->boundstart; - do { - i = v->index; - if (v->ebev) { - vprev = v->prev; - vnext = v->next; - if (vprev->ebev) { - for (ring = 1; ring <= ns2; ring++) { - for (k = 1; k <= ns2; k++) { - if (ns % 2 == 0 && (k == ns2 || ring == ns2)) - continue; /* center line is special case: do after the rest are done */ - nv = mesh_vert(vm, i, ring, k); - nvprev = mesh_vert(vm, vprev->index, k, ns - ring); - mid_v3_v3v3(co, nv->co, nvprev->co); - copy_v3_v3(nv->co, co); - BLI_assert(nv->v == NULL && nvprev->v == NULL); - create_mesh_bmvert(bm, vm, i, ring, k, bv->v); - copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k); - } - } - if (!vprev->prev->ebev) { - for (ring = 1; ring <= ns2; ring++) { - for (k = 1; k <= ns2; k++) { - if (ns % 2 == 0 && (k == ns2 || ring == ns2)) - continue; - create_mesh_bmvert(bm, vm, vprev->index, ring, k, bv->v); - } - } - } - if (!vnext->ebev) { - for (ring = 1; ring <= ns2; ring++) { - for (k = ns - ns2; k < ns; k++) { - if (ns % 2 == 0 && (k == ns2 || ring == ns2)) - continue; - create_mesh_bmvert(bm, vm, i, ring, k, bv->v); - } - } - } - } - } - } while ((v = v->next) != vm->boundstart); - - if (ns % 2 == 0) { - /* Do special case center lines. - * This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2 - * and for (i, r, ns2) for 1 <= r <= ns2-1, - * whenever i is in a sequence of at least two beveled verts */ - v = vm->boundstart; - do { - i = v->index; - if (v->ebev) { - vprev = v->prev; - vnext = v->next; - for (k = 1; k < ns2; k++) { - nv = mesh_vert(vm, i, k, ns2); - if (vprev->ebev) - nvprev = mesh_vert(vm, vprev->index, ns2, ns - k); - if (vnext->ebev) - nvnext = mesh_vert(vm, vnext->index, ns2, k); - if (vprev->ebev && vnext->ebev) { - mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co); - copy_v3_v3(nv->co, co); - create_mesh_bmvert(bm, vm, i, k, ns2, bv->v); - copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2); - copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2); - - } - else if (vprev->ebev) { - mid_v3_v3v3(co, nvprev->co, nv->co); - copy_v3_v3(nv->co, co); - create_mesh_bmvert(bm, vm, i, k, ns2, bv->v); - copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2); - - create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v); - } - else if (vnext->ebev) { - mid_v3_v3v3(co, nv->co, nvnext->co); - copy_v3_v3(nv->co, co); - create_mesh_bmvert(bm, vm, i, k, ns2, bv->v); - copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2); - - create_mesh_bmvert(bm, vm, i, ns2, k, bv->v); - } - } - } - } while ((v = v->next) != vm->boundstart); - - /* center point need to be average of all centers of rings */ - /* TODO: this is wrong if not all verts have ebev: could have - * several disconnected sections of mesh. */ - zero_v3(midco); - nn = 0; - v = vm->boundstart; - do { - i = v->index; - if (v->ebev) { - nv = mesh_vert(vm, i, ns2, ns2); - add_v3_v3(midco, nv->co); - nn++; - } - } while ((v = v->next) != vm->boundstart); - mul_v3_fl(midco, 1.0f / nn); - bmv = BM_vert_create(bm, midco, NULL); - v = vm->boundstart; - do { - i = v->index; - if (v->ebev) { - nv = mesh_vert(vm, i, ns2, ns2); - copy_v3_v3(nv->co, midco); - nv->v = bmv; - } - } while ((v = v->next) != vm->boundstart); - } - - /* Make the ring quads */ - for (ring = 0; ring < ns2; ring++) { - v = vm->boundstart; - do { - i = v->index; - f = boundvert_rep_face(v); - if (v->ebev && (v->prev->ebev || v->next->ebev)) { - for (k = 0; k < ns2 + (ns % 2); k++) { - bmv1 = mesh_vert(vm, i, ring, k)->v; - bmv2 = mesh_vert(vm, i, ring, k + 1)->v; - bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v; - bmv4 = mesh_vert(vm, i, ring + 1, k)->v; - BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); - if (bmv3 == bmv4 || bmv1 == bmv4) - bmv4 = NULL; - bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f); - } - } - else if (v->prev->ebev && v->prev->prev->ebev) { - /* finish off a sequence of beveled edges */ - i = v->prev->index; - f = boundvert_rep_face(v->prev); - for (k = ns2 + (ns % 2); k < ns; k++) { - bmv1 = mesh_vert(vm, i, ring, k)->v; - bmv2 = mesh_vert(vm, i, ring, k + 1)->v; - bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v; - bmv4 = mesh_vert(vm, i, ring + 1, k)->v; - BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); - if (bmv2 == bmv3) { - bmv3 = bmv4; - bmv4 = NULL; - } - bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f); - } - } - } while ((v = v->next) != vm->boundstart); - } - - /* Make center ngon if odd number of segments and fully beveled */ - if (ns % 2 == 1 && vm->count == bv->selcount) { - BMVert **vv = NULL; - BLI_array_declare(vv); - - v = vm->boundstart; - do { - i = v->index; - BLI_assert(v->ebev); - BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v); - } while ((v = v->next) != vm->boundstart); - f = boundvert_rep_face(vm->boundstart); - bev_create_ngon(bm, vv, BLI_array_count(vv), f); - - BLI_array_free(vv); - } - - /* Make 'rest-of-vmesh' polygon if not fully beveled */ - if (vm->count > bv->selcount) { - int j; - BMVert **vv = NULL; - BLI_array_declare(vv); - - v = vm->boundstart; - f = boundvert_rep_face(v); - j = 0; - do { - i = v->index; - if (v->ebev) { - if (!v->prev->ebev) { - for (k = 0; k < ns2; k++) { - bmv1 = mesh_vert(vm, i, ns2, k)->v; - if (!bmv1) - bmv1 = mesh_vert(vm, i, 0, k)->v; - if (!(j > 0 && bmv1 == vv[j - 1])) { - BLI_assert(bmv1 != NULL); - BLI_array_append(vv, bmv1); - j++; - } - } - } - bmv1 = mesh_vert(vm, i, ns2, ns2)->v; - if (!bmv1) - bmv1 = mesh_vert(vm, i, 0, ns2)->v; - if (!(j > 0 && bmv1 == vv[j - 1])) { - BLI_assert(bmv1 != NULL); - BLI_array_append(vv, bmv1); - j++; - } - if (!v->next->ebev) { - for (k = ns - ns2; k < ns; k++) { - bmv1 = mesh_vert(vm, i, ns2, k)->v; - if (!bmv1) - bmv1 = mesh_vert(vm, i, 0, k)->v; - if (!(j > 0 && bmv1 == vv[j - 1])) { - BLI_assert(bmv1 != NULL); - BLI_array_append(vv, bmv1); - j++; - } - } - } - } - else { - BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL); - BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v); - j++; - } - } while ((v = v->next) != vm->boundstart); - if (vv[0] == vv[j - 1]) - j--; - bev_create_ngon(bm, vv, j, f); - - BLI_array_free(vv); - } -} - -static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv) -{ - BMFace *f; - int n, k; - VMesh *vm = bv->vmesh; - BoundVert *v; - BMVert **vv = NULL; - BLI_array_declare(vv); - - v = vm->boundstart; - n = 0; - do { - /* accumulate vertices for vertex ngon */ - BLI_array_append(vv, v->nv.v); - n++; - if (v->ebev && v->ebev->seg > 1) { - for (k = 1; k < v->ebev->seg; k++) { - BLI_array_append(vv, mesh_vert(vm, v->index, 0, k)->v); - n++; - } - } - } while ((v = v->next) != vm->boundstart); - if (n > 2) { - f = bev_create_ngon(bm, vv, n, boundvert_rep_face(v)); - } - else { - f = NULL; - } - BLI_array_free(vv); - return f; -} - -static void bevel_build_poly(BMesh *bm, BevVert *bv) -{ - bevel_build_poly_ex(bm, bv); -} - -static void bevel_build_trifan(BMesh *bm, BevVert *bv) -{ - BMFace *f; - BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1); - - f = bevel_build_poly_ex(bm, bv); - - if (f) { - /* we have a polygon which we know starts at the previous vertex, make it into a fan */ - BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev; - BMVert *v_fan = l_fan->v; - - while (f->len > 3) { - BMLoop *l_new; - BMFace *f_new; - BLI_assert(v_fan == l_fan->v); - f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE); - - if (f_new->len > f->len) { - f = f_new; - if (l_new->v == v_fan) { l_fan = l_new; } - else if (l_new->next->v == v_fan) { l_fan = l_new->next; } - else if (l_new->prev->v == v_fan) { l_fan = l_new->prev; } - else { BLI_assert(0); } - } - else { - if (l_fan->v == v_fan) { l_fan = l_fan; } - else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; } - else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; } - else { BLI_assert(0); } - } - } - } -} - -static void bevel_build_quadstrip(BMesh *bm, BevVert *bv) -{ - BMFace *f; - BLI_assert(bv->selcount == 2); - - f = bevel_build_poly_ex(bm, bv); - - if (f) { - /* we have a polygon which we know starts at this vertex, make it into strips */ - BMVert *v_first = bv->vmesh->boundstart->efirst->next->next->leftv->nv.v; /* magic? */ - //BMLoop *l_start = BM_FACE_FIRST_LOOP(f); - BMLoop *l_start = BM_face_vert_share_loop(f, v_first); - BMLoop *l_a = l_start->prev, *l_a_step; - BMLoop *l_b = l_start->next, *l_b_step; - - while (f->len > 4) { - // BMLoop *l_new; - BMFace *f_new; - BLI_assert(l_a->f == f); - BLI_assert(l_b->f == f); - - l_a_step = l_a->prev; - l_b_step = l_b->next; - - f_new = BM_face_split(bm, f, l_a->v, l_b->v, NULL, NULL, FALSE); - - if (f_new->len > f->len) { - f = f_new; - } - - l_a = l_a_step; - l_b = l_b_step; - } - } -} - -/* Given that the boundary is built, now make the actual BMVerts - * for the boundary and the interior of the vertex mesh. */ -static void build_vmesh(BMesh *bm, BevVert *bv) -{ - VMesh *vm = bv->vmesh; - BoundVert *v, *weld1, *weld2; - int n, ns, ns2, i, k, weld; - float *va, *vb, co[3], midco[3]; - - n = vm->count; - ns = vm->seg; - ns2 = ns / 2; - - vm->mesh = (NewVert *)MEM_callocN(n * (ns2 + 1) * (ns + 1) * sizeof(NewVert), "NewVert"); - - /* special case: two beveled ends welded together */ - weld = (bv->selcount == 2) && (vm->count == 2); - weld1 = weld2 = NULL; /* will hold two BoundVerts involved in weld */ - - /* make (i, 0, 0) mesh verts for all i */ - v = vm->boundstart; - do { - i = v->index; - copy_v3_v3(mesh_vert(vm, i, 0, 0)->co, v->nv.co); - create_mesh_bmvert(bm, vm, i, 0, 0, bv->v); - v->nv.v = mesh_vert(vm, i, 0, 0)->v; - if (weld && v->ebev) { - if (!weld1) - weld1 = v; - else - weld2 = v; - } - } while ((v = v->next) != vm->boundstart); - - /* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */ - v = vm->boundstart; - do { - i = v->index; - copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0); - if (v->ebev) { - va = mesh_vert(vm, i, 0, 0)->co; - vb = mesh_vert(vm, i, 0, ns)->co; - project_to_edge(v->ebev->e, va, vb, midco); - for (k = 1; k < ns; k++) { - get_point_on_round_edge(v->ebev, k, va, midco, vb, co); - copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co); - if (!weld) - create_mesh_bmvert(bm, vm, i, 0, k, bv->v); - } - } - } while ((v = v->next) != vm->boundstart); - - if (weld) { - vm->mesh_kind = M_NONE; - for (k = 1; k < ns; k++) { - va = mesh_vert(vm, weld1->index, 0, k)->co; - vb = mesh_vert(vm, weld2->index, 0, ns - k)->co; - mid_v3_v3v3(co, va, vb); - copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co); - create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v); - } - for (k = 1; k < ns; k++) - copy_mesh_vert(vm, weld2->index, 0, ns - k, weld1->index, 0, k); - } - - if (vm->mesh_kind == M_ADJ) - bevel_build_rings(bm, bv); - else if (vm->mesh_kind == M_POLY) - bevel_build_poly(bm, bv); - else if (vm->mesh_kind == M_TRI_FAN) - bevel_build_trifan(bm, bv); - else if (vm->mesh_kind == M_QUAD_STRIP) - bevel_build_quadstrip(bm, bv); -} - -/* - * Construction around the vertex - */ -static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMOperator *op, BMVert *v) -{ - - BMOIter siter; - BMEdge *bme; - BevVert *bv; - BMEdge *bme2, *unflagged_bme; - BMFace *f; - BMIter iter, iter2; - EdgeHalf *e; - int i, ntot, found_shared_face, ccw_test_sum; - int nsel = 0; - - /* Gather input selected edges. - * Only bevel selected edges that have exactly two incident faces. - * - * TODO, optimization - we could tag edges in 'geom' - * and then just iterate edges-of-vert, checking tags. - */ - BMO_ITER (bme, &siter, bm, op, "geom", BM_EDGE) { - if (BM_vert_in_edge(bme, v)) { - if (BM_edge_is_manifold(bme)) { - BMO_elem_flag_enable(bm, bme, EDGE_SELECTED); - nsel++; - } - } - } - - if (nsel == 0) - return; - - ntot = BM_vert_edge_count(v); - bv = (BevVert *)MEM_callocN(sizeof(BevVert), "BevVert"); - bv->v = v; - bv->edgecount = ntot; - bv->selcount = nsel; - bv->edges = (EdgeHalf *)MEM_callocN(ntot * sizeof(EdgeHalf), "EdgeHalf"); - bv->vmesh = (VMesh *)MEM_callocN(sizeof(VMesh), "VMesh"); - bv->vmesh->seg = bp->seg; - BLI_addtail(&bp->vertList, bv); - - /* add edges to bv->edges in order that keeps adjacent edges sharing - * a face, if possible */ - i = 0; - bme = v->e; - BMO_elem_flag_enable(bm, bme, BEVEL_FLAG); - e = &bv->edges[0]; - e->e = bme; - for (i = 0; i < ntot; i++) { - if (i > 0) { - /* find an unflagged edge bme2 that shares a face f with previous bme */ - found_shared_face = 0; - unflagged_bme = NULL; - BM_ITER_ELEM (bme2, &iter, v, BM_EDGES_OF_VERT) { - if (BMO_elem_flag_test(bm, bme2, BEVEL_FLAG)) - continue; - if (!unflagged_bme) - unflagged_bme = bme2; - BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) { - if (BM_face_edge_share_loop(f, bme)) { - found_shared_face = 1; - break; - } - } - if (found_shared_face) - break; - } - e = &bv->edges[i]; - if (found_shared_face) { - e->e = bme2; - e->fprev = f; - bv->edges[i - 1].fnext = f; - } - else { - e->e = unflagged_bme; - } - } - bme = e->e; - BMO_elem_flag_enable(bm, bme, BEVEL_FLAG); - if (BMO_elem_flag_test(bm, bme, EDGE_SELECTED)) { - e->isbev = 1; - e->seg = bp->seg; - } - else { - e->isbev = 0; - e->seg = 0; - } - e->isrev = (bme->v2 == v); - e->offset = e->isbev ? bp->offset : 0.0f; - } - /* find wrap-around shared face */ - BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) { - if (BM_face_edge_share_loop(f, bv->edges[0].e)) { - if (bv->edges[0].fnext == f) - continue; /* if two shared faces, want the other one now */ - bv->edges[ntot - 1].fnext = f; - bv->edges[0].fprev = f; - break; - } - } - - /* remove BEVEL_FLAG now that we are finished with it*/ - for (i = 0; i < ntot; i++) - BMO_elem_flag_disable(bm, bv->edges[i].e, BEVEL_FLAG); - - /* if edge array doesn't go CCW around vertex from average normal side, - * reverse the array, being careful to reverse face pointers too */ - if (ntot > 1) { - ccw_test_sum = 0; - for (i = 0; i < ntot; i++) - ccw_test_sum += bev_ccw_test(bv->edges[i].e, bv->edges[(i + 1) % ntot].e, - bv->edges[i].fnext); - if (ccw_test_sum < 0) { - for (i = 0; i <= (ntot / 2) - 1; i++) { - SWAP(EdgeHalf, bv->edges[i], bv->edges[ntot - i - 1]); - SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext); - SWAP(BMFace *, bv->edges[ntot - i - 1].fprev, bv->edges[ntot - i - 1].fnext); - } - if (ntot % 2 == 1) { - i = ntot / 2; - SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext); - } - } - } - - for (i = 0; i < ntot; i++) { - e = &bv->edges[i]; - e->next = &bv->edges[(i + 1) % ntot]; - e->prev = &bv->edges[(i + ntot - 1) % ntot]; - } - - build_boundary(bv); - build_vmesh(bm, bv); -} - -/* Face f has at least one beveled vertex. Rebuild f */ -static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) -{ - BMIter liter; - BMLoop *l, *lprev; - BevVert *bv; - BoundVert *v, *vstart, *vend; - EdgeHalf *e, *eprev; - VMesh *vm; - int i, k; - BMVert *bmv; - BMVert **vv = NULL; - BLI_array_declare(vv); - - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - bv = find_bevvert(bp, l->v); - if (bv) { - lprev = l->prev; - e = find_edge_half(bv, l->e); - eprev = find_edge_half(bv, lprev->e); - BLI_assert(e != NULL && eprev != NULL); - vstart = eprev->leftv; - if (e->isbev) - vend = e->rightv; - else - vend = e->leftv; - v = vstart; - vm = bv->vmesh; - BLI_array_append(vv, v->nv.v); - while (v != vend) { - if (vm->mesh_kind == M_NONE && v->ebev && v->ebev->seg > 1 && v->ebev != e && v->ebev != eprev) { - /* case of 3rd face opposite a beveled edge, with no vmesh */ - i = v->index; - e = v->ebev; - for (k = 1; k < e->seg; k++) { - bmv = mesh_vert(vm, i, 0, k)->v; - BLI_array_append(vv, bmv); - } - } - v = v->prev; - BLI_array_append(vv, v->nv.v); - } - } - else { - BLI_array_append(vv, l->v); - } - } - bev_create_ngon(bm, vv, BLI_array_count(vv), f); - BLI_array_free(vv); -} - -/* All polygons touching v need rebuilding because beveling v has made new vertices */ -static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v) -{ - void *faces_stack[BM_DEFAULT_ITER_STACK_SIZE]; - int faces_len, f_index; - BMFace **faces = BM_iter_as_arrayN(bm, BM_FACES_OF_VERT, v, &faces_len, - faces_stack, BM_DEFAULT_ITER_STACK_SIZE); - - if (LIKELY(faces != NULL)) { - for (f_index = 0; f_index < faces_len; f_index++) { - BMFace *f = faces[f_index]; - rebuild_polygon(bm, bp, f); - BM_face_kill(bm, f); - } - - if (faces != (BMFace **)faces_stack) { - MEM_freeN(faces); - } - } -} - - - -/* - * Build the polygons along the selected Edge - */ -static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) -{ - BevVert *bv1, *bv2; - BMVert *bmv1, *bmv2, *bmv3, *bmv4, *bmv1i, *bmv2i, *bmv3i, *bmv4i; - VMesh *vm1, *vm2; - EdgeHalf *e1, *e2; - BMFace *f1, *f2, *f; - int k, nseg, i1, i2; - - if (!BM_edge_is_manifold(bme)) - return; - - bv1 = find_bevvert(bp, bme->v1); - bv2 = find_bevvert(bp, bme->v2); - - BLI_assert(bv1 && bv2); - - e1 = find_edge_half(bv1, bme); - e2 = find_edge_half(bv2, bme); - - BLI_assert(e1 && e2); - - /* v4 v3 - * \ / - * e->v1 - e->v2 - * / \ - * v1 v2 - */ - nseg = e1->seg; - BLI_assert(nseg > 0 && nseg == e2->seg); - - bmv1 = e1->leftv->nv.v; - bmv4 = e1->rightv->nv.v; - bmv2 = e2->rightv->nv.v; - bmv3 = e2->leftv->nv.v; - - BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); - - f1 = boundvert_rep_face(e1->leftv); - f2 = boundvert_rep_face(e1->rightv); - - if (nseg == 1) { - bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f1); - } - else { - i1 = e1->leftv->index; - i2 = e2->leftv->index; - vm1 = bv1->vmesh; - vm2 = bv2->vmesh; - bmv1i = bmv1; - bmv2i = bmv2; - for (k = 1; k <= nseg; k++) { - bmv4i = mesh_vert(vm1, i1, 0, k)->v; - bmv3i = mesh_vert(vm2, i2, 0, nseg - k)->v; - f = (k <= nseg / 2 + (nseg % 2)) ? f1 : f2; - bev_create_quad_tri(bm, bmv1i, bmv2i, bmv3i, bmv4i, f); - bmv1i = bmv4i; - bmv2i = bmv3i; - } - } -} - - -static void free_bevel_params(BevelParams *bp) -{ - BevVert *bv; - VMesh *vm; - BoundVert *v, *vnext; - - for (bv = bp->vertList.first; bv; bv = bv->next) { - MEM_freeN(bv->edges); - vm = bv->vmesh; - v = vm->boundstart; - if (v) { - do { - vnext = v->next; - MEM_freeN(v); - } while ((v = vnext) != vm->boundstart); - } - if (vm->mesh) - MEM_freeN(vm->mesh); - MEM_freeN(vm); - } - BLI_freelistN(&bp->vertList); -} - -void bmo_bevel_exec(BMesh *bm, BMOperator *op) -{ - BMOIter siter; - BMVert *v; - BMEdge *e; - BevelParams bp = {{NULL}}; - - bp.offset = BMO_slot_float_get(op, "offset"); - bp.op = op; - bp.seg = BMO_slot_int_get(op, "segments"); - - if (bp.offset > 0) { - /* The analysis of the input vertices and execution additional constructions */ BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) { - bevel_vert_construct(bm, &bp, op, v); + BM_elem_flag_enable(v, BM_ELEM_TAG); } - /* Build polygons for edges */ + BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) { - bevel_build_edge_polygons(bm, &bp, e); + if (BM_edge_is_manifold(e)) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + } } - BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) { - bevel_rebuild_existing_polygons(bm, &bp, v); - } - - BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) { - if (find_bevvert(&bp, v)) - BM_vert_kill(bm, v); - } - free_bevel_params(&bp); + BM_mesh_bevel(bm, offset, seg); } - } - -#else -#define BEVEL_FLAG 1 -#define BEVEL_DEL 2 -#define FACE_NEW 4 -#define EDGE_OLD 8 -#define FACE_OLD 16 -#define VERT_OLD 32 -#define FACE_SPAN 64 -#define FACE_HOLE 128 - -typedef struct LoopTag { - BMVert *newv; -} LoopTag; - -typedef struct EdgeTag { - BMVert *newv1, *newv2; -} EdgeTag; - -static void calc_corner_co(BMLoop *l, const float fac, float r_co[3], - const short do_dist, const short do_even) -{ - float no[3], l_vec_prev[3], l_vec_next[3], l_co_prev[3], l_co[3], l_co_next[3], co_ofs[3]; - int is_concave; - - /* first get the prev/next verts */ - if (l->f->len > 2) { - copy_v3_v3(l_co_prev, l->prev->v->co); - copy_v3_v3(l_co, l->v->co); - copy_v3_v3(l_co_next, l->next->v->co); - - /* calculate normal */ - sub_v3_v3v3(l_vec_prev, l_co_prev, l_co); - sub_v3_v3v3(l_vec_next, l_co_next, l_co); - - cross_v3_v3v3(no, l_vec_prev, l_vec_next); - is_concave = dot_v3v3(no, l->f->no) > 0.0f; - } - else { - BMIter iter; - BMLoop *l2; - float up[3] = {0.0f, 0.0f, 1.0f}; - - copy_v3_v3(l_co_prev, l->prev->v->co); - copy_v3_v3(l_co, l->v->co); - - BM_ITER_ELEM (l2, &iter, l->v, BM_LOOPS_OF_VERT) { - if (l2->f != l->f) { - copy_v3_v3(l_co_next, BM_edge_other_vert(l2->e, l2->next->v)->co); - break; - } - } - - sub_v3_v3v3(l_vec_prev, l_co_prev, l_co); - sub_v3_v3v3(l_vec_next, l_co_next, l_co); - - cross_v3_v3v3(no, l_vec_prev, l_vec_next); - if (dot_v3v3(no, no) == 0.0f) { - no[0] = no[1] = 0.0f; no[2] = -1.0f; - } - - is_concave = dot_v3v3(no, up) < 0.0f; - } - - - /* now calculate the new location */ - if (do_dist) { /* treat 'fac' as distance */ - - normalize_v3(l_vec_prev); - normalize_v3(l_vec_next); - - add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next); - if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) { /* edges form a straight line */ - cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no); - } - - if (do_even) { - negate_v3(l_vec_next); - mul_v3_fl(co_ofs, fac * shell_angle_to_dist(0.5f * angle_normalized_v3v3(l_vec_prev, l_vec_next))); - /* negate_v3(l_vec_next); */ /* no need unless we use again */ - } - else { - mul_v3_fl(co_ofs, fac); - } - } - else { /* treat as 'fac' as a factor (0 - 1) */ - - /* not strictly necessary, balance vectors - * so the longer edge doesn't skew the result, - * gives nicer, move even output. - * - * Use the minimum rather then the middle value so skinny faces don't flip along the short axis */ - float min_fac = min_ff(normalize_v3(l_vec_prev), normalize_v3(l_vec_next)); - float angle; - - if (do_even) { - negate_v3(l_vec_next); - angle = angle_normalized_v3v3(l_vec_prev, l_vec_next); - negate_v3(l_vec_next); /* no need unless we use again */ - } - else { - angle = 0.0f; - } - - mul_v3_fl(l_vec_prev, min_fac); - mul_v3_fl(l_vec_next, min_fac); - - add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next); - - if (UNLIKELY(is_zero_v3(co_ofs))) { - cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no); - normalize_v3(co_ofs); - mul_v3_fl(co_ofs, min_fac); - } - - /* done */ - if (do_even) { - mul_v3_fl(co_ofs, (fac * 0.5f) * shell_angle_to_dist(0.5f * angle)); - } - else { - mul_v3_fl(co_ofs, fac * 0.5f); - } - } - - /* apply delta vec */ - if (is_concave) - negate_v3(co_ofs); - - add_v3_v3v3(r_co, co_ofs, l->v->co); -} - - -#define ETAG_SET(e, v, nv) ( \ - (v) == (e)->v1 ? \ - (etags[BM_elem_index_get((e))].newv1 = (nv)) : \ - (etags[BM_elem_index_get((e))].newv2 = (nv)) \ - ) - -#define ETAG_GET(e, v) ( \ - (v) == (e)->v1 ? \ - (etags[BM_elem_index_get((e))].newv1) : \ - (etags[BM_elem_index_get((e))].newv2) \ - ) - -void bmo_bevel_exec(BMesh *bm, BMOperator *op) -{ - BMOIter siter; - BMIter iter; - BMEdge *e; - BMVert *v; - BMFace **faces = NULL, *f; - LoopTag *tags = NULL, *tag; - EdgeTag *etags = NULL; - BMVert **verts = NULL; - BMEdge **edges = NULL; - BLI_array_declare(faces); - BLI_array_declare(tags); - BLI_array_declare(etags); - BLI_array_declare(verts); - BLI_array_declare(edges); - SmallHash hash; - float fac = BMO_slot_float_get(op, "percent"); - const short do_even = BMO_slot_bool_get(op, "use_even"); - const short do_dist = BMO_slot_bool_get(op, "use_dist"); - int i, li, has_elens, HasMDisps = CustomData_has_layer(&bm->ldata, CD_MDISPS); - - has_elens = CustomData_has_layer(&bm->edata, CD_PROP_FLT) && BMO_slot_bool_get(op, "use_lengths"); - if (has_elens) { - li = BMO_slot_int_get(op, "lengthlayer"); - } - - BLI_smallhash_init(&hash); - - BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) { - BMO_elem_flag_enable(bm, e, BEVEL_FLAG | BEVEL_DEL); - BMO_elem_flag_enable(bm, e->v1, BEVEL_FLAG | BEVEL_DEL); - BMO_elem_flag_enable(bm, e->v2, BEVEL_FLAG | BEVEL_DEL); - - if (BM_edge_face_count(e) < 2) { - BMO_elem_flag_disable(bm, e, BEVEL_DEL); - BMO_elem_flag_disable(bm, e->v1, BEVEL_DEL); - BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL); - } -#if 0 - if (BM_edge_is_wire(e)) { - BMVert *verts[2] = {e->v1, e->v2}; - BMEdge *edges[2] = {e, BM_edge_create(bm, e->v1, e->v2, e, 0)}; - - BMO_elem_flag_enable(bm, edges[1], BEVEL_FLAG); - BM_face_create(bm, verts, edges, 2, FALSE); - } -#endif - } - - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BMO_elem_flag_enable(bm, v, VERT_OLD); - } - -#if 0 - /* a bit of cleaner code that, alas, doens't work. */ - /* build edge tag */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BMO_elem_flag_test(bm, e->v1, BEVEL_FLAG) || BMO_elem_flag_test(bm, e->v2, BEVEL_FLAG)) { - BMIter liter; - BMLoop *l; - - if (!BMO_elem_flag_test(bm, e, EDGE_OLD)) { - BM_elem_index_set(e, BLI_array_count(etags)); /* set_dirty! */ - BLI_array_grow_one(etags); - - BMO_elem_flag_enable(bm, e, EDGE_OLD); - } - - BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) { - BMLoop *l2; - BMIter liter2; - - if (BMO_elem_flag_test(bm, l->f, BEVEL_FLAG)) - continue; - - BM_ITER_ELEM (l2, &liter2, l->f, BM_LOOPS_OF_FACE) { - BM_elem_index_set(l2, BLI_array_count(tags)); /* set_loop */ - BLI_array_grow_one(tags); - - if (!BMO_elem_flag_test(bm, l2->e, EDGE_OLD)) { - BM_elem_index_set(l2->e, BLI_array_count(etags)); /* set_dirty! */ - BLI_array_grow_one(etags); - - BMO_elem_flag_enable(bm, l2->e, EDGE_OLD); - } - } - - BMO_elem_flag_enable(bm, l->f, BEVEL_FLAG); - BLI_array_append(faces, l->f); - } - } - else { - BM_elem_index_set(e, -1); /* set_dirty! */ - } - } -#endif - - /* create and assign looptag structure */ - BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) { - BMLoop *l; - BMIter liter; - - BMO_elem_flag_enable(bm, e->v1, BEVEL_FLAG | BEVEL_DEL); - BMO_elem_flag_enable(bm, e->v2, BEVEL_FLAG | BEVEL_DEL); - - if (BM_edge_face_count(e) < 2) { - BMO_elem_flag_disable(bm, e, BEVEL_DEL); - BMO_elem_flag_disable(bm, e->v1, BEVEL_DEL); - BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL); - } - - if (!BLI_smallhash_haskey(&hash, (intptr_t)e)) { - BLI_array_grow_one(etags); - BM_elem_index_set(e, BLI_array_count(etags) - 1); /* set_dirty! */ - BLI_smallhash_insert(&hash, (intptr_t)e, NULL); - BMO_elem_flag_enable(bm, e, EDGE_OLD); - } - - /* find all faces surrounding e->v1 and, e->v2 */ - for (i = 0; i < 2; i++) { - BM_ITER_ELEM (l, &liter, i ? e->v2 : e->v1, BM_LOOPS_OF_VERT) { - BMLoop *l2; - BMIter liter2; - - /* see if we've already processed this loop's fac */ - if (BLI_smallhash_haskey(&hash, (intptr_t)l->f)) - continue; - - /* create tags for all loops in l-> */ - BM_ITER_ELEM (l2, &liter2, l->f, BM_LOOPS_OF_FACE) { - BLI_array_grow_one(tags); - BM_elem_index_set(l2, BLI_array_count(tags) - 1); /* set_loop */ - - if (!BLI_smallhash_haskey(&hash, (intptr_t)l2->e)) { - BLI_array_grow_one(etags); - BM_elem_index_set(l2->e, BLI_array_count(etags) - 1); /* set_dirty! */ - BLI_smallhash_insert(&hash, (intptr_t)l2->e, NULL); - BMO_elem_flag_enable(bm, l2->e, EDGE_OLD); - } - } - - BLI_smallhash_insert(&hash, (intptr_t)l->f, NULL); - BMO_elem_flag_enable(bm, l->f, BEVEL_FLAG); - BLI_array_append(faces, l->f); - } - } - } - - bm->elem_index_dirty |= BM_EDGE; - - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BMIter eiter; - - if (!BMO_elem_flag_test(bm, v, BEVEL_FLAG)) - continue; - - BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - if (!BMO_elem_flag_test(bm, e, BEVEL_FLAG) && !ETAG_GET(e, v)) { - BMVert *v2; - float co[3]; - - v2 = BM_edge_other_vert(e, v); - sub_v3_v3v3(co, v2->co, v->co); - if (has_elens) { - float elen = *(float *)CustomData_bmesh_get_n(&bm->edata, e->head.data, CD_PROP_FLT, li); - - normalize_v3(co); - mul_v3_fl(co, elen); - } - - mul_v3_fl(co, fac); - add_v3_v3(co, v->co); - - v2 = BM_vert_create(bm, co, v); - ETAG_SET(e, v, v2); - } - } - } - - for (i = 0; i < BLI_array_count(faces); i++) { - BMLoop *l; - BMIter liter; - - BMO_elem_flag_enable(bm, faces[i], FACE_OLD); - - BM_ITER_ELEM (l, &liter, faces[i], BM_LOOPS_OF_FACE) { - float co[3]; - - if (BMO_elem_flag_test(bm, l->e, BEVEL_FLAG)) { - if (BMO_elem_flag_test(bm, l->prev->e, BEVEL_FLAG)) { - tag = tags + BM_elem_index_get(l); - calc_corner_co(l, fac, co, do_dist, do_even); - tag->newv = BM_vert_create(bm, co, l->v); - } - else { - tag = tags + BM_elem_index_get(l); - tag->newv = ETAG_GET(l->prev->e, l->v); - - if (!tag->newv) { - sub_v3_v3v3(co, l->prev->v->co, l->v->co); - if (has_elens) { - float elen = *(float *)CustomData_bmesh_get_n(&bm->edata, l->prev->e->head.data, - CD_PROP_FLT, li); - - normalize_v3(co); - mul_v3_fl(co, elen); - } - - mul_v3_fl(co, fac); - add_v3_v3(co, l->v->co); - - tag->newv = BM_vert_create(bm, co, l->v); - - ETAG_SET(l->prev->e, l->v, tag->newv); - } - } - } - else if (BMO_elem_flag_test(bm, l->v, BEVEL_FLAG)) { - tag = tags + BM_elem_index_get(l); - tag->newv = ETAG_GET(l->e, l->v); - - if (!tag->newv) { - sub_v3_v3v3(co, l->next->v->co, l->v->co); - if (has_elens) { - float elen = *(float *)CustomData_bmesh_get_n(&bm->edata, l->e->head.data, CD_PROP_FLT, li); - - normalize_v3(co); - mul_v3_fl(co, elen); - } - - mul_v3_fl(co, fac); - add_v3_v3(co, l->v->co); - - tag = tags + BM_elem_index_get(l); - tag->newv = BM_vert_create(bm, co, l->v); - - ETAG_SET(l->e, l->v, tag->newv); - } - } - else { - tag = tags + BM_elem_index_get(l); - tag->newv = l->v; - BMO_elem_flag_disable(bm, l->v, BEVEL_DEL); - } - } - } - - /* create new faces inset from original face */ - for (i = 0; i < BLI_array_count(faces); i++) { - BMLoop *l; - BMIter liter; - BMFace *f; - BMVert *lastv = NULL, *firstv = NULL; - - BMO_elem_flag_enable(bm, faces[i], BEVEL_DEL); - - BLI_array_empty(verts); - BLI_array_empty(edges); - - BM_ITER_ELEM (l, &liter, faces[i], BM_LOOPS_OF_FACE) { - BMVert *v2; - - tag = tags + BM_elem_index_get(l); - BLI_array_append(verts, tag->newv); - - if (!firstv) - firstv = tag->newv; - - if (lastv) { - e = BM_edge_create(bm, lastv, tag->newv, l->e, TRUE); - BM_elem_attrs_copy(bm, bm, l->prev->e, e); - BLI_array_append(edges, e); - } - lastv = tag->newv; - - v2 = ETAG_GET(l->e, l->next->v); - - tag = &tags[BM_elem_index_get(l->next)]; - if (!BMO_elem_flag_test(bm, l->e, BEVEL_FLAG) && v2 && v2 != tag->newv) { - BLI_array_append(verts, v2); - - e = BM_edge_create(bm, lastv, v2, l->e, TRUE); - BM_elem_attrs_copy(bm, bm, l->e, e); - - BLI_array_append(edges, e); - lastv = v2; - } - } - - e = BM_edge_create(bm, firstv, lastv, BM_FACE_FIRST_LOOP(faces[i])->e, TRUE); - if (BM_FACE_FIRST_LOOP(faces[i])->prev->e != e) { - BM_elem_attrs_copy(bm, bm, BM_FACE_FIRST_LOOP(faces[i])->prev->e, e); - } - BLI_array_append(edges, e); - - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), FALSE); - if (UNLIKELY(f == NULL)) { - printf("%s: could not make face!\n", __func__); - continue; - } - - BMO_elem_flag_enable(bm, f, FACE_NEW); - } - - for (i = 0; i < BLI_array_count(faces); i++) { - BMLoop *l; - BMIter liter; - int j; - - /* create quad spans between split edge */ - BM_ITER_ELEM (l, &liter, faces[i], BM_LOOPS_OF_FACE) { - BMVert *v1 = NULL, *v2 = NULL, *v3 = NULL, *v4 = NULL; - - if (!BMO_elem_flag_test(bm, l->e, BEVEL_FLAG)) - continue; - - v1 = tags[BM_elem_index_get(l)].newv; - v2 = tags[BM_elem_index_get(l->next)].newv; - if (l->radial_next != l) { - v3 = tags[BM_elem_index_get(l->radial_next)].newv; - if (l->radial_next->next->v == l->next->v) { - v4 = v3; - v3 = tags[BM_elem_index_get(l->radial_next->next)].newv; - } - else { - v4 = tags[BM_elem_index_get(l->radial_next->next)].newv; - } - } - else { - /* the loop is on a boundar */ - v3 = l->next->v; - v4 = l->v; - - for (j = 0; j < 2; j++) { - BMIter eiter; - BMVert *v = j ? v4 : v3; - - BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - if (!BM_vert_in_edge(e, v3) || !BM_vert_in_edge(e, v4)) - continue; - - if (!BMO_elem_flag_test(bm, e, BEVEL_FLAG) && BMO_elem_flag_test(bm, e, EDGE_OLD)) { - BMVert *vv; - - vv = ETAG_GET(e, v); - if (!vv || BMO_elem_flag_test(bm, vv, BEVEL_FLAG)) - continue; - - if (j) { - v1 = vv; - } - else { - v2 = vv; - } - break; - } - } - } - - BMO_elem_flag_disable(bm, v3, BEVEL_DEL); - BMO_elem_flag_disable(bm, v4, BEVEL_DEL); - } - - if (v1 != v2 && v2 != v3 && v3 != v4) { - BMIter liter2; - BMLoop *l2, *l3; - BMEdge *e1, *e2; - float d1, d2, *d3; - - f = BM_face_create_quad_tri(bm, v4, v3, v2, v1, l->f, TRUE); - - e1 = BM_edge_exists(v4, v3); - e2 = BM_edge_exists(v2, v1); - BM_elem_attrs_copy(bm, bm, l->e, e1); - BM_elem_attrs_copy(bm, bm, l->e, e2); - - /* set edge lengths of cross edges as the average of the cross edges they're based o */ - if (has_elens) { - /* angle happens not to be used. why? - not sure it just isn't - campbell. - * leave this in in case we need to use it later */ -#if 0 - float ang; -#endif - e1 = BM_edge_exists(v1, v4); - e2 = BM_edge_exists(v2, v3); - - if (l->radial_next->v == l->v) { - l2 = l->radial_next->prev; - l3 = l->radial_next->next; - } - else { - l2 = l->radial_next->next; - l3 = l->radial_next->prev; - } - - d3 = CustomData_bmesh_get_n(&bm->edata, e1->head.data, CD_PROP_FLT, li); - d1 = *(float *)CustomData_bmesh_get_n(&bm->edata, l->prev->e->head.data, CD_PROP_FLT, li); - d2 = *(float *)CustomData_bmesh_get_n(&bm->edata, l2->e->head.data, CD_PROP_FLT, li); -#if 0 - ang = angle_v3v3v3(l->prev->v->co, l->v->co, BM_edge_other_vert(l2->e, l->v)->co); -#endif - *d3 = (d1 + d2) * 0.5f; - - d3 = CustomData_bmesh_get_n(&bm->edata, e2->head.data, CD_PROP_FLT, li); - d1 = *(float *)CustomData_bmesh_get_n(&bm->edata, l->next->e->head.data, CD_PROP_FLT, li); - d2 = *(float *)CustomData_bmesh_get_n(&bm->edata, l3->e->head.data, CD_PROP_FLT, li); -#if 0 - ang = angle_v3v3v3(BM_edge_other_vert(l->next->e, l->next->v)->co, l->next->v->co, - BM_edge_other_vert(l3->e, l->next->v)->co); -#endif - *d3 = (d1 + d2) * 0.5f; - } - - if (UNLIKELY(f == NULL)) { - fprintf(stderr, "%s: face index out of range! (bmesh internal error)\n", __func__); - continue; - } - - BMO_elem_flag_enable(bm, f, FACE_NEW | FACE_SPAN); - - /* un-tag edges in f for deletio */ - BM_ITER_ELEM (l2, &liter2, f, BM_LOOPS_OF_FACE) { - BMO_elem_flag_disable(bm, l2->e, BEVEL_DEL); - } - } - else { - f = NULL; - } - } - } - - /* fill in holes at vertices */ - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BMIter eiter; - BMVert *vv, *vstart = NULL, *lastv = NULL; - SmallHash tmphash; - int rad, insorig = 0, err = 0; - - BLI_smallhash_init(&tmphash); - - if (!BMO_elem_flag_test(bm, v, BEVEL_FLAG)) - continue; - - BLI_array_empty(verts); - BLI_array_empty(edges); - - BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - BMIter liter; - BMVert *v1 = NULL, *v2 = NULL; - BMLoop *l; - - if (BM_edge_face_count(e) < 2) - insorig = 1; - - if (BM_elem_index_get(e) == -1) - continue; - - rad = 0; - BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) { - if (!BMO_elem_flag_test(bm, l->f, FACE_OLD)) - continue; - - rad++; - - tag = tags + BM_elem_index_get((l->v == v) ? l : l->next); - - if (!v1) - v1 = tag->newv; - else if (!v2) - v2 = tag->newv; - } - - if (rad < 2) - insorig = 1; - - if (!v1) - v1 = ETAG_GET(e, v); - if (!v2 || v1 == v2) - v2 = ETAG_GET(e, v); - - if (v1) { - if (!BLI_smallhash_haskey(&tmphash, (intptr_t)v1)) { - BLI_array_append(verts, v1); - BLI_smallhash_insert(&tmphash, (intptr_t)v1, NULL); - } - - if (v2 && v1 != v2 && !BLI_smallhash_haskey(&tmphash, (intptr_t)v2)) { - BLI_array_append(verts, v2); - BLI_smallhash_insert(&tmphash, (intptr_t)v2, NULL); - } - } - } - - if (!BLI_array_count(verts)) - continue; - - if (insorig) { - BLI_array_append(verts, v); - BLI_smallhash_insert(&tmphash, (intptr_t)v, NULL); - } - - /* find edges that exist between vertices in verts. this is basically - * a topological walk of the edges connecting them */ - vstart = vstart ? vstart : verts[0]; - vv = vstart; - do { - BM_ITER_ELEM (e, &eiter, vv, BM_EDGES_OF_VERT) { - BMVert *vv2 = BM_edge_other_vert(e, vv); - - if (vv2 != lastv && BLI_smallhash_haskey(&tmphash, (intptr_t)vv2)) { - /* if we've go over the same vert twice, break out of outer loop */ - if (BLI_smallhash_lookup(&tmphash, (intptr_t)vv2) != NULL) { - e = NULL; - err = 1; - break; - } - - /* use self pointer as ta */ - BLI_smallhash_remove(&tmphash, (intptr_t)vv2); - BLI_smallhash_insert(&tmphash, (intptr_t)vv2, vv2); - - lastv = vv; - BLI_array_append(edges, e); - vv = vv2; - break; - } - } - - if (e == NULL) { - break; - } - } while (vv != vstart); - - if (err) { - continue; - } - - /* there may not be a complete loop of edges, so start again and make - * final edge afterwards. in this case, the previous loop worked to - * find one of the two edges at the extremes. */ - if (vv != vstart) { - /* undo previous taggin */ - for (i = 0; i < BLI_array_count(verts); i++) { - BLI_smallhash_remove(&tmphash, (intptr_t)verts[i]); - BLI_smallhash_insert(&tmphash, (intptr_t)verts[i], NULL); - } - - vstart = vv; - lastv = NULL; - BLI_array_empty(edges); - do { - BM_ITER_ELEM (e, &eiter, vv, BM_EDGES_OF_VERT) { - BMVert *vv2 = BM_edge_other_vert(e, vv); - - if (vv2 != lastv && BLI_smallhash_haskey(&tmphash, (intptr_t)vv2)) { - /* if we've go over the same vert twice, break out of outer loo */ - if (BLI_smallhash_lookup(&tmphash, (intptr_t)vv2) != NULL) { - e = NULL; - err = 1; - break; - } - - /* use self pointer as ta */ - BLI_smallhash_remove(&tmphash, (intptr_t)vv2); - BLI_smallhash_insert(&tmphash, (intptr_t)vv2, vv2); - - lastv = vv; - BLI_array_append(edges, e); - vv = vv2; - break; - } - } - if (e == NULL) - break; - } while (vv != vstart); - - if (!err) { - e = BM_edge_create(bm, vv, vstart, NULL, TRUE); - BLI_array_append(edges, e); - } - } - - if (err) - continue; - - if (BLI_array_count(edges) >= 3) { - BMFace *f; - - if (BM_face_exists(bm, verts, BLI_array_count(verts), &f)) - continue; - - f = BM_face_create_ngon(bm, lastv, vstart, edges, BLI_array_count(edges), FALSE); - if (UNLIKELY(f == NULL)) { - fprintf(stderr, "%s: in bevel vert fill! (bmesh internal error)\n", __func__); - } - else { - BMO_elem_flag_enable(bm, f, FACE_NEW | FACE_HOLE); - } - } - BLI_smallhash_release(&tmphash); - } - - /* copy over customdat */ - for (i = 0; i < BLI_array_count(faces); i++) { - BMLoop *l; - BMIter liter; - BMFace *f = faces[i]; - - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BMLoop *l2; - BMIter liter2; - - tag = tags + BM_elem_index_get(l); - if (!tag->newv) - continue; - - BM_ITER_ELEM (l2, &liter2, tag->newv, BM_LOOPS_OF_VERT) { - if (!BMO_elem_flag_test(bm, l2->f, FACE_NEW) || (l2->v != tag->newv && l2->v != l->v)) - continue; - - if (tag->newv != l->v || HasMDisps) { - BM_elem_attrs_copy(bm, bm, l->f, l2->f); - BM_loop_interp_from_face(bm, l2, l->f, TRUE, TRUE); - } - else { - BM_elem_attrs_copy(bm, bm, l->f, l2->f); - BM_elem_attrs_copy(bm, bm, l, l2); - } - - if (HasMDisps) { - BMLoop *l3; - BMIter liter3; - - BM_ITER_ELEM (l3, &liter3, l2->f, BM_LOOPS_OF_FACE) { - BM_loop_interp_multires(bm, l3, l->f); - } - } - } - } - } - - /* handle vertices along boundary edge */ - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (BMO_elem_flag_test(bm, v, VERT_OLD) && - BMO_elem_flag_test(bm, v, BEVEL_FLAG) && - !BMO_elem_flag_test(bm, v, BEVEL_DEL)) - { - BMLoop *l; - BMLoop *lorig = NULL; - BMIter liter; - - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - // BMIter liter2; - // BMLoop *l2 = l->v == v ? l : l->next, *l3; - - if (BMO_elem_flag_test(bm, l->f, FACE_OLD)) { - lorig = l; - break; - } - } - - if (!lorig) - continue; - - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - BMLoop *l2 = l->v == v ? l : l->next; - - BM_elem_attrs_copy(bm, bm, lorig->f, l2->f); - BM_elem_attrs_copy(bm, bm, lorig, l2); - } - } - } -#if 0 - /* clean up any remaining 2-edged face */ - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (f->len == 2) { - BMFace *faces[2] = {f, BM_FACE_FIRST_LOOP(f)->radial_next->f}; - - if (faces[0] == faces[1]) - BM_face_kill(bm, f); - else - BM_faces_join(bm, faces, 2); - } - } -#endif - - BMO_op_callf(bm, op->flag, "delete geom=%fv context=%i", BEVEL_DEL, DEL_VERTS); - - /* clean up any edges that might not get properly delete */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BMO_elem_flag_test(bm, e, EDGE_OLD) && !e->l) - BMO_elem_flag_enable(bm, e, BEVEL_DEL); - } - - BMO_op_callf(bm, op->flag, "delete geom=%fe context=%i", BEVEL_DEL, DEL_EDGES); - BMO_op_callf(bm, op->flag, "delete geom=%ff context=%i", BEVEL_DEL, DEL_FACES); - - BLI_smallhash_release(&hash); - BLI_array_free(tags); - BLI_array_free(etags); - BLI_array_free(verts); - BLI_array_free(edges); - BLI_array_free(faces); - - BMO_slot_buffer_from_enabled_flag(bm, op, "face_spans", BM_FACE, FACE_SPAN); - BMO_slot_buffer_from_enabled_flag(bm, op, "face_holes", BM_FACE, FACE_HOLE); -} -#endif /* NEW_BEVEL */ diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 32270007a0b..aa502203b50 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -181,7 +181,7 @@ static BMFace *copy_face(BMOperator *op, BMesh *source_mesh, * Internal Copy function. */ -static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target) +static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target) { BMVert *v = NULL, *v2; @@ -326,7 +326,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_flag_enable(bm, dupeop, "geom", BM_ALL, DUPE_INPUT); /* use the internal copy function */ - BKE_mesh_copy(dupeop, bm, bm2); + bmo_mesh_copy(dupeop, bm, bm2); /* Output */ /* First copy the input buffers to output buffers - original data */ diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index a632a4446ed..cdfd8372d61 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -1110,10 +1110,13 @@ BMesh *BME_bevel(BMesh *bm, float value, int res, int options, int defgrp_index, td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE); /* recursion math courtesy of Martin Poirier (theeth) */ for (i = 0; i < res - 1; i++) { - if (i == 0) fac += 1.0 / 3.0; else fac += 1.0 / (3.0 * i * 2.0); + if (i == 0) fac += 1.0 / 3.0; + else fac += 1.0 / (3.0 * i * 2.0); } d = 1.0 / fac; + BM_mesh_elem_toolflags_ensure(bm); + for (i = 0; i < res || (res == 0 && i == 0); i++) { BMO_push(bm, NULL); BME_bevel_initialize(bm, options, defgrp_index, angle, td); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c new file mode 100644 index 00000000000..cfc7edb2400 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -0,0 +1,1718 @@ +/* + * ***** 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): + * Joseph Eagar, + * Aleksandr Mokhov, + * Howard Trickey, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/tools/bmesh_bevel.c + * \ingroup bmesh + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_array.h" +#include "BLI_math.h" +#include "BLI_memarena.h" + +#include "BKE_customdata.h" + +#include "bmesh.h" + + + +/* experemental - Campbell */ +// #define USE_ALTERNATE_ADJ + +#define BEVEL_EPSILON 1e-6 + +/* for testing */ +// #pragma GCC diagnostic error "-Wpadded" + +/* Constructed vertex, sometimes later instantiated as BMVert */ +typedef struct NewVert { + BMVert *v; + float co[3]; + int _pad; +} NewVert; + +struct BoundVert; + +/* Data for one end of an edge involved in a bevel */ +typedef struct EdgeHalf { + struct EdgeHalf *next, *prev; /* in CCW order */ + BMEdge *e; /* original mesh edge */ + BMFace *fprev; /* face between this edge and previous, if any */ + BMFace *fnext; /* face between this edge and next, if any */ + struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */ + struct BoundVert *rightv; /* right boundary vert, if beveled */ + short is_bev; /* is this edge beveled? */ + short is_rev; /* is e->v2 the vertex at this end? */ + int seg; /* how many segments for the bevel */ + float offset; /* offset for this edge */ +// int _pad; +} EdgeHalf; + +/* An element in a cyclic boundary of a Vertex Mesh (VMesh) */ +typedef struct BoundVert { + struct BoundVert *next, *prev; /* in CCW order */ + NewVert nv; + EdgeHalf *efirst; /* first of edges attached here: in CCW order */ + EdgeHalf *elast; + EdgeHalf *ebev; /* beveled edge whose left side is attached here, if any */ + int index; /* used for vmesh indexing */ +// int _pad; +} BoundVert; + +/* Mesh structure replacing a vertex */ +typedef struct VMesh { + NewVert *mesh; /* allocated array - size and structure depends on kind */ + BoundVert *boundstart; /* start of boundary double-linked list */ + int count; /* number of vertices in the boundary */ + int seg; /* common # of segments for segmented edges */ + enum { + M_NONE, /* no polygon mesh needed */ + M_POLY, /* a simple polygon */ + M_ADJ, /* "adjacent edges" mesh pattern */ +// M_CROSS, /* "cross edges" mesh pattern */ + M_TRI_FAN, /* a simple polygon - fan filled */ + M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */ + } mesh_kind; +// int _pad; +} VMesh; + +/* Data for a vertex involved in a bevel */ +typedef struct BevVert { + BMVert *v; /* original mesh vertex */ + int edgecount; /* total number of edges around the vertex */ + int selcount; /* number of selected edges around the vertex */ + EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */ + VMesh *vmesh; /* mesh structure for replacing vertex */ +} BevVert; + +/* Bevel parameters and state */ +typedef struct BevelParams { + /* hash of BevVert for each vertex involved in bevel + * GHash: (key=(BMVert *), value=(BevVert *)) */ + GHash *vert_hash; + MemArena *mem_arena; /* use for all allocs while bevel runs, if we need to free we can switch to mempool */ + + float offset; /* blender units to offset each side of a beveled edge */ + int seg; /* number of segments in beveled edge profile */ +} BevelParams; + +// #pragma GCC diagnostic ignored "-Wpadded" + +//#include "bevdebug.c" + +/* Make a new BoundVert of the given kind, insert it at the end of the circular linked + * list with entry point bv->boundstart, and return it. */ +static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) +{ + BoundVert *ans = (BoundVert *)BLI_memarena_alloc(mem_arena, sizeof(BoundVert)); + + copy_v3_v3(ans->nv.co, co); + if (!vm->boundstart) { + ans->index = 0; + vm->boundstart = ans; + ans->next = ans->prev = ans; + } + else { + BoundVert *tail = vm->boundstart->prev; + ans->index = tail->index + 1; + ans->prev = tail; + ans->next = vm->boundstart; + tail->next = ans; + vm->boundstart->prev = ans; + } + vm->count++; + return ans; +} + +/* Mesh verts are indexed (i, j, k) where + * i = boundvert index (0 <= i < nv) + * j = ring index (0 <= j <= ns2) + * k = segment index (0 <= k <= ns) + * Not all of these are used, and some will share BMVerts */ +static NewVert *mesh_vert(VMesh *vm, int i, int j, int k) +{ + int nj = (vm->seg / 2) + 1; + int nk = vm->seg + 1; + + return &vm->mesh[i * nk * nj + j * nk + k]; +} + +static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg) +{ + NewVert *nv = mesh_vert(vm, i, j, k); + nv->v = BM_vert_create(bm, nv->co, eg); +} + +static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto, + int ifrom, int jfrom, int kfrom) +{ + NewVert *nvto, *nvfrom; + + nvto = mesh_vert(vm, ito, jto, kto); + nvfrom = mesh_vert(vm, ifrom, jfrom, kfrom); + nvto->v = nvfrom->v; + copy_v3_v3(nvto->co, nvfrom->co); +} + +/* find the EdgeHalf in bv's array that has edge bme */ +static EdgeHalf *find_edge_half(BevVert *bv, BMEdge *bme) +{ + int i; + + for (i = 0; i < bv->edgecount; i++) { + if (bv->edges[i].e == bme) + return &bv->edges[i]; + } + return NULL; +} + +/* Return the next EdgeHalf after from_e that is beveled. + * If from_e is NULL, find the first beveled edge. */ +static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e) +{ + EdgeHalf *e; + + if (from_e == NULL) + from_e = &bv->edges[bv->edgecount - 1]; + e = from_e; + do { + if (e->is_bev) { + return e; + } + } while ((e = e->next) != from_e); + return NULL; +} + +/* find the BevVert corresponding to BMVert bmv */ +static BevVert *find_bevvert(BevelParams *bp, BMVert *bmv) +{ + return BLI_ghash_lookup(bp->vert_hash, bmv); +} + +/* Return a good respresentative face (for materials, etc.) for faces + * created around/near BoundVert v */ +static BMFace *boundvert_rep_face(BoundVert *v) +{ + BMFace *fans = NULL; + BMFace *firstf = NULL; + BMEdge *e1, *e2; + BMFace *f1, *f2; + BMIter iter1, iter2; + + BLI_assert(v->efirst != NULL && v->elast != NULL); + e1 = v->efirst->e; + e2 = v->elast->e; + BM_ITER_ELEM (f1, &iter1, e1, BM_FACES_OF_EDGE) { + if (!firstf) + firstf = f1; + BM_ITER_ELEM (f2, &iter2, e2, BM_FACES_OF_EDGE) { + if (f1 == f2) { + fans = f1; + break; + } + } + } + if (!fans) + fans = firstf; + + return fans; +} + +/* Make ngon from verts alone. + * Make sure to properly copy face attributes and do custom data interpolation from + * example face, facerep. */ +static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, int totv, BMFace *facerep) +{ + BMIter iter; + BMLoop *l; + BMFace *f; + + if (totv == 3) { + f = BM_face_create_quad_tri_v(bm, vert_arr, 3, facerep, 0); + } + else if (totv == 4) { + f = BM_face_create_quad_tri_v(bm, vert_arr, 4, facerep, 0); + } + else { + int i; + BMEdge **ee = NULL; + BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE); + + BLI_array_grow_items(ee, totv); + for (i = 0; i < totv; i++) { + ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE); + } + f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE); + BLI_array_free(ee); + } + if (facerep && f) { + int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS); + BM_elem_attrs_copy(bm, bm, facerep, f); + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + BM_loop_interp_from_face(bm, l, facerep, TRUE, TRUE); + if (has_mdisps) + BM_loop_interp_multires(bm, l, facerep); + } + } + return f; +} + +static BMFace *bev_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4, + BMFace *facerep) +{ + BMVert *varr[4]; + + varr[0] = v1; + varr[1] = v2; + varr[2] = v3; + varr[3] = v4; + return bev_create_ngon(bm, varr, v4 ? 4 : 3, facerep); +} + +/* + * Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco. + * e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of + * the bevel vertex, e1 precedes e2 in CCW order. + * If on_right is true, offset edge is on right of both edges, where e1 enters v and + * e2 leave it. If on_right is false, then the offset edge is on the left. + * When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2), + * but if the offsets are not equal (allowing for this, as bevel modifier has edge weights that may + * lead to different offsets) then meeting point can be found be intersecting offset lines. + */ +static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, + int on_right, float meetco[3]) +{ + float dir1[3], dir2[3], norm_v[3], norm_perp1[3], norm_perp2[3], + off1a[3], off1b[3], off2a[3], off2b[3], isect2[3]; + + /* get direction vectors for two offset lines */ + sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co); + sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co); + + /* get normal to plane where meet point should be */ + cross_v3_v3v3(norm_v, dir2, dir1); + normalize_v3(norm_v); + if (!on_right) + negate_v3(norm_v); + if (is_zero_v3(norm_v)) { + /* special case: e1 and e2 are parallel; put offset point perp to both, from v. + * need to find a suitable plane. + * if offsets are different, we're out of luck: just use e1->offset */ + if (f) + copy_v3_v3(norm_v, f->no); + else + copy_v3_v3(norm_v, v->no); + cross_v3_v3v3(norm_perp1, dir1, norm_v); + normalize_v3(norm_perp1); + copy_v3_v3(off1a, v->co); + madd_v3_v3fl(off1a, norm_perp1, e1->offset); + copy_v3_v3(meetco, off1a); + } + else { + /* get vectors perp to each edge, perp to norm_v, and pointing into face */ + if (f) { + copy_v3_v3(norm_v, f->no); + } + cross_v3_v3v3(norm_perp1, dir1, norm_v); + cross_v3_v3v3(norm_perp2, dir2, norm_v); + normalize_v3(norm_perp1); + normalize_v3(norm_perp2); + + /* get points that are offset distances from each line, then another point on each line */ + copy_v3_v3(off1a, v->co); + madd_v3_v3fl(off1a, norm_perp1, e1->offset); + add_v3_v3v3(off1b, off1a, dir1); + copy_v3_v3(off2a, v->co); + madd_v3_v3fl(off2a, norm_perp2, e2->offset); + add_v3_v3v3(off2b, off2a, dir2); + + /* intersect the lines; by construction they should be on the same plane and not parallel */ + if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) { + BLI_assert(!"offset_meet failure"); + copy_v3_v3(meetco, off1a); /* just to do something */ + } + } +} + +/* Like offset_meet, but here f1 and f2 must not be NULL and give the + * planes in which to run the offset lines. They may not meet exactly, + * but the line intersection routine will find the closest approach point. */ +static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, + BMFace *f1, BMFace *f2, float meetco[3]) +{ + float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3], + off1a[3], off1b[3], off2a[3], off2b[3], isect2[3]; + + BLI_assert(f1 != NULL && f2 != NULL); + + /* get direction vectors for two offset lines */ + sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co); + sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co); + + /* get directions into offset planes */ + cross_v3_v3v3(norm_perp1, dir1, f1->no); + normalize_v3(norm_perp1); + cross_v3_v3v3(norm_perp2, dir2, f2->no); + normalize_v3(norm_perp2); + + /* get points that are offset distances from each line, then another point on each line */ + copy_v3_v3(off1a, v->co); + madd_v3_v3fl(off1a, norm_perp1, e1->offset); + add_v3_v3v3(off1b, off1a, dir1); + copy_v3_v3(off2a, v->co); + madd_v3_v3fl(off2a, norm_perp2, e2->offset); + add_v3_v3v3(off2b, off2a, dir2); + + if (angle_v3v3(dir1, dir2) < (float)BEVEL_EPSILON) { + /* lines are parallel; off1a is a good meet point */ + copy_v3_v3(meetco, off1a); + } + else if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) { + /* another test says they are parallel */ + copy_v3_v3(meetco, off1a); + } +} + +/* Offset by e->offset in plane with normal plane_no, on left if left==TRUE, + * else on right. If no is NULL, choose an arbitrary plane different + * from eh's direction. */ +static void offset_in_plane(EdgeHalf *e, const float plane_no[3], int left, float r[3]) +{ + float dir[3], no[3]; + BMVert *v; + + v = e->is_rev ? e->e->v1 : e->e->v2; + + sub_v3_v3v3(dir, BM_edge_other_vert(e->e, v)->co, v->co); + normalize_v3(dir); + if (plane_no) { + copy_v3_v3(no, plane_no); + } + else { + zero_v3(no); + if (fabs(dir[0]) < fabs(dir[1])) + no[0] = 1.0f; + else + no[1] = 1.0f; + } + if (left) + cross_v3_v3v3(r, no, dir); + else + cross_v3_v3v3(r, dir, no); + normalize_v3(r); + mul_v3_fl(r, e->offset); +} + +/* Calculate coordinates of a point a distance d from v on e->e and return it in slideco */ +static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3]) +{ + float dir[3], len; + + sub_v3_v3v3(dir, v->co, BM_edge_other_vert(e->e, v)->co); + len = normalize_v3(dir); + if (d > len) + d = len - (float)(50.0 * BEVEL_EPSILON); + copy_v3_v3(slideco, v->co); + madd_v3_v3fl(slideco, dir, -d); +} + +/* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */ +static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3], float projco[3]) +{ + float otherco[3]; + + if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b, projco, otherco)) { + BLI_assert(!"project meet failure"); + copy_v3_v3(projco, e->v1->co); + } +} + +/* return 1 if a and b are in CCW order on the normal side of f, + * and -1 if they are reversed, and 0 if there is no shared face f */ +static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f) +{ + BMLoop *la, *lb; + + if (!f) + return 0; + la = BM_face_edge_share_loop(f, a); + lb = BM_face_edge_share_loop(f, b); + if (!la || !lb) + return 0; + return lb->next == la ? 1 : -1; +} + +#ifdef USE_ALTERNATE_ADJ + +static void vmesh_cent(VMesh *vm, float r_cent[3]) +{ + BoundVert *v; + int tot = 0; + zero_v3(r_cent); + + v = vm->boundstart; + do { + add_v3_v3(r_cent, v->nv.co); + tot++; + } while ((v = v->next) != vm->boundstart); + mul_v3_fl(r_cent, 1.0f / (float)tot); +} + +/** + * + * This example shows a tri fan of quads, + * but could be an NGon fan of quads too. + *
+ *      The whole triangle   X
+ *      represents the      / \
+ *      new bevel face.    /   \
+ *                        /     \
+ *       Split into      /       \
+ *       a quad fan.    /         \
+ *                     /           \
+ *                    /             \
+ *                   /               \
+ *          co_prev +-.             .-+
+ *                 /   `-._     _.-'   \
+ *                / co_cent`-+-'        \
+ *               /           |           \
+ * Quad of      /            |            \
+ * interest -- / ---> X      |             \
+ *            /              |              \
+ *           /               |               \
+ *          /         co_next|                \
+ * co_orig +-----------------+-----------------+
+ *
+ *         For each quad, calcualte UV's based on the following:
+ *           U = k    / (vm->seg * 2)
+ *           V = ring / (vm->seg * 2)
+ *           quad = (co_orig, co_prev, co_cent, co_next)
+ *           ... note that co_cent is the same for all quads in the fan.
+ * 
+ * + */ + +static void get_point_uv(float uv[2], + /* all these args are int's originally + * but pass as floats to the function */ + const float seg, const float ring, const float k) +{ + uv[0] = (ring / seg) * 2.0f; + uv[1] = (k / seg) * 2.0f; +} + +/* TODO: make this a lot smarter!, + * this is the main reason USE_ALTERNATE_ADJ isn't so good right now :S */ +static float get_point_uv_factor(const float uv[2]) +{ + return sinf(1.0f - max_ff(uv[0], uv[1]) / 2.0f); +} + +static void get_point_on_round_edge(const float uv[2], + float quad[4][3], + float r_co[3]) +{ + interp_bilinear_quad_v3(quad, uv[0], uv[1], r_co); +} + +#else /* USE_ALTERNATE_ADJ */ + +/* + * calculation of points on the round profile + * r - result, coordinate of point on round profile + * method: + * Inscribe a circle in angle va - v -vb + * such that it touches the arms at offset from v. + * Rotate the center-va segment by (i/n) of the + * angle va - center -vb, and put the endpoint + * of that segment in r. + */ +static void get_point_on_round_profile(float r_co[3], float offset, int k, int count, + const float va[3], const float v[3], const float vb[3]) +{ + float vva[3], vvb[3], angle, center[3], rv[3], axis[3], co[3]; + + sub_v3_v3v3(vva, va, v); + sub_v3_v3v3(vvb, vb, v); + normalize_v3(vva); + normalize_v3(vvb); + angle = angle_normalized_v3v3(vva, vvb); + + add_v3_v3v3(center, vva, vvb); + normalize_v3(center); + mul_v3_fl(center, offset * (1.0f / cosf(0.5f * angle))); + add_v3_v3(center, v); /* coordinates of the center of the inscribed circle */ + + + sub_v3_v3v3(rv, va, center); /* radius vector */ + + + sub_v3_v3v3(co, v, center); + cross_v3_v3v3(axis, rv, co); /* calculate axis */ + + sub_v3_v3v3(vva, va, center); + sub_v3_v3v3(vvb, vb, center); + angle = angle_v3v3(vva, vvb); + + rotate_v3_v3v3fl(co, rv, axis, angle * (float)k / (float)count); + + add_v3_v3(co, center); + copy_v3_v3(r_co, co); +} + +/* + * Find the point (/n) of the way around the round profile for e, + * where start point is va, midarc point is vmid, and end point is vb. + * Return the answer in profileco. + * Method: + * Adjust va and vb (along edge direction) so that they are perpendicular + * to edge at v, then use get_point_on_round_profile, then project + * back onto original va - vmid - vb plane. + * If va, vmid, and vb are all on the same plane, just interpolate between va and vb. + */ +static void get_point_on_round_edge(EdgeHalf *e, int k, + const float va[3], const float vmid[3], const float vb[3], + float r_co[3]) +{ + float vva[3], vvb[3], point[3], dir[3], vaadj[3], vbadj[3], p2[3], pn[3]; + int n = e->seg; + + sub_v3_v3v3(vva, va, vmid); + sub_v3_v3v3(vvb, vb, vmid); + if (e->is_rev) + sub_v3_v3v3(dir, e->e->v1->co, e->e->v2->co); + else + sub_v3_v3v3(dir, e->e->v2->co, e->e->v1->co); + normalize_v3(dir); + if (fabsf(angle_v3v3(vva, vvb) - (float)M_PI) > (float)BEVEL_EPSILON) { + copy_v3_v3(vaadj, va); + madd_v3_v3fl(vaadj, dir, -len_v3(vva) * cosf(angle_v3v3(vva, dir))); + copy_v3_v3(vbadj, vb); + madd_v3_v3fl(vbadj, dir, -len_v3(vvb) * cosf(angle_v3v3(vvb, dir))); + + get_point_on_round_profile(point, e->offset, k, n, vaadj, vmid, vbadj); + + add_v3_v3v3(p2, point, dir); + cross_v3_v3v3(pn, vva, vvb); + if (!isect_line_plane_v3(r_co, point, p2, vmid, pn, 0)) { + /* TODO: track down why this sometimes fails */ + copy_v3_v3(r_co, point); + } + } + else { + /* planar case */ + interp_v3_v3v3(r_co, va, vb, (float)k / (float)n); + } +} + +#endif /* !USE_ALTERNATE_ADJ */ + +/* Make a circular list of BoundVerts for bv, each of which has the coordinates + * of a vertex on the the boundary of the beveled vertex bv->v. + * Also decide on the mesh pattern that will be used inside the boundary. + * Doesn't make the actual BMVerts */ +static void build_boundary(MemArena *mem_arena, BevVert *bv) +{ + EdgeHalf *efirst, *e; + BoundVert *v; + VMesh *vm; + float co[3]; + const float *no; + float lastd; + + e = efirst = next_bev(bv, NULL); + vm = bv->vmesh; + + BLI_assert(bv->edgecount >= 2); /* since bevel edges incident to 2 faces */ + + if (bv->edgecount == 2 && bv->selcount == 1) { + /* special case: beveled edge meets non-beveled one at valence 2 vert */ + no = e->fprev ? e->fprev->no : (e->fnext ? e->fnext->no : NULL); + offset_in_plane(e, no, TRUE, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = v->elast = v->ebev = e; + e->leftv = v; + no = e->fnext ? e->fnext->no : (e->fprev ? e->fprev->no : NULL); + offset_in_plane(e, no, FALSE, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = v->elast = e; + e->rightv = v; + /* make artifical extra point along unbeveled edge, and form triangle */ + slide_dist(e->next, bv->v, e->offset, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = v->elast = e->next; + vm->mesh_kind = M_POLY; + return; + } + + lastd = e->offset; + vm->boundstart = NULL; + do { + if (e->is_bev) { + /* handle only left side of beveled edge e here: next iteration should do right side */ + if (e->prev->is_bev) { + BLI_assert(e->prev != e); /* see: wire edge special case */ + offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = e->prev; + v->elast = v->ebev = e; + e->leftv = v; + e->prev->rightv = v; + } + else { + /* e->prev is not beveled */ + if (e->prev->prev->is_bev) { + BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */ + /* find meet point between e->prev->prev and e and attach e->prev there */ + /* TODO: fix case when one or both faces in following are NULL */ + offset_in_two_planes(e->prev->prev, e, bv->v, + e->prev->prev->fnext, e->fprev, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = e->prev->prev; + v->elast = v->ebev = e; + e->leftv = v; + e->prev->leftv = v; + e->prev->prev->rightv = v; + } + else { + /* neither e->prev nor e->prev->prev are beveled: make on-edge on e->prev */ + offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = e->prev; + v->elast = v->ebev = e; + e->leftv = v; + e->prev->leftv = v; + } + } + lastd = len_v3v3(bv->v->co, v->nv.co); + } + else { + /* e is not beveled */ + if (e->next->is_bev) { + /* next iteration will place e between beveled previous and next edges */ + /* do nothing... */ + } + else if (e->prev->is_bev) { + /* on-edge meet between e->prev and e */ + offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = e->prev; + v->elast = e; + e->leftv = v; + e->prev->rightv = v; + } + else { + /* None of e->prev, e, e->next are beveled. + * could either leave alone or add slide points to make + * one polygon around bv->v. For now, we choose latter. + * Could slide to make an even bevel plane but for now will + * just use last distance a meet point moved from bv->v. */ + slide_dist(e, bv->v, lastd, co); + v = add_new_bound_vert(mem_arena, vm, co); + v->efirst = v->elast = e; + e->leftv = v; + } + } + } while ((e = e->next) != efirst); + + BLI_assert(vm->count >= 2); + if (vm->count == 2 && bv->edgecount == 3) { + vm->mesh_kind = M_NONE; + } + else if (bv->selcount == 2) { + vm->mesh_kind = M_QUAD_STRIP; + } + else if (efirst->seg == 1 || bv->selcount == 1) { + if (vm->count == 3 && bv->selcount == 1) { + vm->mesh_kind = M_TRI_FAN; + } + else { + vm->mesh_kind = M_POLY; + } + } + else { + vm->mesh_kind = M_ADJ; + } + /* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */ +} + +/* + * Given that the boundary is built and the boundary BMVerts have been made, + * calculate the positions of the interior mesh points for the M_ADJ pattern, + * then make the BMVerts and the new faces. */ +static void bevel_build_rings(BMesh *bm, BevVert *bv) +{ + int k, ring, i, n, ns, ns2, nn; + VMesh *vm = bv->vmesh; + BoundVert *v, *vprev, *vnext; + NewVert *nv, *nvprev, *nvnext; + BMVert *bmv, *bmv1, *bmv2, *bmv3, *bmv4; + BMFace *f; + float co[3], coa[3], cob[3], midco[3]; + +#ifdef USE_ALTERNATE_ADJ + /* ordered as follows (orig, prev, center, next)*/ + float quad_plane[4][3]; + float quad_orig[4][3]; +#endif + + +#ifdef USE_ALTERNATE_ADJ + /* the rest are initialized inline, this remains the same for all */ + vmesh_cent(vm, quad_plane[2]); + copy_v3_v3(quad_orig[2], bv->v->co); +#endif + + n = vm->count; + ns = vm->seg; + ns2 = ns / 2; + BLI_assert(n > 2 && ns > 1); + /* Make initial rings, going between points on neighbors. + * After this loop, will have coords for all (i, r, k) where + * BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */ + for (ring = 1; ring <= ns2; ring++) { + v = vm->boundstart; + + do { + i = v->index; + if (v->ebev) { + /* get points coords of points a and b, on outer rings + * of prev and next edges, k away from this edge */ + vprev = v->prev; + vnext = v->next; + + if (vprev->ebev) + nvprev = mesh_vert(vm, vprev->index, 0, ns - ring); + else + nvprev = mesh_vert(vm, vprev->index, 0, ns); + copy_v3_v3(coa, nvprev->co); + nv = mesh_vert(vm, i, ring, 0); + copy_v3_v3(nv->co, coa); + nv->v = nvprev->v; + + if (vnext->ebev) + nvnext = mesh_vert(vm, vnext->index, 0, ring); + else + nvnext = mesh_vert(vm, vnext->index, 0, 0); + copy_v3_v3(cob, nvnext->co); + nv = mesh_vert(vm, i, ring, ns); + copy_v3_v3(nv->co, cob); + nv->v = nvnext->v; + +#ifdef USE_ALTERNATE_ADJ + /* plane */ + copy_v3_v3(quad_plane[0], v->nv.co); + mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co); + /* quad[2] is set */ + mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co); + + /* orig */ + copy_v3_v3(quad_orig[0], v->nv.co); /* only shared location between 2 quads */ + project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig[1]); + project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig[3]); + + //bl_debug_draw_quad_add(UNPACK4(quad_plane)); + //bl_debug_draw_quad_add(UNPACK4(quad_orig)); +#endif + +#ifdef USE_ALTERNATE_ADJ + for (k = 1; k < ns; k++) { + float uv[2]; + float fac; + float co_plane[3]; + float co_orig[3]; + + get_point_uv(uv, v->ebev->seg, ring, k); + get_point_on_round_edge(uv, quad_plane, co_plane); + get_point_on_round_edge(uv, quad_orig, co_orig); + fac = get_point_uv_factor(uv); + interp_v3_v3v3(co, co_plane, co_orig, fac); + copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co); + } +#else + /* TODO: better calculation of new midarc point? */ + project_to_edge(v->ebev->e, coa, cob, midco); + + for (k = 1; k < ns; k++) { + get_point_on_round_edge(v->ebev, k, coa, midco, cob, co); + copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co); + } +#endif + } + } while ((v = v->next) != vm->boundstart); + } + + /* Now make sure cross points of rings share coordinates and vertices. + * After this loop, will have BMVerts for all (i, r, k) where + * i is for a BoundVert that is beveled and has either a predecessor or + * successor BoundVert beveled too, and + * for odd ns: 0 <= r <= ns2, 0 <= k <= ns + * for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */ + v = vm->boundstart; + do { + i = v->index; + if (v->ebev) { + vprev = v->prev; + vnext = v->next; + if (vprev->ebev) { + for (ring = 1; ring <= ns2; ring++) { + for (k = 1; k <= ns2; k++) { + if (ns % 2 == 0 && (k == ns2 || ring == ns2)) + continue; /* center line is special case: do after the rest are done */ + nv = mesh_vert(vm, i, ring, k); + nvprev = mesh_vert(vm, vprev->index, k, ns - ring); + mid_v3_v3v3(co, nv->co, nvprev->co); +#ifndef USE_ALTERNATE_ADJ + copy_v3_v3(nv->co, co); +#endif + BLI_assert(nv->v == NULL && nvprev->v == NULL); + create_mesh_bmvert(bm, vm, i, ring, k, bv->v); + copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k); + } + } + if (!vprev->prev->ebev) { + for (ring = 1; ring <= ns2; ring++) { + for (k = 1; k <= ns2; k++) { + if (ns % 2 == 0 && (k == ns2 || ring == ns2)) + continue; + create_mesh_bmvert(bm, vm, vprev->index, ring, k, bv->v); + } + } + } + if (!vnext->ebev) { + for (ring = 1; ring <= ns2; ring++) { + for (k = ns - ns2; k < ns; k++) { + if (ns % 2 == 0 && (k == ns2 || ring == ns2)) + continue; + create_mesh_bmvert(bm, vm, i, ring, k, bv->v); + } + } + } + } + } + } while ((v = v->next) != vm->boundstart); + + if (ns % 2 == 0) { + /* Do special case center lines. + * This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2 + * and for (i, r, ns2) for 1 <= r <= ns2-1, + * whenever i is in a sequence of at least two beveled verts */ + v = vm->boundstart; + do { + i = v->index; + if (v->ebev) { + vprev = v->prev; + vnext = v->next; + for (k = 1; k < ns2; k++) { + nv = mesh_vert(vm, i, k, ns2); + if (vprev->ebev) + nvprev = mesh_vert(vm, vprev->index, ns2, ns - k); + if (vnext->ebev) + nvnext = mesh_vert(vm, vnext->index, ns2, k); + if (vprev->ebev && vnext->ebev) { + mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co); +#ifndef USE_ALTERNATE_ADJ + copy_v3_v3(nv->co, co); +#endif + create_mesh_bmvert(bm, vm, i, k, ns2, bv->v); + copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2); + copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2); + + } + else if (vprev->ebev) { + mid_v3_v3v3(co, nvprev->co, nv->co); +#ifndef USE_ALTERNATE_ADJ + copy_v3_v3(nv->co, co); +#endif + create_mesh_bmvert(bm, vm, i, k, ns2, bv->v); + copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2); + + create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v); + } + else if (vnext->ebev) { + mid_v3_v3v3(co, nv->co, nvnext->co); +#ifndef USE_ALTERNATE_ADJ + copy_v3_v3(nv->co, co); +#endif + create_mesh_bmvert(bm, vm, i, k, ns2, bv->v); + copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2); + + create_mesh_bmvert(bm, vm, i, ns2, k, bv->v); + } + } + } + } while ((v = v->next) != vm->boundstart); + + /* center point need to be average of all centers of rings */ + /* TODO: this is wrong if not all verts have ebev: could have + * several disconnected sections of mesh. */ + zero_v3(midco); + nn = 0; + v = vm->boundstart; + do { + i = v->index; + if (v->ebev) { + nv = mesh_vert(vm, i, ns2, ns2); + add_v3_v3(midco, nv->co); + nn++; + } + } while ((v = v->next) != vm->boundstart); + mul_v3_fl(midco, 1.0f / nn); + bmv = BM_vert_create(bm, midco, NULL); + v = vm->boundstart; + do { + i = v->index; + if (v->ebev) { + nv = mesh_vert(vm, i, ns2, ns2); + copy_v3_v3(nv->co, midco); + nv->v = bmv; + } + } while ((v = v->next) != vm->boundstart); + } + + /* Make the ring quads */ + for (ring = 0; ring < ns2; ring++) { + v = vm->boundstart; + do { + i = v->index; + f = boundvert_rep_face(v); + if (v->ebev && (v->prev->ebev || v->next->ebev)) { + for (k = 0; k < ns2 + (ns % 2); k++) { + bmv1 = mesh_vert(vm, i, ring, k)->v; + bmv2 = mesh_vert(vm, i, ring, k + 1)->v; + bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v; + bmv4 = mesh_vert(vm, i, ring + 1, k)->v; + BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); + if (bmv3 == bmv4 || bmv1 == bmv4) + bmv4 = NULL; + bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f); + } + } + else if (v->prev->ebev && v->prev->prev->ebev) { + /* finish off a sequence of beveled edges */ + i = v->prev->index; + f = boundvert_rep_face(v->prev); + for (k = ns2 + (ns % 2); k < ns; k++) { + bmv1 = mesh_vert(vm, i, ring, k)->v; + bmv2 = mesh_vert(vm, i, ring, k + 1)->v; + bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v; + bmv4 = mesh_vert(vm, i, ring + 1, k)->v; + BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); + if (bmv2 == bmv3) { + bmv3 = bmv4; + bmv4 = NULL; + } + bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f); + } + } + } while ((v = v->next) != vm->boundstart); + } + + /* Make center ngon if odd number of segments and fully beveled */ + if (ns % 2 == 1 && vm->count == bv->selcount) { + BMVert **vv = NULL; + BLI_array_declare(vv); + + v = vm->boundstart; + do { + i = v->index; + BLI_assert(v->ebev); + BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v); + } while ((v = v->next) != vm->boundstart); + f = boundvert_rep_face(vm->boundstart); + bev_create_ngon(bm, vv, BLI_array_count(vv), f); + + BLI_array_free(vv); + } + + /* Make 'rest-of-vmesh' polygon if not fully beveled */ + if (vm->count > bv->selcount) { + int j; + BMVert **vv = NULL; + BLI_array_declare(vv); + + v = vm->boundstart; + f = boundvert_rep_face(v); + j = 0; + do { + i = v->index; + if (v->ebev) { + if (!v->prev->ebev) { + for (k = 0; k < ns2; k++) { + bmv1 = mesh_vert(vm, i, ns2, k)->v; + if (!bmv1) + bmv1 = mesh_vert(vm, i, 0, k)->v; + if (!(j > 0 && bmv1 == vv[j - 1])) { + BLI_assert(bmv1 != NULL); + BLI_array_append(vv, bmv1); + j++; + } + } + } + bmv1 = mesh_vert(vm, i, ns2, ns2)->v; + if (!bmv1) + bmv1 = mesh_vert(vm, i, 0, ns2)->v; + if (!(j > 0 && bmv1 == vv[j - 1])) { + BLI_assert(bmv1 != NULL); + BLI_array_append(vv, bmv1); + j++; + } + if (!v->next->ebev) { + for (k = ns - ns2; k < ns; k++) { + bmv1 = mesh_vert(vm, i, ns2, k)->v; + if (!bmv1) + bmv1 = mesh_vert(vm, i, 0, k)->v; + if (!(j > 0 && bmv1 == vv[j - 1])) { + BLI_assert(bmv1 != NULL); + BLI_array_append(vv, bmv1); + j++; + } + } + } + } + else { + BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL); + BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v); + j++; + } + } while ((v = v->next) != vm->boundstart); + if (vv[0] == vv[j - 1]) + j--; + bev_create_ngon(bm, vv, j, f); + + BLI_array_free(vv); + } +} + +static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv) +{ + BMFace *f; + int n, k; + VMesh *vm = bv->vmesh; + BoundVert *v; + BMVert **vv = NULL; + BLI_array_declare(vv); + + v = vm->boundstart; + n = 0; + do { + /* accumulate vertices for vertex ngon */ + BLI_array_append(vv, v->nv.v); + n++; + if (v->ebev && v->ebev->seg > 1) { + for (k = 1; k < v->ebev->seg; k++) { + BLI_array_append(vv, mesh_vert(vm, v->index, 0, k)->v); + n++; + } + } + } while ((v = v->next) != vm->boundstart); + if (n > 2) { + f = bev_create_ngon(bm, vv, n, boundvert_rep_face(v)); + } + else { + f = NULL; + } + BLI_array_free(vv); + return f; +} + +static void bevel_build_poly(BMesh *bm, BevVert *bv) +{ + bevel_build_poly_ex(bm, bv); +} + +static void bevel_build_trifan(BMesh *bm, BevVert *bv) +{ + BMFace *f; + BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1); + + f = bevel_build_poly_ex(bm, bv); + + if (f) { + /* we have a polygon which we know starts at the previous vertex, make it into a fan */ + BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev; + BMVert *v_fan = l_fan->v; + + while (f->len > 3) { + BMLoop *l_new; + BMFace *f_new; + BLI_assert(v_fan == l_fan->v); + f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE); + + if (f_new->len > f->len) { + f = f_new; + if (l_new->v == v_fan) { l_fan = l_new; } + else if (l_new->next->v == v_fan) { l_fan = l_new->next; } + else if (l_new->prev->v == v_fan) { l_fan = l_new->prev; } + else { BLI_assert(0); } + } + else { + if (l_fan->v == v_fan) { l_fan = l_fan; } + else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; } + else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; } + else { BLI_assert(0); } + } + } + } +} + +static void bevel_build_quadstrip(BMesh *bm, BevVert *bv) +{ + BMFace *f; + BLI_assert(bv->selcount == 2); + + f = bevel_build_poly_ex(bm, bv); + + if (f) { + /* we have a polygon which we know starts at this vertex, make it into strips */ + EdgeHalf *eh_a = bv->vmesh->boundstart->elast; + EdgeHalf *eh_b = next_bev(bv, eh_a->next); /* since (selcount == 2) we know this is valid */ + BMLoop *l_a = BM_face_vert_share_loop(f, eh_a->rightv->nv.v); + BMLoop *l_b = BM_face_vert_share_loop(f, eh_b->leftv->nv.v); + int seg_count = bv->vmesh->seg; /* ensure we don't walk past the segments */ + + if (l_a == l_b) { + /* step once around if we hit the same loop */ + l_a = l_a->prev; + l_b = l_b->next; + seg_count--; + } + + BLI_assert(l_a != l_b); + + while (f->len > 4) { + BMLoop *l_new; + BLI_assert(l_a->f == f); + BLI_assert(l_b->f == f); + + BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, FALSE); + if (seg_count-- == 0) { + break; + } + + /* turns out we don't need this, + * because of how BM_face_split works we always get the loop of the next face */ +#if 0 + if (l_new->f->len < l_new->radial_next->f->len) { + l_new = l_new->radial_next; + } +#endif + f = l_new->f; + + /* walk around the new face to get the next verts to split */ + l_a = l_new->prev; + l_b = l_new->next->next; + } + } +} + +/* Given that the boundary is built, now make the actual BMVerts + * for the boundary and the interior of the vertex mesh. */ +static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv) +{ + VMesh *vm = bv->vmesh; + BoundVert *v, *weld1, *weld2; + int n, ns, ns2, i, k, weld; + float *va, *vb, co[3]; + +#ifdef USE_ALTERNATE_ADJ + /* ordered as follows (orig, prev, center, next)*/ + float quad_plane[4][3]; + float quad_orig_a[4][3]; + float quad_orig_b[4][3]; + const int is_odd = (vm->seg % 2); +#else + float midco[3]; +#endif + +#ifdef USE_ALTERNATE_ADJ + /* the rest are initialized inline, this remains the same for all */ + /* NOTE; in this usage we only interpolate on the 'V' so cent and next points are unused (2,3)*/ + vmesh_cent(vm, quad_plane[2]); + copy_v3_v3(quad_orig_a[2], bv->v->co); + copy_v3_v3(quad_orig_b[2], bv->v->co); +#endif + + n = vm->count; + ns = vm->seg; + ns2 = ns / 2; + + vm->mesh = (NewVert *)BLI_memarena_alloc(mem_arena, n * (ns2 + 1) * (ns + 1) * sizeof(NewVert)); + + /* special case: two beveled ends welded together */ + weld = (bv->selcount == 2) && (vm->count == 2); + weld1 = weld2 = NULL; /* will hold two BoundVerts involved in weld */ + + /* make (i, 0, 0) mesh verts for all i */ + v = vm->boundstart; + do { + i = v->index; + copy_v3_v3(mesh_vert(vm, i, 0, 0)->co, v->nv.co); + create_mesh_bmvert(bm, vm, i, 0, 0, bv->v); + v->nv.v = mesh_vert(vm, i, 0, 0)->v; + if (weld && v->ebev) { + if (!weld1) + weld1 = v; + else + weld2 = v; + } + } while ((v = v->next) != vm->boundstart); + + /* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */ + v = vm->boundstart; + do { + i = v->index; + copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0); + if (v->ebev) { + +#ifdef USE_ALTERNATE_ADJ + copy_v3_v3(quad_plane[0], v->nv.co); + mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co); + /* quad[2] is set */ + mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co); + + /* orig 'A' */ + copy_v3_v3(quad_orig_a[0], v->nv.co); /* only shared location between 2 quads */ + project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_a[1]); + project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_a[3]); + + /* orig 'B' */ + copy_v3_v3(quad_orig_b[3], v->next->nv.co); /* only shared location between 2 quads */ + project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_b[1]); + project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_b[0]); + + //bl_debug_draw_quad_add(UNPACK4(quad_plane)); + //bl_debug_draw_quad_add(UNPACK4(quad_orig_a)); + //bl_debug_draw_quad_add(UNPACK4(quad_orig_b)); +#endif /* USE_ALTERNATE_ADJ */ + +#ifdef USE_ALTERNATE_ADJ + for (k = 1; k < ns; k++) { + float uv[2]; + float fac; + float co_plane[3]; + float co_orig[3]; + + /* quad_plane */ + get_point_uv(uv, v->ebev->seg, 0, k); + get_point_on_round_edge(uv, quad_plane, co_plane); + + /* quad_orig */ + /* each half has different UV's */ + if (k <= ns2) { + get_point_uv(uv, v->ebev->seg, 0, k); + get_point_on_round_edge(uv, quad_orig_a, co_orig); + } + else { + get_point_uv(uv, v->ebev->seg, 0, (k - ns2) - (is_odd ? 0.5f : 0.0f)); + get_point_on_round_edge(uv, quad_orig_b, co_orig); + uv[1] = 1.0f - uv[1]; /* so we can get the factor */ + } + fac = get_point_uv_factor(uv); + + /* done. interp */ + interp_v3_v3v3(co, co_plane, co_orig, fac); + copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co); + if (!weld) + create_mesh_bmvert(bm, vm, i, 0, k, bv->v); + } +#else /* USE_ALTERNATE_ADJ */ + va = mesh_vert(vm, i, 0, 0)->co; + vb = mesh_vert(vm, i, 0, ns)->co; + project_to_edge(v->ebev->e, va, vb, midco); + for (k = 1; k < ns; k++) { + get_point_on_round_edge(v->ebev, k, va, midco, vb, co); + copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co); + if (!weld) + create_mesh_bmvert(bm, vm, i, 0, k, bv->v); + } +#endif /* !USE_ALTERNATE_ADJ */ + } + } while ((v = v->next) != vm->boundstart); + + if (weld) { + vm->mesh_kind = M_NONE; + for (k = 1; k < ns; k++) { + va = mesh_vert(vm, weld1->index, 0, k)->co; + vb = mesh_vert(vm, weld2->index, 0, ns - k)->co; + mid_v3_v3v3(co, va, vb); + copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co); + create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v); + } + for (k = 1; k < ns; k++) + copy_mesh_vert(vm, weld2->index, 0, ns - k, weld1->index, 0, k); + } + + switch (vm->mesh_kind) { + case M_NONE: + /* do nothing */ + break; + case M_POLY: + bevel_build_poly(bm, bv); + break; + case M_ADJ: + bevel_build_rings(bm, bv); + break; + case M_TRI_FAN: + bevel_build_trifan(bm, bv); + break; + case M_QUAD_STRIP: + bevel_build_quadstrip(bm, bv); + break; + } +} + +/* take care, this flag isn't cleared before use, it just so happens that its not set */ +#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_elem_flag_enable( (bme)->l, BM_ELEM_TAG) +#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_elem_flag_disable( (bme)->l, BM_ELEM_TAG) +#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_elem_flag_test( (bme)->l, BM_ELEM_TAG) + +/* + * Construction around the vertex + */ +static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) +{ + BMEdge *bme; + BevVert *bv; + BMEdge *bme2, *unflagged_bme; + BMFace *f; + BMIter iter, iter2; + EdgeHalf *e; + int i, ntot, found_shared_face, ccw_test_sum; + int nsel = 0; + + /* Gather input selected edges. + * Only bevel selected edges that have exactly two incident faces. + */ + + BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) { + if (BM_elem_flag_test(bme, BM_ELEM_TAG)) { + BLI_assert(BM_edge_is_manifold(bme)); + nsel++; + } + } + + if (nsel == 0) + return; + + ntot = BM_vert_edge_count(v); + bv = (BevVert *)BLI_memarena_alloc(bp->mem_arena, (sizeof(BevVert))); + bv->v = v; + bv->edgecount = ntot; + bv->selcount = nsel; + bv->edges = (EdgeHalf *)BLI_memarena_alloc(bp->mem_arena, ntot * sizeof(EdgeHalf)); + bv->vmesh = (VMesh *)BLI_memarena_alloc(bp->mem_arena, sizeof(VMesh)); + bv->vmesh->seg = bp->seg; + BLI_ghash_insert(bp->vert_hash, v, bv); + + /* add edges to bv->edges in order that keeps adjacent edges sharing + * a face, if possible */ + i = 0; + bme = v->e; + BM_BEVEL_EDGE_TAG_ENABLE(bme); + e = &bv->edges[0]; + e->e = bme; + for (i = 0; i < ntot; i++) { + if (i > 0) { + /* find an unflagged edge bme2 that shares a face f with previous bme */ + found_shared_face = 0; + unflagged_bme = NULL; + BM_ITER_ELEM (bme2, &iter, v, BM_EDGES_OF_VERT) { + if (BM_BEVEL_EDGE_TAG_TEST(bme2)) + continue; + if (!unflagged_bme) + unflagged_bme = bme2; + BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) { + if (BM_face_edge_share_loop(f, bme)) { + found_shared_face = 1; + break; + } + } + if (found_shared_face) + break; + } + e = &bv->edges[i]; + if (found_shared_face) { + e->e = bme2; + e->fprev = f; + bv->edges[i - 1].fnext = f; + } + else { + e->e = unflagged_bme; + } + } + bme = e->e; + BM_BEVEL_EDGE_TAG_ENABLE(bme); + if (BM_elem_flag_test(bme, BM_ELEM_TAG)) { + e->is_bev = TRUE; + e->seg = bp->seg; + } + else { + e->is_bev = FALSE; + e->seg = 0; + } + e->is_rev = (bme->v2 == v); + e->offset = e->is_bev ? bp->offset : 0.0f; + } + /* find wrap-around shared face */ + BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) { + if (BM_face_edge_share_loop(f, bv->edges[0].e)) { + if (bv->edges[0].fnext == f) + continue; /* if two shared faces, want the other one now */ + bv->edges[ntot - 1].fnext = f; + bv->edges[0].fprev = f; + break; + } + } + + /* clear BEVEL_EDGE_TAG now that we are finished with it*/ + for (i = 0; i < ntot; i++) { + BM_BEVEL_EDGE_TAG_DISABLE(bv->edges[i].e); + } + + /* if edge array doesn't go CCW around vertex from average normal side, + * reverse the array, being careful to reverse face pointers too */ + if (ntot > 1) { + ccw_test_sum = 0; + for (i = 0; i < ntot; i++) + ccw_test_sum += bev_ccw_test(bv->edges[i].e, bv->edges[(i + 1) % ntot].e, + bv->edges[i].fnext); + if (ccw_test_sum < 0) { + for (i = 0; i <= (ntot / 2) - 1; i++) { + SWAP(EdgeHalf, bv->edges[i], bv->edges[ntot - i - 1]); + SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext); + SWAP(BMFace *, bv->edges[ntot - i - 1].fprev, bv->edges[ntot - i - 1].fnext); + } + if (ntot % 2 == 1) { + i = ntot / 2; + SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext); + } + } + } + + for (i = 0; i < ntot; i++) { + e = &bv->edges[i]; + e->next = &bv->edges[(i + 1) % ntot]; + e->prev = &bv->edges[(i + ntot - 1) % ntot]; + } + + build_boundary(bp->mem_arena, bv); + build_vmesh(bp->mem_arena, bm, bv); +} + +/* Face f has at least one beveled vertex. Rebuild f */ +static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) +{ + BMIter liter; + BMLoop *l, *lprev; + BevVert *bv; + BoundVert *v, *vstart, *vend; + EdgeHalf *e, *eprev; + VMesh *vm; + int i, k; + BMVert *bmv; + BMVert **vv = NULL; + BLI_array_declare(vv); + + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + bv = find_bevvert(bp, l->v); + if (bv) { + lprev = l->prev; + e = find_edge_half(bv, l->e); + eprev = find_edge_half(bv, lprev->e); + BLI_assert(e != NULL && eprev != NULL); + vstart = eprev->leftv; + if (e->is_bev) + vend = e->rightv; + else + vend = e->leftv; + v = vstart; + vm = bv->vmesh; + BLI_array_append(vv, v->nv.v); + while (v != vend) { + if (vm->mesh_kind == M_NONE && v->ebev && v->ebev->seg > 1 && v->ebev != e && v->ebev != eprev) { + /* case of 3rd face opposite a beveled edge, with no vmesh */ + i = v->index; + e = v->ebev; + for (k = 1; k < e->seg; k++) { + bmv = mesh_vert(vm, i, 0, k)->v; + BLI_array_append(vv, bmv); + } + } + v = v->prev; + BLI_array_append(vv, v->nv.v); + } + } + else { + BLI_array_append(vv, l->v); + } + } + bev_create_ngon(bm, vv, BLI_array_count(vv), f); + BLI_array_free(vv); +} + +/* All polygons touching v need rebuilding because beveling v has made new vertices */ +static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v) +{ + void *faces_stack[BM_DEFAULT_ITER_STACK_SIZE]; + int faces_len, f_index; + BMFace **faces = BM_iter_as_arrayN(bm, BM_FACES_OF_VERT, v, &faces_len, + faces_stack, BM_DEFAULT_ITER_STACK_SIZE); + + if (LIKELY(faces != NULL)) { + for (f_index = 0; f_index < faces_len; f_index++) { + BMFace *f = faces[f_index]; + rebuild_polygon(bm, bp, f); + BM_face_kill(bm, f); + } + + if (faces != (BMFace **)faces_stack) { + MEM_freeN(faces); + } + } +} + + + +/* + * Build the polygons along the selected Edge + */ +static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) +{ + BevVert *bv1, *bv2; + BMVert *bmv1, *bmv2, *bmv3, *bmv4, *bmv1i, *bmv2i, *bmv3i, *bmv4i; + VMesh *vm1, *vm2; + EdgeHalf *e1, *e2; + BMFace *f1, *f2, *f; + int k, nseg, i1, i2; + + if (!BM_edge_is_manifold(bme)) + return; + + bv1 = find_bevvert(bp, bme->v1); + bv2 = find_bevvert(bp, bme->v2); + + BLI_assert(bv1 && bv2); + + e1 = find_edge_half(bv1, bme); + e2 = find_edge_half(bv2, bme); + + BLI_assert(e1 && e2); + + /* v4 v3 + * \ / + * e->v1 - e->v2 + * / \ + * v1 v2 + */ + nseg = e1->seg; + BLI_assert(nseg > 0 && nseg == e2->seg); + + bmv1 = e1->leftv->nv.v; + bmv4 = e1->rightv->nv.v; + bmv2 = e2->rightv->nv.v; + bmv3 = e2->leftv->nv.v; + + BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); + + f1 = boundvert_rep_face(e1->leftv); + f2 = boundvert_rep_face(e1->rightv); + + if (nseg == 1) { + bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f1); + } + else { + i1 = e1->leftv->index; + i2 = e2->leftv->index; + vm1 = bv1->vmesh; + vm2 = bv2->vmesh; + bmv1i = bmv1; + bmv2i = bmv2; + for (k = 1; k <= nseg; k++) { + bmv4i = mesh_vert(vm1, i1, 0, k)->v; + bmv3i = mesh_vert(vm2, i2, 0, nseg - k)->v; + f = (k <= nseg / 2 + (nseg % 2)) ? f1 : f2; + bev_create_quad_tri(bm, bmv1i, bmv2i, bmv3i, bmv4i, f); + bmv1i = bmv4i; + bmv2i = bmv3i; + } + } +} + +/** + * currently only bevels BM_ELEM_TAG'd verts and edges + * all tagged edges _must_ be manifold. + */ +void BM_mesh_bevel(BMesh *bm, const float offset, const float segments) +{ + BMIter iter; + BMVert *v; + BMEdge *e; + BevelParams bp = {NULL}; + + bp.offset = offset; + bp.seg = segments; + + if (bp.offset > 0) { + /* primary alloc */ + bp.vert_hash = BLI_ghash_ptr_new(__func__); + bp.mem_arena = BLI_memarena_new((1 << 16), __func__); + BLI_memarena_use_calloc(bp.mem_arena); + + /* The analysis of the input vertices and execution additional constructions */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + bevel_vert_construct(bm, &bp, v); + } + } + + /* Build polygons for edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + bevel_build_edge_polygons(bm, &bp, e); + } + } + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + bevel_rebuild_existing_polygons(bm, &bp, v); + } + } + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + if (find_bevvert(&bp, v)) { + BM_vert_kill(bm, v); + } + } + } + + /* primary free */ + BLI_ghash_free(bp.vert_hash, NULL, NULL); + BLI_memarena_free(bp.mem_arena); + } +} diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h new file mode 100644 index 00000000000..a80e4f3a4a2 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_BEVEL_H__ +#define __BMESH_BEVEL_H__ + +/** \file blender/bmesh/tools/bmesh_bevel.h + * \ingroup bmesh + */ + +void BM_mesh_bevel(BMesh *bm, const float offset, const float segments); + +#endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h similarity index 97% rename from source/blender/bmesh/intern/bmesh_decimate.h rename to source/blender/bmesh/tools/bmesh_decimate.h index 04dc0cfd2ea..4d382d65659 100644 --- a/source/blender/bmesh/intern/bmesh_decimate.h +++ b/source/blender/bmesh/tools/bmesh_decimate.h @@ -23,7 +23,7 @@ #ifndef __BMESH_DECIMATE_H__ #define __BMESH_DECIMATE_H__ -/** \file blender/bmesh/intern/bmesh_decimate.h +/** \file blender/bmesh/tools/bmesh_decimate.h * \ingroup bmesh */ diff --git a/source/blender/bmesh/intern/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c similarity index 99% rename from source/blender/bmesh/intern/bmesh_decimate_collapse.c rename to source/blender/bmesh/tools/bmesh_decimate_collapse.c index 74792d1d558..781001508f2 100644 --- a/source/blender/bmesh/intern/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/intern/bmesh_decimate_collapse.c +/** \file blender/bmesh/tools/bmesh_decimate_collapse.c * \ingroup bmesh * * BMesh decimator that uses an edge collapse method. @@ -39,9 +39,10 @@ #include "BKE_customdata.h" #include "bmesh.h" -#include "bmesh_structure.h" #include "bmesh_decimate.h" /* own include */ +#include "../intern/bmesh_structure.h" + /* defines for testing */ #define USE_CUSTOMDATA #define USE_TRIANGULATE diff --git a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c similarity index 99% rename from source/blender/bmesh/intern/bmesh_decimate_dissolve.c rename to source/blender/bmesh/tools/bmesh_decimate_dissolve.c index fb78050988d..d2a5c580ae6 100644 --- a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/intern/bmesh_decimate_dissolve.c +/** \file blender/bmesh/tools/bmesh_decimate_dissolve.c * \ingroup bmesh * * BMesh decimator that dissolves flat areas into polygons (ngons). diff --git a/source/blender/bmesh/intern/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c similarity index 99% rename from source/blender/bmesh/intern/bmesh_decimate_unsubdivide.c rename to source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c index 1ec13010d80..acdab2510a4 100644 --- a/source/blender/bmesh/intern/bmesh_decimate_unsubdivide.c +++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/intern/bmesh_decimate_unsubdivide.c +/** \file blender/bmesh/tools/bmesh_decimate_unsubdivide.c * \ingroup bmesh * * BMesh decimator that uses a grid un-subdivide method. diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 1c4f0974c6d..084f71e0afc 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -552,8 +552,8 @@ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScen } /** When this method is called, the writer must handle all nodes contained in the -* library nodes. -* \return The writer should return true, if writing succeeded, false otherwise.*/ + * library nodes. + * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes) { if (mImportStage != General) diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h index e878a5a5b48..d54b8db9f00 100644 --- a/source/blender/collada/DocumentImporter.h +++ b/source/blender/collada/DocumentImporter.h @@ -81,8 +81,8 @@ public: /** * 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. - */ + * \param errorMessage A message containing informations about the error that occurred. + */ void cancel(const COLLADAFW::String& errorMessage); /** This is the method called. The writer hast to prepare to receive data.*/ diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 2e0c0f1ea57..aba290f5ce4 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -61,7 +61,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies) if (not_yet_exported) { - ImBuf *imbuf = BKE_image_get_ibuf(image, NULL); + ImBuf *imbuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (!imbuf) { fprintf(stderr, "Collada export: image does not exist:\n%s\n", image->name); return; @@ -147,6 +147,8 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies) img.add(mSW); fprintf(stdout, "Collada export: Added image: %s\n", export_file); mImages.push_back(translated_name); + + BKE_image_release_ibuf(image, imbuf, NULL); } } diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index b3e76a287ea..8259cb6f297 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -267,6 +267,8 @@ set(SRC nodes/COM_MathNode.h nodes/COM_MapValueNode.cpp nodes/COM_MapValueNode.h + nodes/COM_MapRangeNode.cpp + nodes/COM_MapRangeNode.h operations/COM_NormalizeOperation.cpp operations/COM_NormalizeOperation.h @@ -572,6 +574,8 @@ set(SRC operations/COM_SetAlphaOperation.h operations/COM_MapValueOperation.cpp operations/COM_MapValueOperation.h + operations/COM_MapRangeOperation.cpp + operations/COM_MapRangeOperation.h # Distort operation operations/COM_TranslateOperation.h diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 2b09c9d5b8c..9c4a32f20c9 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -83,6 +83,7 @@ #include "COM_LuminanceMatteNode.h" #include "COM_MapUVNode.h" #include "COM_MapValueNode.h" +#include "COM_MapRangeNode.h" #include "COM_MaskNode.h" #include "COM_MathNode.h" #include "COM_MixNode.h" @@ -351,6 +352,9 @@ Node *Converter::convert(bNode *b_node, bool fast) case CMP_NODE_MAP_VALUE: node = new MapValueNode(b_node); break; + case CMP_NODE_MAP_RANGE: + node = new MapRangeNode(b_node); + break; case CMP_NODE_TRANSFORM: node = new TransformNode(b_node); break; diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index 4f120ea5a6e..6a4987c2075 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -31,6 +31,7 @@ #include "COM_FastGaussianBlurOperation.h" #include "COM_MathBaseOperation.h" #include "COM_SetValueOperation.h" +#include "COM_GammaCorrectOperation.h" BlurNode::BlurNode(bNode *editorNode) : Node(editorNode) { @@ -48,16 +49,17 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value; CompositorQuality quality = context->getQuality(); - + NodeOperation *input_operation = NULL, *output_operation = NULL; + if (data->filtertype == R_FILTER_FAST_GAUSS) { FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation(); operationfgb->setData(data); operationfgb->setbNode(editorNode); - this->getInputSocket(0)->relinkConnections(operationfgb->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph); - this->getOutputSocket(0)->relinkConnections(operationfgb->getOutputSocket(0)); graph->addOperation(operationfgb); - addPreviewOperation(graph, context, operationfgb->getOutputSocket()); + + input_operation = operationfgb; + output_operation = operationfgb; } else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) { MathAddOperation *clamp = new MathAddOperation(); @@ -93,48 +95,68 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co operation->setData(data); operation->setbNode(editorNode); operation->setQuality(quality); - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1)); graph->addOperation(operation); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - addPreviewOperation(graph, context, operation->getOutputSocket()); + + output_operation = operation; + input_operation = operation; } else if (!data->bokeh) { GaussianXBlurOperation *operationx = new GaussianXBlurOperation(); operationx->setData(data); operationx->setbNode(editorNode); operationx->setQuality(quality); - this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); graph->addOperation(operationx); GaussianYBlurOperation *operationy = new GaussianYBlurOperation(); operationy->setData(data); operationy->setbNode(editorNode); operationy->setQuality(quality); - this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket()); + graph->addOperation(operationy); addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0)); addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1)); - addPreviewOperation(graph, context, operationy->getOutputSocket()); if (!connectedSizeSocket) { operationx->setSize(size); operationy->setSize(size); } + + input_operation = operationx; + output_operation = operationy; } else { GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation(); operation->setData(data); operation->setbNode(editorNode); - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); operation->setQuality(quality); graph->addOperation(operation); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - addPreviewOperation(graph, context, operation->getOutputSocket()); if (!connectedSizeSocket) { operation->setSize(size); } + + input_operation = operation; + output_operation = operation; + } + + if (data->gamma) { + GammaCorrectOperation *correct = new GammaCorrectOperation(); + GammaUncorrectOperation *inverse = new GammaUncorrectOperation(); + + this->getInputSocket(0)->relinkConnections(correct->getInputSocket(0), 0, graph); + addLink(graph, correct->getOutputSocket(), input_operation->getInputSocket(0)); + addLink(graph, output_operation->getOutputSocket(), inverse->getInputSocket(0)); + this->getOutputSocket()->relinkConnections(inverse->getOutputSocket()); + graph->addOperation(correct); + graph->addOperation(inverse); + + addPreviewOperation(graph, context, inverse->getOutputSocket()); + } + else { + this->getInputSocket(0)->relinkConnections(input_operation->getInputSocket(0), 0, graph); + this->getOutputSocket()->relinkConnections(output_operation->getOutputSocket()); + addPreviewOperation(graph, context, output_operation->getOutputSocket()); } } diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 4ebd28d710a..729cb1b70a0 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -73,7 +73,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c /* force a load, we assume iuser index will be set OK anyway */ if (image && image->type == IMA_TYPE_MULTILAYER) { bool is_multilayer_ok = false; - BKE_image_get_ibuf(image, imageuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, imageuser, NULL); if (image->rr) { RenderLayer *rl = (RenderLayer *)BLI_findlink(&image->rr->layers, imageuser->layer); if (rl) { @@ -118,6 +118,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c } } } + BKE_image_release_ibuf(image, ibuf, NULL); /* without this, multilayer that fail to load will crash blender [#32490] */ if (is_multilayer_ok == false) { diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.cpp b/source/blender/compositor/nodes/COM_MapRangeNode.cpp new file mode 100644 index 00000000000..232be3d41b0 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MapRangeNode.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + * Daniel Salazar + */ + +#include "COM_MapRangeNode.h" + +#include "COM_MapRangeOperation.h" +#include "COM_ExecutionSystem.h" + +MapRangeNode::MapRangeNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} + +void MapRangeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) +{ + InputSocket *valueSocket = this->getInputSocket(0); + InputSocket *sourceMinSocket = this->getInputSocket(1); + InputSocket *sourceMaxSocket = this->getInputSocket(2); + InputSocket *destMinSocket = this->getInputSocket(3); + InputSocket *destMaxSocket = this->getInputSocket(4); + OutputSocket *outputSocket = this->getOutputSocket(0); + + MapRangeOperation *operation = new MapRangeOperation(); + + valueSocket->relinkConnections(operation->getInputSocket(0), 0, graph); + sourceMinSocket->relinkConnections(operation->getInputSocket(1), 1, graph); + sourceMaxSocket->relinkConnections(operation->getInputSocket(2), 2, graph); + destMinSocket->relinkConnections(operation->getInputSocket(3), 3, graph); + destMaxSocket->relinkConnections(operation->getInputSocket(4), 4, graph); + outputSocket->relinkConnections(operation->getOutputSocket(0)); + + operation->setUseClamp(this->getbNode()->custom1); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.h b/source/blender/compositor/nodes/COM_MapRangeNode.h new file mode 100644 index 00000000000..6667720be3d --- /dev/null +++ b/source/blender/compositor/nodes/COM_MapRangeNode.h @@ -0,0 +1,38 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + * Daniel Salazar + */ + +#ifndef __COM_MAPRANGENODE_H__ +#define __COM_MAPRANGENODE_H__ + +#include "COM_Node.h" +#include "DNA_node_types.h" +/** + * @brief MapRangeNode + * @ingroup Node + */ +class MapRangeNode : public Node { +public: + MapRangeNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); +}; + +#endif /* __COM_MAPRANGENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_NormalNode.cpp b/source/blender/compositor/nodes/COM_NormalNode.cpp index e00e71e50e9..fbfff8386d0 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.cpp +++ b/source/blender/compositor/nodes/COM_NormalNode.cpp @@ -41,9 +41,14 @@ void NormalNode::convertToOperations(ExecutionSystem *graph, CompositorContext * SetVectorOperation *operationSet = new SetVectorOperation(); bNodeSocket *insock = (bNodeSocket *)editorNode->outputs.first; bNodeSocketValueVector *dval = (bNodeSocketValueVector *)insock->default_value; - operationSet->setX(dval->value[0]); - operationSet->setY(dval->value[1]); - operationSet->setZ(dval->value[2]); + float normal[3]; + + /* animation can break normalization, this restores it */ + normalize_v3_v3(normal, dval->value); + + operationSet->setX(normal[0]); + operationSet->setY(normal[1]); + operationSet->setZ(normal[2]); operationSet->setW(0.0f); outputSocket->relinkConnections(operationSet->getOutputSocket(0)); diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp index af990f4f3e0..c36a6f896c2 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp @@ -49,14 +49,11 @@ void GammaCorrectOperation::executePixel(float output[4], float x, float y, Pixe output[1] = inputColor[1] > 0.0f ? inputColor[1] * inputColor[1] : 0.0f; output[2] = inputColor[2] > 0.0f ? inputColor[2] * inputColor[2] : 0.0f; - inputColor[0] *= inputColor[3]; - inputColor[1] *= inputColor[3]; - inputColor[2] *= inputColor[3]; - - output[0] = inputColor[0]; - output[1] = inputColor[1]; - output[2] = inputColor[2]; - output[3] = inputColor[3]; + if (inputColor[3] > 0.0f) { + output[0] *= inputColor[3]; + output[1] *= inputColor[3]; + output[2] *= inputColor[3]; + } } void GammaCorrectOperation::deinitExecution() @@ -90,14 +87,11 @@ void GammaUncorrectOperation::executePixel(float output[4], float x, float y, Pi output[1] = inputColor[1] > 0.0f ? sqrtf(inputColor[1]) : 0.0f; output[2] = inputColor[2] > 0.0f ? sqrtf(inputColor[2]) : 0.0f; - inputColor[0] *= inputColor[3]; - inputColor[1] *= inputColor[3]; - inputColor[2] *= inputColor[3]; - - output[0] = inputColor[0]; - output[1] = inputColor[1]; - output[2] = inputColor[2]; - output[3] = inputColor[3]; + if (inputColor[3] > 0.0f) { + output[0] *= inputColor[3]; + output[1] *= inputColor[3]; + output[2] *= inputColor[3]; + } } void GammaUncorrectOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index fb3efbb67ed..d4c35f5afaa 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -65,8 +65,9 @@ ImBuf *BaseImageOperation::getImBuf() { ImBuf *ibuf; - ibuf = BKE_image_get_ibuf(this->m_image, this->m_imageUser); + ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, NULL); if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) { + BKE_image_release_ibuf(this->m_image, ibuf, NULL); return NULL; } @@ -93,6 +94,7 @@ void BaseImageOperation::initExecution() void BaseImageOperation::deinitExecution() { this->m_imageBuffer = NULL; + BKE_image_release_ibuf(this->m_image, this->m_buffer, NULL); } void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) @@ -106,6 +108,8 @@ void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigne resolution[0] = stackbuf->x; resolution[1] = stackbuf->y; } + + IMB_freeImBuf(stackbuf); } void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 0874e2f59be..201dc99eb9e 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -202,9 +202,9 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri INIT_MINMAX2(min, max); - DO_MINMAX2(a->co, min, max); - DO_MINMAX2(b->co, min, max); - DO_MINMAX2(c->co, min, max); + minmax_v2v2_v2(min, max, a->co); + minmax_v2v2_v2(min, max, b->co); + minmax_v2v2_v2(min, max, c->co); rect->xmin = min[0]; rect->ymin = min[1]; diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp new file mode 100644 index 00000000000..a18f418e48e --- /dev/null +++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + * Daniel Salazar + */ + +#include "COM_MapRangeOperation.h" + +MapRangeOperation::MapRangeOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->m_inputOperation = NULL; + this->m_useClamp = FALSE; +} + +void MapRangeOperation::initExecution() +{ + this->m_inputOperation = this->getInputSocketReader(0); + this->m_sourceMinOperation = this->getInputSocketReader(1); + this->m_sourceMaxOperation = this->getInputSocketReader(2); + this->m_destMinOperation = this->getInputSocketReader(3); + this->m_destMaxOperation = this->getInputSocketReader(4); +} + +void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + float inputs[8]; /* includes the 5 inputs + 3 pads */ + float value; + float source_min, source_max; + float dest_min, dest_max; + + this->m_inputOperation->read(inputs, x, y, sampler); + this->m_sourceMinOperation->read(inputs + 1, x, y, sampler); + this->m_sourceMaxOperation->read(inputs + 2, x, y, sampler); + this->m_destMinOperation->read(inputs + 3, x, y, sampler); + this->m_destMaxOperation->read(inputs + 4, x, y, sampler); + + value = inputs[0]; + source_min = inputs[1]; + source_max = inputs[2]; + dest_min = inputs[3]; + dest_max = inputs[4]; + + value = (value - source_min) / (source_max - source_min); + value = dest_min + value * (dest_max - dest_min); + + if (this->m_useClamp) { + if (dest_max > dest_min) { + CLAMP(value, dest_min, dest_max); + } + else { + CLAMP(value, dest_max, dest_min); + } + } + + output[0] = value; +} + +void MapRangeOperation::deinitExecution() +{ + this->m_inputOperation = NULL; + this->m_sourceMinOperation = NULL; + this->m_sourceMaxOperation = NULL; + this->m_destMinOperation = NULL; + this->m_destMaxOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h new file mode 100644 index 00000000000..00dfc68168c --- /dev/null +++ b/source/blender/compositor/operations/COM_MapRangeOperation.h @@ -0,0 +1,71 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + * Daniel Salazar + */ + +#ifndef _COM_MapRangeOperation_h +#define _COM_MapRangeOperation_h +#include "COM_NodeOperation.h" +#include "DNA_texture_types.h" + +/** + * this program converts an input color to an output value. + * it assumes we are in sRGB color space. + */ +class MapRangeOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader *m_inputOperation; + SocketReader *m_sourceMinOperation; + SocketReader *m_sourceMaxOperation; + SocketReader *m_destMinOperation; + SocketReader *m_destMaxOperation; + + bool m_useClamp; +public: + /** + * Default constructor + */ + MapRangeOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float output[4], float x, float y, PixelSampler sampler); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + /** + * Clamp the output + */ + void setUseClamp(bool value) { this->m_useClamp = value; } + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index 4d4c1199f3e..cc313512316 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -87,20 +87,16 @@ void ViewerBaseOperation::initImage() /* now we combine the input with ibuf */ this->m_outputBuffer = ibuf->rect_float; - /* needed for display buffer update - * - * no need to lock / reference the image buffer because it's seems - * to be the single place which changes buffers of viewer image - * which is this node - */ + /* needed for display buffer update */ this->m_ibuf = ibuf; if (m_doDepthBuffer) { this->m_depthBuffer = ibuf->zbuf_float; } - BKE_image_release_ibuf(this->m_image, this->m_lock); + BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock); } + void ViewerBaseOperation:: updateImage(rcti *rect) { IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0, diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 957dcfbd848..348b98a0380 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3678,10 +3678,12 @@ static int is_u_selected(Nurb *nu, int u) /* what about resolu == 2? */ bp = &nu->bp[u]; for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) { - if (v) if (bp->f1 & SELECT) return 1; + if ((v != 0) && (bp->f1 & SELECT)) { + return TRUE; + } } - return 0; + return FALSE; } typedef struct NurbSort { @@ -6464,7 +6466,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type bp->vec[0] += fac * grid; fac = (float)b - 1.5f; bp->vec[1] += fac * grid; - if (a == 1 || a == 2) if (b == 1 || b == 2) { + if ((a == 1 || a == 2) && (b == 1 || b == 2)) { bp->vec[2] += grid; } mul_m4_v3(mat, bp->vec); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index fd87e6752f2..257dfca051f 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1289,6 +1289,13 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt) insert_into_textbuf(obedit, ascii); accentcode = 0; } + else if (ascii) { + insert_into_textbuf(obedit, ascii); + accentcode = 0; + } + else { + BLI_assert(0); + } kill_selection(obedit, 1); text_update_edited(C, scene, obedit, 1, FO_EDIT); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 77f6d2bda5c..e04bbc1f2bf 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -110,7 +110,7 @@ typedef struct tGPsdata { double ocurtime; /* Used when converting to path */ float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space - * to region space */ + * to region space */ float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */ diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index a50b33966c6..9b726cea56c 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -49,7 +49,7 @@ void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sim int ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]); struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r); -void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock); +void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock); int ED_space_image_has_buffer(struct SpaceImage *sima); void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 9eec7c195b2..e000265bb1e 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -430,7 +430,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in but->type = NUMSLI; } } - else if (subtype == PROP_DIRECTION) { + else if (subtype == PROP_DIRECTION && !expand) { uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, 0, 0, 0, -1, -1, NULL); } else { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9b77072dee1..c1547593f96 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1409,8 +1409,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, dir1 &= (UI_TOP | UI_DOWN); } - if (dir2 == 0) if (dir1 == UI_LEFT || dir1 == UI_RIGHT) dir2 = UI_DOWN; - if (dir2 == 0) if (dir1 == UI_TOP || dir1 == UI_DOWN) dir2 = UI_LEFT; + if ((dir2 == 0) && (dir1 == UI_LEFT || dir1 == UI_RIGHT)) dir2 = UI_DOWN; + if ((dir2 == 0) && (dir1 == UI_TOP || dir1 == UI_DOWN)) dir2 = UI_LEFT; /* no space at all? don't change */ if (left || right) { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c836d62021e..527f383c837 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2623,6 +2623,11 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat } +static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) +{ + ui_draw_but_NORMAL(but, wcol, rect); +} + static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) { if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) { @@ -3030,6 +3035,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) break; case UI_WTYPE_NORMAL: + wt.custom = widget_normal; break; case UI_WTYPE_SCROLL: @@ -3269,7 +3275,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct break; case BUT_NORMAL: - ui_draw_but_NORMAL(but, &tui->wcol_regular, rect); + wt = widget_type(UI_WTYPE_NORMAL); break; case BUT_IMAGE: diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 82eb9457147..2b3f7faf8fc 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2183,7 +2183,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BMEdit_FromObject(obedit); BMOperator bmop; - const float mergedist = RNA_float_get(op->ptr, "mergedist"); + const float threshold = RNA_float_get(op->ptr, "threshold"); int use_unselected = RNA_boolean_get(op->ptr, "use_unselected"); int totvert_orig = em->bm->totvert; int count; @@ -2191,7 +2191,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) if (use_unselected) { EDBM_op_init(em, &bmop, op, "automerge verts=%hv dist=%f", - BM_ELEM_SELECT, mergedist); + BM_ELEM_SELECT, threshold); BMO_op_exec(em->bm, &bmop); if (!EDBM_op_finish(em, &bmop, op, TRUE)) { @@ -2201,7 +2201,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) else { EDBM_op_init(em, &bmop, op, "find_doubles verts=%hv dist=%f", - BM_ELEM_SELECT, mergedist); + BM_ELEM_SELECT, threshold); BMO_op_exec(em->bm, &bmop); if (!EDBM_op_callf(em, op, "weld_verts targetmap=%s", &bmop, "targetmapout")) { @@ -2236,8 +2236,7 @@ void MESH_OT_remove_doubles(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_float(ot->srna, "mergedist", 0.0001f, 0.000001f, 50.0f, - "Merge Distance", + RNA_def_float(ot->srna, "threshold", 0.0001f, 0.000001f, 50.0f, "Merge Distance", "Minimum distance between elements to merge", 0.00001, 10.0); RNA_def_boolean(ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices"); } @@ -2439,7 +2438,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) totshape = CustomData_number_of_layers(&em->bm->vdata, CD_SHAPEKEY); if (totshape == 0 || shape < 0 || shape >= totshape) return OPERATOR_CANCELLED; - + /* get shape key - needed for finding reference shape (for add mode only) */ if (key) { kb = BLI_findlink(&key->block, shape); @@ -2518,7 +2517,7 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_blend_from_shape_exec; - ot->invoke = WM_operator_props_popup; + ot->invoke = WM_operator_props_popup_call; ot->poll = ED_operator_editmesh; /* flags */ @@ -3007,6 +3006,8 @@ static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh BMesh *bm_new; bm_new = BM_mesh_create(&bm_mesh_allocsize_default); + BM_mesh_elem_toolflags_ensure(bm_new); /* needed for 'duplicate' bmo */ + CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index ee3c66b6eac..e144c38a350 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -114,7 +114,7 @@ typedef struct { } MultiresBakeRender; typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, - const int face_index, const int lvl, const float st[2], + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], float tangmat[3][3], const int x, const int y); typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima); @@ -133,6 +133,7 @@ typedef struct { DerivedMesh *lores_dm, *hires_dm; int lvl; void *bake_data; + ImBuf *ibuf; MPassKnownData pass_data; } MResolvePixelData; @@ -257,7 +258,7 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y) /* sequence end */ data->pass_data(data->lores_dm, data->hires_dm, data->bake_data, - data->face_index, data->lvl, st, to_tang, x, y); + data->ibuf, data->face_index, data->lvl, st, to_tang, x, y); } static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y) @@ -368,7 +369,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData) { DerivedMesh *dm = bkr->lores_dm; - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); const int lvl = bkr->lvl; const int tot_face = dm->getNumTessFaces(dm); MVert *mvert = dm->getVertArray(dm); @@ -414,6 +415,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData continue; data.face_index = f; + data.ibuf = ibuf; /* might support other forms of diagonal splits later on such as * split by shortest diagonal.*/ @@ -449,32 +451,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData if (freeBakeData) freeBakeData(data.bake_data); } -} -static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3]) -{ - float vec[3]; - - copy_v3_v3(res, data[0]); - mul_v3_fl(res, (1 - u) * (1 - v)); - copy_v3_v3(vec, data[1]); - mul_v3_fl(vec, u * (1 - v)); add_v3_v3(res, vec); - copy_v3_v3(vec, data[2]); - mul_v3_fl(vec, u * v); add_v3_v3(res, vec); - copy_v3_v3(vec, data[3]); - mul_v3_fl(vec, (1 - u) * v); add_v3_v3(res, vec); -} - -static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3]) -{ - float vec[3]; - - copy_v3_v3(res, data[0]); - mul_v3_fl(res, u); - copy_v3_v3(vec, data[1]); - mul_v3_fl(vec, v); add_v3_v3(res, vec); - copy_v3_v3(vec, data[2]); - mul_v3_fl(vec, 1.0f - u - v); add_v3_v3(res, vec); + BKE_image_release_ibuf(ima, ibuf, NULL); } /* mode = 0: interpolate normals, @@ -507,7 +485,7 @@ static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1)); } - interp_bilinear_quad_data(data, u, v, res); + interp_bilinear_quad_v3(data, u, v, res); } static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, @@ -579,7 +557,7 @@ static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, dm->getVertCo(dm, mface->v4, data[3]); } - interp_bilinear_quad_data(data, u, v, res); + interp_bilinear_quad_v3(data, u, v, res); } /* mode = 0: interpolate normals, @@ -599,13 +577,13 @@ static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float dm->getVertCo(dm, mface->v3, data[2]); } - interp_barycentric_tri_data(data, u, v, res); + interp_barycentric_tri_v3(data, u, v, res); } static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) { MHeightBakeData *height_data; - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); DerivedMesh *lodm = bkr->lores_dm; height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); @@ -635,6 +613,8 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); + BKE_image_release_ibuf(ima, ibuf, NULL); + return (void *)height_data; } @@ -661,7 +641,7 @@ static void free_normal_data(void *bake_data) static void apply_heights_data(void *bake_data) { MHeightBakeData *height_data = (MHeightBakeData *)bake_data; - ImBuf *ibuf = BKE_image_get_ibuf(height_data->ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL); int x, y, i; float height, *heights = height_data->heights; float min = height_data->height_min, max = height_data->height_max; @@ -693,6 +673,8 @@ static void apply_heights_data(void *bake_data) } ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID; + + BKE_image_release_ibuf(height_data->ima, ibuf, NULL); } static void free_heights_data(void *bake_data) @@ -713,13 +695,11 @@ static void free_heights_data(void *bake_data) * mesh to make texture smoother) let's call this point p0 and n. * - height wound be dot(n, p1-p0) */ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, - const int face_index, const int lvl, const float st[2], + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], float UNUSED(tangmat[3][3]), const int x, const int y) { MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); MFace mface; - Image *ima = mtface[face_index].tpage; - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); MHeightBakeData *height_data = (MHeightBakeData *)bake_data; float uv[2], *st0, *st1, *st2, *st3; int pixel = ibuf->x * y + x; @@ -790,13 +770,11 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, * - multiply it by tangmat * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, - const int face_index, const int lvl, const float st[2], + ImBuf *ibuf, const int face_index, const int lvl, const float st[2], float tangmat[3][3], const int x, const int y) { MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); MFace mface; - Image *ima = mtface[face_index].tpage; - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; float uv[2], *st0, *st1, *st2, *st3; int pixel = ibuf->x * y + x; @@ -879,7 +857,7 @@ static void bake_images(MultiresBakeRender *bkr) for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ibuf->x > 0 && ibuf->y > 0) { ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); @@ -895,6 +873,8 @@ static void bake_images(MultiresBakeRender *bkr) } } + BKE_image_release_ibuf(ima, ibuf, NULL); + ima->id.flag |= LIB_DOIT; } } @@ -905,7 +885,7 @@ static void finish_images(MultiresBakeRender *bkr) for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ibuf->x <= 0 || ibuf->y <= 0) continue; @@ -926,6 +906,8 @@ static void finish_images(MultiresBakeRender *bkr) MEM_freeN(ibuf->userdata); ibuf->userdata = NULL; } + + BKE_image_release_ibuf(ima, ibuf, NULL); } } @@ -1000,7 +982,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ok = 0; } else { - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (!ibuf) { BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); @@ -1017,6 +999,8 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (!ok) BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); } + + BKE_image_release_ibuf(ima, ibuf, NULL); } } } @@ -1087,10 +1071,12 @@ static void clear_images(MTFace *mtface, int totface) Image *ima = mtface[a].tpage; if ((ima->id.flag & LIB_DOIT) == 0) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); ima->id.flag |= LIB_DOIT; + + BKE_image_release_ibuf(ima, ibuf, NULL); } } @@ -1384,7 +1370,7 @@ static void finish_bake_internal(BakeRender *bkr) /* force OpenGL reload and mipmap recalc */ for (ima = G.main->image.first; ima; ima = ima->id.next) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); /* some of the images could have been changed during bake, * so recreate mipmaps regardless bake result status @@ -1409,6 +1395,8 @@ static void finish_bake_internal(BakeRender *bkr) ibuf->userdata = NULL; } } + + BKE_image_release_ibuf(ima, ibuf, NULL); } } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index c0c2195592b..4d6b9ed10bb 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1380,7 +1380,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d) if (ma->mtex[b] && ma->mtex[b]->tex) { tex = ma->mtex[b]->tex; if (tex->type == TEX_IMAGE && tex->ima) { - ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, NULL, NULL); /* texturespace */ space = 1.0; @@ -1402,6 +1402,8 @@ static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d) done = TRUE; DAG_id_tag_update(&ob->id, OB_RECALC_OB); + + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } } if (done) break; diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index f8ec51c7a7c..0c88519b62b 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2437,7 +2437,8 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_float(ot->srna, "threshold", 0.0002f, 0.0f, FLT_MAX, "Threshold", "Threshold distance withing which particles are removed", 0.00001f, 0.1f); + RNA_def_float(ot->srna, "threshold", 0.0002f, 0.0f, FLT_MAX, + "Merge Distance", "Threshold distance withing which particles are removed", 0.00001f, 0.1f); } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 4b177629f72..7b67f63c646 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -375,7 +375,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec /* make jobs timer to send notifier */ *(rj->do_update) = TRUE; } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); } static void render_startjob(void *rjv, short *stop, short *do_update, float *progress) diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index e4592a4f77e..effb984c083 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -288,7 +288,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } } - BKE_image_release_ibuf(oglrender->ima, lock); + BKE_image_release_ibuf(oglrender->ima, ibuf, lock); } static int screen_opengl_render_init(bContext *C, wmOperator *op) @@ -613,7 +613,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) IMB_freeImBuf(ibuf); } - BKE_image_release_ibuf(oglrender->ima, lock); + BKE_image_release_ibuf(oglrender->ima, ibuf, lock); /* movie stats prints have no line break */ printf("\n"); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index b119165fbd0..a864fe306b3 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -934,13 +934,15 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat /* elubie: this needs to be changed: here image is always loaded if not * already there. Very expensive for large images. Need to find a way to * only get existing ibuf */ - ibuf = BKE_image_get_ibuf(ima, &iuser); + ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); if (ibuf == NULL || ibuf->rect == NULL) return; icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect); *do_update = TRUE; + + BKE_image_release_ibuf(ima, ibuf, NULL); } else if (idtype == ID_BR) { Brush *br = (Brush *)id; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 4b400623920..676f033af32 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -500,7 +500,7 @@ static void image_undo_restore(bContext *C, ListBase *lb) ima = BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name)); } - ibuf = BKE_image_get_ibuf(ima, NULL); + ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ima && ibuf && strcmp(tile->ibufname, ibuf->name) != 0) { /* current ImBuf filename was changed, probably current frame @@ -508,19 +508,27 @@ static void image_undo_restore(bContext *C, ListBase *lb) * full image user (which isn't so obvious, btw) try to find ImBuf with * matched file name in list of already loaded images */ + BKE_image_release_ibuf(ima, ibuf, NULL); + ibuf = BLI_findstring(&ima->ibufs, tile->ibufname, offsetof(ImBuf, name)); } - if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) + if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) { + BKE_image_release_ibuf(ima, ibuf, NULL); continue; + } - if (ima->gen_type != tile->gen_type || ima->source != tile->source) + if (ima->gen_type != tile->gen_type || ima->source != tile->source) { + BKE_image_release_ibuf(ima, ibuf, NULL); continue; + } use_float = ibuf->rect_float ? 1 : 0; - if (use_float != tile->use_float) + if (use_float != tile->use_float) { + BKE_image_release_ibuf(ima, ibuf, NULL); continue; + } undo_copy_tile(tile, tmpibuf, ibuf, 1); @@ -530,6 +538,8 @@ static void image_undo_restore(bContext *C, ListBase *lb) if (ibuf->mipmap[0]) ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + + BKE_image_release_ibuf(ima, ibuf, NULL); } IMB_freeImBuf(tmpibuf); @@ -1049,11 +1059,11 @@ static int pixel_bounds_uv( INIT_MINMAX2(min_uv, max_uv); - DO_MINMAX2(uv1, min_uv, max_uv); - DO_MINMAX2(uv2, min_uv, max_uv); - DO_MINMAX2(uv3, min_uv, max_uv); + minmax_v2v2_v2(min_uv, max_uv, uv1); + minmax_v2v2_v2(min_uv, max_uv, uv2); + minmax_v2v2_v2(min_uv, max_uv, uv3); if (is_quad) - DO_MINMAX2(uv4, min_uv, max_uv); + minmax_v2v2_v2(min_uv, max_uv, uv4); bounds_px->xmin = (int)(ibuf_x * min_uv[0]); bounds_px->ymin = (int)(ibuf_y * min_uv[1]); @@ -1079,7 +1089,7 @@ static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, INIT_MINMAX2(min_uv, max_uv); while (tot--) { - DO_MINMAX2((*uv), min_uv, max_uv); + minmax_v2v2_v2(min_uv, max_uv, (*uv)); uv++; } @@ -1398,8 +1408,8 @@ static float project_paint_uvpixel_mask( Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index); const MTFace *tf_other = ps->dm_mtface_stencil + face_index; - if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) { - /* BKE_image_get_ibuf - TODO - this may be slow */ + if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) { + /* BKE_image_acquire_ibuf - TODO - this may be slow */ unsigned char rgba_ub[4]; float rgba_f[4]; @@ -1411,7 +1421,9 @@ static float project_paint_uvpixel_mask( else { /* from char to float */ mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f); } - + + BKE_image_release_ibuf(other_tpage, ibuf_other, NULL); + if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */ mask = (1.0f - mask); @@ -1579,8 +1591,8 @@ static ProjPixel *project_paint_uvpixel_init( Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index); const MTFace *tf_other = ps->dm_mtface_clone + face_index; - if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) { - /* BKE_image_get_ibuf - TODO - this may be slow */ + if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) { + /* BKE_image_acquire_ibuf - TODO - this may be slow */ if (ibuf->rect_float) { if (ibuf_other->rect_float) { /* from float to float */ @@ -1602,6 +1614,8 @@ static ProjPixel *project_paint_uvpixel_init( project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL); } } + + BKE_image_release_ibuf(other_tpage, ibuf_other, NULL); } else { if (ibuf->rect_float) { @@ -2926,7 +2940,7 @@ static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf, fidx = mf->v4 ? 3 : 2; do { vCoSS = ps->screenCoords[*(&mf->v1 + fidx)]; - DO_MINMAX2(vCoSS, min, max); + minmax_v2v2_v2(min, max, vCoSS); } while (fidx--); project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax); @@ -3191,7 +3205,7 @@ static void project_paint_begin(ProjPaintState *ps) /* screen space, not clamped */ projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0]; projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1]; - DO_MINMAX2(projScreenCo, ps->screenMin, ps->screenMax); + minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo); } } else { @@ -3206,7 +3220,7 @@ static void project_paint_begin(ProjPaintState *ps) projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0] / projScreenCo[3]; projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1] / projScreenCo[3]; projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; /* Use the depth for bucket point occlusion */ - DO_MINMAX2(projScreenCo, ps->screenMin, ps->screenMax); + minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo); } else { /* TODO - deal with cases where 1 side of a face goes behind the view ? @@ -3408,7 +3422,7 @@ static void project_paint_begin(ProjPaintState *ps) image_index = BLI_linklist_index(image_LinkList, tpage); - if (image_index == -1 && BKE_image_get_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */ + if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */ BLI_linklist_append(&image_LinkList, tpage); image_index = ps->image_tot; ps->image_tot++; @@ -3431,7 +3445,7 @@ static void project_paint_begin(ProjPaintState *ps) for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) { projIma->ima = node->link; projIma->touch = 0; - projIma->ibuf = BKE_image_get_ibuf(projIma->ima, NULL); + projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL); projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); } @@ -3458,6 +3472,7 @@ static void project_paint_begin_clone(ProjPaintState *ps, int mouse[2]) static void project_paint_end(ProjPaintState *ps) { int a; + ProjPaintImage *projIma; /* build undo data from original pixel colors */ if (U.uiflag & USER_GLOBALUNDO) { @@ -3545,7 +3560,14 @@ static void project_paint_end(ProjPaintState *ps) if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float); } /* done calculating undo data */ - + + /* dereference used image buffers */ + for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) { + BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL); + } + + BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL); + MEM_freeN(ps->screenCoords); MEM_freeN(ps->bucketRect); MEM_freeN(ps->bucketFaces); @@ -4672,7 +4694,7 @@ static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float static int imapaint_canvas_set(ImagePaintState *s, Image *ima) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, s->sima ? &s->sima->iuser : NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL); /* verify that we can paint and set canvas */ if (ima == NULL) { @@ -4695,10 +4717,12 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima) /* set clone canvas */ if (s->tool == PAINT_TOOL_CLONE) { ima = s->brush->clone.image; - ibuf = BKE_image_get_ibuf(ima, s->sima ? &s->sima->iuser : NULL); + ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL); - if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) + if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) { + BKE_image_release_ibuf(ima, ibuf, NULL); return 0; + } s->clonecanvas = ibuf; @@ -4713,13 +4737,15 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima) return 1; } -static void imapaint_canvas_free(ImagePaintState *UNUSED(s)) +static void imapaint_canvas_free(ImagePaintState *s) { + BKE_image_release_ibuf(s->image, s->canvas, NULL); + BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL); } static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure) { - ImBuf *ibuf = BKE_image_get_ibuf(image, s->sima ? &s->sima->iuser : NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, s->sima ? &s->sima->iuser : NULL, NULL); float pos[2]; int is_data; @@ -4739,9 +4765,13 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) { if (update) imapaint_image_update(s->scene, s->sima, image, ibuf, texpaint); + BKE_image_release_ibuf(image, ibuf, NULL); return 1; } - else return 0; + else { + BKE_image_release_ibuf(image, ibuf, NULL); + return 0; + } } static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPainter *painter, short texpaint, const int prevmval[2], const int mval[2], double time, float pressure) @@ -4759,7 +4789,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint ImBuf *ibuf; newimage = imapaint_face_image(s, newfaceindex); - ibuf = BKE_image_get_ibuf(newimage, s->sima ? &s->sima->iuser : NULL); + ibuf = BKE_image_acquire_ibuf(newimage, s->sima ? &s->sima->iuser : NULL, NULL); if (ibuf && ibuf->rect) imapaint_pick_uv(s->scene, s->ob, newfaceindex, mval, newuv); @@ -4767,6 +4797,8 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint newimage = NULL; newuv[0] = newuv[1] = 0.0f; } + + BKE_image_release_ibuf(newimage, ibuf, NULL); } else newuv[0] = newuv[1] = 0.0f; @@ -5890,7 +5922,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) } ps.reproject_image = image; - ps.reproject_ibuf = BKE_image_get_ibuf(image, NULL); + ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) { BKE_report(op->reports, RPT_ERROR, "Image data could not be found"); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index d523d598925..9cf389c4508 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1284,7 +1284,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, BKE_tracking_undistort_v2(tracking, pos, tpos); - DO_MINMAX2(tpos, min, max); + minmax_v2v2_v2(min, max, tpos); } copy_v2_v2(pos, min); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 71589517c83..1a62af39600 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -349,7 +349,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) mul_v3_m4v3(pos, sc->stabmat, pos); - DO_MINMAX2(pos, min, max); + minmax_v2v2_v2(min, max, pos); ok = TRUE; } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index ae7a718ab5b..0a3db59096a 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -593,7 +593,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char if (ima->source == IMA_SRC_VIEWER) { ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); image_info(scene, iuser, ima, ibuf, str); - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); uiItemL(layout, ima->id.name + 2, ICON_NONE); uiItemL(layout, str, ICON_NONE); @@ -663,7 +663,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char if (compact == 0) { ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); image_info(scene, iuser, ima, ibuf, str); - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); uiItemL(layout, str, ICON_NONE); } } @@ -722,7 +722,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char split = uiLayoutSplit(layout, 0.0f, FALSE); col = uiLayoutColumn(split, TRUE); - uiLayoutSetEnabled(col, 0); uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE); uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 9fc2b981547..d565e6f9e9a 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -652,7 +652,7 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int if (!brush || !brush->clone.image) return NULL; - ibuf = BKE_image_get_ibuf(brush->clone.image, NULL); + ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL); if (!ibuf) return NULL; @@ -660,6 +660,7 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); if (!display_buffer) { + BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); IMB_display_buffer_release(cache_handle); return NULL; @@ -669,8 +670,10 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int IMB_display_buffer_release(cache_handle); - if (!rect) + if (!rect) { + BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); return NULL; + } *width = ibuf->x; *height = ibuf->y; @@ -684,6 +687,8 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int cp += 4; } + BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); + return rect; } @@ -799,7 +804,7 @@ void draw_image_main(const bContext *C, ARegion *ar) } #endif - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); if (show_viewer) { BLI_unlock_thread(LOCK_DRAW_IMAGE); diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 4ca2f8888f8..c4e2230e7a7 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -117,8 +117,12 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r) #endif ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r); - if (ibuf && (ibuf->rect || ibuf->rect_float)) - return ibuf; + if (ibuf) { + if (ibuf->rect || ibuf->rect_float) + return ibuf; + + BKE_image_release_ibuf(sima->image, ibuf, NULL); + } } else *lock_r = NULL; @@ -126,10 +130,10 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r) return NULL; } -void ED_space_image_release_buffer(SpaceImage *sima, void *lock) +void ED_space_image_release_buffer(SpaceImage *sima, ImBuf *ibuf, void *lock) { if (sima && sima->image) - BKE_image_release_ibuf(sima->image, lock); + BKE_image_release_ibuf(sima->image, ibuf, lock); } int ED_space_image_has_buffer(SpaceImage *sima) @@ -140,7 +144,7 @@ int ED_space_image_has_buffer(SpaceImage *sima) ibuf = ED_space_image_acquire_buffer(sima, &lock); has_buffer = (ibuf != NULL); - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return has_buffer; } @@ -175,7 +179,7 @@ void ED_space_image_get_size(SpaceImage *sima, int *width, int *height) *height = IMG_SIZE_FALLBACK; } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); } void ED_space_image_get_size_fl(SpaceImage *sima, float size[2]) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index ce3c6e1fd26..d4f24babff6 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -167,7 +167,7 @@ static int space_image_file_exists_poll(bContext *C) ret = TRUE; } } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return ret; } @@ -1188,7 +1188,7 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, BKE_color_managed_view_settings_copy(&simopts->im_format.view_settings, &scene->view_settings); } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return (ibuf != NULL); } @@ -1328,7 +1328,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI IMB_freeImBuf(colormanaged_ibuf); } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); } static void image_save_as_free(wmOperator *op) @@ -1743,17 +1743,14 @@ void IMAGE_OT_new(wmOperatorType *ot) static int image_invert_poll(bContext *C) { Image *ima = CTX_data_edit_image(C); - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); - - if (ibuf != NULL) - return 1; - return 0; + + return BKE_image_has_ibuf(ima, NULL); } static int image_invert_exec(bContext *C, wmOperator *op) { Image *ima = CTX_data_edit_image(C); - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); /* flags indicate if this channel should be inverted */ const short r = RNA_boolean_get(op->ptr, "invert_r"); @@ -1792,6 +1789,7 @@ static int image_invert_exec(bContext *C, wmOperator *op) } } else { + BKE_image_release_ibuf(ima, ibuf, NULL); return OPERATOR_CANCELLED; } @@ -1800,6 +1798,9 @@ static int image_invert_exec(bContext *C, wmOperator *op) ibuf->userflags |= IB_MIPMAP_INVALID; WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); + + BKE_image_release_ibuf(ima, ibuf, NULL); + return OPERATOR_FINISHED; } @@ -1848,7 +1849,7 @@ static int image_pack_exec(bContext *C, wmOperator *op) { struct Main *bmain = CTX_data_main(C); Image *ima = CTX_data_edit_image(C); - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); int as_png = RNA_boolean_get(op->ptr, "as_png"); if (!image_pack_test(C, op)) @@ -1865,30 +1866,38 @@ static int image_pack_exec(bContext *C, wmOperator *op) ima->packedfile = newPackedFile(op->reports, ima->name, ID_BLEND_PATH(bmain, &ima->id)); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); - + + BKE_image_release_ibuf(ima, ibuf, NULL); + return OPERATOR_FINISHED; } static int image_pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { Image *ima = CTX_data_edit_image(C); - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf; uiPopupMenu *pup; uiLayout *layout; int as_png = RNA_boolean_get(op->ptr, "as_png"); if (!image_pack_test(C, op)) return OPERATOR_CANCELLED; - + + ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) { pup = uiPupMenuBegin(C, "OK", ICON_QUESTION); layout = uiPupMenuLayout(pup); uiItemBooleanO(layout, "Can't pack edited image from disk. Pack as internal PNG?", ICON_NONE, op->idname, "as_png", 1); uiPupMenuEnd(C, pup); + BKE_image_release_ibuf(ima, ibuf, NULL); + return OPERATOR_CANCELLED; } + BKE_image_release_ibuf(ima, ibuf, NULL); + return image_pack_exec(C, op); } @@ -2032,7 +2041,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa int ret = FALSE; if (ibuf == NULL) { - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return FALSE; } @@ -2058,7 +2067,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa } } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return ret; } @@ -2074,7 +2083,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event) CurveMapping *curve_mapping = scene->view_settings.curve_mapping; if (ibuf == NULL) { - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); info->draw = 0; return; } @@ -2175,7 +2184,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event) info->draw = 0; } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); ED_area_tag_redraw(CTX_wm_area(C)); } @@ -2266,12 +2275,12 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) float x1f, y1f, x2f, y2f; if (ibuf == NULL) { - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return OPERATOR_CANCELLED; } /* hmmmm */ if (ibuf->channels < 3) { - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); return OPERATOR_CANCELLED; } @@ -2288,7 +2297,7 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) /* reset y zoom */ hist->ymax = 1.0f; - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); ED_area_tag_redraw(CTX_wm_area(C)); @@ -2383,11 +2392,13 @@ static int image_record_composite_apply(bContext *C, wmOperator *op) ED_area_tag_redraw(CTX_wm_area(C)); - ibuf = BKE_image_get_ibuf(sima->image, &sima->iuser); + ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, NULL); /* save memory in flipbooks */ if (ibuf) imb_freerectfloatImBuf(ibuf); - + + BKE_image_release_ibuf(sima->image, ibuf, NULL); + scene->r.cfra++; return (scene->r.cfra <= rcd->efra); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 4131cbfdd0d..ea696772957 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -780,7 +780,7 @@ static void image_scope_area_draw(const bContext *C, ARegion *ar) } scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings); } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); ED_region_panels(C, ar, 1, NULL, -1); } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 131908bc9db..48b5eaf7b44 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -87,10 +87,14 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) // first check for dirty images for (ima = bmain->image.first; ima; ima = ima->id.next) { if (ima->ibufs.first) { /* XXX FIX */ - ibuf = BKE_image_get_ibuf(ima, NULL); + ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) + if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) { + BKE_image_release_ibuf(ima, ibuf, NULL); break; + } + + BKE_image_release_ibuf(ima, ibuf, NULL); } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8d44da2e367..92edac356e6 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -398,29 +398,15 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0); } -static void node_normal_cb(bContext *C, void *ntree_v, void *node_v) -{ - Main *bmain = CTX_data_main(C); - - ED_node_generic_update(bmain, ntree_v, node_v); - WM_event_add_notifier(C, NC_NODE | NA_EDITED, ntree_v); -} - static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiBlock *block = uiLayoutAbsoluteBlock(layout); - bNodeTree *ntree = ptr->id.data; - bNode *node = ptr->data; - rctf *butr = &node->butr; + bNodeTree *ntree = (bNodeTree*)ptr->id.data; + bNode *node = (bNode*)ptr->data; bNodeSocket *sock = node->outputs.first; /* first socket stores normal */ - float *nor = ((bNodeSocketValueVector *)sock->default_value)->value; - uiBut *bt; - - bt = uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", - (int)butr->xmin, (int)butr->xmin, - (short)BLI_rctf_size_x(butr), (short)BLI_rctf_size_x(butr), - nor, 0.0f, 1.0f, 0, 0, ""); - uiButSetFunc(bt, node_normal_cb, ntree, node); + PointerRNA sockptr; + + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &sockptr); + uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE); } #if 0 /* not used in 2.5x yet */ static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v) @@ -1485,9 +1471,10 @@ static void node_shader_buts_script_details(uiLayout *layout, bContext *C, Point node_shader_buts_script(layout, C, ptr); - /* not implemented yet +#if 0 /* not implemented yet */ if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL) - uiItemR(layout, ptr, "use_auto_update", 0, NULL, ICON_NONE);*/ + uiItemR(layout, ptr, "use_auto_update", 0, NULL, ICON_NONE); +#endif } /* only once called */ @@ -1887,6 +1874,14 @@ static void node_composit_buts_double_edge_mask(uiLayout *layout, bContext *UNUS uiItemR(col, ptr, "edge_mode", 0, "", ICON_NONE); } +static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *col; + + col = uiLayoutColumn(layout, TRUE); + uiItemR(col, ptr, "use_clamp", 0, NULL, ICON_NONE); +} + static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *sub, *col; @@ -2825,6 +2820,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_MAP_VALUE: ntype->uifunc = node_composit_buts_map_value; break; + case CMP_NODE_MAP_RANGE: + ntype->uifunc = node_composit_buts_map_range; + break; case CMP_NODE_TIME: ntype->uifunc = node_buts_time; break; @@ -3302,7 +3300,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) glPopMatrix(); } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); } } @@ -3315,7 +3313,7 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode) if (snode->flag & SNODE_BACKDRAW) { Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ibuf) { int x, y; float zoom = 1.0; @@ -3351,6 +3349,8 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode) glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + + BKE_image_release_ibuf(ima, ibuf, NULL); } } } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index 5f8b5db7766..4dd9c89375d 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -29,13 +29,18 @@ * \ingroup spnode */ +#include + #include "MEM_guardedalloc.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_anim_types.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_rect.h" +#include "BLI_math.h" #include "BKE_action.h" #include "BKE_animsys.h" @@ -865,7 +870,7 @@ static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, if (node == gnode) continue; if (node->flag & NODE_SELECT) { - DO_MINMAX2((&node->locx), min, max); + minmax_v2v2_v2(min, max, &node->locx); } } } diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index ccf5c4b540f..f386657c460 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -241,7 +241,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf == NULL) { - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); return OPERATOR_CANCELLED; } @@ -255,7 +255,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) nvm->ymin = -(ar->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad; nvm->ymax = (ar->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad; - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); /* add modal handler */ WM_event_add_modal_handler(C, op); @@ -330,6 +330,12 @@ typedef struct ImageSampleInfo { unsigned char col[4]; float colf[4]; + + int z; + float zf; + + int *zp; + float *zfp; int draw; int color_manage; @@ -343,8 +349,7 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info) if (info->draw) { ED_image_draw_info(scene, ar, info->color_manage, FALSE, info->channels, info->x, info->y, info->col, info->colf, - NULL, NULL /* zbuf - unused for nodes */ - ); + info->zp, info->zfp); } } @@ -398,7 +403,7 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float } } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); return ret; } @@ -443,6 +448,9 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event) info->draw = 1; info->channels = ibuf->channels; + info->zp = NULL; + info->zfp = NULL; + if (ibuf->rect) { cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); @@ -468,6 +476,15 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event) info->color_manage = TRUE; } + + if (ibuf->zbuf) { + info->z = ibuf->zbuf[y * ibuf->x + x]; + info->zp = &info->z; + } + if (ibuf->zbuf_float) { + info->zf = ibuf->zbuf_float[y * ibuf->x + x]; + info->zfp = &info->zf; + } ED_node_sample_set(info->colf); } @@ -476,7 +493,7 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event) ED_node_sample_set(NULL); } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); ED_area_tag_redraw(CTX_wm_area(C)); } diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript index 0b429ae750b..bc72786fc5f 100644 --- a/source/blender/editors/space_sequencer/SConscript +++ b/source/blender/editors/space_sequencer/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('*.c') -incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf' +incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../makesrna ../../blenloader ../../blenfont' incs += ' #/intern/audaspace/intern' diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index f463b015bf5..76908e5b369 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1494,6 +1494,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) Text *text = st->text; int vcurl, vcurc, vsell, vselc, hidden = 0; int x, y, w, i; + int lheight = st->lheight + TXT_LINE_SPACING; /* Draw the selection */ if (text->curl != text->sell || text->curc != text->selc) { @@ -1514,11 +1515,11 @@ static void draw_cursor(SpaceText *st, ARegion *ar) y = ar->winy - 2; if (vcurl == vsell) { - y -= vcurl * st->lheight; + y -= vcurl * lheight; if (vcurc < vselc) - glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - st->lheight); + glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight + TXT_LINE_SPACING); else - glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - st->lheight); + glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight + TXT_LINE_SPACING); } else { int froml, fromc, tol, toc; @@ -1532,12 +1533,12 @@ static void draw_cursor(SpaceText *st, ARegion *ar) fromc = vselc; toc = vcurc; } - y -= froml * st->lheight; - glRecti(x + fromc * st->cwidth - 1, y, ar->winx, y - st->lheight); y -= st->lheight; + y -= froml * lheight; + glRecti(x + fromc * st->cwidth - 1, y, ar->winx, y - lheight); y -= lheight; for (i = froml + 1; i < tol; i++) - glRecti(x - 4, y, ar->winx, y - st->lheight), y -= st->lheight; + glRecti(x - 4, y, ar->winx, y - lheight), y -= lheight; - glRecti(x - 4, y, x + toc * st->cwidth, y - st->lheight); y -= st->lheight; + glRecti(x - 4, y, x + toc * st->cwidth, y - lheight + TXT_LINE_SPACING); y -= lheight; } } else { @@ -1561,12 +1562,12 @@ static void draw_cursor(SpaceText *st, ARegion *ar) wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc); - y1 = ar->winy - 2 - (vsell - offl) * st->lheight; - y2 = y1 - st->lheight * visible_lines + 1; + y1 = ar->winy - 2 - (vsell - offl) * lheight; + y2 = y1 - lheight * visible_lines + 1; } else { - y1 = ar->winy - 2 - vsell * st->lheight; - y2 = y1 - st->lheight + 1; + y1 = ar->winy - 2 - vsell * lheight; + y2 = y1 - lheight + 1; } if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */ @@ -1577,7 +1578,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - glRecti(x1 - 4, y1, x2, y2); + glRecti(x1 - 4, y1, x2, y2 + TXT_LINE_SPACING); glDisable(GL_BLEND); } } @@ -1586,20 +1587,21 @@ static void draw_cursor(SpaceText *st, ARegion *ar) /* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */ x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET; x += vselc * st->cwidth; - y = ar->winy - 2 - vsell * st->lheight; + y = ar->winy - 2 - vsell * lheight; if (st->overwrite) { char ch = text->sell->line[text->selc]; + y += TXT_LINE_SPACING; w = st->cwidth; if (ch == '\t') w *= st->tabnumber - (vselc + st->left) % st->tabnumber; UI_ThemeColor(TH_HILITE); - glRecti(x, y - st->lheight - 1, x + w, y - st->lheight + 1); + glRecti(x, y - lheight - 1, x + w, y - lheight + 1); } else { UI_ThemeColor(TH_HILITE); - glRecti(x - 1, y, x + 1, y - st->lheight); + glRecti(x - 1, y, x + 1, y - lheight + TXT_LINE_SPACING); } } } @@ -1714,8 +1716,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (viewc >= 0) { viewl = txt_get_span(text->lines.first, startl) - st->top + offl; - text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * st->lheight, ch); - text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * st->lheight, ch); + text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); } /* draw closing bracket */ @@ -1726,8 +1728,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (viewc >= 0) { viewl = txt_get_span(text->lines.first, endl) - st->top + offl; - text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * st->lheight, ch); - text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * st->lheight, ch); + text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); } } @@ -1743,7 +1745,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) int wraplinecount = 0, wrap_skip = 0; int margin_column_x; - if (st->lheight) st->viewlines = (int)ar->winy / st->lheight; + if (st->lheight) st->viewlines = (int)ar->winy / (st->lheight + TXT_LINE_SPACING); else st->viewlines = 0; /* if no text, nothing to do */ @@ -1839,6 +1841,8 @@ void draw_text_main(SpaceText *st, ARegion *ar) text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format); y -= st->lheight; } + + y-= TXT_LINE_SPACING; wrap_skip = 0; } diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index 4f973e7076b..d687f4cdd8a 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -57,6 +57,7 @@ void text_update_cursor_moved(struct bContext *C); #define TXT_OFFSET 15 #define TXT_SCROLL_WIDTH 20 #define TXT_SCROLL_SPACE 2 +#define TXT_LINE_SPACING 4 /* space between lines */ #define TEXTXLOC (st->cwidth * st->linenrs_tot) diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 1be50a54b68..ae5de4c6a25 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1135,7 +1135,8 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) tmp = text->lines.first; - //first convert to all space, this make it a lot easier to convert to tabs because there is no mixtures of ' ' && '\t' + /* first convert to all space, this make it a lot easier to convert to tabs + * because there is no mixtures of ' ' && '\t' */ while (tmp) { text_check_line = tmp->line; number = flatten_string(st, &fs, text_check_line) + 1; @@ -1664,16 +1665,15 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel) Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, i, j, max, start, end, endj, chop, loop; + int oldc, i, j, max, start, end, endj, chop, loop; char ch; text_update_character_width(st); - if (sel) linep = &text->sell, charp = &text->selc; - else linep = &text->curl, charp = &text->curc; + if (sel) { linep = &text->sell; charp = &text->selc; } + else { linep = &text->curl; charp = &text->curc; } oldc = *charp; - oldl = txt_get_span(text->lines.first, *linep); max = wrap_width(st, ar); @@ -1724,7 +1724,6 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel) } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp); } static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel) @@ -1732,16 +1731,15 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel) Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, i, j, max, start, end, endj, chop, loop; + int oldc, i, j, max, start, end, endj, chop, loop; char ch; text_update_character_width(st); - if (sel) linep = &text->sell, charp = &text->selc; - else linep = &text->curl, charp = &text->curc; + if (sel) { linep = &text->sell; charp = &text->selc; } + else { linep = &text->curl; charp = &text->curc; } oldc = *charp; - oldl = txt_get_span(text->lines.first, *linep); max = wrap_width(st, ar); @@ -1790,7 +1788,6 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel) } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp); } static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel) @@ -1798,22 +1795,17 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel) Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, offl, offc, col, newl; + int offl, offc, col; text_update_character_width(st); - if (sel) linep = &text->sell, charp = &text->selc; - else linep = &text->curl, charp = &text->curc; - - /* store previous position */ - oldc = *charp; - newl = oldl = txt_get_span(text->lines.first, *linep); + if (sel) { linep = &text->sell; charp = &text->selc; } + else { linep = &text->curl; charp = &text->curc; } wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); col = text_get_char_pos(st, (*linep)->line, *charp) + offc; if (offl) { *charp = text_get_cursor_rel(st, ar, *linep, offl - 1, col); - newl = BLI_findindex(&text->lines, linep); } else { if ((*linep)->prev) { @@ -1822,13 +1814,11 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel) *linep = (*linep)->prev; visible_lines = text_get_visible_lines(st, ar, (*linep)->line); *charp = text_get_cursor_rel(st, ar, *linep, visible_lines - 1, col); - newl--; } else *charp = 0; } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, newl, *charp); } static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel) @@ -1836,35 +1826,28 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel) Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, offl, offc, col, newl, visible_lines; + int offl, offc, col, visible_lines; text_update_character_width(st); - if (sel) linep = &text->sell, charp = &text->selc; - else linep = &text->curl, charp = &text->curc; - - /* store previous position */ - oldc = *charp; - newl = oldl = txt_get_span(text->lines.first, *linep); + if (sel) { linep = &text->sell; charp = &text->selc; } + else { linep = &text->curl; charp = &text->curc; } wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); col = text_get_char_pos(st, (*linep)->line, *charp) + offc; visible_lines = text_get_visible_lines(st, ar, (*linep)->line); if (offl < visible_lines - 1) { *charp = text_get_cursor_rel(st, ar, *linep, offl + 1, col); - newl = BLI_findindex(&text->lines, linep); } else { if ((*linep)->next) { *linep = (*linep)->next; *charp = text_get_cursor_rel(st, ar, *linep, 0, col); - newl++; } else *charp = (*linep)->len; } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, newl, *charp); } /* Moves the cursor vertically by the specified number of lines. @@ -1876,12 +1859,10 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel) static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int sel) { TextLine **linep; - int oldl, oldc, *charp; + int *charp; - if (sel) linep = &text->sell, charp = &text->selc; - else linep = &text->curl, charp = &text->curc; - oldl = txt_get_span(text->lines.first, *linep); - oldc = *charp; + if (sel) { linep = &text->sell; charp = &text->selc; } + else { linep = &text->curl; charp = &text->curc; } if (st && ar && st->wordwrap) { int rell, relc; @@ -1904,7 +1885,6 @@ static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int s if (*charp > (*linep)->len) *charp = (*linep)->len; if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, *linep), *charp); } static int text_move_cursor(bContext *C, int type, int select) @@ -2222,10 +2202,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event) if (!tsc->scrollbar) { txtdelta[0] = -tsc->delta[0] / st->cwidth; - txtdelta[1] = tsc->delta[1] / st->lheight; + txtdelta[1] = tsc->delta[1] / (st->lheight + TXT_LINE_SPACING); tsc->delta[0] %= st->cwidth; - tsc->delta[1] %= st->lheight; + tsc->delta[1] %= (st->lheight + TXT_LINE_SPACING); } else { txtdelta[1] = -tsc->delta[1] * st->pix_per_line; @@ -2611,7 +2591,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in if (linep && charp != -1) { if (sel) { text->sell = linep; text->selc = charp; } - else { text->curl = linep; text->curc = charp; } + else { text->curl = linep; text->curc = charp; } } } @@ -2619,7 +2599,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int { Text *text = st->text; text_update_character_width(st); - y = (ar->winy - 2 - y) / st->lheight; + y = (ar->winy - 2 - y) / (st->lheight + TXT_LINE_SPACING); if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC; else x -= TXT_OFFSET; @@ -2636,7 +2616,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int int w; if (sel) { linep = &text->sell; charp = &text->selc; } - else { linep = &text->curl; charp = &text->curc; } + else { linep = &text->curl; charp = &text->curc; } y -= txt_get_span(text->lines.first, *linep) - st->top; @@ -2696,7 +2676,6 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op) SpaceText *st = CTX_wm_space_text(C); Text *text = st->text; SetSelection *ssel = op->customdata; - int linep2, charp2; char *buffer; if (txt_has_sel(text)) { @@ -2705,12 +2684,6 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op) MEM_freeN(buffer); } - linep2 = txt_get_span(st->text->lines.first, st->text->sell); - charp2 = st->text->selc; - - if (ssel->sell != linep2 || ssel->selc != charp2) - txt_undo_add_toop(st->text, UNDO_STO, ssel->sell, ssel->selc, linep2, charp2); - text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); @@ -2786,19 +2759,12 @@ void TEXT_OT_selection_set(wmOperatorType *ot) static int text_cursor_set_exec(bContext *C, wmOperator *op) { SpaceText *st = CTX_wm_space_text(C); - Text *text = st->text; ARegion *ar = CTX_wm_region(C); int x = RNA_int_get(op->ptr, "x"); int y = RNA_int_get(op->ptr, "y"); - int oldl, oldc; - - oldl = txt_get_span(text->lines.first, text->curl); - oldc = text->curc; text_cursor_set_to_pos(st, ar, x, y, 0); - txt_undo_add_toop(text, UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, text->curl), text->curc); - text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index cb5556396dd..f35a844afc9 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -728,7 +728,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) BKE_bproperty_set_valstr(prop, string); characters = strlen(string); - if (!BKE_image_get_ibuf(mtpoly->tpage, NULL)) + if (!BKE_image_has_ibuf(mtpoly->tpage, NULL)) characters = 0; if (!mf_smooth) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index d46eb51f2c5..79c34f93a10 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -530,7 +530,7 @@ void drawaxes(float size, char drawtype) static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4]) { Image *ima = (Image *)ob->data; - ImBuf *ibuf = ima ? BKE_image_get_ibuf(ima, NULL) : NULL; + ImBuf *ibuf = ima ? BKE_image_acquire_ibuf(ima, NULL, NULL) : NULL; float scale, ofs_x, ofs_y, sca_x, sca_y; int ima_x, ima_y; @@ -615,6 +615,8 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char /* Reset GL settings */ glMatrixMode(GL_MODELVIEW); glPopMatrix(); + + BKE_image_release_ibuf(ima, ibuf, NULL); } static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4]) @@ -3630,9 +3632,12 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B return 0; } -/* returns 1 when nothing was drawn */ -static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, - const short dt, const short dflag, const unsigned char ob_wire_col[4]) +/** + * Only called by #drawDispList + * \return 1 when nothing was drawn + */ +static int drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4]) { Object *ob = base->object; ListBase *lb = NULL; @@ -3640,20 +3645,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas Curve *cu; const short render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE); const short solid = (dt > OB_WIRE); - int retval = 0; - - /* backface culling */ - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - /* not all displists use same in/out normal direction convention */ - glEnable(GL_CULL_FACE); - glCullFace((ob->type == OB_MBALL) ? GL_BACK : GL_FRONT); - } if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == 0) { - if (v3d->flag2 & V3D_BACKFACE_CULLING) - glDisable(GL_CULL_FACE); - - return 0; + return FALSE; } switch (ob->type) { @@ -3665,7 +3659,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (solid) { dl = lb->first; - if (dl == NULL) return 1; + if (dl == NULL) { + return TRUE; + } if (dl->nors == NULL) BKE_displist_normals_add(lb); index3_nors_incr = 0; @@ -3699,9 +3695,11 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } else { if (!render_only || (render_only && BKE_displist_has_faces(lb))) { + int retval; draw_index_wire = 0; retval = drawDispListwire(lb); draw_index_wire = 1; + return retval; } } break; @@ -3711,7 +3709,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (solid) { dl = lb->first; - if (dl == NULL) return 1; + if (dl == NULL) { + return TRUE; + } if (dl->nors == NULL) BKE_displist_normals_add(lb); @@ -3727,7 +3727,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } } else { - retval = drawDispListwire(lb); + return drawDispListwire(lb); } break; case OB_MBALL: @@ -3735,7 +3735,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (BKE_mball_is_basis(ob)) { lb = &ob->disp; if (lb->first == NULL) BKE_displist_make_mball(scene, ob); - if (lb->first == NULL) return 1; + if (lb->first == NULL) { + return TRUE; + } if (solid) { @@ -3752,14 +3754,31 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } else { /* MetaBalls use DL_INDEX4 type of DispList */ - retval = drawDispListwire(lb); + return drawDispListwire(lb); } } break; } - - if (v3d->flag2 & V3D_BACKFACE_CULLING) + + return FALSE; +} +static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4]) +{ + int retval; + + /* backface culling */ + if (v3d->flag2 & V3D_BACKFACE_CULLING) { + /* not all displists use same in/out normal direction convention */ + glEnable(GL_CULL_FACE); + glCullFace((base->object->type == OB_MBALL) ? GL_BACK : GL_FRONT); + } + + retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); + + if (v3d->flag2 & V3D_BACKFACE_CULLING) { glDisable(GL_CULL_FACE); + } return retval; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 24fc6adae6d..7a1b97ff1d6 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -95,6 +95,16 @@ #include "view3d_intern.h" /* own include */ +/* handy utility for drawing shapes in the viewport for arbitrary code. + * could add lines and points too */ +// #define DEBUG_DRAW +#ifdef DEBUG_DRAW +static void bl_debug_draw(void); +/* add these locally when using these functions for testing */ +extern void bl_debug_draw_quad_clear(void); +extern void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3]); +extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]); +#endif static void star_stuff_init_func(void) { @@ -1218,7 +1228,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) hmargin = 0.035f * (x2 - x1); vmargin = 0.035f * (y2 - y1); - uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1+vmargin, x2 - hmargin, y2 - vmargin, 2.0f); + uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f); } if (ca && (ca->flag & CAM_SHOWSENSOR)) { /* determine sensor fit, and get sensor x/y, for auto fit we @@ -1561,7 +1571,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, ibuf = NULL; /* frame is out of range, dont show */ } else { - ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser); + ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL); + freeibuf = ibuf; } image_aspect[0] = ima->aspx; @@ -3206,6 +3217,9 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) { view3d_main_area_draw_objects(C, ar, &grid_unit); +#ifdef DEBUG_DRAW + bl_debug_draw(); +#endif ED_region_pixelspace(ar); } @@ -3218,3 +3232,57 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) v3d->flag |= V3D_INVALID_BACKBUF; } +#ifdef DEBUG_DRAW +/* debug drawing */ +#define _DEBUG_DRAW_QUAD_TOT 1024 +static float _bl_debug_draw_quads[_DEBUG_DRAW_QUAD_TOT][4][3]; +static int _bl_debug_draw_quads_tot = 0; + +void bl_debug_draw_quad_clear(void) +{ + _bl_debug_draw_quads_tot = 0; +} +void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3]) +{ + if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) { + printf("%s: max quad count hit %d!", __func__, _bl_debug_draw_quads_tot); + } + else { + float *pt = &_bl_debug_draw_quads[_bl_debug_draw_quads_tot][0][0]; + copy_v3_v3(pt, v0); pt += 3; + copy_v3_v3(pt, v1); pt += 3; + copy_v3_v3(pt, v2); pt += 3; + copy_v3_v3(pt, v3); pt += 3; + _bl_debug_draw_quads_tot++; + } +} +void bl_debug_draw_edge_add(const float v0[3], const float v1[3]) +{ + if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) { + printf("%s: max edge count hit %d!", __func__, _bl_debug_draw_quads_tot); + } + else { + float *pt = &_bl_debug_draw_quads[_bl_debug_draw_quads_tot][0][0]; + copy_v3_v3(pt, v0); pt += 3; + copy_v3_v3(pt, v1); pt += 3; + copy_v3_v3(pt, v0); pt += 3; + copy_v3_v3(pt, v1); pt += 3; + _bl_debug_draw_quads_tot++; + } +} +static void bl_debug_draw(void) +{ + if (_bl_debug_draw_quads_tot) { + int i; + cpack(0x00FF0000); + glBegin(GL_LINE_LOOP); + for (i = 0; i < _bl_debug_draw_quads_tot; i ++) { + glVertex3fv(_bl_debug_draw_quads[i][0]); + glVertex3fv(_bl_debug_draw_quads[i][1]); + glVertex3fv(_bl_debug_draw_quads[i][2]); + glVertex3fv(_bl_debug_draw_quads[i][3]); + } + glEnd(); + } +} +#endif diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 9bbd3f59cbf..5b79b69f7ec 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2486,7 +2486,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize) max[0] = aspx; max[1] = aspy; for (a = 0, td = t->data; a < t->total; a++, td++) { - DO_MINMAX2(td->loc, min, max); + minmax_v2v2_v2(min, max, td->loc); } if (resize) { diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 3828064185e..6664f8e860e 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -616,7 +616,7 @@ int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], f BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - DO_MINMAX2(luv->uv, r_min, r_max); + minmax_v2v2_v2(r_min, r_max, luv->uv); sel = 1; } } @@ -1327,7 +1327,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - DO_MINMAX2(luv->uv, min, max); + minmax_v2v2_v2(min, max, luv->uv); } } } @@ -1562,22 +1562,20 @@ typedef struct UVvert { static int remove_doubles_exec(bContext *C, wmOperator *op) { + const float threshold = RNA_float_get(op->ptr, "threshold"); + const int use_unselected = RNA_boolean_get(op->ptr, "use_unselected"); + SpaceImage *sima; Scene *scene; Object *obedit; Image *ima; BMEditMesh *em; MTexPoly *tf; - int UV_a; - int UV_b; - float UVp1[2]; - float UVp2[2]; - float weld_dist; - MLoopUV **loop_arr = NULL; - BLI_array_declare(loop_arr); + int uv_a_index; + int uv_b_index; + float *uv_a; + float *uv_b; - UVvert *vert_arr = NULL; - BLI_array_declare(vert_arr); BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1588,55 +1586,113 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) em = BMEdit_FromObject(obedit); ima = CTX_data_edit_image(C); - weld_dist = RNA_float_get(op->ptr, "weld_dist"); + if (use_unselected == FALSE) { + UVvert *vert_arr = NULL; + BLI_array_declare(vert_arr); + MLoopUV **loop_arr = NULL; + BLI_array_declare(loop_arr); + /* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */ + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if (!uvedit_face_visible_test(scene, ima, efa, tf)) + continue; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if (!uvedit_face_visible_test(scene, ima, efa, tf)) - continue; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + if (uvedit_uv_select_test(em, scene, l)) { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + UVvert vert; + vert.uv_loop = luv; + vert.weld = FALSE; + BLI_array_append(vert_arr, vert); + } - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(em, scene, l)) { - MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - UVvert vert; - vert.uv_loop = luv; - vert.weld = FALSE; - BLI_array_append(vert_arr, vert); } - } - } - for (UV_a = 0; UV_auv); + uv_a = vert_arr[uv_a_index].uv_loop->uv; - copy_v2_v2(near_UV, UVp1); - copy_v2_v2(far_UV, UVp1); + copy_v2_v2(uv_max, uv_a); + copy_v2_v2(uv_min, uv_a); - vert_arr[UV_a].weld = TRUE; - for (UV_b = 0; UV_buv); - if (UV_b != UV_a && vert_arr[UV_b].weld == FALSE && UVp1[0]-UVp2[0] > -weld_dist && UVp1[0] - UVp2[0] < weld_dist && UVp1[1] - UVp2[1] > -weld_dist && UVp1[1] - UVp2[1] < weld_dist){ - minmax_v2v2_v2(near_UV, far_UV, UVp2); - BLI_array_append(loop_arr, vert_arr[UV_b].uv_loop); - vert_arr[UV_b].weld = TRUE; + vert_arr[uv_a_index].weld = TRUE; + for (uv_b_index = uv_a_index + 1; uv_b_index < BLI_array_count(vert_arr); uv_b_index++) { + uv_b = vert_arr[uv_b_index].uv_loop->uv; + if ((vert_arr[uv_b_index].weld == FALSE) && + (len_manhattan_v2v2(uv_a, uv_b) < threshold)) + { + minmax_v2v2_v2(uv_max, uv_min, uv_b); + BLI_array_append(loop_arr, vert_arr[uv_b_index].uv_loop); + vert_arr[uv_b_index].weld = TRUE; + } + } + if (BLI_array_count(loop_arr)) { + float uv_mid[2]; + mid_v2_v2v2(uv_mid, uv_min, uv_max); + for (uv_b_index = 0; uv_b_index < BLI_array_count(loop_arr); uv_b_index++) { + copy_v2_v2(loop_arr[uv_b_index]->uv, uv_mid); + } } } - for (UV_b = 0; UV_buv, far_UV, near_UV); + } + + BLI_array_free(vert_arr); + BLI_array_free(loop_arr); + } + else { + /* selected -> unselected + * + * No need to use 'UVvert' here */ + MLoopUV **loop_arr = NULL; + BLI_array_declare(loop_arr); + MLoopUV **loop_arr_unselected = NULL; + BLI_array_declare(loop_arr_unselected); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if (!uvedit_face_visible_test(scene, ima, efa, tf)) + continue; + + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if (uvedit_uv_select_test(em, scene, l)) { + BLI_array_append(loop_arr, luv); + } + else { + BLI_array_append(loop_arr_unselected, luv); + } } } + + for (uv_a_index = 0; uv_a_index < BLI_array_count(loop_arr); uv_a_index++) { + float dist_best = FLT_MAX, dist; + float *uv_best = NULL; + + uv_a = loop_arr[uv_a_index]->uv; + for (uv_b_index = 0; uv_b_index < BLI_array_count(loop_arr_unselected); uv_b_index++) { + uv_b = loop_arr_unselected[uv_b_index]->uv; + dist = len_manhattan_v2v2(uv_a, uv_b); + if ((dist < threshold) && (dist < dist_best)) { + uv_best = uv_b; + dist_best = dist; + } + } + if (uv_best) { + copy_v2_v2(uv_a, uv_best); + } + } + + BLI_array_free(loop_arr); + BLI_array_free(loop_arr_unselected); } - BLI_array_free(loop_arr); - BLI_array_free(vert_arr); uvedit_live_unwrap_update(sima, scene, obedit); DAG_id_tag_update(obedit->data, 0); @@ -1648,7 +1704,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) static void UV_OT_remove_doubles(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove Doubles"; + ot->name = "Remove Doubles UV"; ot->description = "Selected UV vertices that are within a radius of eachother are welded together"; ot->idname = "UV_OT_remove_doubles"; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1657,7 +1713,9 @@ static void UV_OT_remove_doubles(wmOperatorType *ot) ot->exec = remove_doubles_exec; ot->poll = ED_operator_uvedit; - RNA_def_float(ot->srna, "weld_dist", 0.02f, 0.0f, 1.0f, "Weld Distance", "Maximum distance between welded vertices", 0.001f, 10.0f); + RNA_def_float(ot->srna, "threshold", 0.02f, 0.0f, 10.0f, + "Merge Distance", "Maximum distance between welded vertices", 0.0f, 1.0f); + RNA_def_boolean(ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices"); } /* ******************** weld operator **************** */ diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 5b6125b558b..8703234122a 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -450,7 +450,7 @@ static void p_chart_uv_bbox(PChart *chart, float minv[2], float maxv[2]) INIT_MINMAX2(minv, maxv); for (v = chart->verts; v; v = v->nextlink) { - DO_MINMAX2(v->uv, minv, maxv); + minmax_v2v2_v2(minv, maxv, v->uv); } } @@ -3891,9 +3891,9 @@ static void p_smooth(PChart *chart) INIT_MINMAX2(fmin, fmax); - DO_MINMAX2(e1->vert->uv, fmin, fmax); - DO_MINMAX2(e2->vert->uv, fmin, fmax); - DO_MINMAX2(e3->vert->uv, fmin, fmax); + minmax_v2v2_v2(fmin, fmax, e1->vert->uv); + minmax_v2v2_v2(fmin, fmax, e2->vert->uv); + minmax_v2v2_v2(fmin, fmax, e3->vert->uv); bx1 = (int)((fmin[0] - minv[0]) * invmedian); by1 = (int)((fmin[1] - minv[1]) * invmedian); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index fc60c5a3a0f..efe9d1fedfe 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1089,7 +1089,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - DO_MINMAX2(luv->uv, min, max); + minmax_v2v2_v2(min, max, luv->uv); } } diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index f7ed9effc7a..9b8a86eac15 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -27,7 +27,6 @@ sources.extend(( os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"), - os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"), )) diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7bd72430969..e3ba4cb1f95 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -318,7 +318,7 @@ static void gpu_make_repbind(Image *ima) { ImBuf *ibuf; - ibuf = BKE_image_get_ibuf(ima, NULL); + ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ibuf==NULL) return; @@ -333,6 +333,8 @@ static void gpu_make_repbind(Image *ima) if (ima->totbind>1) ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind"); + + BKE_image_release_ibuf(ima, ibuf, NULL); } static void gpu_clear_tpage(void) @@ -479,7 +481,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int return 0; /* check if we have a valid image buffer */ - ibuf= BKE_image_get_ibuf(ima, iuser); + ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL); if (ibuf==NULL) return 0; @@ -574,6 +576,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int if (*bind != 0) { /* enable opengl drawing with textures */ glBindTexture(GL_TEXTURE_2D, *bind); + BKE_image_release_ibuf(ima, ibuf, NULL); return *bind; } @@ -635,6 +638,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int if (srgb_frect) MEM_freeN(srgb_frect); + BKE_image_release_ibuf(ima, ibuf, NULL); + return *bind; } @@ -896,7 +901,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) { ImBuf *ibuf; - ibuf = BKE_image_get_ibuf(ima, NULL); + ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || !ima->bindcode || !ibuf || (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) || @@ -935,6 +940,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } + BKE_image_release_ibuf(ima, ibuf, NULL); return; } @@ -959,6 +965,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } } + + BKE_image_release_ibuf(ima, ibuf, NULL); } void GPU_update_images_framechange(void) diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index ef73764753c..497105d94ec 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1165,13 +1165,14 @@ static void do_material_tex(GPUShadeInput *shi) // resolve texture resolution if ( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) { - ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser); + ImBuf *ibuf= BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only if (ibuf) { ima_x= ibuf->x; ima_y= ibuf->y; aspect = ((float) ima_y) / ima_x; } + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } // The negate on norfac is done because the diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index aedce52a7bf..4c9b5e620dd 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -457,7 +457,7 @@ LogImageFile *dpxCreate(const char *filename, int width, int height, int bitsPer } /* Header should be rounded to next 8k block - 6044 = 8092 - sizeof(DpxMainHeader) */ + * 6044 = 8092 - sizeof(DpxMainHeader) */ memset(&pad, 0, 6044); if (fwrite(&pad, 6044, 1, dpx->file) == 0) { if (verbose) printf("DPX: Couldn't write image header\n"); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 3fd31f9a58c..1c68a466ade 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2465,7 +2465,8 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag } display_space = display_transform_get_colorspace(applied_view_settings, display_settings); - cm_processor->is_data_result = display_space->is_data; + if (display_space) + cm_processor->is_data_result = display_space->is_data; cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, applied_view_settings->exposure, applied_view_settings->gamma); diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h index 0291816cd03..7e5a1e504b8 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -147,7 +147,7 @@ struct BlockDXT3 struct AlphaBlockDXT5 { // uint64 unions do not compile on all platforms - /* +#if 0 union { struct { uint64 alpha0 : 8; // 8 @@ -171,7 +171,7 @@ struct AlphaBlockDXT5 }; uint64 u; }; - */ +#endif uint64 u; uint8 alpha0() const { return u & 0xffLL; } uint8 alpha1() const { return (u >> 8) & 0xffLL; } diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript index d5a613f5981..475d21135aa 100644 --- a/source/blender/imbuf/intern/dds/SConscript +++ b/source/blender/imbuf/intern/dds/SConscript @@ -3,16 +3,17 @@ Import ('env') source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp', 'FlipDXT.cpp'] -incs = ['.', - '../../', - '../..', +incs = [ + '.', '..', + '../..', '../../../makesdna', '../../../blenkernel', '../../../blenlib', 'intern/include', '#/intern/guardedalloc', - '#/intern/utfconv'] + '#/intern/utfconv' + ] defs = ['WITH_DDS'] diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index b9525ccccf1..1e701b8d615 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -1467,10 +1467,10 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int return ibuf; } - if (newx < ibuf->x) if (newx) scaledownx(ibuf, newx); - if (newy < ibuf->y) if (newy) scaledowny(ibuf, newy); - if (newx > ibuf->x) if (newx) scaleupx(ibuf, newx); - if (newy > ibuf->y) if (newy) scaleupy(ibuf, newy); + if (newx && (newx < ibuf->x)) scaledownx(ibuf, newx); + if (newy && (newy < ibuf->y)) scaledowny(ibuf, newy); + if (newx && (newx > ibuf->x)) scaleupx(ibuf, newx); + if (newy && (newy > ibuf->y)) scaleupy(ibuf, newy); return(ibuf); } diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h index cf26dae402d..810628ac29b 100644 --- a/source/blender/makesdna/DNA_text_types.h +++ b/source/blender/makesdna/DNA_text_types.h @@ -78,7 +78,6 @@ typedef struct Text { /* text flags */ #define TXT_ISDIRTY 0x0001 -#define TXT_DEPRECATED 0x0004 /* deprecated ISTMP flag */ #define TXT_ISMEM 0x0004 #define TXT_ISEXT 0x0008 #define TXT_ISSCRIPT 0x0010 /* used by space handler scriptlinks */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index c327319c403..8885349ecc5 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -148,6 +148,7 @@ extern StructRNA RNA_CompositorNodeLevels; extern StructRNA RNA_CompositorNodeLumaMatte; extern StructRNA RNA_CompositorNodeMapUV; extern StructRNA RNA_CompositorNodeMapValue; +extern StructRNA RNA_CompositorNodeMapRange; extern StructRNA RNA_CompositorNodeMath; extern StructRNA RNA_CompositorNodeMask; extern StructRNA RNA_CompositorNodeMixRGB; diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index f8af2427827..9fedbee41ff 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -113,7 +113,7 @@ static void rna_Image_fields_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); } static void rna_Image_free_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -187,8 +187,12 @@ static EnumPropertyItem *rna_Image_source_itemf(bContext *UNUSED(C), PointerRNA static int rna_Image_file_format_get(PointerRNA *ptr) { Image *image = (Image *)ptr->data; - ImBuf *ibuf = BKE_image_get_ibuf(image, NULL); - return BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); + int imtype = BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0); + + BKE_image_release_ibuf(image, ibuf, NULL); + + return imtype; } static void rna_Image_file_format_set(PointerRNA *ptr, int value) @@ -199,12 +203,13 @@ static void rna_Image_file_format_set(PointerRNA *ptr, int value) int ftype = BKE_imtype_to_ftype(value); #if 0 - ibuf = BKE_image_get_ibuf(image, NULL); + ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf) ibuf->ftype = ftype; #endif /* to be safe change all buffer file types */ + /* TODO: this is never threadsafe */ for (ibuf = image->ibufs.first; ibuf; ibuf = ibuf->next) { ibuf->ftype = ftype; } @@ -237,7 +242,7 @@ static void rna_Image_size_get(PointerRNA *ptr, int *values) values[1] = 0; } - BKE_image_release_ibuf(im, lock); + BKE_image_release_ibuf(im, ibuf, lock); } static void rna_Image_resolution_get(PointerRNA *ptr, float *values) @@ -256,7 +261,7 @@ static void rna_Image_resolution_get(PointerRNA *ptr, float *values) values[1] = 0; } - BKE_image_release_ibuf(im, lock); + BKE_image_release_ibuf(im, ibuf, lock); } static void rna_Image_resolution_set(PointerRNA *ptr, const float *values) @@ -271,7 +276,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values) ibuf->ppm[1] = values[1]; } - BKE_image_release_ibuf(im, lock); + BKE_image_release_ibuf(im, ibuf, lock); } static int rna_Image_depth_get(PointerRNA *ptr) @@ -290,7 +295,7 @@ static int rna_Image_depth_get(PointerRNA *ptr) else planes = ibuf->planes; - BKE_image_release_ibuf(im, lock); + BKE_image_release_ibuf(im, ibuf, lock); return planes; } @@ -317,7 +322,7 @@ static int rna_Image_pixels_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY else length[0] = 0; - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); return length[0]; } @@ -343,7 +348,7 @@ static void rna_Image_pixels_get(PointerRNA *ptr, float *values) } } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); } static void rna_Image_pixels_set(PointerRNA *ptr, const float *values) @@ -369,7 +374,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values) ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); } #else diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index cb5c515ce1f..686e6c80f1d 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -99,7 +99,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports IMB_freeImBuf(write_ibuf); } - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); } else { BKE_report(reports, RPT_ERROR, "Scene not in context, could not get save parameters"); @@ -108,7 +108,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports static void rna_Image_save(Image *image, ReportList *reports) { - ImBuf *ibuf = BKE_image_get_ibuf(image, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf) { char filename[FILE_MAX]; BLI_strncpy(filename, image->name, sizeof(filename)); @@ -136,11 +136,13 @@ static void rna_Image_save(Image *image, ReportList *reports) else { BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2); } + + BKE_image_release_ibuf(image, ibuf, NULL); } static void rna_Image_pack(Image *image, ReportList *reports, int as_png) { - ImBuf *ibuf = BKE_image_get_ibuf(image, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) { BKE_report(reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG"); @@ -153,6 +155,8 @@ static void rna_Image_pack(Image *image, ReportList *reports, int as_png) image->packedfile = newPackedFile(reports, image->name, ID_BLEND_PATH(G.main, &image->id)); } } + + BKE_image_release_ibuf(image, ibuf, NULL); } static void rna_Image_unpack(Image *image, ReportList *reports, int method) @@ -177,7 +181,7 @@ static void rna_Image_reload(Image *image) static void rna_Image_update(Image *image, ReportList *reports) { - ImBuf *ibuf = BKE_image_get_ibuf(image, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf == NULL) { BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2); @@ -188,6 +192,8 @@ static void rna_Image_update(Image *image, ReportList *reports) IMB_rect_from_float(ibuf); ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + + BKE_image_release_ibuf(image, ibuf, NULL); } static void rna_Image_scale(Image *image, ReportList *reports, int width, int height) @@ -206,10 +212,11 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int if (*bind) return error; - ibuf = BKE_image_get_ibuf(image, NULL); + ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf == NULL || ibuf->rect == NULL) { BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2); + BKE_image_release_ibuf(image, ibuf, NULL); return (int)GL_INVALID_OPERATION; } @@ -238,6 +245,8 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int image->bindcode = 0; } + BKE_image_release_ibuf(image, ibuf, NULL); + return error; } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index a68bcf62df8..1da9a450c2c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2199,6 +2199,16 @@ static void def_cmp_map_value(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_cmp_map_range(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); + RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_cmp_vector_blur(StructRNA *srna) { PropertyRNA *prop; @@ -4641,18 +4651,22 @@ static void rna_def_node(BlenderRNA *brna) prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SELECT); RNA_def_property_ui_text(prop, "Select", ""); + RNA_def_property_update(prop, NC_NODE | NA_SELECTED, NULL); prop = RNA_def_property(srna, "show_options", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_OPTIONS); RNA_def_property_ui_text(prop, "Show Options", ""); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); prop = RNA_def_property(srna, "show_preview", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_PREVIEW); RNA_def_property_ui_text(prop, "Show Preview", ""); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_HIDDEN); RNA_def_property_ui_text(prop, "Hide", ""); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_MUTED); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index fbbcbae6c12..14cdbc6cf7d 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -114,6 +114,7 @@ DefNode( CompositorNode, CMP_NODE_ALPHAOVER, def_cmp_alpha_over, "ALPHA DefNode( CompositorNode, CMP_NODE_BLUR, def_cmp_blur, "BLUR", Blur, "Blur", "" ) DefNode( CompositorNode, CMP_NODE_FILTER, def_cmp_filter, "FILTER", Filter, "Filter", "" ) DefNode( CompositorNode, CMP_NODE_MAP_VALUE, def_cmp_map_value, "MAP_VALUE", MapValue, "Map Value", "" ) +DefNode( CompositorNode, CMP_NODE_MAP_RANGE, def_cmp_map_range, "MAP_RANGE", MapRange, "Map Range", "" ) DefNode( CompositorNode, CMP_NODE_TIME, def_time, "TIME", Time, "Time", "" ) DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBLUR", VecBlur, "Vector Blur", "" ) DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" ) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index d436e4719ea..a669cb2558a 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1643,21 +1643,23 @@ static void rna_def_object_game_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed"); + /* Character physics */ prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "step_height"); - RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_range(prop, 0.01, 1.0); RNA_def_property_ui_text(prop, "Step Height", "Maximum height of steps the character can run over"); prop = RNA_def_property(srna, "jump_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "jump_speed"); RNA_def_property_range(prop, 0.0, 1000.0); - RNA_def_property_ui_text(prop, "Jump Force", "Upward velocity applied to the character when jumping (with the Motion actuator)"); + RNA_def_property_ui_text(prop, "Jump Force", "Upward velocity applied to the character when jumping"); prop = RNA_def_property(srna, "fall_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fall_speed"); RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall"); + /* Collision Masks */ prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1); RNA_def_property_array(prop, OB_MAX_COL_MASKS); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 6011af2626e..09d0eeb1e34 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1126,6 +1126,12 @@ static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value) } } +static char *rna_SceneRenderLayer_path(PointerRNA *ptr) +{ + SceneRenderLayer *srl = (SceneRenderLayer*)ptr->data; + return BLI_sprintfN("render.layers[\"%s\"]", srl->name); +} + static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr)) { return (BLI_countlist(&R_engines) > 1); @@ -3202,6 +3208,7 @@ static void rna_def_scene_render_layer(BlenderRNA *brna) srna = RNA_def_struct(brna, "SceneRenderLayer", NULL); RNA_def_struct_ui_text(srna, "Scene Render Layer", "Render layer"); RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS); + RNA_def_struct_path_func(srna, "rna_SceneRenderLayer_path"); rna_def_render_layer_common(srna, 1); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 70daba9790f..2aa907b72f2 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -598,7 +598,7 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *UNUS alpha = ibuf && (ibuf->channels == 4); zbuf = ibuf && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1)); - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); if (alpha && zbuf) return draw_channels_items; @@ -678,7 +678,7 @@ static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings); WM_main_add_notifier(NC_IMAGE, sima->image); } - ED_space_image_release_buffer(sima, lock); + ED_space_image_release_buffer(sima, ibuf, lock); } /* Space Text Editor */ diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 7219038b087..7ab3a5df531 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -58,7 +58,7 @@ static void initData(ModifierData *md) { ArmatureModifierData *amd = (ArmatureModifierData *) md; - amd->deformflag = ARM_DEF_ENVELOPE | ARM_DEF_VGROUP; + amd->deformflag = ARM_DEF_VGROUP; } static void copyData(ModifierData *md, ModifierData *target) diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index b9dd37ac50c..8ddae9f3c57 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -408,6 +408,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, * cleaner way to do this. One possibility: a "mirror" BMOp would * certainly help by compressing it all into one top-level BMOp that * executes a lot of second-level BMOps. */ + BM_mesh_elem_toolflags_ensure(bm); BMO_push(bm, NULL); bmesh_edit_begin(bm, 0); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 3e3bcb73491..59befe4db05 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -92,20 +92,15 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) #ifdef USE_BM_BEVEL_OP_AS_MOD -#define EDGE_MARK 1 - /* BMESH_TODO * - * this bevel calls the operator which is missing many of the options - * which the bevel modifier in trunk has. + * this bevel calls the new bevel code (added since 2.64) + * which is missing many of the options which the bevel modifier from 2.4x has. * - no vertex bevel * - no weight bevel * * These will need to be added to the bmesh operator. - * - campbell - * - * note: this code is very close to MOD_edgesplit.c. - * note: if 0'd code from trunk included below. + * - campbell */ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob), DerivedMesh *dm, @@ -116,22 +111,20 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob), BMIter iter; BMEdge *e; BevelModifierData *bmd = (BevelModifierData *) md; - float threshold = cos((bmd->bevel_angle + 0.00001f) * M_PI / 180.0f); + const float threshold = cosf((bmd->bevel_angle + 0.00001f) * (float)M_PI / 180.0f); + const int segments = 16; /* XXX */ bm = DM_to_bmesh(dm); - BM_mesh_normals_update(bm, FALSE); - BMO_push(bm, NULL); - if (bmd->lim_flags & BME_BEVEL_ANGLE) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { /* check for 1 edge having 2 face users */ - BMLoop *l1, *l2; - if ((l1 = e->l) && - (l2 = e->l->radial_next) != l1) - { - if (dot_v3v3(l1->f->no, l2->f->no) < threshold) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BMLoop *l_a, *l_b; + if (BM_edge_loop_pair(e, &l_a, &l_b)) { + if (dot_v3v3(l_a->f->no, l_b->f->no) < threshold) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); } } } @@ -139,18 +132,23 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob), else { /* crummy, is there a way just to operator on all? - campbell */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + if (BM_edge_is_manifold(e)) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); + } } } - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, - "bevel geom=%fe percent=%f use_even=%b use_dist=%b", - EDGE_MARK, bmd->value, (bmd->flags & BME_BEVEL_EVEN) != 0, (bmd->flags & BME_BEVEL_DIST) != 0); - BMO_pop(bm); + BM_mesh_bevel(bm, bmd->value, segments); result = CDDM_from_bmesh(bm, TRUE); + + BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */ BM_mesh_free(bm); + CDDM_calc_normals(result); + return result; } diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index dc29e59d549..3f8eaa438c9 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -186,6 +186,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* update for display only */ dmd->face_count = bm->totface; result = CDDM_from_bmesh(bm, FALSE); + BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */ BM_mesh_free(bm); #ifdef USE_TIMEIT diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 21717d07fef..ec81c5ce699 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -67,8 +67,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f); bm = DM_to_bmesh(dm); - - BMO_push(bm, NULL); + BM_mesh_elem_toolflags_ensure(bm); if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -103,8 +102,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "split_edges edges=%fe", EDGE_MARK); - - BMO_pop(bm); /* BM_mesh_validate(bm); */ /* for troubleshooting */ diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 38ec0e8bb4c..96f97a6fa8a 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -537,6 +537,7 @@ static int connection_node_mat(float mat[3][3], int v, const MeshElemMap *emap, /* Get axis and angle to rotate frame by */ angle = angle_normalized_v3v3(ine[0], oute[0]) / 2.0f; cross_v3_v3v3(axis, ine[0], oute[0]); + normalize_v3(axis); /* Build frame matrix (don't care about X axis here) */ copy_v3_v3(mat[0], ine[0]); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 7dca4d07b24..9e412785467 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -84,6 +84,7 @@ set(SRC composite/nodes/node_composite_lummaMatte.c composite/nodes/node_composite_mapUV.c composite/nodes/node_composite_mapValue.c + composite/nodes/node_composite_mapRange.c composite/nodes/node_composite_math.c composite/nodes/node_composite_mask.c composite/nodes/node_composite_mixrgb.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index ee67ac88085..eecc1e46827 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -72,6 +72,7 @@ void register_node_type_cmp_huecorrect(struct bNodeTreeType *ttype); void register_node_type_cmp_normal(struct bNodeTreeType *ttype); void register_node_type_cmp_curve_vec(struct bNodeTreeType *ttype); void register_node_type_cmp_map_value(struct bNodeTreeType *ttype); +void register_node_type_cmp_map_range(struct bNodeTreeType *ttype); void register_node_type_cmp_normalize(struct bNodeTreeType *ttype); void register_node_type_cmp_filter(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c index e9d26ebebbc..df49e537788 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c @@ -49,14 +49,14 @@ static bNodeSocketTemplate cmp_node_colorbalance_out[] = { #ifdef WITH_COMPOSITOR_LEGACY /* this function implements ASC-CDL according to the spec at http://www.asctech.org/ - Slope - S = in * slope - Offset - O = S + offset - = (in * slope) + offset - Power - out = Clamp(O) ^ power - = Clamp((in * slope) + offset) ^ power + * Slope + * S = in * slope + * Offset + * O = S + offset + * = (in * slope) + offset + * Power + * out = Clamp(O) ^ power + * = Clamp((in * slope) + offset) ^ power */ DO_INLINE float colorbalance_cdl(float in, float offset, float power, float slope) { diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index 150382c1f8f..88d78df190f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -173,9 +173,10 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) Image *ima= (Image *)node->id; if (ima) { ImageUser *iuser= node->storage; + ImBuf *ibuf; /* make sure ima->type is correct */ - BKE_image_get_ibuf(ima, iuser); + ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if (ima->rr) { RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); @@ -191,6 +192,8 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) } else cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z); + + BKE_image_release_ibuf(ima, ibuf, NULL); } else cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); @@ -312,7 +315,7 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) } /* note: this function is used for multilayer too, to ensure uniform - * handling with BKE_image_get_ibuf() */ + * handling with BKE_image_acquire_ibuf() */ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser) { ImBuf *ibuf; @@ -322,7 +325,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i float *rect; int alloc= FALSE; - ibuf= BKE_image_get_ibuf(ima, iuser); + ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL); if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { return NULL; } @@ -374,12 +377,15 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i } } #endif + + BKE_image_release_ibuf(ima, ibuf, NULL); + return stackbuf; } static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) { - ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage); + ImBuf *ibuf= BKE_image_acquire_ibuf((Image *)node->id, node->storage, NULL); CompBuf *zbuf= NULL; if (ibuf && ibuf->zbuf_float) { @@ -391,6 +397,9 @@ static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) zbuf->rect= ibuf->zbuf_float; } } + + BKE_image_release_ibuf((Image *)node->id, ibuf, NULL); + return zbuf; } @@ -418,13 +427,14 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE RenderData *rd= data; Image *ima= (Image *)node->id; ImageUser *iuser= (ImageUser *)node->storage; + ImBuf *ibuf = NULL; /* first set the right frame number in iuser */ BKE_image_user_frame_calc(iuser, rd->cfra, 0); /* force a load, we assume iuser index will be set OK anyway */ if (ima->type==IMA_TYPE_MULTILAYER) - BKE_image_get_ibuf(ima, iuser); + ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if (ima->type==IMA_TYPE_MULTILAYER && ima->rr) { RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); @@ -505,6 +515,8 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE generate_preview(data, node, stackbuf); } } + + BKE_image_release_ibuf(ima, ibuf, NULL); } } diff --git a/source/blender/nodes/composite/nodes/node_composite_mapRange.c b/source/blender/nodes/composite/nodes/node_composite_mapRange.c new file mode 100644 index 00000000000..f96e133b19f --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_mapRange.c @@ -0,0 +1,58 @@ +/* + * ***** 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) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_mapRange.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** MAP VALUE ******************** */ +static bNodeSocketTemplate cmp_node_map_range_in[] = { + { SOCK_FLOAT, 1, N_("Value"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, N_("From Min"), 0.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + { SOCK_FLOAT, 1, N_("From Max"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + { SOCK_FLOAT, 1, N_("To Min"), 0.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + { SOCK_FLOAT, 1, N_("To Max"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + { -1, 0, "" } +}; +static bNodeSocketTemplate cmp_node_map_range_out[] = { + { SOCK_FLOAT, 0, N_("Value")}, + { -1, 0, "" } +}; + +void register_node_type_cmp_map_range(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, CMP_NODE_MAP_RANGE, "Map Range", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_map_range_in, cmp_node_map_range_out); + node_type_size(&ntype, 120, 60, 150); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_normal.c b/source/blender/nodes/composite/nodes/node_composite_normal.c index 93fd7ca1c1b..d104e8f03e6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normal.c +++ b/source/blender/nodes/composite/nodes/node_composite_normal.c @@ -40,7 +40,7 @@ static bNodeSocketTemplate cmp_node_normal_in[] = { }; static bNodeSocketTemplate cmp_node_normal_out[] = { - { SOCK_VECTOR, 0, N_("Normal")}, + { SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION}, { SOCK_FLOAT, 0, N_("Dot")}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c index 73cf039c6df..41fb0e822ed 100644 --- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c @@ -77,7 +77,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack * ibuf= BKE_image_acquire_ibuf(ima, node->storage, &lock); if (ibuf==NULL) { printf("node_composit_exec_viewer error\n"); - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); return; } @@ -128,7 +128,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack * composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL); - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); generate_preview(data, node, cbuf); free_compbuf(cbuf); diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c index 938f75cf3f5..1c27cc21b06 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c @@ -62,7 +62,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, ibuf = BKE_image_acquire_ibuf(ima, node->storage, &lock); if (ibuf == NULL) { printf("node_composit_exec_viewer error\n"); - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); return; } @@ -112,7 +112,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, free_compbuf(zbuf); } - BKE_image_release_ibuf(ima, lock); + BKE_image_release_ibuf(ima, ibuf, lock); generate_preview(data, node, cbuf); free_compbuf(cbuf); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index abe8e0190c8..d2d0870e2ed 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -75,12 +75,13 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, GPUNod ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, isdata)); if (ret) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && GPU_material_do_color_management(mat)) { GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link); } + BKE_image_release_ibuf(ima, ibuf, NULL); } return ret; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index 9b17f76bd47..49b38434246 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -75,12 +75,13 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, GPUNodeStack ret = GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); if (ret) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && GPU_material_do_color_management(mat)) { GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link); } + BKE_image_release_ibuf(ima, ibuf, NULL); } return ret; diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c index 6d1b3ff6dba..b77c7d07407 100644 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -128,12 +128,13 @@ static int gpu_shader_texture(GPUMaterial *mat, bNode *node, GPUNodeStack *in, G int ret = GPU_stack_link(mat, "texture_image", in, out, texlink); if (ret) { - ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) ==0 && GPU_material_do_color_management(mat)) { GPU_link(mat, "srgb_to_linearrgb", out[1].link, &out[1].link); } + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } return ret; diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c index f3fdaf0bb64..2ef1669a266 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.c +++ b/source/blender/nodes/texture/nodes/node_texture_image.c @@ -46,7 +46,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i ImageUser *iuser= (ImageUser *)node->storage; if ( ima ) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if ( ibuf ) { float xsize, ysize; float xoff, yoff; @@ -77,6 +77,8 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i result = ibuf->rect_float + py*ibuf->x*4 + px*4; copy_v4_v4(out, result); + + BKE_image_release_ibuf(ima, ibuf, NULL); } } } diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index ad97ceb68d4..8d146bedb48 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -59,6 +59,19 @@ static PyMethodDef bpy_reload_meth; static PyObject *imp_reload_orig = NULL; /* 'builtins' is most likely PyEval_GetBuiltins() */ + +/** + * \note to the discerning developer, yes - this is nasty + * monkey-patching our own import into Python's builtin 'imp' module. + * + * However Python's alternative is to use import hooks, + * which are implemented in a way that we can't use our own importer as a + * fall-back (instead we must try and fail - raise an exception evert time). + * Since importing from blenders text-blocks is not the common case + * I prefer to use Pythons import by default and fall-back to + * Blenders - which we can only do by intercepting import calls I'm afraid. + * - Campbell + */ void bpy_import_init(PyObject *builtins) { PyObject *item; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 28f70211a9c..c3126e57b53 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -687,11 +687,12 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o env->ima = tex->ima; if (env->ima && env->ima->ok) { if (env->cube[1] == NULL) { - ImBuf *ibuf_ima = BKE_image_get_ibuf(env->ima, NULL); + ImBuf *ibuf_ima = BKE_image_acquire_ibuf(env->ima, NULL, NULL); if (ibuf_ima) envmap_split_ima(env, ibuf_ima); else env->ok = 0; + BKE_image_release_ibuf(env->ima, ibuf_ima, NULL); } } } diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index db1454fd82f..cd06839b004 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -124,13 +124,16 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul /* hack for icon render */ if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval; - - ibuf= BKE_image_get_ibuf(ima, &tex->iuser); + + ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); ima->flag|= IMA_USED_FOR_RENDER; } - if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) + if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; + } /* setup mapping */ if (tex->imaflag & TEX_IMAROT) { @@ -155,11 +158,17 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul /* pass */ } else { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { - if ((xs+ys) & 1) return retval; + if ((xs+ys) & 1) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + return retval; + } } /* scale around center, (0.5, 0.5) */ if (tex->checkerdist<1.0f) { @@ -173,11 +182,15 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul if (tex->extend == TEX_CLIPCUBE) { if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } else if ( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) { if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } @@ -287,6 +300,9 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul texres->tb*= fx; } + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + BRICONTRGB; return retval; @@ -1056,10 +1072,14 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex if (ima) { /* hack for icon render */ if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval; - ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); } - if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval; + if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + return retval; + } if (ima) { ima->flag |= IMA_USED_FOR_RENDER; @@ -1172,8 +1192,16 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex } } else { - if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval; - if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval; + if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + return retval; + } + if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + return retval; + } fx -= xs; fy -= ys; } @@ -1189,10 +1217,18 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex } if (tex->extend == TEX_CLIPCUBE) { - if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) return retval; + if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + return retval; + } } else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) { - if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval; + if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + return retval; + } } else { if (tex->extend == TEX_EXTEND) { @@ -1413,6 +1449,9 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex texres->tb *= fx; } + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + BRICONTRGB; return retval; @@ -1449,12 +1488,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval; - ibuf= BKE_image_get_ibuf(ima, &tex->iuser); + ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); ima->flag|= IMA_USED_FOR_RENDER; } - if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) + if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; + } /* mipmap test */ image_mipmap_test(tex, ibuf); @@ -1565,11 +1607,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const /* pass */ } else { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { if ((xs + ys) & 1) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } @@ -1605,11 +1651,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const if (tex->extend == TEX_CLIPCUBE) { if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f || texvec[2]<-1.0f || texvec[2]>1.0f) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) { if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) { + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); return retval; } } @@ -1804,6 +1854,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const mul_v3_fl(&texres->tr, 1.0f / texres->ta); } + if (ima) + BKE_image_release_ibuf(ima, ibuf, NULL); + BRICONTRGB; return retval; @@ -1812,7 +1865,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4]) { TexResult texres; - ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); if (UNLIKELY(ibuf == NULL)) { zero_v4(result); @@ -1830,6 +1883,8 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu ibuf->rect-= (ibuf->x*ibuf->y); ima->flag|= IMA_USED_FOR_RENDER; + + BKE_image_release_ibuf(ima, ibuf, NULL); } void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4]) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 23065e5bd84..75d45144ccd 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -64,6 +64,7 @@ #include "BLI_string.h" #include "BLI_path_util.h" #include "BLI_fileops.h" +#include "BLI_threads.h" #include "BLI_rand.h" #include "BLI_callbacks.h" diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index c507d6595e0..e6daa5f9094 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1233,11 +1233,13 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { - ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); /* don't linearize float buffers, assumed to be linear */ if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); + + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } } else { @@ -1264,11 +1266,13 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output); { - ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); /* don't linearize float buffers, assumed to be linear */ if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); + + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } } @@ -1723,11 +1727,12 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) { /* in case we have no proper derivatives, fall back to * computing du/dv it based on image size */ - ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); if (ibuf) { du = 1.f/(float)ibuf->x; dv = 1.f/(float)ibuf->y; } + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } else if (shi->osatex) { /* we have derivatives, can compute proper du/dv */ @@ -1900,12 +1905,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T /* resolve image dimensions */ if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) { - ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); if (ibuf) { dimx = ibuf->x; dimy = ibuf->y; aspect = ((float) dimy) / dimx; } + BKE_image_release_ibuf(tex->ima, ibuf, NULL); } if (found_deriv_map) { @@ -2396,11 +2402,13 @@ void do_material_tex(ShadeInput *shi, Render *re) /* inverse gamma correction */ if (tex->type==TEX_IMAGE) { Image *ima = tex->ima; - ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); /* don't linearize float buffers, assumed to be linear */ if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); + + BKE_image_release_ibuf(ima, ibuf, NULL); } if (mtex->mapto & MAP_COL) { @@ -2928,11 +2936,13 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) /* inverse gamma correction */ if (mtex->tex->type==TEX_IMAGE) { Image *ima = mtex->tex->ima; - ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &mtex->tex->iuser, NULL); /* don't linearize float buffers, assumed to be linear */ if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); + + BKE_image_release_ibuf(ima, ibuf, NULL); } fact= texres.tin*mtex->colfac; @@ -3147,11 +3157,13 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h /* inverse gamma correction */ if (tex->type==TEX_IMAGE) { Image *ima = tex->ima; - ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); /* don't linearize float buffers, assumed to be linear */ if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); + + BKE_image_release_ibuf(ima, ibuf, NULL); } if (mtex->mapto & WOMAP_HORIZ) { @@ -3361,11 +3373,13 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r /* inverse gamma correction */ if (tex->type==TEX_IMAGE) { Image *ima = tex->ima; - ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); /* don't linearize float buffers, assumed to be linear */ if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); + + BKE_image_release_ibuf(ima, ibuf, NULL); } /* lamp colors were premultiplied with this */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 9fe2620747c..3431c3ff5de 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2506,21 +2506,26 @@ static int get_next_bake_face(BakeShade *bs) if (tface && tface->tpage) { Image *ima= tface->tpage; - ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f}; const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f}; if (ibuf==NULL) continue; - if (ibuf->rect==NULL && ibuf->rect_float==NULL) + if (ibuf->rect==NULL && ibuf->rect_float==NULL) { + BKE_image_release_ibuf(ima, ibuf, NULL); continue; + } - if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) + if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) { + BKE_image_release_ibuf(ima, ibuf, NULL); continue; + } if (ima->flag & IMA_USED_FOR_RENDER) { ima->id.flag &= ~LIB_DOIT; + BKE_image_release_ibuf(ima, ibuf, NULL); continue; } @@ -2548,6 +2553,9 @@ static int get_next_bake_face(BakeShade *bs) v++; BLI_unlock_thread(LOCK_CUSTOM1); + + BKE_image_release_ibuf(ima, ibuf, NULL); + return 1; } } @@ -2571,8 +2579,10 @@ static void shade_tface(BakeShade *bs) /* check valid zspan */ if (ima!=bs->ima) { + BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL); + bs->ima= ima; - bs->ibuf= BKE_image_get_ibuf(ima, NULL); + bs->ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); /* note, these calls only free/fill contents of zspan struct, not zspan itself */ zbuf_free_span(bs->zspan); zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop); @@ -2638,7 +2648,9 @@ static void *do_bake_thread(void *bs_v) *bs->do_update= TRUE; } bs->ready= 1; - + + BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL); + return NULL; } @@ -2689,12 +2701,13 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up /* baker uses this flag to detect if image was initialized */ for (ima= G.main->image.first; ima; ima= ima->id.next) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); ima->id.flag |= LIB_DOIT; ima->flag&= ~IMA_USED_FOR_RENDER; if (ibuf) { ibuf->userdata = NULL; /* use for masking if needed */ } + BKE_image_release_ibuf(ima, ibuf, NULL); } BLI_init_threads(&threads, do_bake_thread, re->r.threads); @@ -2747,7 +2760,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up /* filter and refresh images */ for (ima= G.main->image.first; ima; ima= ima->id.next) { if ((ima->id.flag & LIB_DOIT)==0) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); if (ima->flag & IMA_USED_FOR_RENDER) result= BAKE_RESULT_FEEDBACK_LOOP; @@ -2758,6 +2771,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter); ibuf->userflags |= IB_BITMAPDIRTY; + BKE_image_release_ibuf(ima, ibuf, NULL); } } diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 42849a01971..77d6644479a 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -157,10 +157,10 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) /* find the first valid ibuf and use it to initialize the resolution of the data set */ /* need to do this in advance so we know how much memory to allocate */ - ibuf = BKE_image_get_ibuf(ima, &iuser); + ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); while (!ibuf && (iuser.framenr < iuser.frames)) { iuser.framenr++; - ibuf = BKE_image_get_ibuf(ima, &iuser); + ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); } if (!ibuf) return; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); @@ -175,7 +175,8 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) /* get a new ibuf for each frame */ if (z > 0) { iuser.framenr++; - ibuf = BKE_image_get_ibuf(ima, &iuser); + BKE_image_release_ibuf(ima, ibuf, NULL); + ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); if (!ibuf) break; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); } @@ -191,7 +192,9 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) BKE_image_free_anim_ibufs(ima, iuser.framenr); } - + + BKE_image_release_ibuf(ima, ibuf, NULL); + vd->ok = 1; return; } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c53c4dca74c..e35e3edfa33 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -181,6 +181,7 @@ int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const char imt /* poll callback, context checks */ int WM_operator_winactive (struct bContext *C); /* invoke callback, exec + redo popup */ +int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_operator_props_dialog_popup (struct bContext *C, struct wmOperator *op, int width, int height); int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 60e3f7d6164..bd6e752076d 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -711,14 +711,14 @@ static int wm_automatic_draw_method(wmWindow *win) if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) return USER_DRAW_OVERLAP; /* also Intel drivers are slow */ - /* 2.64 BCon3 period, let's try if intel now works... +#if 0 /* 2.64 BCon3 period, let's try if intel now works... */ else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_UNIX, GPU_DRIVER_ANY)) return USER_DRAW_OVERLAP; else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) return USER_DRAW_OVERLAP_FLIP; else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_ANY)) return USER_DRAW_OVERLAP_FLIP; - */ +#endif /* Windows software driver darkens color on each redraw */ else if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE)) return USER_DRAW_OVERLAP_FLIP; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 54e61df4f6a..5cbad42134c 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -340,7 +340,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve int retval; /* UI code doesn't handle return values - it just always returns break. - to make the DBL_CLICK conversion work, we just don't send this to UI */ + * to make the DBL_CLICK conversion work, we just don't send this to UI */ if (event->val == KM_DBL_CLICK) return WM_HANDLER_CONTINUE; @@ -1288,9 +1288,9 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi) /* the matching rules */ if (kmitype == KM_TEXTINPUT) - if (winevent->val == KM_PRESS) { // prevent double clicks + if (winevent->val == KM_PRESS) { /* prevent double clicks */ /* NOT using ISTEXTINPUT anymore because (at least on Windows) some key codes above 255 - could have printable ascii keys - BUG [#30479] */ + * could have printable ascii keys - BUG [#30479] */ if (ISKEYBOARD(winevent->type) && (winevent->ascii || winevent->utf8_buf[0])) return 1; } @@ -1550,8 +1550,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa if (handler->op->reports->list.first) { /* FIXME, temp setting window, this is really bad! - * only have because lib linking errors need to be seen by users :( - * it can be removed without breaking anything but then no linking errors - campbell */ + * only have because lib linking errors need to be seen by users :( + * it can be removed without breaking anything but then no linking errors - campbell */ wmWindow *win_prev = CTX_wm_window(C); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 126d497e08e..896a24f3fba 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1201,8 +1201,11 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) return OPERATOR_RUNNING_MODAL; } -/* operator menu needs undo, for redo callback */ -int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +/** + * For use by #WM_operator_props_popup_call, #WM_operator_props_popup only. + * + * \note operator menu needs undo flag enabled , for redo callback */ +static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_call) { if ((op->type->flag & OPTYPE_REGISTER) == 0) { @@ -1210,15 +1213,34 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) "Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } - + ED_undo_push_op(C, op); + wm_operator_register(C, op); uiPupBlock(C, wm_block_create_redo, op); + if (do_call) { + WM_operator_repeat(C, op); + } + return OPERATOR_RUNNING_MODAL; } +/* Same as WM_operator_props_popup but call the operator first, + * This way - the button values correspond to the result of the operator. + * Without this, first access to a button will make the result jump, + * see [#32452] */ +int WM_operator_props_popup_call(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + return wm_operator_props_popup_ex(C, op, TRUE); +} + +int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + return wm_operator_props_popup_ex(C, op, FALSE); +} + int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height) { wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup"); diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 96bbedfee1b..f4c2c13dcac 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -61,6 +61,7 @@ #include "BKE_blender.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -74,6 +75,9 @@ #include "WM_api.h" /* only for WM_main_playanim */ +struct PlayState; +static void playanim_window_zoom(const struct PlayState *ps, const float zoom_offset); + typedef struct PlayState { /* playback state */ @@ -84,7 +88,6 @@ typedef struct PlayState { short pingpong; short noskip; short sstep; - short pause; short wait2; short stopped; short go; @@ -132,6 +135,7 @@ typedef enum eWS_Qual { WS_QUAL_ALT = (WS_QUAL_LALT | WS_QUAL_RALT), WS_QUAL_LCTRL = (1 << 4), WS_QUAL_RCTRL = (1 << 5), + WS_QUAL_CTRL = (WS_QUAL_LCTRL | WS_QUAL_RCTRL), WS_QUAL_LMOUSE = (1 << 16), WS_QUAL_MMOUSE = (1 << 17), WS_QUAL_RMOUSE = (1 << 18), @@ -179,12 +183,12 @@ static void playanim_event_qual_update(void) /* Alt */ GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyLeftAlt, &val); - if (val) g_WS.qual |= WS_QUAL_LCTRL; - else g_WS.qual &= ~WS_QUAL_LCTRL; + if (val) g_WS.qual |= WS_QUAL_LALT; + else g_WS.qual &= ~WS_QUAL_LALT; GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyRightAlt, &val); - if (val) g_WS.qual |= WS_QUAL_RCTRL; - else g_WS.qual &= ~WS_QUAL_RCTRL; + if (val) g_WS.qual |= WS_QUAL_RALT; + else g_WS.qual &= ~WS_QUAL_RALT; /* LMB */ GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskLeft, &val); @@ -234,7 +238,7 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon { if (ibuf == NULL) { - printf("no ibuf !\n"); + printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : ""); return; } if (ibuf->rect == NULL && ibuf->rect_float) { @@ -432,6 +436,11 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) ps->stopped = FALSE; } + if (ps->wait2) { + pupdate_time(); + ptottime = 0; + } + switch (type) { case GHOST_kEventKeyDown: case GHOST_kEventKeyUp: @@ -539,28 +548,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) } } break; - case GHOST_kKeyEqual: - if (val) { - if (g_WS.qual & WS_QUAL_SHIFT) { - ps->pause++; - printf("pause:%d\n", ps->pause); - } - else { - swaptime /= 1.1; - } - } - break; - case GHOST_kKeyMinus: - if (val) { - if (g_WS.qual & WS_QUAL_SHIFT) { - ps->pause--; - printf("pause:%d\n", ps->pause); - } - else { - swaptime *= 1.1; - } - } - break; case GHOST_kKeyNumpad0: if (val) { if (ps->once) { @@ -588,29 +575,28 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) } } break; + case GHOST_kKeyEqual: case GHOST_kKeyNumpadPlus: + { if (val == 0) break; - zoomx += 2.0f; - zoomy += 2.0f; - /* no break??? - is this intentional? - campbell XXX25 */ + if (g_WS.qual & WS_QUAL_CTRL) { + playanim_window_zoom(ps, 1.0f); + } + else { + swaptime /= 1.1; + } + break; + } + case GHOST_kKeyMinus: case GHOST_kKeyNumpadMinus: { - int sizex, sizey; - /* int ofsx, ofsy; */ /* UNUSED */ - if (val == 0) break; - if (zoomx > 1.0f) zoomx -= 1.0f; - if (zoomy > 1.0f) zoomy -= 1.0f; - // playanim_window_get_position(&ofsx, &ofsy); - playanim_window_get_size(&sizex, &sizey); - /* ofsx += sizex / 2; */ /* UNUSED */ - /* ofsy += sizey / 2; */ /* UNUSED */ - sizex = zoomx * ps->ibufx; - sizey = zoomy * ps->ibufy; - /* ofsx -= sizex / 2; */ /* UNUSED */ - /* ofsy -= sizey / 2; */ /* UNUSED */ - // window_set_position(g_WS.ghost_window,sizex,sizey); - GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey); + if (g_WS.qual & WS_QUAL_CTRL) { + playanim_window_zoom(ps, -1.0f); + } + else { + swaptime *= 1.1; + } break; } case GHOST_kKeyEsc: @@ -716,6 +702,25 @@ static void playanim_window_open(const char *title, int posx, int posy, int size FALSE /* no stereo */, FALSE); } +static void playanim_window_zoom(const PlayState *ps, const float zoom_offset) +{ + int sizex, sizey; + /* int ofsx, ofsy; */ /* UNUSED */ + + if (zoomx + zoom_offset > 0.0f) zoomx += zoom_offset; + if (zoomy + zoom_offset > 0.0f) zoomy += zoom_offset; + + // playanim_window_get_position(&ofsx, &ofsy); + playanim_window_get_size(&sizex, &sizey); + /* ofsx += sizex / 2; */ /* UNUSED */ + /* ofsy += sizey / 2; */ /* UNUSED */ + sizex = zoomx * ps->ibufx; + sizey = zoomy * ps->ibufy; + /* ofsx -= sizex / 2; */ /* UNUSED */ + /* ofsy -= sizey / 2; */ /* UNUSED */ + // window_set_position(g_WS.ghost_window,sizex,sizey); + GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey); +} void WM_main_playanim(int argc, const char **argv) { @@ -736,13 +741,12 @@ void WM_main_playanim(int argc, const char **argv) /* ps.doubleb = TRUE;*/ /* UNUSED */ ps.go = TRUE; ps.direction = TRUE; - ps.next = TRUE; + ps.next = 1; ps.once = FALSE; ps.turbo = FALSE; ps.pingpong = FALSE; ps.noskip = FALSE; ps.sstep = FALSE; - ps.pause = FALSE; ps.wait2 = FALSE; ps.stopped = FALSE; ps.picture = NULL; @@ -939,6 +943,7 @@ void WM_main_playanim(int argc, const char **argv) if (ptottime > 0.0) ptottime = 0.0; while (ps.picture) { + int hasevent; #ifndef USE_IMB_CACHE if (ibuf != NULL && ibuf->ftype == 0) IMB_freeImBuf(ibuf); #endif @@ -992,19 +997,22 @@ void WM_main_playanim(int argc, const char **argv) ps.next = ps.direction; - { - int hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0); + while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) { if (hasevent) { GHOST_DispatchEvents(g_WS.ghost_system); } - } - - /* XXX25 - we should not have to do this, but it makes scrubbing functional! */ - if (g_WS.qual & WS_QUAL_LMOUSE) { - ps.next = 0; - } - else { - ps.sstep = 0; + if (ps.wait2) { + if (hasevent) { + if (ibuf) { + while (pupdate_time()) PIL_sleep_ms(1); + ptottime -= swaptime; + playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); + } + } + } + if (!ps.go) { + break; + } } ps.wait2 = ps.sstep; @@ -1082,6 +1090,7 @@ void WM_main_playanim(int argc, const char **argv) /* we still miss freeing a lot!, * but many areas could skip initialization too for anim play */ IMB_exit(); + BKE_images_exit(); BLF_exit(); #endif GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index fbb3466032d..09f7e1692d9 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -337,7 +337,7 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) int scr_w, scr_h, posy; /* force setting multisamples only once, it requires restart - and you cannot - mix it, either all windows have it, or none (tested in OSX opengl) */ + * mix it, either all windows have it, or none (tested in OSX opengl) */ if (multisamples == -1) multisamples = U.ogl_multisamples; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index ca0e9659a22..4d3d6ef89d9 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -285,9 +285,9 @@ enum { /* for event checks */ /* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */ - /* UNUSED - see wm_eventmatch - BUG [#30479] -#define ISTEXTINPUT(event) (event >= ' ' && event <= 255) - */ + /* UNUSED - see wm_eventmatch - BUG [#30479] */ +// #define ISTEXTINPUT(event) (event >= ' ' && event <= 255) + /* test whether the event is a key on the keyboard */ #define ISKEYBOARD(event) (event >= ' ' && event <= 320) diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 11e790451cd..85bb07d6e83 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -60,7 +60,7 @@ elseif(APPLE) add_executable(blenderplayer ${EXETYPE} bad_level_call_stubs/stubs.c) # setup Info.plist execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BLENDER_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) - set(PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blenderplayer.app) + set(PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blenderplayer.app) set(PLAYER_SOURCEINFO ${PLAYER_SOURCEDIR}/Contents/Info.plist) set_target_properties(blenderplayer PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PLAYER_SOURCEINFO} diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 5da08cf67da..8e86ecbff93 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -619,18 +619,7 @@ elseif(WIN32) install( # x86 builds can run on x64 Windows, so this is required at all times FILES ${LIBDIR}/thumbhandler/lib/BlendThumb64.dll DESTINATION ${TARGETDIR} - ) - - if(WITH_OPENIMAGEIO) - if(NOT MINGW) - set(OIIOBIN ${LIBDIR}/openimageio) - install( - FILES - ${OIIOBIN}/bin/OpenImageIO.dll - DESTINATION ${TARGETDIR} - ) - endif() - endif() + ) if(WITH_OPENCOLORIO) set(OCIOBIN ${LIBDIR}/opencolorio/bin) @@ -668,7 +657,7 @@ elseif(APPLE) ) endmacro() - set(OSX_APP_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app) + set(OSX_APP_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blender.app) # setup Info.plist execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BLENDER_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -727,7 +716,7 @@ elseif(APPLE) # install blenderplayer bundle - copy of blender.app above. re-using macros et al # note we are using OSX Bundle as base and copying Blender dummy bundle on top of it if(WITH_GAMEENGINE AND WITH_PLAYER) - set(OSX_APP_PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blenderplayer.app) + set(OSX_APP_PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blenderplayer.app) set(PLAYER_SOURCEINFO ${OSX_APP_PLAYER_SOURCEDIR}/Contents/Info.plist) set(PLAYER_TARGETDIR_VER ${TARGETDIR}/blenderplayer.app/Contents/MacOS/${BLENDER_VERSION}) diff --git a/source/creator/creator.c b/source/creator/creator.c index 99f56d0c0ec..26162051147 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -1079,7 +1079,9 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) "\n\t\t-p \tOpen with lower left corner at , " "\n\t\t-m\t\tRead from disk (Don't buffer)" "\n\t\t-f \t\tSpecify FPS to start with" - "\n\t\t-j \tSet frame step to "; + "\n\t\t-j \tSet frame step to " + "\n\t\t-s \tPlay from " + "\n\t\t-j \tPlay until "; static char game_doc[] = "Game Engine specific options" "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames" @@ -1272,6 +1274,7 @@ int main(int argc, const char **argv) initglobals(); /* blender.c */ IMB_init(); + BKE_images_init(); #ifdef WITH_FFMPEG IMB_ffmpeg_init(); diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index bfd44dc90fc..b9c70910283 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -11,7 +11,7 @@ incs += ' #source/gameengine/BlenderRoutines #source/blender/imbuf' incs += ' #intern/moto/include #source/gameengine/Ketsji #source/gameengine/Ketsji/KXNetwork' incs += ' #source/blender/blenlib #source/blender/blenkernel #source/blender' incs += ' #source/blender/editors/include #source/blender/makesdna #source/gameengine/Rasterizer' -incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #source/gameengine/GameLogic' +incs += ' #source/gameengine/GameLogic' incs += ' #source/gameengine/Expressions #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' #source/gameengine/Physics/common #source/gameengine/Physics/Bullet' incs += ' #source/gameengine/Physics/Dummy' diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 83b7c8c8771..37e26e88750 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -526,7 +526,7 @@ typedef struct KX_PYATTRIBUTE_DEF { /*------------------------------ * PyObjectPlus -------------------------------*/ + *------------------------------ */ typedef PyTypeObject *PyParentObject; /* Define the PyParent Object */ #else // WITH_PYTHON diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index d5e1f081d21..6a1f47c51af 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -31,7 +31,6 @@ incs = ['.', '#source/blender', '#source/blender/include', '#source/blender/makesdna', - '#source/gameengine/BlenderRoutines', '#source/gameengine/Rasterizer', '#source/gameengine/GameLogic', '#source/gameengine/Expressions', diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 3e8755c41ce..4451c78b99c 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -60,6 +60,7 @@ extern "C" #include "BKE_blender.h" #include "BKE_global.h" #include "BKE_icons.h" +#include "BKE_image.h" #include "BKE_node.h" #include "BKE_report.h" #include "BKE_library.h" @@ -446,6 +447,7 @@ int main(int argc, char** argv) G.main = NULL; IMB_init(); + BKE_images_init(); // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c) BLF_init(11, U.dpi); @@ -1067,6 +1069,7 @@ int main(int argc, char** argv) #endif IMB_exit(); + BKE_images_exit(); free_nodesystem(); SYS_DeleteSystem(syshandle); diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 9fb0f053ed8..fb046d0fdf8 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -26,7 +26,6 @@ incs = ['.', '#source/blender/include', '#source/blender/makesdna', '#source/blender/makesrna', - '#source/gameengine/BlenderRoutines', '#source/gameengine/Rasterizer', '#source/gameengine/GameLogic', '#source/gameengine/Expressions', diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 26523df8db3..66423ed820e 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -109,7 +109,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) return mOk; } - ibuf= BKE_image_get_ibuf(img, NULL); + ibuf= BKE_image_acquire_ibuf(img, NULL, NULL); if (ibuf==NULL) { img->ok = 0; @@ -128,6 +128,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) if (mTexture != 0) { glBindTexture(GL_TEXTURE_2D, mTexture ); Validate(); + BKE_image_release_ibuf(img, ibuf, NULL); return mOk; } @@ -140,6 +141,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) mTexture = mapLook->second.gl_texture; glBindTexture(GL_TEXTURE_2D, mTexture); mOk = IsValid(); + BKE_image_release_ibuf(img, ibuf, NULL); return mOk; } } @@ -166,6 +168,9 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) glDisable(GL_TEXTURE_2D); ActivateUnit(0); Validate(); + + BKE_image_release_ibuf(img, ibuf, NULL); + return mOk; } @@ -251,7 +256,7 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) return mOk; } - ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL); + ImBuf *ibuf= BKE_image_acquire_ibuf(cubemap->ima, NULL, NULL); if (ibuf==0) { cubemap->ima->ok = 0; @@ -274,6 +279,7 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) mTexture = mapLook->second.gl_texture; glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture); mOk = IsValid(); + BKE_image_release_ibuf(cubemap->ima, ibuf, NULL); return mOk; } } @@ -307,6 +313,7 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) my_free_envmapdata(cubemap); mOk = false; + BKE_image_release_ibuf(cubemap->ima, ibuf, NULL); return mOk; } @@ -341,6 +348,9 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) ActivateUnit(0); mOk = IsValid(); + + BKE_image_release_ibuf(cubemap->ima, ibuf, NULL); + return mOk; } @@ -646,9 +656,11 @@ int BL_Texture::GetPow2(int n) void BL_Texture::SplitEnvMap(EnvMap *map) { if (!map || !map->ima || (map->ima && !map->ima->ok)) return; - ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL); - if (ibuf) + ImBuf *ibuf= BKE_image_acquire_ibuf(map->ima, NULL, NULL); + if (ibuf) { my_envmap_split_ima(map, ibuf); + BKE_image_release_ibuf(map->ima, ibuf, NULL); + } } unsigned int BL_Texture::mDisableState = 0; diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index fca407f6398..9f530f80e37 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -1,25 +1,27 @@ /* - * ----------------------------------------------------------------------------- + * ***** BEGIN GPL LICENSE BLOCK ***** * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. + * 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 Lesser General Public License for more details. + * 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 Lesser General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA, or go to - * http://www.gnu.org/copyleft/lesser.txt. + * 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): Dalai Felinto * * This code is originally inspired on some of the ideas and codes from Paul Bourke. - * Developed as part of a Research and Development project for SAT - La Société des arts technologiques. - * ----------------------------------------------------------------------------- + * Developed as part of a Research and Development project for + * SAT - La Société des arts technologiques. + * + * ***** END GPL LICENSE BLOCK ***** */ /** \file gameengine/Ketsji/KX_Dome.cpp diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 17eec3a5fcb..3bc90bf6c35 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -1,26 +1,28 @@ /* ------------------------------------------------------------------------------ - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. - -Contributor(s): Dalai Felinto - -This source uses some of the ideas and code from Paul Bourke. -Developed as part of a Research and Development project for SAT - La Société des arts technologiques. ------------------------------------------------------------------------------ -*/ + * ***** 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): Dalai Felinto + * + * This source uses some of the ideas and code from Paul Bourke. + * Developed as part of a Research and Development project for + * SAT - La Société des arts technologiques. + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file KX_Dome.h * \ingroup ketsji diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 0188a7e15b8..dbbf6bd8c2a 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -292,7 +292,7 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds) MT_Matrix4x4 transform; - if (!PyArg_ParseTuple(args,"iO|iii:transform_uv", &matindex, &pymat, &uvindex, &uvindex_from) || + if (!PyArg_ParseTuple(args,"iO|iii:transformUV", &matindex, &pymat, &uvindex, &uvindex_from) || !PyMatTo(pymat, transform)) { return NULL; @@ -300,12 +300,12 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds) if (uvindex < -1 || uvindex > 1) { PyErr_Format(PyExc_ValueError, - "mesh.transform_uv(...): invalid uv_index %d", uvindex); + "mesh.transformUV(...): invalid uv_index %d", uvindex); return NULL; } if (uvindex_from < -1 || uvindex_from > 1 || uvindex == -1) { PyErr_Format(PyExc_ValueError, - "mesh.transform_uv(...): invalid uv_index_from %d", uvindex); + "mesh.transformUV(...): invalid uv_index_from %d", uvindex); return NULL; } if (uvindex_from == uvindex) { @@ -365,7 +365,7 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds) if (ok == false) { PyErr_Format(PyExc_ValueError, - "mesh.transform_uv(...): invalid material index %d", matindex); + "mesh.transformUV(...): invalid material index %d", matindex); return NULL; } diff --git a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp index 99d9fc7f9ee..8798f42fa07 100644 --- a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp +++ b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp @@ -1,6 +1,4 @@ /* - * Simulation for obstacle avoidance behavior - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -22,6 +20,12 @@ * ***** END GPL LICENSE BLOCK ***** */ +/** \file gameengine/Ketsji/KX_ObstacleSimulation.cpp + * \ingroup ketsji + * + * Simulation for obstacle avoidance behavior + */ + #include "KX_ObstacleSimulation.h" #include "KX_NavMeshObject.h" #include "KX_PythonInit.h" diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index 5f3af7360ff..63b28a90412 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -8,7 +8,7 @@ defs = [ 'GLEW_STATIC' ] incs = '. #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines ' incs += ' #intern/container #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel' -incs += ' #intern/guardedalloc #source/blender/blenlib #source/gameengine/BlenderRoutines' +incs += ' #intern/guardedalloc #source/blender/blenlib' if env['WITH_BF_CXX_GUARDEDALLOC']: defs.append('WITH_CXX_GUARDEDALLOC') diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index 6b57db1a467..72a04064834 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -152,8 +152,8 @@ struct SG_Callbacks }; /** -base object that can be part of the scenegraph. -*/ + * base object that can be part of the scenegraph. + */ class SG_IObject : public SG_QList { private : diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h index e19aadc49d2..28eebe07789 100644 --- a/source/gameengine/VideoTexture/BlendType.h +++ b/source/gameengine/VideoTexture/BlendType.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2006 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2006 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file BlendType.h * \ingroup bgevideotex */ - + #ifndef __BLENDTYPE_H__ #define __BLENDTYPE_H__ diff --git a/source/gameengine/VideoTexture/Common.h b/source/gameengine/VideoTexture/Common.h index e6e0ffa1ebc..90f7e66452a 100644 --- a/source/gameengine/VideoTexture/Common.h +++ b/source/gameengine/VideoTexture/Common.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2006 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2006 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file VideoTexture/Common.h * \ingroup bgevideotex */ - + #if defined WIN32 #define WINDOWS_LEAN_AND_MEAN #endif diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index 8609cd73875..8b8918d8141 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2006 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2006 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/Exception.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h index bc08742de8d..e0c1fdd568d 100644 --- a/source/gameengine/VideoTexture/Exception.h +++ b/source/gameengine/VideoTexture/Exception.h @@ -1,30 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2006 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ - + * ***** 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. + * + * Copyright (c) 2006 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file Exception.h * \ingroup bgevideotex */ - + #ifndef __EXCEPTION_H__ #define __EXCEPTION_H__ diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp index 6ec5e237ac2..a232bcc1201 100644 --- a/source/gameengine/VideoTexture/FilterBase.cpp +++ b/source/gameengine/VideoTexture/FilterBase.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/FilterBase.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h index 98bc495375a..f8fe2c772f0 100644 --- a/source/gameengine/VideoTexture/FilterBase.h +++ b/source/gameengine/VideoTexture/FilterBase.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file FilterBase.h * \ingroup bgevideotex */ - + #ifndef __FILTERBASE_H__ #define __FILTERBASE_H__ diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp index 8559e8f87f4..551694bf8c0 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/FilterBlueScreen.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.h b/source/gameengine/VideoTexture/FilterBlueScreen.h index 28ab16d966e..5a90590a39d 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.h +++ b/source/gameengine/VideoTexture/FilterBlueScreen.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file FilterBlueScreen.h * \ingroup bgevideotex */ - + #ifndef __FILTERBLUESCREEN_H__ #define __FILTERBLUESCREEN_H__ diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index 35a6414f383..75803e46516 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/FilterColor.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/FilterColor.h b/source/gameengine/VideoTexture/FilterColor.h index cd61900bbda..350f7270874 100644 --- a/source/gameengine/VideoTexture/FilterColor.h +++ b/source/gameengine/VideoTexture/FilterColor.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file FilterColor.h * \ingroup bgevideotex */ - + #ifndef __FILTERCOLOR_H__ #define __FILTERCOLOR_H__ diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index 03c500a7e14..8499934d61b 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/FilterNormal.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/FilterNormal.h b/source/gameengine/VideoTexture/FilterNormal.h index 19664e8b5f2..b21afb3ec26 100644 --- a/source/gameengine/VideoTexture/FilterNormal.h +++ b/source/gameengine/VideoTexture/FilterNormal.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file FilterNormal.h * \ingroup bgevideotex */ - + #ifndef __FILTERNORMAL_H__ #define __FILTERNORMAL_H__ diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp index e5fe4711cff..1fac87f2b04 100644 --- a/source/gameengine/VideoTexture/FilterSource.cpp +++ b/source/gameengine/VideoTexture/FilterSource.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/FilterSource.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index cb9e22a133d..f1d2615ee32 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file FilterSource.h * \ingroup bgevideotex */ - + #ifndef __FILTERSOURCE_H__ #define __FILTERSOURCE_H__ diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index de54d8e8940..3b6dec21e52 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/ImageBase.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h index a9f25f61406..3bb9c8cb090 100644 --- a/source/gameengine/VideoTexture/ImageBase.h +++ b/source/gameengine/VideoTexture/ImageBase.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file ImageBase.h * \ingroup bgevideotex */ - + #ifndef __IMAGEBASE_H__ #define __IMAGEBASE_H__ diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index eec0bccbe56..1593a08bb4b 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/ImageBuff.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/ImageBuff.h b/source/gameengine/VideoTexture/ImageBuff.h index b2bdbc17dc9..19299506747 100644 --- a/source/gameengine/VideoTexture/ImageBuff.h +++ b/source/gameengine/VideoTexture/ImageBuff.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file ImageBuff.h * \ingroup bgevideotex */ - + #ifndef __IMAGEBUFF_H__ #define __IMAGEBUFF_H__ diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index f09454a517b..27c4fed6fe6 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/ImageMix.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h index 2746635c611..712efde7dd4 100644 --- a/source/gameengine/VideoTexture/ImageMix.h +++ b/source/gameengine/VideoTexture/ImageMix.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file ImageMix.h * \ingroup bgevideotex */ - + #ifndef __IMAGEMIX_H__ #define __IMAGEMIX_H__ diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 2cc2cfb6bfc..b8dd4ad4552 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/ImageRender.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h index df6337e1c24..27882a9d117 100644 --- a/source/gameengine/VideoTexture/ImageRender.h +++ b/source/gameengine/VideoTexture/ImageRender.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file ImageRender.h * \ingroup bgevideotex */ - + #ifndef __IMAGERENDER_H__ #define __IMAGERENDER_H__ diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index af44e394fce..b221cb96624 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/ImageViewport.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/ImageViewport.h b/source/gameengine/VideoTexture/ImageViewport.h index 198655c6ebf..2c2b2a26ec2 100644 --- a/source/gameengine/VideoTexture/ImageViewport.h +++ b/source/gameengine/VideoTexture/ImageViewport.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file ImageViewport.h * \ingroup bgevideotex */ - + #ifndef __IMAGEVIEWPORT_H__ #define __IMAGEVIEWPORT_H__ diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp index 9fe98544961..96ac1cc5b6b 100644 --- a/source/gameengine/VideoTexture/PyTypeList.cpp +++ b/source/gameengine/VideoTexture/PyTypeList.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/PyTypeList.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/PyTypeList.h b/source/gameengine/VideoTexture/PyTypeList.h index 4872b3c3d5c..b36f11ed75a 100644 --- a/source/gameengine/VideoTexture/PyTypeList.h +++ b/source/gameengine/VideoTexture/PyTypeList.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of blendTex library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of blendTex library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file PyTypeList.h * \ingroup bgevideotex */ - + #ifndef __PYTYPELIST_H__ #define __PYTYPELIST_H__ diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index f58d17f949c..98d36d19ddf 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/Texture.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h index cc265725b29..157eea56c09 100644 --- a/source/gameengine/VideoTexture/Texture.h +++ b/source/gameengine/VideoTexture/Texture.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2006 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2006 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file VideoTexture/Texture.h * \ingroup bgevideotex */ - + #ifndef __TEXTURE_H__ #define __TEXTURE_H__ diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp index 1eb2e830d37..f723001fa5a 100644 --- a/source/gameengine/VideoTexture/VideoBase.cpp +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/VideoBase.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h index 4cf913d755d..9880165c198 100644 --- a/source/gameengine/VideoTexture/VideoBase.h +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file VideoBase.h * \ingroup bgevideotex */ - + #ifndef __VIDEOBASE_H__ #define __VIDEOBASE_H__ diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 3f42d5c4fed..937705c963e 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/VideoFFmpeg.cpp * \ingroup bgevideotex diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index d5b575851ee..92043bb1f74 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -1,29 +1,33 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2007 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2007 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file VideoFFmpeg.h * \ingroup bgevideotex */ - + #ifndef __VIDEOFFMPEG_H__ #define __VIDEOFFMPEG_H__ diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index dd9d83c043f..72415026bb9 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -1,24 +1,28 @@ /* ------------------------------------------------------------------------------ -This source file is part of VideoTexture library - -Copyright (c) 2006 The Zdeno Ash Miklas - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 2 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place - Suite 330, Boston, MA 02111-1307, USA, or go to -http://www.gnu.org/copyleft/lesser.txt. ------------------------------------------------------------------------------ -*/ + * ***** 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. + * + * Copyright (c) 2006 The Zdeno Ash Miklas + * + * This source file is part of VideoTexture library + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file gameengine/VideoTexture/blendVideoTex.cpp * \ingroup bgevideotex