diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-12 06:02:53 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-12 06:02:53 +0400 |
commit | 94ae0232b0337ab70cecaef03cd845887cd36eaa (patch) | |
tree | caea2819c7fe0400fb91c9bdf0e99a9e0fd50cf6 | |
parent | 9a109c22ae1ef8a5c75932d661610b23ec685bd7 (diff) | |
parent | f68e9db583489d541d535791536ea20bc1ae1d76 (diff) |
Merged changes in the trunk up to revision 53729.
Conflicts resolved:
release/datafiles/startup.blend
source/blender/blenloader/intern/readfile.c
237 files changed, 5396 insertions, 2404 deletions
diff --git a/SConstruct b/SConstruct index a16805bbfaf..171ebc8ddef 100644 --- a/SConstruct +++ b/SConstruct @@ -276,6 +276,11 @@ if 'blenderlite' in B.targets: if k not in B.arguments: env[k] = v +if 'cudakernels' in B.targets: + env['WITH_BF_CYCLES'] = True + env['WITH_BF_CYCLES_CUDA_BINARIES'] = True + env['WITH_BF_PYTHON'] = False + # Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX if env['OURPLATFORM']=='darwin': print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --" @@ -652,6 +657,7 @@ datafileslist = [] datafilestargetlist = [] dottargetlist = [] scriptinstall = [] +cubininstall = [] if env['OURPLATFORM']!='darwin': dotblenderinstall = [] @@ -745,29 +751,30 @@ if env['OURPLATFORM']!='darwin': source=['intern/cycles/doc/license/'+s for s in source] scriptinstall.append(env.Install(dir=dir,source=source)) - # cuda binaries - if env['WITH_BF_CYCLES_CUDA_BINARIES']: - dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib') - for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']: - kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel') - cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch) - scriptinstall.append(env.Install(dir=dir,source=cubin_file)) + if env['WITH_BF_CYCLES']: + # cuda binaries + if env['WITH_BF_CYCLES_CUDA_BINARIES']: + dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib') + for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']: + kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel') + cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch) + cubininstall.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 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') + 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)) + 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)) + 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') @@ -862,9 +869,9 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist) if env['OURPLATFORM']=='darwin': allinstall = [blenderinstall, textinstall] elif env['OURPLATFORM']=='linux': - allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall] + allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall, cubininstall] else: - allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall] + allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, cubininstall] if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'): dllsources = [] @@ -994,6 +1001,20 @@ buildslave_alias = env.Alias('buildslave', buildslave_cmd) Depends(buildslave_cmd, allinstall) +cudakernels_action = env.Action(btools.cudakernels, btools.cudakernels_print) +cudakernels_cmd = env.Command('cudakernels_exec', None, cudakernels_action) +cudakernels_alias = env.Alias('cudakernels', cudakernels_cmd) + +cudakernel_dir = os.path.join(os.path.abspath(os.path.normpath(B.root_build_dir)), 'intern/cycles/kernel') +cuda_kernels = [] + +for x in env['BF_CYCLES_CUDA_BINARIES_ARCH']: + cubin = os.path.join(cudakernel_dir, 'kernel_' + x + '.cubin') + cuda_kernels.append(cubin) + +Depends(cudakernels_cmd, cuda_kernels) +Depends(cudakernels_cmd, cubininstall) + Default(B.program_list) if not env['WITHOUT_BF_INSTALL']: diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py new file mode 100644 index 00000000000..e72218e6615 --- /dev/null +++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py @@ -0,0 +1,5 @@ +BF_BUILDDIR = '../blender-build/linux-glibc211-i686' +BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' +BF_NUMJOBS = 1 + +BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py new file mode 100644 index 00000000000..10738a11eaa --- /dev/null +++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py @@ -0,0 +1,5 @@ +BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' +BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' +BF_NUMJOBS = 1 + +BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index 149a01433a6..540416ee1fb 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -1,6 +1,7 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686' BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 +WITHOUT_BF_OVERWRITE_INSTALL = True # Python configuration BF_PYTHON_VERSION = '3.3' @@ -109,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a' # Cycles WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] +WITH_BF_CYCLES_CUDA_BINARIES = False WITH_BF_OIIO = True WITH_BF_STATICOIIO = True 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 0fae7f0cdb3..c0ba8060712 100644 --- a/build_files/buildbot/config/user-config-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py @@ -1,6 +1,7 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 +WITHOUT_BF_OVERWRITE_INSTALL = True # Python configuration BF_PYTHON_VERSION = '3.3' @@ -109,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a' # Cycles WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] +WITH_BF_CYCLES_CUDA_BINARIES = False WITH_BF_OIIO = True WITH_BF_STATICOIIO = True diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py deleted file mode 100644 index 46f3ccb3df7..00000000000 --- a/build_files/buildbot/config/user-config-glibc27-i686.py +++ /dev/null @@ -1,149 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-i686' -BF_INSTALLDIR = '../blender-install/linux-glibc27-i686' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = True -BF_OPENCOLLADA = '/opt/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' -BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib32' -BF_PCRE_LIB = '' -BF_EXPAT_LIB = '' - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = True -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = True -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = True - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Blender player (would be enabled in it's own config) -WITH_BF_PLAYER = False - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32' - -# FFT -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True - -# JACK -WITH_BF_JACK = False - -# Cycles -WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] - -WITH_BF_OIIO = True -WITH_BF_STATICOIIO = True -BF_OIIO = '/opt/oiio' -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 -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# Ocean Simulation -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] -BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py deleted file mode 100644 index 23ddcf7a5b9..00000000000 --- a/build_files/buildbot/config/user-config-glibc27-x86_64.py +++ /dev/null @@ -1,149 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64' -BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = True -BF_OPENCOLLADA = '/opt/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' -BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib64' -BF_PCRE_LIB = '' -BF_EXPAT_LIB = '' - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = True -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = True -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = True - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Blender player (would be enabled in it's own config) -WITH_BF_PLAYER = False - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64' - -# FFT -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True - -# JACK -WITH_BF_JACK = False - -# Cycles -WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] - -WITH_BF_OIIO = True -WITH_BF_STATICOIIO = True -BF_OIIO = '/opt/oiio' -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 -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# Ocean Simulation -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] -BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py index 37fe511fac8..a99337f03e6 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py @@ -1,6 +1,6 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686' BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 # Python configuration BF_PYTHON_VERSION = '3.3' diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py index 8f51c5ad8be..c17cff2893d 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py @@ -1,6 +1,6 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 # Python configuration BF_PYTHON_VERSION = '3.3' diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py deleted file mode 100644 index 300af2295f0..00000000000 --- a/build_files/buildbot/config/user-config-player-glibc27-i686.py +++ /dev/null @@ -1,114 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-i686' -BF_INSTALLDIR = '../blender-install/linux-glibc27-i686' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = False - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = False -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = False -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = False - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Do not build blender when building blenderplayer -WITH_BF_NOBLENDER = True -WITH_BF_PLAYER = True - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32' - -# Color management -WITH_BF_OCIO = True -WITH_BF_STATICOCIO = True -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# JACK -WITH_BF_JACK = False - -# Motion Tracking -WITH_BF_LIBMV = False - -# Ocean Simulation -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py deleted file mode 100644 index 722c3a00a66..00000000000 --- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py +++ /dev/null @@ -1,114 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64' -BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = False - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = False -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = False -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = False - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Do not build blender when building blenderplayer -WITH_BF_NOBLENDER = True -WITH_BF_PLAYER = True - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64' - -# Color management -WITH_BF_OCIO = True -WITH_BF_STATICOCIO = True -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# JACK -WITH_BF_JACK = False - -# Motion Tracking -WITH_BF_LIBMV = False - -# Ocean Simulation -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index 90f0c805f58..9d0839bd0d7 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -116,10 +116,10 @@ add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True) add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder) add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder) #add_builder(c, 'linux_x86_64_cmake', '', generic_builder) -add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder) +#add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder) add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder) #add_builder(c, 'salad_linux_i386_scons', '', generic_builder, 'soc-2011-salad') -add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder) +#add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder) add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder) #add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad') add_builder(c, 'win32_scons', 'windows', generic_builder) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index bedada93a5a..dab8a8e6483 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -60,6 +60,27 @@ else: if builder.find('linux') != -1: import shutil + configs = [] + if builder.endswith('linux_glibc211_x86_64_scons'): + configs = ['user-config-player-glibc211-x86_64.py', + 'user-config-cuda-glibc211-x86_64.py', + 'user-config-glibc211-x86_64.py' + ] + chroot_name = 'buildbot_squeeze_x86_64' + cuda_chroot = 'buildbot_squeeze_x86_64' + elif builder.endswith('linux_glibc211_i386_scons'): + configs = ['user-config-player-glibc211-i686.py', + 'user-config-cuda-glibc211-i686.py', + 'user-config-glibc211-i686.py'] + chroot_name = 'buildbot_squeeze_i686' + + # use 64bit cuda toolkit, so there'll be no memory limit issues + cuda_chroot = 'buildbot_squeeze_x86_64' + + # Compilation will happen inside of chroot environment + prog_scons_cmd = ['schroot', '-c', chroot_name, '--'] + scons_cmd + cuda_scons_cmd = ['schroot', '-c', cuda_chroot, '--'] + scons_cmd + # We're using the same rules as release builder, so tweak # build and install dirs build_dir = os.path.join('..', 'build', builder) @@ -74,20 +95,6 @@ else: buildbot_dir = os.path.dirname(os.path.realpath(__file__)) config_dir = os.path.join(buildbot_dir, 'config') - configs = [] - if builder.endswith('linux_glibc27_x86_64_scons'): - configs = ['user-config-player-glibc27-x86_64.py', - 'user-config-glibc27-x86_64.py'] - elif builder.endswith('linux_glibc27_i386_scons'): - configs = ['user-config-player-glibc27-i686.py', - 'user-config-glibc27-i686.py'] - if builder.endswith('linux_glibc211_x86_64_scons'): - configs = ['user-config-player-glibc211-x86_64.py', - 'user-config-glibc211-x86_64.py'] - elif builder.endswith('linux_glibc211_i386_scons'): - configs = ['user-config-player-glibc211-i686.py', - 'user-config-glibc211-i686.py'] - for config in configs: config_fpath = os.path.join(config_dir, config) @@ -100,14 +107,24 @@ else: scons_options += common_options - if config.find('player') == -1: - scons_options.append('blender') - else: + if config.find('player') != -1: scons_options.append('blenderplayer') + cur_scons_cmd = prog_scons_cmd + elif config.find('cuda') != -1: + scons_options.append('cudakernels') + cur_scons_cmd = cuda_scons_cmd + + if config.find('i686') != -1: + scons_options.append('BF_BITNESS=32') + elif config.find('x86_64') != -1: + scons_options.append('BF_BITNESS=64') + else: + scons_options.append('blender') + cur_scons_cmd = prog_scons_cmd scons_options.append('BF_CONFIG=' + config_fpath) - retcode = subprocess.call(scons_cmd + scons_options) + retcode = subprocess.call(cur_scons_cmd + scons_options) if retcode != 0: print('Error building rules wuth config ' + config) sys.exit(retcode) diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index b7775ef872f..3d4f423be9c 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -57,17 +57,13 @@ if builder.find('scons') != -1: config = None bits = None - if builder.endswith('linux_glibc27_x86_64_scons'): - config = 'user-config-glibc27-x86_64.py' - bits = 64 - elif builder.endswith('linux_glibc27_i386_scons'): - config = 'user-config-glibc27-i686.py' - bits = 32 if builder.endswith('linux_glibc211_x86_64_scons'): config = 'user-config-glibc211-x86_64.py' + chroot_name = 'buildbot_squeeze_x86_64' bits = 64 elif builder.endswith('linux_glibc211_i386_scons'): config = 'user-config-glibc211-i686.py' + chroot_name = 'buildbot_squeeze_i686' bits = 32 if config is not None: @@ -76,7 +72,7 @@ if builder.find('scons') != -1: blender = os.path.join(install_dir, 'blender') blenderplayer = os.path.join(install_dir, 'blenderplayer') - subprocess.call(['strip', '--strip-all', blender, blenderplayer]) + subprocess.call(['schroot', '-c', chroot_name, '--', 'strip', '--strip-all', blender, blenderplayer]) extra = '/' + os.path.join('home', 'sources', 'release-builder', 'extra') mesalibs = os.path.join(extra, 'mesalibs' + str(bits) + '.tar.bz2') @@ -86,7 +82,7 @@ if builder.find('scons') != -1: os.system('cp %s %s' % (software_gl, install_dir)) os.system('chmod 755 %s' % (os.path.join(install_dir, 'blender-softwaregl'))) - retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) + retcode = subprocess.call(['schroot', '-c', chroot_name, '--', 'python', 'scons/scons.py'] + scons_options) sys.exit(retcode) else: diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py index 2f36cad4d24..17490e36bb3 100755 --- a/build_files/cmake/cmake_netbeans_project.py +++ b/build_files/cmake/cmake_netbeans_project.py @@ -56,6 +56,10 @@ def create_nb_project_main(): pass else: includes, defines = cmake_advanced_info() + + if (includes, defines) == (None, None): + return + # for some reason it doesnt give all internal includes includes = list(set(includes) | set(dirname(f) for f in files if is_c_header(f))) includes.sort() diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index 86201da23de..4cf854aad77 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -81,6 +81,9 @@ def create_qtc_project_main(): else: includes, defines = cmake_advanced_info() + if (includes, defines) == (None, None): + return + # for some reason it doesnt give all internal includes includes = list(set(includes) | set(os.path.dirname(f) for f in files_rel if is_c_header(f))) diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index 495ca71263e..e73b94a7051 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -149,14 +149,20 @@ def cmake_advanced_info(): raise Exception("Unknown make program %r" % make_exe) os.system(cmd) + return join(CMAKE_DIR, ".cproject") + includes = [] defines = [] - create_eclipse_project() + project_path = create_eclipse_project() + + if not exists(project_path): + print("Generating Eclipse Prokect File Failed: %r not found" % project_path) + return None, None from xml.dom.minidom import parse - tree = parse(join(CMAKE_DIR, ".cproject")) + tree = parse(project_path) # to check on nicer xml # f = open(".cproject_pretty", 'w') diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index 521138cba6a..82d7350bfce 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -216,7 +216,8 @@ def print_targets(targs, bc): def validate_targets(targs, bc): valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin', 'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release', - 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave'] + 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave', + 'cudakernels'] oklist = [] for t in targs: if t in valid_list: @@ -829,6 +830,18 @@ def NSIS_Installer(target=None, source=None, env=None): print data.strip().split("\n")[-1] return rv +def cudakernels_print(target, source, env): + return "Running cudakernels target" + +def cudakernels(target=None, source=None, env=None): + """ + Builder for cuda kernels compilation. Used by release build environment only + """ + + # Currently nothing to do, everything is handled by a dependency resolver + + pass + def check_environ(): problematic_envvars = "" for i in os.environ: diff --git a/doc/python_api/examples/bpy.props.5.py b/doc/python_api/examples/bpy.props.5.py new file mode 100644 index 00000000000..e49d0f2a0a0 --- /dev/null +++ b/doc/python_api/examples/bpy.props.5.py @@ -0,0 +1,85 @@ +""" +Get/Set Example +++++++++++++++ + +Get/Set functions can be used for boolean, int, float, string and enum properties. +If these callbacks are defined the property will not be stored in the ID properties +automatically, instead the get/set functions will be called when the property is +read or written from the API. +""" + +import bpy + + +# Simple property reading/writing from ID properties. +# This is what the RNA would do internally. +def get_float(self): + return self["testprop"] + +def set_float(self, value): + self["testprop"] = value + +bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float) + + +# Read-only string property, returns the current date +def get_date(self): + import datetime + return str(datetime.datetime.now()) + +bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date) + + +# Boolean array. Set function stores a single boolean value, returned as the second component. +# Array getters must return a list or tuple +# Array size must match the property vector size exactly +def get_array(self): + return (True, self["somebool"]) + +def set_array(self, values): + self["somebool"] = values[0] and values[1] + +bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array) + + +# Enum property. +# Note: the getter/setter callback must use integer identifiers! +test_items = [ + ("RED", "Red", "", 1), + ("GREEN", "Red", "", 2), + ("BLUE", "Red", "", 3), + ("YELLOW", "Red", "", 4), + ] + +def get_enum(self): + import random + return random.randint(1, 4) + +def set_enum(self, value): + print("setting value", value) + +bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum) + + +# Testing + +scene = bpy.context.scene + +scene.test_float = 12.34 +print (scene.test_float) + +scene.test_array = (True, False) +print ([x for x in scene.test_array]) + +#scene.test_date = "blah" # this would fail, property is read-only +print (scene.test_date) + +scene.test_enum = 'BLUE' +print (scene.test_enum) + + +# >>> 12.34000015258789 +# >>> [True, False] +# >>> 2013-01-05 16:33:52.135340 +# >>> setting value 3 +# >>> GREEN diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 2bc4afe969e..8b90b0bd4ff 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -95,6 +95,14 @@ enum_curves_interpolation = ( ('CARDINAL', "Cardinal interpolation", "Use cardinal interpolation between segments"), ('BSPLINE', "B-spline interpolation", "Use b-spline interpolation between segments"), ) + +enum_tile_order = ( + ('CENTER', "Center", "Render from center to the edges"), + ('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"), + ('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"), + ('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"), + ('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"), + ) class CyclesRenderSettings(bpy.types.PropertyGroup): @classmethod @@ -352,6 +360,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Cache last built BVH to disk for faster re-render if no geometry changed", default=False, ) + cls.tile_order = EnumProperty( + name="Tile Order", + description="Tile order for rendering", + items=enum_tile_order, + default='CENTER', + ) cls.use_progressive_refine = BoolProperty( name="Progressive Refine", description="Instead of rendering each tile until it is finished, " diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 554a9204c7f..6a3a0c63236 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -191,7 +191,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.prop(rd, "threads") sub = col.column(align=True) - sub.label(text="Tile Size:") + sub.label(text="Tiles:") + sub.prop(cscene, "tile_order", text="") sub.prop(rd, "tile_x", text="X") sub.prop(rd, "tile_y", text="Y") diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 4fad7d45162..41e1249dae7 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -330,13 +330,17 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents) { +#if 0 int keyno = 0; +#endif if(!(mesh && b_mesh && b_ob && CData)) return false; +#if 0 Transform tfm = get_transform(b_ob->matrix_world()); Transform itfm = transform_quick_inverse(tfm); +#endif BL::Object::modifiers_iterator b_mod; for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { @@ -348,12 +352,13 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) { - +#if 0 int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1); int shader = mesh->used_shaders[mi]; int draw_step = b_psys.settings().draw_step(); int ren_step = (int)pow((float)2.0f,(float)draw_step); - /*b_psys.settings().render_step(draw_step);*/ + b_psys.settings().render_step(draw_step); +#endif int totparts = b_psys.particles.length(); int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100; @@ -397,13 +402,16 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num) { +#if 0 int keyno = 0; - +#endif if(!(mesh && b_mesh && b_ob && CData)) return false; +#if 0 Transform tfm = get_transform(b_ob->matrix_world()); Transform itfm = transform_quick_inverse(tfm); +#endif BL::Object::modifiers_iterator b_mod; for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { @@ -415,13 +423,13 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) { - +#if 0 int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1); int shader = mesh->used_shaders[mi]; int draw_step = b_psys.settings().draw_step(); int ren_step = (int)pow((float)2.0f,(float)draw_step); - /*b_psys.settings().render_step(draw_step);*/ - + b_psys.settings().render_step(draw_step); +#endif int totparts = b_psys.particles.length(); int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100; int totcurves = totchild; diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index ad701266c5b..e9bcea70ab6 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -127,8 +127,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI case BL::Lamp::type_AREA: { BL::AreaLamp b_area_lamp(b_lamp); light->size = 1.0f; - light->axisu = make_float3(tfm.x.x, tfm.y.x, tfm.z.x); - light->axisv = make_float3(tfm.x.y, tfm.y.y, tfm.z.y); + light->axisu = transform_get_column(&tfm, 0); + light->axisv = transform_get_column(&tfm, 1); light->sizeu = b_area_lamp.size(); if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE) light->sizev = b_area_lamp.size_y(); @@ -140,8 +140,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI } /* location and (inverted!) direction */ - light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w); - light->dir = -make_float3(tfm.x.z, tfm.y.z, tfm.z.z); + light->co = transform_get_column(&tfm, 3); + light->dir = -transform_get_column(&tfm, 2); /* shader */ vector<uint> used_shaders; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 770b71afcdc..d0c7c06cbb3 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -139,6 +139,8 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_) session->progress.reset(); scene->reset(); + session->tile_manager.set_tile_order(session_params.tile_order); + /* peak memory usage should show current render peak, not peak for all renders * made by this render session */ diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index b9860ca90f2..a2a8c23404f 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -396,6 +396,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use params.tile_size = make_int2(tile_x, tile_y); } + + params.tile_order = RNA_enum_get(&cscene, "tile_order"); params.start_resolution = get_int(cscene, "preview_start_resolution"); diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index 0071bbe5cdc..661d43ab036 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -18,11 +18,14 @@ set(SRC device_cpu.cpp device_cuda.cpp device_multi.cpp - device_network.cpp device_opencl.cpp device_task.cpp ) +if(WITH_NETWORK) + list(APPEND SRC device_network.cpp) +endif() + set(SRC_HEADERS device.h device_memory.h diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 97d37a8b3f4..cd896ffe133 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -199,7 +199,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f)); ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D; - #endif } diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index d5506ad1dd0..54bc0717b60 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -66,6 +66,8 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, else eval = make_float3(0.0f, 0.0f, 0.0f); } + + eval *= ls->eval_fac; shader_release(kg, &sd); @@ -74,29 +76,29 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval, - bool *is_lamp) + int *lamp) { LightSample ls; - float pdf = -1.0f; - #ifdef __NON_PROGRESSIVE__ if(lindex != -1) { /* sample position on a specified light */ - light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf); + light_select(kg, lindex, randu, randv, sd->P, &ls); } else #endif { /* sample a light and position on int */ - light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf); + light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls); } - /* compute pdf */ - if(pdf < 0.0f) - pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t); + /* return lamp index for MIS */ + if(ls.use_mis) + *lamp = ls.lamp; + else + *lamp= ~0; - if(pdf == 0.0f) + if(ls.pdf == 0.0f) return false; /* evaluate closure */ @@ -112,13 +114,13 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf); - if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) { + if(ls.use_mis) { /* multiple importance sampling */ - float mis_weight = power_heuristic(pdf, bsdf_pdf); + float mis_weight = power_heuristic(ls.pdf, bsdf_pdf); light_eval *= mis_weight; } - bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf)); + bsdf_eval_mul(eval, light_eval/ls.pdf); if(bsdf_eval_is_zero(eval)) return false; @@ -144,14 +146,12 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, ray->t = 0.0f; } - *is_lamp = (ls.prim == ~0); - return true; } -/* Indirect Emission */ +/* Indirect Primitive Emission */ -__device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf) +__device float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf) { /* evaluate emissive closure */ float3 L = shader_emissive_eval(kg, sd); @@ -172,6 +172,35 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in return L; } +/* Indirect Lamp Emission */ + +__device bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission) +{ + LightSample ls; + int lamp = lamp_light_eval_sample(kg, randt); + + if(lamp == ~0) + return false; + + if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls)) + return false; + + /* todo: missing texture coordinates */ + float u = 0.0f; + float v = 0.0f; + float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ls.t, ray->time); + + if(!(path_flag & PATH_RAY_MIS_SKIP)) { + /* multiple importance sampling, get regular light pdf, + * and compute weight with respect to BSDF pdf */ + float mis_weight = power_heuristic(bsdf_pdf, ls.pdf); + L *= mis_weight; + } + + *emission = L; + return true; +} + /* Indirect Background */ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index ea0e4d014fe..e0d0802ae84 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -18,49 +18,27 @@ CCL_NAMESPACE_BEGIN +/* Light Sample result */ + typedef struct LightSample { - float3 P; - float3 D; - float3 Ng; - float t; - float eval_fac; - int object; - int prim; - int shader; - LightType type; + float3 P; /* position on light, or direction for distant light */ + float3 Ng; /* normal on light */ + float3 D; /* direction from shading point to light */ + float t; /* distance to light (FLT_MAX for distant light) */ + float pdf; /* light sampling probability density function */ + float eval_fac; /* intensity multiplier */ + int object; /* object id for triangle/curve lights */ + int prim; /* primitive id for triangle/curve ligths */ + int shader; /* shader id */ + int lamp; /* lamp id */ + int use_mis; /* for lamps with size zero */ + LightType type; /* type of light */ } LightSample; -/* Regular Light */ - -__device float3 disk_light_sample(float3 v, float randu, float randv) -{ - float3 ru, rv; - - make_orthonormals(v, &ru, &rv); - to_unit_disk(&randu, &randv); - - return ru*randu + rv*randv; -} - -__device float3 distant_light_sample(float3 D, float size, float randu, float randv) -{ - return normalize(D + disk_light_sample(D, randu, randv)*size); -} - -__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv) -{ - return disk_light_sample(normalize(P - center), randu, randv)*size; -} - -__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv) -{ - randu = randu - 0.5f; - randv = randv - 0.5f; - - return axisu*randu + axisv*randv; -} +/* Background Light */ #ifdef __BACKGROUND_MIS__ + __device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf) { /* for the following, the CDF values are actually a pair of floats, with the @@ -169,33 +147,108 @@ __device float background_light_pdf(KernelGlobals *kg, float3 direction) } #endif -__device void regular_light_sample(KernelGlobals *kg, int point, - float randu, float randv, float3 P, LightSample *ls, float *pdf) +/* Regular Light */ + +__device float3 disk_light_sample(float3 v, float randu, float randv) +{ + float3 ru, rv; + + make_orthonormals(v, &ru, &rv); + to_unit_disk(&randu, &randv); + + return ru*randu + rv*randv; +} + +__device float3 distant_light_sample(float3 D, float radius, float randu, float randv) +{ + return normalize(D + disk_light_sample(D, randu, randv)*radius); +} + +__device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv) { - float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0); - float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1); + return disk_light_sample(normalize(P - center), randu, randv)*radius; +} + +__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv) +{ + randu = randu - 0.5f; + randv = randv - 0.5f; + + return axisu*randu + axisv*randv; +} + +__device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls) +{ + float3 dir = make_float3(data2.y, data2.z, data2.w); + float3 I = ls->Ng; + + float spot_angle = data1.w; + float spot_smooth = data2.x; + + float attenuation = dot(dir, I); + + if(attenuation <= spot_angle) { + attenuation = 0.0f; + } + else { + float t = attenuation - spot_angle; + + if(t < spot_smooth && spot_smooth != 0.0f) + attenuation *= smoothstepf(t/spot_smooth); + } + + return attenuation; +} + +__device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) +{ + float cos_pi = dot(Ng, I); + + if(cos_pi <= 0.0f) + return 0.0f; + + return t*t/cos_pi; +} + +__device void lamp_light_sample(KernelGlobals *kg, int lamp, + float randu, float randv, float3 P, LightSample *ls) +{ + float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0); + float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1); LightType type = (LightType)__float_as_int(data0.x); ls->type = type; +#ifdef __LAMP_MIS__ + ls->use_mis = true; +#else + ls->use_mis = false; +#endif if(type == LIGHT_DISTANT) { /* distant light */ - float3 D = make_float3(data0.y, data0.z, data0.w); - float size = data1.y; + float3 lightD = make_float3(data0.y, data0.z, data0.w); + float3 D = lightD; + float radius = data1.y; + float invarea = data1.w; - if(size > 0.0f) - D = distant_light_sample(D, size, randu, randv); + if(radius > 0.0f) + D = distant_light_sample(D, radius, randu, randv); + else + ls->use_mis = false; ls->P = D; ls->Ng = D; ls->D = -D; ls->t = FLT_MAX; - ls->eval_fac = 1.0f; + + float costheta = dot(lightD, D); + ls->pdf = invarea/(costheta*costheta*costheta); + ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights; } #ifdef __BACKGROUND_MIS__ else if(type == LIGHT_BACKGROUND) { /* infinite area light (e.g. light dome or env light) */ - float3 D = background_light_sample(kg, randu, randv, pdf); + float3 D = background_light_sample(kg, randu, randv, &ls->pdf); ls->P = D; ls->Ng = D; @@ -207,127 +260,235 @@ __device void regular_light_sample(KernelGlobals *kg, int point, else { ls->P = make_float3(data0.y, data0.z, data0.w); - if(type == LIGHT_POINT) { - float size = data1.y; - - /* sphere light */ - if(size > 0.0f) - ls->P += sphere_light_sample(P, ls->P, size, randu, randv); + if(type == LIGHT_POINT || type == LIGHT_SPOT) { + float radius = data1.y; - ls->Ng = normalize(P - ls->P); - ls->eval_fac = 0.25f*M_1_PI_F; - } - else if(type == LIGHT_SPOT) { - float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2); - float size = data1.y; - - /* spot light */ - if(size > 0.0f) - ls->P += sphere_light_sample(P, ls->P, size, randu, randv); - - float3 dir = make_float3(data1.z, data1.w, data2.x); - float3 I = normalize(P - ls->P); + if(radius > 0.0f) + /* sphere light */ + ls->P += sphere_light_sample(P, ls->P, radius, randu, randv); + else + ls->use_mis = false; - float spot_angle = data2.y; - float spot_smooth = data2.z; + ls->D = normalize_len(ls->P - P, &ls->t); + ls->Ng = -ls->D; - float eval_fac = dot(dir, I); + float invarea = data1.z; + ls->eval_fac = (0.25f*M_1_PI_F)*invarea; + ls->pdf = invarea; - if(eval_fac <= spot_angle) { - eval_fac = 0.0f; + if(type == LIGHT_SPOT) { + /* spot light attentuation */ + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + ls->eval_fac *= spot_light_attenuation(data1, data2, ls); } - else { - float t = eval_fac - spot_angle; - - if(t < spot_smooth && spot_smooth != 0.0f) - eval_fac *= smoothstepf(t/spot_smooth); - } - - ls->Ng = I; - ls->eval_fac = eval_fac*0.25f*M_1_PI_F; } else { /* area light */ - float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2); - float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3); + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3); - float3 axisu = make_float3(data1.y, data1.z, data2.w); + float3 axisu = make_float3(data1.y, data1.z, data1.w); float3 axisv = make_float3(data2.y, data2.z, data2.w); float3 D = make_float3(data3.y, data3.z, data3.w); ls->P += area_light_sample(axisu, axisv, randu, randv); ls->Ng = D; - ls->eval_fac = 0.25f; + ls->D = normalize_len(ls->P - P, &ls->t); + + float invarea = data2.x; + + if(invarea == 0.0f) { + ls->use_mis = false; + invarea = 1.0f; + } + + ls->eval_fac = 0.25f*invarea; + ls->pdf = invarea; } - ls->t = 0.0f; + ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; + ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); } ls->shader = __float_as_int(data1.x); ls->object = ~0; ls->prim = ~0; + ls->lamp = lamp; } -__device float regular_light_pdf(KernelGlobals *kg, - const float3 Ng, const float3 I, float t) +__device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls) { - float pdf = kernel_data.integrator.pdf_lights; + float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0); + float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1); - if(t == FLT_MAX) - return pdf; + LightType type = (LightType)__float_as_int(data0.x); + ls->type = type; + ls->shader = __float_as_int(data1.x); + ls->object = ~0; + ls->prim = ~0; + ls->lamp = lamp; + ls->use_mis = false; /* flag not used for eval */ - float cos_pi = dot(Ng, I); + if(type == LIGHT_DISTANT) { + /* distant light */ + float radius = data1.y; + + if(radius == 0.0f) + return false; + if(t != FLT_MAX) + return false; + + /* a distant light is infinitely far away, but equivalent to a disk + * shaped light exactly 1 unit away from the current shading point. + * + * radius t^2/cos(theta) + * <----------> t = sqrt(1^2 + tan(theta)^2) + * tan(th) area = radius*radius*pi + * <-----> + * \ | (1 + tan(theta)^2)/cos(theta) + * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta) + * t \th| 1 simplifies to + * \-| 1/(cos(theta)^3) + * \| magic! + * P + */ + + float3 lightD = make_float3(data0.y, data0.z, data0.w); + float costheta = dot(-lightD, D); + float cosangle = data1.z; + + if(costheta < cosangle) + return false; + + ls->P = -D; + ls->Ng = -D; + ls->D = D; + ls->t = FLT_MAX; - if(cos_pi <= 0.0f) - return 0.0f; + float invarea = data1.w; + ls->pdf = invarea/(costheta*costheta*costheta); + ls->eval_fac = ls->pdf; + } + else if(type == LIGHT_POINT || type == LIGHT_SPOT) { + float3 lightP = make_float3(data0.y, data0.z, data0.w); + float radius = data1.y; - return t*t*pdf/cos_pi; + /* sphere light */ + if(radius == 0.0f) + return false; + + if(!ray_aligned_disk_intersect(P, D, t, + lightP, radius, &ls->P, &ls->t)) + return false; + + ls->Ng = -D; + ls->D = D; + + float invarea = data1.z; + ls->eval_fac = (0.25f*M_1_PI_F)*invarea; + ls->pdf = invarea; + + if(type == LIGHT_SPOT) { + /* spot light attentuation */ + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + ls->eval_fac *= spot_light_attenuation(data1, data2, ls); + + if(ls->eval_fac == 0.0f) + return false; + } + } + else if(type == LIGHT_AREA) { + /* area light */ + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3); + + float invarea = data2.x; + if(invarea == 0.0f) + return false; + + float3 axisu = make_float3(data1.y, data1.z, data1.w); + float3 axisv = make_float3(data2.y, data2.z, data2.w); + float3 Ng = make_float3(data3.y, data3.z, data3.w); + + /* one sided */ + if(dot(D, Ng) >= 0.0f) + return false; + + ls->P = make_float3(data0.y, data0.z, data0.w); + + if(!ray_quad_intersect(P, D, t, + ls->P, axisu, axisv, &ls->P, &ls->t)) + return false; + + ls->D = D; + ls->Ng = Ng; + ls->pdf = invarea; + ls->eval_fac = 0.25f*ls->pdf; + } + else + return false; + + /* compute pdf */ + if(ls->t != FLT_MAX) + ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); + ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; + + return true; } /* Triangle Light */ -__device void triangle_light_sample(KernelGlobals *kg, int prim, int object, - float randu, float randv, float time, LightSample *ls) +__device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time) { - /* triangle, so get position, normal, shader */ - ls->P = triangle_sample_MT(kg, prim, randu, randv); - ls->Ng = triangle_normal_MT(kg, prim, &ls->shader); - ls->object = object; - ls->prim = prim; - ls->t = 0.0f; - ls->type = LIGHT_AREA; - ls->eval_fac = 1.0f; - #ifdef __INSTANCING__ /* instance transform */ - if(ls->object >= 0) { + if(object >= 0) { #ifdef __OBJECT_MOTION__ Transform itfm; Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); #else - Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); - Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif ls->P = transform_point(&tfm, ls->P); - ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng)); + ls->Ng = normalize(transform_direction(&tfm, ls->Ng)); } #endif } +__device void triangle_light_sample(KernelGlobals *kg, int prim, int object, + float randu, float randv, float time, LightSample *ls) +{ + /* triangle, so get position, normal, shader */ + ls->P = triangle_sample_MT(kg, prim, randu, randv); + ls->Ng = triangle_normal_MT(kg, prim, &ls->shader); + ls->object = object; + ls->prim = prim; + ls->lamp = ~0; + ls->use_mis = true; + ls->t = 0.0f; + ls->type = LIGHT_AREA; + ls->eval_fac = 1.0f; + + object_transform_light_sample(kg, ls, object, time); +} + __device float triangle_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) { + float pdf = kernel_data.integrator.pdf_triangles; float cos_pi = fabsf(dot(Ng, I)); if(cos_pi == 0.0f) return 0.0f; - return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi; + return t*t*pdf/cos_pi; } +/* Curve Light */ + #ifdef __HAIR__ -/* Strand Light */ __device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object, int segment, float randu, float randv, float time, LightSample *ls) @@ -358,27 +519,16 @@ __device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object ls->P = randu * l * tg + (gd * l + r1) * ls->Ng; ls->object = object; ls->prim = prim; + ls->lamp = ~0; + ls->use_mis = true; ls->t = 0.0f; ls->type = LIGHT_STRAND; ls->eval_fac = 1.0f; ls->shader = __float_as_int(v00.z); -#ifdef __INSTANCING__ - /* instance transform */ - if(ls->object >= 0) { -#ifdef __OBJECT_MOTION__ - Transform itfm; - Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); -#else - Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); - Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); -#endif - - ls->P = transform_point(&tfm, ls->P); - ls->Ng = normalize(transform_direction(&tfm, ls->Ng)); - } -#endif + object_transform_light_sample(kg, ls, object, time); } + #endif /* Light Distribution */ @@ -412,7 +562,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt) /* Generic Light */ -__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf) +__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls) { /* sample index */ int index = light_distribution_sample(kg, randt); @@ -420,12 +570,12 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra /* fetch light data */ float4 l = kernel_tex_fetch(__light_distribution, index); int prim = __float_as_int(l.y); -#ifdef __HAIR__ - int segment = __float_as_int(l.z); -#endif if(prim >= 0) { int object = __float_as_int(l.w); +#ifdef __HAIR__ + int segment = __float_as_int(l.z); +#endif #ifdef __HAIR__ if (segment != ~0) @@ -433,27 +583,15 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra else #endif triangle_light_sample(kg, prim, object, randu, randv, time, ls); + + /* compute incoming direction, distance and pdf */ + ls->D = normalize_len(ls->P - P, &ls->t); + ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t); } else { - int point = -prim-1; - regular_light_sample(kg, point, randu, randv, P, ls, pdf); + int lamp = -prim-1; + lamp_light_sample(kg, lamp, randu, randv, P, ls); } - - /* compute incoming direction and distance */ - if(ls->t != FLT_MAX) - ls->D = normalize_len(ls->P - P, &ls->t); -} - -__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) -{ - float pdf; - - if(ls->prim != ~0) - pdf = triangle_light_pdf(kg, ls->Ng, I, t); - else - pdf = regular_light_pdf(kg, ls->Ng, I, t); - - return pdf; } __device int light_select_num_samples(KernelGlobals *kg, int index) @@ -462,18 +600,26 @@ __device int light_select_num_samples(KernelGlobals *kg, int index) return __float_as_int(data3.x); } -__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf) +__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls) { - regular_light_sample(kg, index, randu, randv, P, ls, pdf); - - /* compute incoming direction and distance */ - if(ls->t != FLT_MAX) - ls->D = normalize_len(ls->P - P, &ls->t); + lamp_light_sample(kg, index, randu, randv, P, ls); } -__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) +__device int lamp_light_eval_sample(KernelGlobals *kg, float randt) { - return regular_light_pdf(kg, ls->Ng, I, t); + /* sample index */ + int index = light_distribution_sample(kg, randt); + + /* fetch light data */ + float4 l = kernel_tex_fetch(__light_distribution, index); + int prim = __float_as_int(l.y); + + if(prim < 0) { + int lamp = -prim-1; + return lamp; + } + else + return ~0; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 20feaf50a2e..532c32896d9 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -238,6 +238,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, float min_ray_pdf = FLT_MAX; float ray_pdf = 0.0f; +#ifdef __LAMP_MIS__ + float ray_t = 0.0f; +#endif PathState state; int rng_offset = PRNG_BASE_NUM; @@ -248,8 +251,29 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* intersect scene */ Intersection isect; uint visibility = path_state_ray_visibility(kg, &state); + bool hit = scene_intersect(kg, &ray, visibility, &isect); - if(!scene_intersect(kg, &ray, visibility, &isect)) { +#ifdef __LAMP_MIS__ + if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) { + /* ray starting from previous non-transparent bounce */ + Ray light_ray; + + light_ray.P = ray.P - ray_t*ray.D; + ray_t += isect.t; + light_ray.D = ray.D; + light_ray.t = ray_t; + light_ray.time = ray.time; + + /* intersect with lamp */ + float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT); + float3 emission; + + if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission)) + path_radiance_accum_emission(&L, throughput, emission, state.bounce); + } +#endif + + if(!hit) { /* eval background shader if nothing hit */ if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) { L_transparent += average(throughput); @@ -313,7 +337,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, #ifdef __EMISSION__ /* emission */ if(sd.flag & SD_EMISSION) { - float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + /* todo: is isect.t wrong here for transparent surfaces? */ + float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); path_radiance_accum_emission(&L, throughput, emission, state.bounce); } #endif @@ -374,18 +399,19 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, Ray light_ray; BsdfEval L_light; - bool is_lamp; + int lamp; #ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif - if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp); } } @@ -422,6 +448,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; +#ifdef __LAMP_MIS__ + ray_t = 0.0f; +#endif min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } @@ -457,15 +486,41 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, #ifdef __NON_PROGRESSIVE__ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, - float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) + float3 throughput, float throughput_normalize, + float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) { +#ifdef __LAMP_MIS__ + float ray_t = 0.0f; +#endif + /* path iteration */ for(;; rng_offset += PRNG_BOUNCE_NUM) { /* intersect scene */ Intersection isect; uint visibility = path_state_ray_visibility(kg, &state); + bool hit = scene_intersect(kg, &ray, visibility, &isect); - if(!scene_intersect(kg, &ray, visibility, &isect)) { +#ifdef __LAMP_MIS__ + if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) { + /* ray starting from previous non-transparent bounce */ + Ray light_ray; + + light_ray.P = ray.P - ray_t*ray.D; + ray_t += isect.t; + light_ray.D = ray.D; + light_ray.t = ray_t; + light_ray.time = ray.time; + + /* intersect with lamp */ + float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT); + float3 emission; + + if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission)) + path_radiance_accum_emission(L, throughput, emission, state.bounce); + } +#endif + + if(!hit) { #ifdef __BACKGROUND__ /* sample background shader */ float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); @@ -496,7 +551,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray #ifdef __EMISSION__ /* emission */ if(sd.flag & SD_EMISSION) { - float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); path_radiance_accum_emission(L, throughput, emission, state.bounce); } #endif @@ -504,7 +559,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray /* path termination. this is a strange place to put the termination, it's * mainly due to the mixed in MIS that we use. gives too many unneeded * shader evaluations, only need emission if we are going to terminate */ - float probability = path_state_terminate_probability(kg, &state, throughput); + float probability = path_state_terminate_probability(kg, &state, throughput*throughput_normalize); float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE); if(terminate >= probability) { @@ -557,19 +612,20 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray Ray light_ray; BsdfEval L_light; - bool is_lamp; + int lamp; #ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif /* sample random light */ - if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp); } } @@ -606,6 +662,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; +#ifdef __LAMP_MIS__ + ray_t = 0.0f; +#endif min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } @@ -697,7 +756,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam #ifdef __EMISSION__ /* emission */ if(sd.flag & SD_EMISSION) { - float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); path_radiance_accum_emission(&L, throughput, emission, state.bounce); } #endif @@ -760,7 +819,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam if(sd.flag & SD_BSDF_HAS_EVAL) { Ray light_ray; BsdfEval L_light; - bool is_lamp; + int lamp; #ifdef __OBJECT_MOTION__ light_ray.time = sd.time; @@ -778,12 +837,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U); float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V); - if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp); } } @@ -807,12 +867,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam if(kernel_data.integrator.num_all_lights) light_t = 0.5f*light_t; - if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp); } } @@ -885,8 +946,9 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam bsdf_ray.time = sd.time; #endif - kernel_path_indirect(kg, rng, sample*num_samples, bsdf_ray, buffer, - tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); + kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer, + tp*num_samples_inv, num_samples, + min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); } } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 2bd6b5859f3..102be440978 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -48,6 +48,7 @@ CCL_NAMESPACE_BEGIN #endif #define __NON_PROGRESSIVE__ #define __HAIR__ +#define __LAMP_MIS__ #endif #ifdef __KERNEL_CUDA__ @@ -384,7 +385,7 @@ typedef enum AttributeStandard { /* Closure data */ -#define MAX_CLOSURE 8 +#define MAX_CLOSURE 16 typedef struct ShaderClosure { ClosureType type; @@ -636,6 +637,7 @@ typedef struct KernelIntegrator { int num_all_lights; float pdf_triangles; float pdf_lights; + float inv_pdf_lights; int pdf_background_res; /* bounces */ @@ -671,7 +673,7 @@ typedef struct KernelIntegrator { int transmission_samples; int ao_samples; int mesh_light_samples; - int pad1, pad2; + int pad1; } KernelIntegrator; typedef struct KernelBVH { diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 28742d56e3b..92a023bd765 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -605,7 +605,11 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD return set_attribute_int(3, type, derivatives, val); } else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) +#ifdef __HAIR__ && sd->segment == ~0) { +#else + ) { +#endif float3 P[3]; triangle_vertices(kg, sd->prim, P); @@ -675,7 +679,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri else { object = sd->object; prim = sd->prim; +#ifdef __HAIR__ segment = sd->segment; +#else + segment = ~0; +#endif if (object == ~0) return get_background_attribute(kg, sd, name, type, derivatives, val); diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 59e307bb408..a32c526a2be 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -457,7 +457,11 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem) { /* for OSL, a hash map is used to lookup the attribute by name. */ - int object = sd->object*ATTR_PRIM_TYPES + (sd->segment != ~0); + int object = sd->object*ATTR_PRIM_TYPES; +#ifdef __HAIR__ + if(sd->segment != ~0) object += ATTR_PRIM_CURVE; +#endif + OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object]; ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id))); OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname); diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl index 541f26b4e56..38232ea0aeb 100644 --- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl +++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl @@ -37,14 +37,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float int i; for (i = 0; i < (int)octaves; i++) { - value += noise("perlin", p) * pwr; + value += safe_noise(p) * pwr; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); if (rmd != 0.0) - value += rmd * noise("perlin", p) * pwr; + value += rmd * safe_noise(p) * pwr; return value; } @@ -65,14 +65,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar int i; for (i = 0; i < (int)octaves; i++) { - value *= (pwr * noise("perlin", p) + 1.0); + value *= (pwr * safe_noise(p) + 1.0); pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); if (rmd != 0.0) - value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */ + value *= (rmd * pwr * safe_noise(p) + 1.0); /* correct? */ return value; } @@ -93,11 +93,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna int i; /* first unscaled octave of function; later octaves are scaled */ - value = offset + noise("perlin", p); + value = offset + safe_noise(p); p *= lacunarity; for (i = 1; i < (int)octaves; i++) { - increment = (noise("perlin", p) + offset) * pwr * value; + increment = (safe_noise(p) + offset) * pwr * value; value += increment; pwr *= pwHL; p *= lacunarity; @@ -105,7 +105,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna rmd = octaves - floor(octaves); if (rmd != 0.0) { - increment = (noise("perlin", p) + offset) * pwr * value; + increment = (safe_noise(p) + offset) * pwr * value; value += rmd * increment; } @@ -128,7 +128,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float pwr = pwHL; int i; - result = noise("perlin", p) + offset; + result = safe_noise(p) + offset; weight = gain * result; p *= lacunarity; @@ -136,7 +136,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, if (weight > 1.0) weight = 1.0; - signal = (noise("perlin", p) + offset) * pwr; + signal = (safe_noise(p) + offset) * pwr; pwr *= pwHL; result += weight * signal; weight *= gain * signal; @@ -145,7 +145,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, rmd = octaves - floor(octaves); if (rmd != 0.0) - result += rmd * ((noise("perlin", p) + offset) * pwr); + result += rmd * ((safe_noise(p) + offset) * pwr); return result; } @@ -166,7 +166,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float pwr = pwHL; int i; - signal = offset - fabs(noise("perlin", p)); + signal = offset - fabs(safe_noise(p)); signal *= signal; result = signal; weight = 1.0; @@ -174,7 +174,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, for (i = 1; i < (int)octaves; i++) { p *= lacunarity; weight = clamp(signal * gain, 0.0, 1.0); - signal = offset - fabs(noise("perlin", p)); + signal = offset - fabs(safe_noise(p)); signal *= signal; signal *= weight; result += signal * pwr; diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h index 1b3ba8207ab..2de0fc0ea57 100644 --- a/intern/cycles/kernel/shaders/node_texture.h +++ b/intern/cycles/kernel/shaders/node_texture.h @@ -151,12 +151,23 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; } /* Noise Bases */ +float safe_noise(point p) +{ + float f = noise(p); + + /* can happen for big coordinates, things even out to 0.5 then anyway */ + if(!isfinite(f)) + return 0.5; + + return f; +} + float noise_basis(point p, string basis) { float result = 0.0; if (basis == "Perlin") - result = noise(p); /* returns perlin noise in range 0..1 */ + result = safe_noise(p); /* returns perlin noise in range 0..1 */ if (basis == "Voronoi F1") result = voronoi_F1S(p); if (basis == "Voronoi F2") diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 224a1d96543..5ead6486dd6 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -84,9 +84,8 @@ __device uint phash(int kx, int ky, int kz, int3 p) __device float floorfrac(float x, int* i) { - float f = floorf(x); - *i = (int)f; - return x - f; + *i = quick_floor(x); + return x - *i; } __device float fade(float t) @@ -133,7 +132,10 @@ __device_noinline float perlin(float x, float y, float z) grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ), grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f )))); - return scale3(result); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r))? r: 0.0f; } __device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod) @@ -162,7 +164,10 @@ __device_noinline float perlin_periodic(float x, float y, float z, float3 pperio grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ), grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f )))); - return scale3(result); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r))? r: 0.0f; } /* perlin noise in range 0..1 */ diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index c8e3e94ec98..1b94d603a26 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -323,6 +323,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen /* precompute pdfs */ kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_lights = 0.0f; + kintegrator->inv_pdf_lights = 0.0f; /* sample one, with 0.5 probability of light or triangle */ kintegrator->num_all_lights = num_lights; @@ -337,6 +338,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen kintegrator->pdf_lights = 1.0f/num_lights; if(trianglearea > 0.0f) kintegrator->pdf_lights *= 0.5f; + + kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights; } /* CDF */ @@ -349,6 +352,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen kintegrator->num_all_lights = 0; kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_lights = 0.0f; + kintegrator->inv_pdf_lights = 0.0f; } } @@ -475,16 +479,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce if(light->type == LIGHT_POINT) { shader_id &= ~SHADER_AREA_LIGHT; + float radius = light->size; + float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f; + light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); - light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_DISTANT) { shader_id &= ~SHADER_AREA_LIGHT; + float radius = light->size; + float angle = atanf(radius); + float cosangle = cosf(angle); + float area = M_PI_F*radius*radius; + float invarea = (area > 0.0f)? 1.0f/area: 1.0f; + light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z); - light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } @@ -499,21 +512,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce else if(light->type == LIGHT_AREA) { float3 axisu = light->axisu*(light->sizeu*light->size); float3 axisv = light->axisv*(light->sizev*light->size); + float area = len(axisu)*len(axisv); + float invarea = (area > 0.0f)? 1.0f/area: 0.0f; light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z); - light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z); + light_data[i*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z); } else if(light->type == LIGHT_SPOT) { shader_id &= ~SHADER_AREA_LIGHT; + float radius = light->size; + float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f; float spot_angle = cosf(light->spot_angle*0.5f); float spot_smooth = (1.0f - spot_angle)*light->spot_smooth; light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); - light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y); - light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle); + light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } } diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 36948adce17..e49a4a3ed34 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN Session::Session(const SessionParams& params_) : params(params_), tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution, - params.background == false || params.progressive_refine, params.background, + params.background == false || params.progressive_refine, params.background, params.tile_order, max(params.device.multi_devices.size(), 1)), stats() { diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index cfc1502287d..27073d2fd9c 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -51,6 +51,7 @@ public: bool experimental; int samples; int2 tile_size; + int tile_order; int start_resolution; int threads; diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index bbcdb47260e..d62ecd8a88c 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -24,10 +24,11 @@ CCL_NAMESPACE_BEGIN TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, - bool preserve_tile_device_, bool background_, int num_devices_) + bool preserve_tile_device_, bool background_, int tile_order_, int num_devices_) { progressive = progressive_; tile_size = tile_size_; + tile_order = tile_order_; start_resolution = start_resolution_; num_devices = num_devices_; preserve_tile_device = preserve_tile_device_; @@ -165,6 +166,20 @@ void TileManager::set_tiles() state.buffer.full_height = max(1, params.full_height/resolution); } +list<Tile>::iterator TileManager::next_viewport_tile(int device) +{ + list<Tile>::iterator iter; + + int logical_device = preserve_tile_device? device: 0; + + for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { + if(iter->device == logical_device && iter->rendering == false) + return iter; + } + + return state.tiles.end(); +} + list<Tile>::iterator TileManager::next_center_tile(int device) { list<Tile>::iterator iter, best = state.tiles.end(); @@ -210,28 +225,53 @@ list<Tile>::iterator TileManager::next_center_tile(int device) return best; } -list<Tile>::iterator TileManager::next_simple_tile(int device) +list<Tile>::iterator TileManager::next_simple_tile(int device, int tile_order) { - list<Tile>::iterator iter; + list<Tile>::iterator iter, best = state.tiles.end(); + int resolution = state.resolution_divider; int logical_device = preserve_tile_device? device: 0; + int64_t cordx = max(1, params.width/resolution); + int64_t cordy = max(1, params.height/resolution); + int64_t mindist = cordx * cordy; + for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { - if(iter->device == logical_device && iter->rendering == false) - return iter; + if(iter->device == logical_device && iter->rendering == false) { + Tile &cur_tile = *iter; + + int64_t distx = cordx; + + if (tile_order == TileManager::RIGHT_TO_LEFT) + distx = cordx - cur_tile.x; + else if (tile_order == TileManager::LEFT_TO_RIGHT) + distx = cordx + cur_tile.x; + else if (tile_order == TileManager::TOP_TO_BOTTOM) + distx = cordx - cur_tile.y; + else /* TileManager::BOTTOM_TO_TOP */ + distx = cordx + cur_tile.y; + + if(distx < mindist) { + best = iter; + mindist = distx; + } + } } - return state.tiles.end(); + return best; } bool TileManager::next_tile(Tile& tile, int device) { list<Tile>::iterator tile_it; - - if(background) - tile_it = next_center_tile(device); + if (background) { + if(tile_order == TileManager::CENTER) + tile_it = next_center_tile(device); + else + tile_it = next_simple_tile(device, tile_order); + } else - tile_it = next_simple_tile(device); + tile_it = next_viewport_tile(device); if(tile_it != state.tiles.end()) { tile_it->rendering = true; diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index 6f7a8f20734..99cffb49c08 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -59,7 +59,7 @@ public: } state; TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution, - bool preserve_tile_device, bool background, int num_devices = 1); + bool preserve_tile_device, bool background, int tile_order, int num_devices = 1); ~TileManager(); void reset(BufferParams& params, int num_samples); @@ -68,12 +68,23 @@ public: bool next_tile(Tile& tile, int device = 0); bool done(); + void set_tile_order(int tile_order_) { tile_order = tile_order_; } protected: + /* Note: this should match enum_tile_order in properties.py */ + enum { + CENTER = 0, + RIGHT_TO_LEFT = 1, + LEFT_TO_RIGHT = 2, + TOP_TO_BOTTOM = 3, + BOTTOM_TO_TOP = 4 + } TileOrder; + void set_tiles(); bool progressive; int num_samples; int2 tile_size; + int tile_order; int start_resolution; int num_devices; @@ -106,9 +117,12 @@ protected: * mimics behavior of blender internal's tile order */ list<Tile>::iterator next_center_tile(int device); + + /* returns simple tile order */ + list<Tile>::iterator next_simple_tile(int device, int tile_order); - /* returns first unhandled tile starting from left bottom corner of the image */ - list<Tile>::iterator next_simple_tile(int device); + /* returns first unhandled tile (for viewport) */ + list<Tile>::iterator next_viewport_tile(int device); }; CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 8932c85db07..c37fa1a4dc6 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1161,6 +1161,130 @@ __device float safe_divide(float a, float b) return result; } +/* Ray Intersection */ + +__device bool ray_sphere_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 sphere_P, float sphere_radius, + float3 *isect_P, float *isect_t) +{ + float3 d = sphere_P - ray_P; + float radiussq = sphere_radius*sphere_radius; + float tsq = dot(d, d); + + if(tsq > radiussq) { /* ray origin outside sphere */ + float tp = dot(d, ray_D); + + if(tp < 0.0f) /* dir points away from sphere */ + return false; + + float dsq = tsq - tp*tp; /* pythagoras */ + + if(dsq > radiussq) /* closest point on ray outside sphere */ + return false; + + float t = tp - sqrtf(radiussq - dsq); /* pythagoras */ + + if(t < ray_t) { + *isect_t = t; + *isect_P = ray_P + ray_D*t; + return true; + } + } + + return false; +} + +__device bool ray_aligned_disk_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 disk_P, float disk_radius, + float3 *isect_P, float *isect_t) +{ + /* aligned disk normal */ + float disk_t; + float3 disk_N = normalize_len(ray_P - disk_P, &disk_t); + float div = dot(ray_D, disk_N); + + if(div == 0.0f) + return false; + + /* compute t to intersection point */ + float t = -disk_t/div; + if(t < 0.0f || t > ray_t) + return false; + + /* test if within radius */ + float3 P = ray_P + ray_D*t; + if(len_squared(P - disk_P) > disk_radius*disk_radius) + return false; + + *isect_P = P; + *isect_t = t; + + return true; +} + +__device bool ray_triangle_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 v0, float3 v1, float3 v2, + float3 *isect_P, float *isect_t) +{ + /* Calculate intersection */ + float3 e1 = v1 - v0; + float3 e2 = v2 - v0; + float3 s1 = cross(ray_D, e2); + + const float divisor = dot(s1, e1); + if(divisor == 0.0f) + return false; + + const float invdivisor = 1.0f/divisor; + + /* compute first barycentric coordinate */ + const float3 d = ray_P - v0; + const float u = dot(d, s1)*invdivisor; + if(u < 0.0f) + return false; + + /* Compute second barycentric coordinate */ + const float3 s2 = cross(d, e1); + const float v = dot(ray_D, s2)*invdivisor; + if(v < 0.0f) + return false; + + const float b0 = 1.0f - u - v; + if(b0 < 0.0f) + return false; + + /* compute t to intersection point */ + const float t = dot(e2, s2)*invdivisor; + if(t < 0.0f || t > ray_t) + return false; + + *isect_t = t; + *isect_P = ray_P + ray_D*t; + + return true; +} + +__device bool ray_quad_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 quad_P, float3 quad_u, float3 quad_v, + float3 *isect_P, float *isect_t) +{ + float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; + float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; + float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f; + float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f; + + if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t)) + return true; + else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t)) + return true; + + return false; +} + CCL_NAMESPACE_END #endif /* __UTIL_MATH_H__ */ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 2d9d89d9ad0..ac3e22368bc 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -574,13 +574,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() rstring = (char*)malloc( len ); sysctl( mib, 2, rstring, &len, NULL, 0 ); - //Hack on MacBook revision, as multitouch avail. function missing - //MacbookAir or MacBook version >= 5 (retina is MacBookPro10,1) - if (strstr(rstring,"MacBookAir") || - (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')) || - (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-4]>='1') && (rstring[strlen(rstring)-4]<='9'))) - m_hasMultiTouchTrackpad = true; - else m_hasMultiTouchTrackpad = false; + m_hasMultiTouchTrackpad = false; free( rstring ); rstring = NULL; @@ -1445,6 +1439,27 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) } +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 +enum { + NSEventPhaseNone = 0, + NSEventPhaseBegan = 0x1 << 0, + NSEventPhaseStationary = 0x1 << 1, + NSEventPhaseChanged = 0x1 << 2, + NSEventPhaseEnded = 0x1 << 3, + NSEventPhaseCancelled = 0x1 << 4, +}; +typedef NSUInteger NSEventPhase; + +@interface NSEvent (AvailableOn1070AndLater) +- (BOOL)hasPreciseScrollingDeltas; +- (CGFloat)scrollingDeltaX; +- (CGFloat)scrollingDeltaY; +- (NSEventPhase)momentumPhase; +- (BOOL)isDirectionInvertedFromDevice; +- (NSEventPhase)phase; +@end +#endif + GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; @@ -1577,15 +1592,23 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } break; + /* these events only happen on swiping trackpads */ + case NSEventTypeBeginGesture: + m_hasMultiTouchTrackpad = 1; + break; + case NSEventTypeEndGesture: + m_hasMultiTouchTrackpad = 0; + break; + case NSScrollWheel: { - int momentum = 0; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - m_hasMultiTouchTrackpad = 0; - momentum = [event momentumPhase] || [event phase]; -#endif - /* standard scrollwheel case */ - if (!m_hasMultiTouchTrackpad && momentum == 0) { + int *momentum = NULL; + + if ([event respondsToSelector:@selector(momentumPhase)]) + momentum = (int *)[event momentumPhase]; + + /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ + if (!m_hasMultiTouchTrackpad && momentum == NULL) { GHOST_TInt32 delta; double deltaF = [event deltaY]; diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 9f62ed76735..75d606a5d79 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -761,6 +761,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_ if (type == GHOST_kEventWindowActivate) { system->getWindowManager()->setActiveWindow(window); + ((GHOST_WindowWin32*)window)->bringTabletContextToFront(); } return new GHOST_Event(system->getMilliSeconds(), type, window); diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 2d3cc4f88dc..f5cb0d9323c 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -132,7 +132,7 @@ GHOST_SystemX11( GHOST_ASSERT(false, "Could not instantiate timer!"); } - /* Taking care not to overflow the tv.tv_sec*1000 */ + /* Taking care not to overflow the tv.tv_sec * 1000 */ m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000; @@ -190,7 +190,7 @@ getMilliSeconds() const GHOST_ASSERT(false, "Could not compute time!"); } - /* Taking care not to overflow the tv.tv_sec*1000 */ + /* Taking care not to overflow the tv.tv_sec * 1000 */ return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; } diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 2d58f0612ce..e89dd1b41dc 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -428,6 +428,14 @@ extern "C" { #pragma mark initialization / finalization +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 +@interface NSView (NSOpenGLSurfaceResolution) +- (BOOL)wantsBestResolutionOpenGLSurface; +- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; +- (NSRect)convertRectToBacking:(NSRect)bounds; +@end +#endif + NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil; GHOST_WindowCocoa::GHOST_WindowCocoa( @@ -579,13 +587,15 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( setDrawingContextType(type); updateDrawingContext(); activateDrawingContext(); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // retina support started with 10.7.4 afaik + if (m_systemCocoa->m_nativePixel) { - [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; - NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; - m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width; + if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { + [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; + + NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; + m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width; + } } -#endif m_tablet.Active = GHOST_kTabletModeNone; diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index fead1884f8a..bf429527199 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -1192,6 +1192,16 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam) } } +void GHOST_WindowWin32::bringTabletContextToFront() +{ + if (m_wintab) { + GHOST_WIN32_WTOverlap fpWTOverlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab, "WTOverlap"); + if (fpWTOverlap) { + fpWTOverlap(m_tablet, TRUE); + } + } +} + /** Reverse the bits in a GHOST_TUns8 */ static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) { diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 9e4377b8225..7f50d58ce35 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -58,6 +58,7 @@ typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID); typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL); typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX); typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID); +typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL); /** * GHOST window on M$ Windows OSs. @@ -273,6 +274,7 @@ public: void processWin32TabletInitEvent(); void processWin32TabletEvent(WPARAM wParam, LPARAM lParam); + void bringTabletContextToFront(); protected: GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd); diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index 44c02d1442b..d01d8d4c8f4 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -331,7 +331,7 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *) } OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription"); diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc index 18fa4b7cb1b..4f839a61fad 100644 --- a/intern/opencolorio/ocio_capi.cc +++ b/intern/opencolorio/ocio_capi.cc @@ -238,12 +238,12 @@ void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) } OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); } -void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) { impl->OCIO_PackedImageDescRelease(id); } diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 0ce5f8a1456..19fd8fe643b 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -105,9 +105,9 @@ void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_Const void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes); + long chanStrideBytes, long xStrideBytes, long yStrideBytes); -void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); +void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void); void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index 2d73d2ff56b..b073a038f0d 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -479,7 +479,7 @@ void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) } OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { try { void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__); diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend Binary files differindex c66002de805..dc684178f40 100644 --- a/release/datafiles/startup.blend +++ b/release/datafiles/startup.blend diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index d870ef963ea..7b6013f3044 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -49,8 +49,13 @@ def extend(obj, operator, EXTEND_MODE): # our own local walker def walk_face_init(faces, f_act): + # first tag all faces True (so we dont uvmap them) + for f in bm.faces: + f.tag = True + # then tag faces arg False for f in faces: f.tag = False + # tag the active face True since we begin there f_act.tag = True def walk_face(f): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index c24e0920213..00cc763c4e1 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -44,7 +44,7 @@ class MESH_OT_delete_edgeloop(Operator): 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): + if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0, correct_uv=True): bpy.ops.mesh.select_more() bpy.ops.mesh.remove_doubles() ret = {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 538063cb038..5fdb71b855f 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -330,7 +330,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): row = layout.row() col = row.column() - col.template_list("MESH_UL_uvmaps_vcols", "", me, "uv_textures", me.uv_textures, "active_index", rows=2) + col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=2) col = row.column(align=True) col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="") @@ -353,7 +353,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): row = layout.row() col = row.column() - col.template_list("MESH_UL_uvmaps_vcols", "", me, "vertex_colors", me.vertex_colors, "active_index", rows=2) + col.template_list("MESH_UL_uvmaps_vcols", "vcols", me, "vertex_colors", me.vertex_colors, "active_index", rows=2) col = row.column(align=True) col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="") @@ -372,17 +372,20 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): def draw(self, context): layout = self.layout - # me = context.mesh + obj = context.object + me = context.mesh col = layout.column() - # sticky has no UI access since 2.49 - we may remove - ''' - row = col.row(align=True) - row.operator("mesh.customdata_create_sticky") - row.operator("mesh.customdata_clear_sticky", icon='X') - ''' + col.operator("mesh.customdata_clear_mask", icon='X') col.operator("mesh.customdata_clear_skin", icon='X') + col = layout.column() + + col.enabled = (obj.mode != 'EDIT') + col.prop(me, "use_customdata_vertex_bevel") + col.prop(me, "use_customdata_edge_bevel") + col.prop(me, "use_customdata_edge_crease") + class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 8a668b5d95b..951807488e7 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -289,6 +289,9 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): row.active = ((ob.parent is not None) and (ob.use_slow_parent)) row.prop(ob, "slow_parent_offset", text="Offset") + layout.prop(ob, "extra_recalc_object") + layout.prop(ob, "extra_recalc_data") + from bl_ui.properties_animviz import (MotionPathButtonsPanel, OnionSkinButtonsPanel) diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index eddb542ccc3..6842b324b0e 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -64,7 +64,7 @@ class TEXTURE_UL_texslots(UIList): tex = slot.texture if slot else None if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.label(tex.name if tex else "", icon_value=icon) - if tex: + if tex and isinstance(item, bpy.types.MaterialTextureSlot): layout.prop(ma, "use_textures", text="", index=index) elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 58c433d3772..a9712b1557e 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -200,7 +200,7 @@ class USERPREF_PT_interface(Panel): col.prop(view, "show_playback_fps", text="Playback FPS") col.prop(view, "use_global_scene") col.prop(view, "object_origin_size") - + col.separator() col.separator() col.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 0e1f5d8dff2..3c56ff82a77 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1120,11 +1120,11 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text) row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA') - row = layout.row() - row.active = (settings.brush.image_tool == 'CLONE') - row.prop(ipaint, "use_clone_layer", text="Clone") + col = layout.column() + col.active = (settings.brush.image_tool == 'CLONE') + col.prop(ipaint, "use_clone_layer", text="Clone from UV map") clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else "" - row.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text) + col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text) layout.prop(ipaint, "seam_bleed") diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 9c7623f3757..12c0088e93e 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -83,7 +83,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table)); memset(gc->bucket, 0, sizeof(gc->bucket)); - gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256); + gc->textures = (GLuint *)MEM_mallocN(sizeof(GLuint) * 256, __func__); gc->ntex = 256; gc->cur_tex = -1; gc->x_offs = 0; @@ -150,7 +150,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc) if (gc->cur_tex + 1 > 0) glDeleteTextures(gc->cur_tex + 1, gc->textures); - free((void *)gc->textures); + MEM_freeN((void *)gc->textures); MEM_freeN(gc); } @@ -178,8 +178,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) gc->p2_height = font->max_tex_size; tot_mem = gc->p2_width * gc->p2_height; - buf = (unsigned char *)malloc(tot_mem); - memset((void *)buf, 0, tot_mem); + buf = (unsigned char *)MEM_callocN(tot_mem, __func__); glGenTextures(1, &gc->textures[gc->cur_tex]); glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex])); @@ -189,7 +188,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf); - free((void *)buf); + MEM_freeN((void *)buf); } GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index ed90c63d949..f06547fe2e3 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -173,6 +173,9 @@ struct DerivedMesh { float auto_bump_scale; DMDirtyFlag dirty; + /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */ + char cd_flag; + /** Calculate vert and face normals */ void (*calcNormals)(DerivedMesh *dm); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 10528f1b270..9c6d26c08bc 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 5 +#define BLENDER_SUBVERSION 8 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 2b2497f3f50..af5e925987d 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -63,14 +63,12 @@ DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_ /* merge verts */ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap); -DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob); - /* creates a CDDerivedMesh from the given curve object */ struct DerivedMesh *CDDM_from_curve(struct Object *ob); /* creates a CDDerivedMesh from the given curve object and specified dispbase */ /* useful for OrcoDM creation for curves with constructive modifiers */ -DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr); +DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase); /* Copies the given DerivedMesh with verts, faces & edges stored as * custom element data. diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 4736e7b7312..36733d1ced0 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -39,6 +39,7 @@ extern "C" { #endif #include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */ +#include "BLI_utildefines.h" struct BMesh; struct ID; @@ -215,6 +216,8 @@ void CustomData_free_elem(struct CustomData *data, int index, int count); void CustomData_interp(const struct CustomData *source, struct CustomData *dest, int *src_indices, float *weights, float *sub_weights, int count, int dest_index); +void CustomData_bmesh_interp_n(struct CustomData *data, void **src_blocks, const float *weights, + const float *sub_weights, int count, void *dest_block, int n); void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks, const float *weights, const float *sub_weights, int count, void *dest_block); @@ -246,6 +249,8 @@ void *CustomData_get_layer(const struct CustomData *data, int type); void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); +int CustomData_get_offset(const struct CustomData *data, int type); +int CustomData_get_n_offset(const struct CustomData *data, int type, int n); int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); @@ -304,7 +309,7 @@ void CustomData_bmesh_free_block(struct CustomData *data, void **block); /* copy custom data to/from layers as in mesh/derivedmesh, to editmesh * blocks of data. the CustomData's must not be compatible */ void CustomData_to_bmesh_block(const struct CustomData *source, - struct CustomData *dest, int src_index, void **dest_block); + struct CustomData *dest, int src_index, void **dest_block, bool use_default_init); void CustomData_from_bmesh_block(const struct CustomData *source, struct CustomData *dest, void *src_block, int dest_index); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index ec465502ca0..be42ee524de 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -96,7 +96,7 @@ typedef struct Main { } Main; #define MAIN_VERSION_ATLEAST(main, ver, subver) \ - ((main)->versionfile >= (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver))) + ((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver))) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index db9f1228f76..3466a914bce 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -154,13 +154,9 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot int *totloop, int *totpoly); int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly, - int *_totloop, int *_totpoly, int **orco_index_ptr); -void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly, - struct MLoop *mloops, struct MLoopUV *mloopuvs, - float (*orco)[3], int (*orco_index)[4]); + struct MLoopUV **alluv, int *_totloop, int *_totpoly); +void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv); void BKE_mesh_from_nurbs(struct Object *ob); -void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, - int **orco_index_ptr); void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob); void BKE_mesh_delete_material_index(struct Mesh *me, short index); void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth); @@ -334,6 +330,8 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop, struct MPoly *mp, float angles[]); +void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 4d69a013101..e659954a3ac 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -35,6 +35,7 @@ extern "C" { #endif #include "DNA_windowmanager_types.h" +#include "BLI_utildefines.h" /* Reporting Information and Errors * @@ -72,7 +73,10 @@ void BKE_reports_print(ReportList *reports, ReportType level); Report *BKE_reports_last_displayable(ReportList *reports); int BKE_reports_contain(ReportList *reports, ReportType level); - + +bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header); +bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ec8d37e1ae3..dde1d5870ca 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -313,6 +313,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH, CD_CALLOC, numPolys); + dm->cd_flag = source->cd_flag; + dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; @@ -483,11 +485,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) totedge = tmp.totedge = dm->getNumEdges(dm); totloop = tmp.totloop = dm->getNumLoops(dm); totpoly = tmp.totpoly = dm->getNumPolys(dm); + tmp.totface = 0; CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop); CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly); + me->cd_flag = dm->cd_flag; if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) { KeyBlock *kb; @@ -538,9 +542,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) } /* yes, must be before _and_ after tessellate */ - mesh_update_customdata_pointers(&tmp, TRUE); + mesh_update_customdata_pointers(&tmp, false); - BKE_mesh_tessface_calc(&tmp); + /* since 2.65 caller must do! */ + // BKE_mesh_tessface_calc(&tmp); CustomData_free(&me->vdata, me->totvert); CustomData_free(&me->edata, me->totedge); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 51890851ebc..85dd4c67fdf 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -647,6 +647,23 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, index_mp_to_orig = NULL; } + /* TODO: not entirely correct, but currently dynamic topology will + * destroy UVs anyway, so textured display wouldn't work anyway + * + * this will do more like solid view with lights set up for + * textured view, but object itself will be displayed gray + * (the same as it'll display without UV maps in textured view) + */ + if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { + if (dm->numTessFaceData) { + glDisable(GL_TEXTURE_2D); + BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE); + glEnable(GL_TEXTURE_2D); + } + + return; + } + colType = CD_TEXTURE_MCOL; mcol = dm->getTessFaceDataArray(dm, colType); if (!mcol) { @@ -1726,6 +1743,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) mesh->totloop, mesh->totpoly); dm->deformedOnly = 1; + dm->cd_flag = mesh->cd_flag; alloctype = CD_REFERENCE; @@ -1757,49 +1775,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *CDDM_from_curve(Object *ob) { - return CDDM_from_curve_displist(ob, &ob->disp, NULL); + return CDDM_from_curve_displist(ob, &ob->disp); } -DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob) -{ - int *orco_index_ptr = NULL; - int (*orco_index)[4] = NULL; - float (*orco)[3] = NULL; - DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr); - - if (orco_index_ptr) { - orco = (float (*)[3])BKE_curve_make_orco(scene, ob); - } - - if (orco && orco_index_ptr) { - const char *uvname = "Orco"; - - int totpoly = dm->getNumPolys(dm); - - MPoly *mpolys = dm->getPolyArray(dm); - MLoop *mloops = dm->getLoopArray(dm); - - MLoopUV *mloopuvs; - - CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname); - mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname); - - BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly, - mloops, mloopuvs, - orco, orco_index); - } - - if (orco_index) { - MEM_freeN(orco_index); - } - if (orco) { - MEM_freeN(orco); - } - - return dm; -} - -DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) +DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) { DerivedMesh *dm; CDDerivedMesh *cddm; @@ -1810,7 +1789,8 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco int totvert, totedge, totloop, totpoly; if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, - &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) + &totedge, &allloop, &allpoly, NULL, + &totloop, &totpoly) != 0) { /* Error initializing mdata. This often happens when curve is empty */ return CDDM_new(0, 0, 0, 0, 0); @@ -1909,13 +1889,12 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); int *index, add_orig; - int has_crease, has_edge_bweight, has_vert_bweight; CustomDataMask mask; unsigned int i, j; - has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT); - has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT); - has_crease = CustomData_has_layer(&bm->edata, CD_CREASE); + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); dm->deformedOnly = 1; @@ -1955,8 +1934,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, mv->flag = BM_vert_flag_to_mflag(eve); - if (has_vert_bweight) - mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f); + if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); if (add_orig) *index = i; @@ -1974,11 +1952,6 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, med->v1 = BM_elem_index_get(eed->v1); med->v2 = BM_elem_index_get(eed->v2); - if (has_crease) - med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f); - if (has_edge_bweight) - med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f); - med->flag = BM_edge_flag_to_mflag(eed); /* handle this differently to editmode switching, @@ -1989,6 +1962,9 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, } } + if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); + CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i); if (add_orig) *index = i; } @@ -2051,6 +2027,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, } bm->elem_index_dirty &= ~BM_FACE; + dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); + return dm; } @@ -2088,6 +2066,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces) DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); dm->deformedOnly = source->deformedOnly; + dm->cd_flag = source->cd_flag; dm->dirty = source->dirty; CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 1d199cdf1e2..fe8bd0cc5a4 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -875,7 +875,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv) -/* coord_array has to be 3*4*resolu*resolv in size, and zero-ed */ +/* coord_array has to be (3 * 4 * resolu * resolv) in size, and zero-ed */ { BPoint *bp; float *basisu, *basis, *basisv, *sum, *fp, *in; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 0f352dede23..f3548f776f5 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2095,6 +2095,23 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, return data->layers[layer_index].data; } +int CustomData_get_offset(const CustomData *data, int type) +{ + /* get the layer index of the active layer of type */ + int layer_index = CustomData_get_active_layer_index(data, type); + if (layer_index < 0) return -1; + + return data->layers[layer_index].offset; +} + +int CustomData_get_n_offset(const CustomData *data, int type, int n) +{ + /* get the layer index of the active layer of type */ + int layer_index = CustomData_get_layer_index_n(data, type, n); + if (layer_index < 0) return -1; + + return data->layers[layer_index].offset; +} int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name) { @@ -2298,34 +2315,46 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest, BMIter iter; CustomData destold; void *tmp; - int t; + int iter_type; + int totelem; /* copy old layer description so that old data can be copied into * the new allocation */ destold = *dest; - if (destold.layers) destold.layers = MEM_dupallocN(destold.layers); - - CustomData_merge(source, dest, mask, alloctype, 0); - dest->pool = NULL; - CustomData_bmesh_init_pool(dest, 512, htype); + if (destold.layers) { + destold.layers = MEM_dupallocN(destold.layers); + } switch (htype) { case BM_VERT: - t = BM_VERTS_OF_MESH; break; + iter_type = BM_VERTS_OF_MESH; + totelem = bm->totvert; + break; case BM_EDGE: - t = BM_EDGES_OF_MESH; break; + iter_type = BM_EDGES_OF_MESH; + totelem = bm->totedge; + break; case BM_LOOP: - t = BM_LOOPS_OF_FACE; break; + iter_type = BM_LOOPS_OF_FACE; + totelem = bm->totloop; + break; case BM_FACE: - t = BM_FACES_OF_MESH; break; + iter_type = BM_FACES_OF_MESH; + totelem = bm->totface; + break; default: /* should never happen */ BLI_assert(!"invalid type given"); - t = BM_VERTS_OF_MESH; + iter_type = BM_VERTS_OF_MESH; + totelem = bm->totvert; } - if (t != BM_LOOPS_OF_FACE) { + CustomData_merge(source, dest, mask, alloctype, 0); + dest->pool = NULL; + CustomData_bmesh_init_pool(dest, totelem, htype); + + if (iter_type != BM_LOOPS_OF_FACE) { /*ensure all current elements follow new customdata layout*/ - BM_ITER_MESH (h, &iter, bm, t) { + BM_ITER_MESH (h, &iter, bm, iter_type) { tmp = NULL; CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp); CustomData_bmesh_free_block(&destold, &h->data); @@ -2618,6 +2647,19 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so memcpy(dest, source, typeInfo->size); } +/** + * \param src_blocks must be pointers to the data, offset by layer->offset already. + */ +void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float *weights, + const float *sub_weights, int count, void *dest_block, int n) +{ + CustomDataLayer *layer = &data->layers[n]; + const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); + + typeInfo->interp(src_blocks, weights, sub_weights, count, + (char *)dest_block + layer->offset); +} + void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights, const float *sub_weights, int count, void *dest_block) { @@ -2640,36 +2682,47 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w for (j = 0; j < count; ++j) { sources[j] = (char *)src_blocks[j] + layer->offset; } - - typeInfo->interp(sources, weights, sub_weights, count, - (char *)dest_block + layer->offset); + CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i); } } if (count > SOURCE_BUF_SIZE) MEM_freeN(sources); } -void CustomData_bmesh_set_default(CustomData *data, void **block) +static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n) { const LayerTypeInfo *typeInfo; + int offset = data->layers[n].offset; + + typeInfo = layerType_getInfo(data->layers[n].type); + + if (typeInfo->set_default) { + typeInfo->set_default((char *)*block + offset, 1); + } + else { + memset((char *)*block + offset, 0, typeInfo->size); + } +} + +void CustomData_bmesh_set_default(CustomData *data, void **block) +{ int i; if (*block == NULL) CustomData_bmesh_alloc_block(data, block); for (i = 0; i < data->totlayer; ++i) { - int offset = data->layers[i].offset; - - typeInfo = layerType_getInfo(data->layers[i].type); - - if (typeInfo->set_default) - typeInfo->set_default((char *)*block + offset, 1); - else memset((char *)*block + offset, 0, typeInfo->size); + CustomData_bmesh_set_default_n(data, block, i); } } +/** + * \param use_default_init initializes data which can't be copied, + * typically you'll want to use this if the BM_xxx create function + * is called with BM_CREATE_SKIP_CD flag + */ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, - int src_index, void **dest_block) + int src_index, void **dest_block, bool use_default_init) { const LayerTypeInfo *typeInfo; int dest_i, src_i, src_offset; @@ -2685,11 +2738,14 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { + if (use_default_init) { + CustomData_bmesh_set_default_n(dest, dest_block, dest_i); + } dest_i++; } /* if there are no more dest layers, we're done */ - if (dest_i >= dest->totlayer) return; + if (dest_i >= dest->totlayer) break; /* if we found a matching layer, copy the data */ if (dest->layers[dest_i].type == source->layers[src_i].type) { @@ -2712,6 +2768,13 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, dest_i++; } } + + if (use_default_init) { + while (dest_i < dest->totlayer) { + CustomData_bmesh_set_default_n(dest, dest_block, dest_i); + dest_i++; + } + } } void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 71e9daaee6b..643c7b1d972 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -975,7 +975,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba curve_to_filledpoly(cu, nurb, dispbase); } - dm = CDDM_from_curve_displist(ob, dispbase, NULL); + dm = CDDM_from_curve_displist(ob, dispbase); CDDM_calc_normals_mapping(dm); } @@ -1065,7 +1065,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) /* OrcoDM should be created from underformed disp lists */ BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); - dm = CDDM_from_curve_displist(ob, &disp, NULL); + dm = CDDM_from_curve_displist(ob, &disp); BKE_displist_free(&disp); @@ -1485,8 +1485,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba float *cur_data = data; if (cu->taperobj == NULL) { - if ( (cu->bevobj != NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ) - fac = bevp->radius; + fac = bevp->radius; } else { float len, taper_fac; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 1c43b418a1c..91577320a9c 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -782,22 +782,18 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, if (poly_prev != GL_ZERO) glEnd(); } -static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3], - int has_uv, int has_col) +static void bmdm_get_tri_uv(BMLoop *ls[3], MLoopUV *luv[3], const int cd_loop_uv_offset) { - if (has_uv) { - luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV); - luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV); - luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV); - } - - if (has_col) { - lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL); - lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL); - lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL); - } - + luv[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_uv_offset); + luv[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_uv_offset); + luv[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_uv_offset); +} +static void bmdm_get_tri_col(BMLoop *ls[3], MLoopCol *lcol[3], const int cd_loop_color_offset) +{ + lcol[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_color_offset); + lcol[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_color_offset); + lcol[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_color_offset); } static void emDM_drawFacesTex_common(DerivedMesh *dm, @@ -813,15 +809,19 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, float (*vertexNos)[3] = bmdm->vertexNos; BMFace *efa; MLoopUV *luv[3], dummyluv = {{0}}; - MLoopCol *lcol[3] = {NULL}, dummylcol = {0}; - int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL); - int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY); + MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL); + const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); + bool has_uv = (cd_loop_uv_offset != -1); + bool has_vcol = (cd_loop_color_offset != -1); + int i; (void) compareDrawOptions; luv[0] = luv[1] = luv[2] = &dummyluv; - dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; + // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; /* UNUSED */ /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); @@ -833,7 +833,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, for (i = 0; i < em->tottri; i++) { BMLoop **ls = em->looptris[i]; - MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL; + MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL; MTFace mtf = {{{0}}}; /*unsigned char *cp = NULL;*/ /*UNUSED*/ int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH); @@ -841,7 +841,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, efa = ls[0]->f; - if (has_uv) { + if (cd_poly_tex_offset != -1) { ME_MTEXFACE_CPY(&mtf, tp); } @@ -858,25 +858,27 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, if (!drawSmooth) { glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]); - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); glTexCoord2fv(luv[0]->uv); - if (lcol[0]) + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[0]->r)); glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]); glTexCoord2fv(luv[1]->uv); - if (lcol[1]) + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[1]->r)); glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]); glTexCoord2fv(luv[2]->uv); - if (lcol[2]) + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[2]->r)); glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]); } else { - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); glTexCoord2fv(luv[0]->uv); if (lcol[0]) @@ -905,7 +907,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, for (i = 0; i < em->tottri; i++) { BMLoop **ls = em->looptris[i]; - MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL; + MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL; MTFace mtf = {{{0}}}; /*unsigned char *cp = NULL;*/ /*UNUSED*/ int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH); @@ -913,12 +915,12 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, efa = ls[0]->f; - if (has_uv) { + if (cd_poly_tex_offset != -1) { ME_MTEXFACE_CPY(&mtf, tp); } if (drawParams) - draw_option = drawParams(&mtf, has_vcol, efa->mat_nr); + draw_option = drawParams(&mtf, (has_vcol), efa->mat_nr); else if (drawParamsMapped) draw_option = drawParamsMapped(userData, BM_elem_index_get(efa)); else @@ -930,46 +932,42 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, if (!drawSmooth) { glNormal3fv(efa->no); - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); - if (luv[0]) - glTexCoord2fv(luv[0]->uv); - if (lcol[0]) + glTexCoord2fv(luv[0]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[0]->r)); glVertex3fv(ls[0]->v->co); - if (luv[1]) - glTexCoord2fv(luv[1]->uv); - if (lcol[1]) + glTexCoord2fv(luv[1]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[1]->r)); glVertex3fv(ls[1]->v->co); - if (luv[2]) - glTexCoord2fv(luv[2]->uv); - if (lcol[2]) + glTexCoord2fv(luv[2]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[2]->r)); glVertex3fv(ls[2]->v->co); } else { - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); - if (luv[0]) - glTexCoord2fv(luv[0]->uv); - if (lcol[0]) + glTexCoord2fv(luv[0]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[0]->r)); glNormal3fv(ls[0]->v->no); glVertex3fv(ls[0]->v->co); - if (luv[1]) - glTexCoord2fv(luv[1]->uv); - if (lcol[1]) + glTexCoord2fv(luv[1]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[1]->r)); glNormal3fv(ls[1]->v->no); glVertex3fv(ls[1]->v->co); - if (luv[2]) - glTexCoord2fv(luv[2]->uv); - if (lcol[2]) + glTexCoord2fv(luv[2]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[2]->r)); glNormal3fv(ls[2]->v->no); glVertex3fv(ls[2]->v->co); @@ -1309,14 +1307,16 @@ static int emDM_getNumPolys(DerivedMesh *dm) static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r) { + float *f; + copy_v3_v3(vert_r->co, ev->co); normal_float_to_short_v3(vert_r->no, ev->no); vert_r->flag = BM_vert_flag_to_mflag(ev); - if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT) * 255.0f); + if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) { + vert_r->bweight = (unsigned char)((*f) * 255.0f); } return 1; @@ -1332,8 +1332,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) return; } - // ev = EDBM_vert_at_index(bmdm->tc, index); - ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ + ev = bmdm->tc->vert_index[index]; /* should be EDBM_vert_at_index() */ + // ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ bmvert_to_mvert(bmdm->tc->bm, ev, vert_r); if (bmdm->vertexCos) @@ -1345,27 +1345,27 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r) EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMesh *bm = bmdm->tc->bm; BMEdge *e; + float *f; if (index < 0 || index >= bmdm->te) { printf("error in emDM_getEdge.\n"); return; } - // e = EDBM_edge_at_index(bmdm->tc, index); - e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ - - if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) * 255.0f); - } - - if (CustomData_has_layer(&bm->edata, CD_CREASE)) { - edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE) * 255.0f); - } + e = bmdm->tc->edge_index[index]; /* should be EDBM_edge_at_index() */ + // e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ edge_r->flag = BM_edge_flag_to_mflag(e); edge_r->v1 = BM_elem_index_get(e->v1); edge_r->v2 = BM_elem_index_get(e->v2); + + if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) { + edge_r->bweight = (unsigned char)((*f) * 255.0f); + } + if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) { + edge_r->crease = (unsigned char)((*f) * 255.0f); + } } static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r) @@ -1400,7 +1400,7 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) BMesh *bm = bmdm->tc->bm; BMVert *eve; BMIter iter; - const int has_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT); + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); if (bmdm->vertexCos) { int i; @@ -1410,9 +1410,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) normal_float_to_short_v3(vert_r->no, eve->no); vert_r->flag = BM_vert_flag_to_mflag(eve); - if (has_bweight) { - vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f); - } + if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); + vert_r++; } } @@ -1422,9 +1421,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) normal_float_to_short_v3(vert_r->no, eve->no); vert_r->flag = BM_vert_flag_to_mflag(eve); - if (has_bweight) { - vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f); - } + if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); + vert_r++; } } @@ -1435,24 +1433,20 @@ static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm; BMEdge *eed; BMIter iter; - const int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT); - const int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE); + + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (has_bweight) { - edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f); - } - - if (has_crease) { - edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f); - } + edge_r->v1 = BM_elem_index_get(eed->v1); + edge_r->v2 = BM_elem_index_get(eed->v2); edge_r->flag = BM_edge_flag_to_mflag(eed); - edge_r->v1 = BM_elem_index_get(eed->v1); - edge_r->v2 = BM_elem_index_get(eed->v2); + if (cd_edge_crease_offset != -1) edge_r->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) edge_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); edge_r++; } @@ -1660,6 +1654,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert, em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface); + /* could also get from the objects mesh directly */ + bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm); + bmdm->dm.getVertCos = emDM_getVertCos; bmdm->dm.getMinMax = emDM_getMinMax; diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 2b393b4d90b..7b007af86d6 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -141,55 +141,34 @@ static void fcm_generator_verify(FModifier *fcm) switch (data->mode) { case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ { + const int arraysize_new = data->poly_order + 1; /* arraysize needs to be order+1, so resize if not */ - if (data->arraysize != (data->poly_order + 1)) { - float *nc; - - /* make new coefficients array, and copy over as much data as can fit */ - nc = MEM_callocN(sizeof(float) * (data->poly_order + 1), "FMod_Generator_Coefs"); - + if (data->arraysize != arraysize_new) { if (data->coefficients) { - if ((int)data->arraysize > (data->poly_order + 1)) - memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order + 1)); - else - memcpy(nc, data->coefficients, sizeof(float) * data->arraysize); - - /* free the old data */ - MEM_freeN(data->coefficients); + data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); } - - /* set the new data */ - data->coefficients = nc; - data->arraysize = data->poly_order + 1; + else { + data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs"); + } + data->arraysize = arraysize_new; } + break; } - break; - case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */ { - /* arraysize needs to be 2*order, so resize if not */ - if (data->arraysize != (data->poly_order * 2)) { - float *nc; - - /* make new coefficients array, and copy over as much data as can fit */ - nc = MEM_callocN(sizeof(float) * (data->poly_order * 2), "FMod_Generator_Coefs"); - + const int arraysize_new = data->poly_order * 2; + /* arraysize needs to be (2 * order), so resize if not */ + if (data->arraysize != arraysize_new) { if (data->coefficients) { - if (data->arraysize > (unsigned int)(data->poly_order * 2)) - memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order * 2)); - else - memcpy(nc, data->coefficients, sizeof(float) * data->arraysize); - - /* free the old data */ - MEM_freeN(data->coefficients); + data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); } - - /* set the new data */ - data->coefficients = nc; - data->arraysize = data->poly_order * 2; + else { + data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs"); + } + data->arraysize = arraysize_new; } + break; } - break; } } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index dbc423f98b3..21417386d65 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -904,7 +904,7 @@ void BKE_image_free_all_textures(void) image_free_buffers(ima); } } - /* printf("freed total %d MB\n", totsize/(1024*1024)); */ + /* printf("freed total %d MB\n", totsize / (1024 * 1024)); */ } /* except_frame is weak, only works for seqs without offset... */ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 30e7cb3bb36..dec7556392f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1204,8 +1204,8 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp, allvert, totvert, alledge, totedge, - allloop, allpoly, - totloop, totpoly, NULL); + allloop, allpoly, NULL, + totloop, totpoly); } /* BMESH: this doesn't calculate all edges from polygons, @@ -1213,25 +1213,24 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */ /* use specified dispbase */ -/* TODO: orco values for non DL_SURF types */ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, MVert **allvert, int *_totvert, MEdge **alledge, int *_totedge, MLoop **allloop, MPoly **allpoly, - int *_totloop, int *_totpoly, - int **orco_index_ptr) + MLoopUV **alluv, + int *_totloop, int *_totpoly) { DispList *dl; Curve *cu; MVert *mvert; MPoly *mpoly; MLoop *mloop; + MLoopUV *mloopuv = NULL; MEdge *medge; float *data; int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0; int p1, p2, p3, p4, *index; int conv_polys = 0; - int (*orco_index)[4] = NULL; cu = ob->data; @@ -1278,15 +1277,13 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, *alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge"); *allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop *allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop"); + + if (alluv) + *alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv"); /* verts and faces */ vertcount = 0; - if (orco_index_ptr) { - *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco"); - orco_index = (int (*)[4]) *orco_index_ptr; - } - dl = dispbase->first; while (dl) { int smooth = dl->rt & CU_SMOOTH ? 1 : 0; @@ -1359,6 +1356,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mpoly->totloop = 3; mpoly->mat_nr = dl->col; + if (mloopuv) { + int i; + + for (i = 0; i < 3; i++, mloopuv++) { + mloopuv->uv[0] = (mloop[i].v - startvert)/(float)(dl->nr - 1); + mloopuv->uv[1] = 0.0f; + } + } + if (smooth) mpoly->flag |= ME_SMOOTH; mpoly++; mloop += 3; @@ -1408,13 +1414,29 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mpoly->totloop = 4; mpoly->mat_nr = dl->col; - if (orco_index) { - const int poly_index = mpoly - *allpoly; - const int p_orco_base = startvert + ((dl->nr + 1) * a) + b; - orco_index[poly_index][0] = p_orco_base + 1; - orco_index[poly_index][1] = p_orco_base + dl->nr + 2; - orco_index[poly_index][2] = p_orco_base + dl->nr + 1; - orco_index[poly_index][3] = p_orco_base; + if (mloopuv) { + int orco_sizeu = dl->nr - 1; + int orco_sizev = dl->parts - 1; + int i; + + /* exception as handled in convertblender.c too */ + if (dl->flag & DL_CYCL_U) { + orco_sizeu++; + if (dl->flag & DL_CYCL_V) + orco_sizev++; + } + + for (i = 0; i < 4; i++, mloopuv++) { + /* find uv based on vertex index into grid array */ + int v = mloop[i].v - startvert; + + mloopuv->uv[0] = (v / dl->nr)/(float)orco_sizev; + mloopuv->uv[1] = (v % dl->nr)/(float)orco_sizeu; + + /* cyclic correction */ + if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f) + mloopuv->uv[1] = 1.0f; + } } if (smooth) mpoly->flag |= ME_SMOOTH; @@ -1427,7 +1449,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, p1++; } } - } dl = dl->next; @@ -1448,33 +1469,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, } -MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2]) -{ - r[0] = 0.5f + a[0] * 0.5f; - r[1] = 0.5f + a[1] * 0.5f; -} - -/** - * orco is normally from #BKE_curve_make_orco - */ -void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly, - MLoop *mloops, MLoopUV *mloopuvs, - float (*orco)[3], int (*orco_index)[4]) -{ - MPoly *mp; - - int i, j; - for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { - MLoop *ml = mloops + mp->loopstart; - MLoopUV *mluv = mloopuvs + mp->loopstart; - for (j = 0; j < mp->totloop; j++, ml++, mluv++) { - copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]); - } - } -} - /* this may fail replacing ob->data, be sure to check ob->type */ -void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) +void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_uv) { Main *bmain = G.main; Object *ob1; @@ -1484,6 +1480,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind MVert *allvert = NULL; MEdge *alledge = NULL; MLoop *allloop = NULL; + MLoopUV *alluv = NULL; MPoly *allpoly = NULL; int totvert, totedge, totloop, totpoly; @@ -1492,7 +1489,8 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind if (dm == NULL) { if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, &totedge, &allloop, - &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) + &allpoly, (use_orco_uv)? &alluv: NULL, + &totloop, &totpoly) != 0) { /* Error initializing */ return; @@ -1510,6 +1508,12 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop); me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly); + if (alluv) { + const char *uvname = "Orco"; + me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname); + me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname); + } + BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL); BKE_mesh_calc_edges(me, TRUE); @@ -1548,7 +1552,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind void BKE_mesh_from_nurbs(Object *ob) { - BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL); + BKE_mesh_from_nurbs_displist(ob, &ob->disp, false); } typedef struct EdgeLink { @@ -3337,3 +3341,39 @@ void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop, } } #endif + + +void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) +{ + if (UNLIKELY(mesh->cd_flag)) { + return; + } + else { + MVert *mv; + MEdge *med; + int i; + + for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) { + if (mv->bweight != 0) { + mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; + break; + } + } + + for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) { + if (med->bweight != 0) { + mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) { + break; + } + } + if (med->crease != 0) { + mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE; + if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + break; + } + } + } + + } +} diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 7df7561a1a1..a6c2325c740 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -59,9 +59,14 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; - int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + bool is_cddm = (dm->type == DM_TYPE_CDDM); /* duplicate the arrays for non cddm */ char has_orig_hflag = 0; + int cd_vert_bweight_offset; + int cd_edge_bweight_offset; + int cd_edge_crease_offset; + if (is_init == FALSE) { /* check if we have an origflag */ has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0; @@ -75,43 +80,45 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP); CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE); + if (is_init) { + BM_mesh_cd_flag_apply(bm, dm->cd_flag); + } + + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + totvert = dm->getNumVerts(dm); totedge = dm->getNumEdges(dm); /* totface = dm->getNumPolys(dm); */ /* UNUSED */ - /* add crease layer */ - BM_data_layer_add(bm, &bm->edata, CD_CREASE); - /* add bevel weight layers */ - BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); - BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); - vtable = MEM_callocN(sizeof(void **) * totvert, __func__); etable = MEM_callocN(sizeof(void **) * totedge, __func__); /*do verts*/ - mv = mvert = dm->dupVertArray(dm); + mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm); for (i = 0; i < totvert; i++, mv++) { v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); BM_elem_index_set(v, i); /* set_inline */ - CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); + CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true); vtable[i] = v; /* add bevel weight */ - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f); + if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f); if (UNLIKELY(has_orig_hflag & BM_VERT)) { int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX); *orig_index = ORIGINDEX_NONE; } } - MEM_freeN(mvert); + if (!is_cddm) MEM_freeN(mvert); if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ - me = medge = dm->dupEdgeArray(dm); + me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD); @@ -119,20 +126,18 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) e->head.hflag = BM_edge_flag_from_mflag(me->flag); BM_elem_index_set(e, i); /* set_inline */ - CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); + CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true); etable[i] = e; - /* add crease */ - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f); - /* add bevel weight */ - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); + if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f); + if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)me->crease / 255.0f); if (UNLIKELY(has_orig_hflag & BM_EDGE)) { int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX); *orig_index = ORIGINDEX_NONE; } } - MEM_freeN(medge); + if (!is_cddm) MEM_freeN(medge); if (is_init) bm->elem_index_dirty &= ~BM_EDGE; /* do faces */ @@ -156,7 +161,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) edges[j] = etable[ml->e]; } - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD); + f = BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD); if (UNLIKELY(f == NULL)) { continue; @@ -169,10 +174,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) { - CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data); + CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true); } - CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data); + CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true); if (face_normals) { copy_v3_v3(f->no, face_normals[i]); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3b897e94241..5eac86a7e77 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2396,6 +2396,7 @@ typedef struct SPHRangeData { ParticleData *pa; float h; + float mass; float massfac; int use_size; } SPHRangeData; @@ -2408,7 +2409,7 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], for (i=0; i < 10 && psys[i]; i++) { pfr->npsys = psys[i]; - pfr->massfac = psys[i]->part->mass; + pfr->massfac = psys[i]->part->mass / pfr->mass; pfr->use_size = psys[i]->part->flag & PART_SIZEMASS; if (tree) { @@ -2491,7 +2492,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa ParticleSpring *spring = NULL; SPHRangeData pfr; SPHNeighbor *pfn; - float mass = sphdata->mass; float *gravity = sphdata->gravity; EdgeHash *springhash = sphdata->eh; @@ -2501,7 +2501,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float visc = fluid->viscosity_omega; float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f); - float inv_mass = 1.0f/mass; + float inv_mass = 1.0f / sphdata->mass; float spring_constant = fluid->spring_k; /* 4.0 seems to be a pretty good value */ @@ -2526,6 +2526,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa pfr.data = data; pfr.h = h; pfr.pa = pa; + pfr.mass = sphdata->mass; sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb); @@ -2644,7 +2645,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSE * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x) * plot [0:2] q1(x) */ q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h); - q *= pfr->massfac; + q *= pfr->npsys->part->mass; if (pfr->use_size) q *= pfr->pa->size; @@ -2696,7 +2697,8 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo /* 4.77 is an experimentally determined density factor */ float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f); - float stiffness = fluid->stiffness_k; + // Use speed of sound squared + float stiffness = pow2(fluid->stiffness_k); ParticleData *npa; float vec[3]; @@ -2792,6 +2794,7 @@ static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData pfr.data = data; pfr.h = interaction_radius * sphdata->hfac; pfr.pa = pa; + pfr.mass = sphdata->mass; sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb); pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f); @@ -2851,7 +2854,8 @@ void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2 density[0] = density[1] = 0.0f; pfr.data = density; - pfr.h = interaction_radius*sphdata->hfac; + pfr.h = interaction_radius * sphdata->hfac; + pfr.mass = sphdata->mass; sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb); @@ -4220,7 +4224,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) ParticleSettings *part = sim->psys->part; psys_sph_init(sim, &sphdata); - if (part->fluid->flag & SPH_SOLVER_DDR) { + if (part->fluid->solver == SPH_SOLVER_DDR) { /* Apply SPH forces using double-density relaxation algorithm * (Clavat et. al.) */ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 9c3c1b0e508..97948683e22 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -272,7 +272,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf ParticleSystem *psys= psys_v; ParticleData *pa; BoidParticle *boid; - float timestep = 0.04f*psys->part->timetweak; + float timestep = 0.04f * psys->part->timetweak; if (index >= psys->totpart) return; @@ -333,7 +333,7 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f ParticleSystem *psys= psys_v; ParticleData *pa; ParticleKey keys[4]; - float dfra, timestep = 0.04f*psys->part->timetweak; + float dfra, timestep = 0.04f * psys->part->timetweak; if (index >= psys->totpart) return; @@ -559,7 +559,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int in_len = sizeof(float)*(unsigned int)res; - unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); + unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer"); //int mode = res >= 1000000 ? 2 : 1; int mode=1; // light if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy @@ -792,7 +792,7 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v) int cache_compress = 1; /* version header */ - ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char)*4); + ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char) * 4); if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) { int total_points=surface->data->total_points; @@ -831,7 +831,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v) char version[4]; /* version header */ - ptcache_file_read(pf, version, 1, sizeof(char)*4); + ptcache_file_read(pf, version, 1, sizeof(char) * 4); if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;} if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) { @@ -1163,7 +1163,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup */ #define MAX_PTCACHE_PATH FILE_MAX -#define MAX_PTCACHE_FILE ((FILE_MAX)*2) +#define MAX_PTCACHE_FILE (FILE_MAX * 2) static int ptcache_path(PTCacheID *pid, char *filename) { @@ -1258,7 +1258,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra) { PTCacheFile *pf; FILE *fp = NULL; - char filename[(FILE_MAX)*2]; + char filename[FILE_MAX * 2]; #ifndef DURIAN_POINTCACHE_LIB_OK /* don't allow writing for linked objects */ @@ -1311,7 +1311,7 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result, size_t out_len = len; #endif unsigned char *in; - unsigned char *props = MEM_callocN(16*sizeof(char), "tmp"); + unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp"); ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char)); if (compressed) { @@ -1354,7 +1354,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns int r = 0; unsigned char compressed = 0; size_t out_len= 0; - unsigned char *props = MEM_callocN(16*sizeof(char), "tmp"); + unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp"); size_t sizeOfIt = 5; (void)mode; /* unused when building w/o compression */ @@ -1787,7 +1787,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) for (i=0; i<BPHYS_TOT_DATA; i++) { if (pm->data[i]) { unsigned int in_len = pm->totpoint*ptcache_data_size[i]; - unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); + unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression); MEM_freeN(out); } @@ -1820,7 +1820,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) if (pid->cache->compression) { unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type]; - unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); + unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression); MEM_freeN(out); } diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 185aeac5452..1fd7dc14c23 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -27,6 +27,10 @@ * \ingroup bke */ +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> #include "MEM_guardedalloc.h" @@ -39,10 +43,6 @@ #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ -#include <stdarg.h> -#include <stdio.h> -#include <string.h> - static const char *report_type_str(int type) { switch (type) { @@ -302,3 +302,36 @@ int BKE_reports_contain(ReportList *reports, ReportType level) return FALSE; } +bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header) +{ + Report *report; + + if (header) { + fputs(header, fp); + } + + for (report = reports->list.first; report; report = report->next) { + fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr); + } + + return true; +} + +bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header) +{ + FILE *fp; + + errno = 0; + fp = BLI_fopen(filepath, "wb"); + if (fp == NULL) { + fprintf(stderr, "Unable to save '%s': %s\n", + filepath, errno ? strerror(errno) : "Unknown error opening file"); + return false; + } + + BKE_report_write_file_fp(fp, reports, header); + + fclose(fp); + + return true; +} diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 04e612d1a33..eb56f34b99b 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1045,6 +1045,47 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene) } } +/* deps hack - do extra recalcs at end */ +static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent) +{ + Base *base; + + scene->customdata_mask = scene_parent->customdata_mask; + + /* sets first, we allow per definition current scene to have + * dependencies on sets, but not the other way around. */ + if (scene->set) + scene_depsgraph_hack(scene->set, scene_parent); + + for (base = scene->base.first; base; base = base->next) { + Object *ob = base->object; + + if (ob->depsflag) { + int recalc = 0; + // printf("depshack %s\n", ob->id.name+2); + + if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC) + recalc |= OB_RECALC_OB; + if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC) + recalc |= OB_RECALC_DATA; + + ob->recalc |= recalc; + BKE_object_handle_update(scene_parent, ob); + + if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) { + GroupObject *go; + + for (go = ob->dup_group->gobject.first; go; go = go->next) { + if (go->ob) + go->ob->recalc |= recalc; + } + group_handle_recalc_and_update(scene_parent, ob, ob->dup_group); + } + } + } + +} + static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent) { Base *base; @@ -1080,6 +1121,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* update masking curves */ BKE_mask_update_scene(bmain, scene, FALSE); + } /* this is called in main loop, doing tagged updates before redraw */ @@ -1172,6 +1214,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) /* BKE_object_handle_update() on all objects, groups and sets */ scene_update_tagged_recursive(bmain, sce, sce); + scene_depsgraph_hack(sce, sce); + /* notify editors and python about recalc */ BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST); BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 81bcdc4b06e..95b72d0185c 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -167,6 +167,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar) newar->prev = newar->next = NULL; newar->handlers.first = newar->handlers.last = NULL; newar->uiblocks.first = newar->uiblocks.last = NULL; + newar->ui_lists.first = newar->ui_lists.last = NULL; newar->swinid = 0; /* use optional regiondata callback */ diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 3ca04f235b8..c64609c8e70 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1150,7 +1150,7 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned fac3 = (int)(256.0f * facf1); /* formula: - * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx + * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx * yaux = -s * px + c * py; //+centy */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 8d010de408a..2c1fd092fbb 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2391,7 +2391,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX, - TRUE, FALSE, err_out); + TRUE, scene->r.alphamode, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index b1917c6091d..01409a0f7e4 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1322,8 +1322,8 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop) for (index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */ - /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */ + /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */ + /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */ for (S = 0; S < numVerts; S++) { for (y = 0; y < gridSize - 1; y++) { @@ -3328,7 +3328,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /*I think this is for interpolating the center vert?*/ - w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1); + w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1); DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum); if (vertOrigIndex) { diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index b322d9d7aef..448396811d3 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -53,6 +53,7 @@ float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2] float area_tri_v3(const float a[3], const float b[3], const float c[3]); float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]); float area_poly_v3(int nr, float verts[][3], const float normal[3]); +float area_poly_v2(int nr, float verts[][2]); int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); @@ -260,7 +261,12 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f); float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]); -void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]); +void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]); +float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +#endif +; MINLINE int max_axis_v3(const float vec[3]); MINLINE int min_axis_v3(const float vec[3]); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index f2e26093711..3c9363039b2 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -56,6 +56,8 @@ void BLI_rctf_translate(struct rctf *rect, float x, float y); void BLI_rcti_translate(struct rcti *rect, int x, int y); void BLI_rcti_resize(struct rcti *rect, int x, int y); void BLI_rctf_resize(struct rctf *rect, float x, float y); +void BLI_rcti_scale(rcti *rect, const float scale); +void BLI_rctf_scale(rctf *rect, const float scale); void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac); //void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac); int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]); diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 5204e0dd718..7830c0675b4 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -103,7 +103,7 @@ enum { BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1), /* note: This flag removes checks for overlapping polygons. - * when this flag is set, we'll never get back more faces then (totvert - 2)*/ + * when this flag is set, we'll never get back more faces then (totvert - 2) */ BLI_SCANFILL_CALC_HOLES = (1 << 2) }; diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index cb30138c4f9..43b1e7871cd 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -32,6 +32,10 @@ * \ingroup bli */ +#ifndef NDEBUG /* for BLI_assert */ +#include <stdio.h> +#endif + /* note: use of (int, TRUE / FALSE) is deprecated, * use (bool, true / false) instead */ #ifdef HAVE_STDBOOL_H diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 3527af365ec..fc1d0e99a30 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -131,35 +131,43 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]) float area_poly_v3(int nr, float verts[][3], const float normal[3]) { - float x, y, z, area, max; - float *cur, *prev; - int a, px = 0, py = 1; - - /* first: find dominant axis: 0==X, 1==Y, 2==Z - * don't use 'axis_dominant_v3()' because we need max axis too */ - x = fabsf(normal[0]); - y = fabsf(normal[1]); - z = fabsf(normal[2]); - max = max_fff(x, y, z); - if (max == y) py = 2; - else if (max == x) { - px = 1; - py = 2; - } + int a, px, py; + const float max = axis_dominant_v3_max(&px, &py, normal); + float area; + float *co_curr, *co_prev; /* The Trapezium Area Rule */ - prev = verts[nr - 1]; - cur = verts[0]; - area = 0; + co_prev = verts[nr - 1]; + co_curr = verts[0]; + area = 0.0f; for (a = 0; a < nr; a++) { - area += (cur[px] - prev[px]) * (cur[py] + prev[py]); - prev = verts[a]; - cur = verts[a + 1]; + area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]); + co_prev = verts[a]; + co_curr = verts[a + 1]; } return fabsf(0.5f * area / max); } +float area_poly_v2(int nr, float verts[][2]) +{ + int a; + float area; + float *co_curr, *co_prev; + + /* The Trapezium Area Rule */ + co_prev = verts[nr - 1]; + co_curr = verts[0]; + area = 0.0f; + for (a = 0; a < nr; a++) { + area += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]); + co_prev = verts[a]; + co_curr = verts[a + 1]; + } + + return fabsf(0.5f * area); +} + /********************************* Distance **********************************/ /* distance p to line v1-v2 @@ -329,7 +337,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], return; } /* Check if P in edge region of AB, if so return projection of P onto AB */ - vc = d1*d4 - d3*d2; + vc = d1 * d4 - d3 * d2; if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { float v = d1 / (d1 - d3); /* barycentric coordinates (1-v,v,0) */ @@ -346,7 +354,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], return; } /* Check if P in edge region of AC, if so return projection of P onto AC */ - vb = d5*d2 - d1*d6; + vb = d5 * d2 - d1 * d6; if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { float w = d2 / (d2 - d6); /* barycentric coordinates (1-w,0,w) */ @@ -354,7 +362,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], return; } /* Check if P in edge region of BC, if so return projection of P onto BC */ - va = d3*d6 - d5*d4; + va = d3 * d6 - d5 * d4; if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { float w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); /* barycentric coordinates (0,1-w,w) */ @@ -1817,7 +1825,7 @@ static int point_in_slice_as(float p[3], float origin[3], float normal[3]) return 1; } -/*mama (knowing the squared length of the normal)*/ +/*mama (knowing the squared length of the normal) */ static int point_in_slice_m(float p[3], float origin[3], float normal[3], float lns) { float h, rp[3]; @@ -1952,15 +1960,27 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int, /****************************** Interpolation ********************************/ /* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */ -void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]) +void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]) +{ + const float xn = fabsf(axis[0]); + const float yn = fabsf(axis[1]); + const float zn = fabsf(axis[2]); + + if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; } + else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; } + else { *r_axis_a = 1; *r_axis_b = 2; } +} + +/* same as axis_dominant_v3 but return the max value */ +float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) { const float xn = fabsf(axis[0]); const float yn = fabsf(axis[1]); const float zn = fabsf(axis[2]); - if (zn >= xn && zn >= yn) { *axis_a = 0; *axis_b = 1; } - else if (yn >= xn && yn >= zn) { *axis_a = 0; *axis_b = 2; } - else { *axis_a = 1; *axis_b = 2; } + if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; } + else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; } + else { *r_axis_a = 1; *r_axis_b = 2; return xn; } } static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j) @@ -2334,14 +2354,25 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ { /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; - int i; + int i, i_next, i_curr; + bool edge_interp = false; totweight = 0.0f; for (i = 0; i < n; i++) { + i_curr = i; + i_next = (i == n - 1) ? 0 : i + 1; + vmid = v[i]; vprev = (i == 0) ? v[n - 1] : v[i - 1]; - vnext = (i == n - 1) ? v[0] : v[i + 1]; + vnext = v[i_next]; + + /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close + * to borders of face. In that case, do simple linear interpolation between the two edge vertices */ + if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) { + edge_interp = true; + break; + } t1 = mean_value_half_tan_v3(co, vprev, vmid); t2 = mean_value_half_tan_v3(co, vmid, vnext); @@ -2351,25 +2382,49 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ totweight += w[i]; } - if (totweight != 0.0f) { - for (i = 0; i < n; i++) { - w[i] /= totweight; + if (edge_interp) { + float len_curr = len_v3v3(co, vmid); + float len_next = len_v3v3(co, vnext); + float edge_len = len_curr + len_next; + for (i = 0; i < n; i++) + w[i] = 0.0; + + w[i_curr] = len_next / edge_len; + w[i_next] = len_curr / edge_len; + } + else { + if (totweight != 0.0f) { + for (i = 0; i < n; i++) { + w[i] /= totweight; + } } } } + void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2]) { /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; - int i; + int i, i_next, i_curr; + bool edge_interp = false; totweight = 0.0f; for (i = 0; i < n; i++) { + i_curr = i; + i_next = (i == n - 1) ? 0 : i + 1; + vmid = v[i]; vprev = (i == 0) ? v[n - 1] : v[i - 1]; - vnext = (i == n - 1) ? v[0] : v[i + 1]; + vnext = v[i_next]; + + /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close + * to borders of face. In that case, do simple linear interpolation between the two edge vertices */ + if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) { + edge_interp = true; + break; + } t1 = mean_value_half_tan_v2(co, vprev, vmid); t2 = mean_value_half_tan_v2(co, vmid, vnext); @@ -2379,9 +2434,21 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ totweight += w[i]; } - if (totweight != 0.0f) { - for (i = 0; i < n; i++) { - w[i] /= totweight; + if (edge_interp) { + float len_curr = len_v2v2(co, vmid); + float len_next = len_v2v2(co, vnext); + float edge_len = len_curr + len_next; + for (i = 0; i < n; i++) + w[i] = 0.0; + + w[i_curr] = len_next / edge_len; + w[i_next] = len_curr / edge_len; + } + else { + if (totweight != 0.0f) { + for (i = 0; i < n; i++) { + w[i] /= totweight; + } } } } diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index fb767f54e55..4bd7715ea7a 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -317,6 +317,30 @@ void BLI_rctf_resize(rctf *rect, float x, float y) rect->ymax = rect->ymin + y; } +void BLI_rcti_scale(rcti *rect, const float scale) +{ + const int cent_x = BLI_rcti_cent_x(rect); + const int cent_y = BLI_rcti_cent_y(rect); + const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f); + const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f); + rect->xmin = cent_x - size_x_half; + rect->ymin = cent_y - size_y_half; + rect->xmax = cent_x + size_x_half; + rect->ymax = cent_y + size_y_half; +} + +void BLI_rctf_scale(rctf *rect, const float scale) +{ + const float cent_x = BLI_rctf_cent_x(rect); + const float cent_y = BLI_rctf_cent_y(rect); + const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f); + const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f); + rect->xmin = cent_x - size_x_half; + rect->ymin = cent_y - size_y_half; + rect->xmax = cent_x + size_x_half; + rect->ymax = cent_y + size_y_half; +} + void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac) { const float ifac = 1.0f - fac; diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index f23f75f69d9..28fdf7b61db 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -412,7 +412,7 @@ int BLI_natstrcmp(const char *s1, const char *s2) void BLI_timestr(double _time, char *str) { /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ - int hr = ( (int) _time) / (60*60); + int hr = ( (int) _time) / (60 * 60); int min = (((int) _time) / 60 ) % 60; int sec = ( (int) (_time)) % 60; int hun = ( (int) (_time * 100.0)) % 100; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 151a929a445..df68f711843 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5137,6 +5137,16 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->imapaint.paintcursor = NULL; sce->toolsettings->particle.paintcursor = NULL; + + /* in rare cases this is needed, see [#33806] */ + if (sce->toolsettings->vpaint) { + sce->toolsettings->vpaint->vpaint_prev = NULL; + sce->toolsettings->vpaint->tot = 0; + } + if (sce->toolsettings->wpaint) { + sce->toolsettings->wpaint->wpaint_prev = NULL; + sce->toolsettings->wpaint->tot = 0; + } } if (sce->ed) { @@ -8811,6 +8821,49 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) { + Curve *cu; + + for (cu = main->curve.first; cu; cu = cu->id.next) { + if (cu->flag & (CU_FRONT | CU_BACK)) { + if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) { + Nurb *nu; + + for (nu = cu->nurb.first; nu; nu = nu->next) { + int a; + + if (nu->bezt) { + BezTriple *bezt = nu->bezt; + a = nu->pntsu; + + while (a--) { + bezt->radius = 1.0f; + bezt++; + } + } + else if (nu->bp) { + BPoint *bp = nu->bp; + a = nu->pntsu * nu->pntsv; + + while (a--) { + bp->radius = 1.0f; + bp++; + } + } + } + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(main, 265, 8)) { + Mesh *me; + for (me = main->mesh.first; me; me = me->id.next) { + BKE_mesh_do_versions_cd_flag_init(me); + } + } + + // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) { #ifdef WITH_FREESTYLE /* default values in Freestyle settings */ diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index 5d8a865eea8..cbbaf713e84 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -48,11 +48,12 @@ #include "BLO_readfile.h" #include "BLO_runtime.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + #include "BKE_blender.h" #include "BKE_report.h" -#include "BLI_blenlib.h" - /* Runtime reading */ static int handle_read_msb_int(int handle) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b1aee9f498a..63d8c9b0e0e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1423,8 +1423,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) int size = mmd->dyngridsize; writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences); - writedata(wd, DATA, sizeof(int)*(mmd->totvert+1), mmd->bindoffsets); - writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert, + writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets); + writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert, mmd->bindcagecos); writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid); writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences); @@ -1681,7 +1681,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external) MDisps *md = &mdlist[i]; if (md->disps) { if (!external) - writedata(wd, DATA, sizeof(float)*3*md->totdisp, md->disps); + writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps); } if (md->hidden) diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 0961106f141..e838b130cef 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -184,10 +184,10 @@ typedef struct BMesh { * BM_LOOP isn't handled so far. */ char elem_index_dirty; - /*element pools*/ + /* element pools */ struct BLI_mempool *vpool, *epool, *lpool, *fpool; - /*operator api stuff (must be all NULL or all alloc'd)*/ + /* operator api stuff (must be all NULL or all alloc'd) */ struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool; int stackdepth; @@ -205,7 +205,7 @@ typedef struct BMesh { * Only use when the edit mesh cant be accessed - campbell */ short selectmode; - /*ID of the shape key this bmesh came from*/ + /* ID of the shape key this bmesh came from */ int shapenr; int walkers, totflags; @@ -257,6 +257,18 @@ enum { /* defines */ +#define BM_ELEM_CD_GET_VOID_P(ele, offset) \ + ((void)0, (void *)((char *)(ele)->head.data + (offset))) + +#define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \ + { *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0 + +#define BM_ELEM_CD_GET_FLOAT(ele, offset) \ + ((void)0, *((float *)((char *)(ele)->head.data + (offset)))) + +#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \ + (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f) + /*forward declarations*/ #ifdef USE_BMESH_HOLES diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 4ec91b8d8d7..1afaf851e2a 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -606,9 +606,9 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, void **vblocks = do_vertex ? BLI_array_alloca(vblocks, source->len) : NULL; void **blocks = BLI_array_alloca(blocks, source->len); float (*cos)[3] = BLI_array_alloca(cos, source->len); + float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len); float *w = BLI_array_alloca(w, source->len); - float co[3]; - float cent[3] = {0.0f, 0.0f, 0.0f}; + float co[2]; int i, ax, ay; BM_elem_attrs_copy(bm, bm, source, target->f); @@ -617,7 +617,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, l_iter = l_first = BM_FACE_FIRST_LOOP(source); do { copy_v3_v3(cos[i], l_iter->v->co); - add_v3_v3(cent, cos[i]); w[i] = 0.0f; blocks[i] = l_iter->head.data; @@ -634,28 +633,17 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, axis_dominant_v3(&ax, &ay, source->no); - /* scale source face coordinates a bit, so points sitting directly on an - * edge will work. */ - mul_v3_fl(cent, 1.0f / (float)source->len); for (i = 0; i < source->len; i++) { - float vec[3], tmp[3]; - sub_v3_v3v3(vec, cent, cos[i]); - mul_v3_fl(vec, 0.001f); - add_v3_v3(cos[i], vec); - - copy_v3_v3(tmp, cos[i]); - cos[i][0] = tmp[ax]; - cos[i][1] = tmp[ay]; - cos[i][2] = 0.0f; + cos_2d[i][0] = cos[i][ax]; + cos_2d[i][1] = cos[i][ay]; } /* interpolate */ co[0] = target->v->co[ax]; co[1] = target->v->co[ay]; - co[2] = 0.0f; - interp_weights_poly_v3(w, cos, source->len, co); + interp_weights_poly_v2(w, cos_2d, source->len, co); CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data); if (do_vertex) { CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data); @@ -676,30 +664,18 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) void **blocks = BLI_array_alloca(blocks, source->len); float (*cos)[3] = BLI_array_alloca(cos, source->len); float *w = BLI_array_alloca(w, source->len); - float cent[3] = {0.0f, 0.0f, 0.0f}; int i; i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(source); do { copy_v3_v3(cos[i], l_iter->v->co); - add_v3_v3(cent, cos[i]); w[i] = 0.0f; blocks[i] = l_iter->v->head.data; i++; } while ((l_iter = l_iter->next) != l_first); - /* scale source face coordinates a bit, so points sitting directly on an - * edge will work. */ - mul_v3_fl(cent, 1.0f / (float)source->len); - for (i = 0; i < source->len; i++) { - float vec[3]; - sub_v3_v3v3(vec, cent, cos[i]); - mul_v3_fl(vec, 0.01f); - add_v3_v3(cos[i], vec); - } - /* interpolate */ interp_weights_poly_v3(w, cos, source->len, v->co); CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data); diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index b821c9875db..a2510129df6 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -523,14 +523,14 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log) i = 0; varr = MEM_mallocN(sizeof(int) * bm->totvert, AT); BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) { - ((unsigned int*)varr)[i++] = bm_log_vert_id_get(log, v); + ((unsigned int *)varr)[i++] = bm_log_vert_id_get(log, v); } /* Put all face IDs into an array */ i = 0; farr = MEM_mallocN(sizeof(int) * bm->totface, AT); BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) { - ((unsigned int*)farr)[i++] = bm_log_face_id_get(log, f); + ((unsigned int *)farr)[i++] = bm_log_face_id_get(log, f); } /* Create BMVert index remap array */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 388d148377a..8198e30bac6 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -98,6 +98,70 @@ #include "bmesh.h" #include "intern/bmesh_private.h" /* for element checking */ +void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag) +{ + const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag; + BM_mesh_cd_flag_apply(bm, cd_flag_all); + if (mesh) { + mesh->cd_flag = cd_flag_all; + } +} + +void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) +{ + /* CustomData_bmesh_init_pool() must run first */ + BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL); + BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL); + + if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) { + if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); + } + } + else { + if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT); + } + } + + if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT); + } + } + + if (cd_flag & ME_CDFLAG_EDGE_CREASE) { + if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { + BM_data_layer_add(bm, &bm->edata, CD_CREASE); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_CREASE)) { + BM_data_layer_free(bm, &bm->edata, CD_CREASE); + } + } +} + +char BM_mesh_cd_flag_from_bmesh(BMesh *bm) +{ + char cd_flag = 0; + if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + cd_flag |= ME_CDFLAG_VERT_BWEIGHT; + } + if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + } + if (CustomData_has_layer(&bm->edata, CD_CREASE)) { + cd_flag |= ME_CDFLAG_EDGE_CREASE; + } + return cd_flag; +} + /* Mesh -> BMesh */ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) { @@ -116,6 +180,10 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) int *keyi; int totuv, i, j; + int cd_vert_bweight_offset; + int cd_edge_bweight_offset; + int cd_edge_crease_offset; + /* free custom data */ /* this isnt needed in most cases but do just incase */ CustomData_free(&bm->vdata, bm->totvert); @@ -152,15 +220,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name); } - if (!CustomData_has_layer(&bm->edata, CD_CREASE)) - CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0); - - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) - CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0); - - if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) - CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0); - if ((act_key_nr != 0) && (me->key != NULL)) { actkey = BLI_findlink(&me->key->block, act_key_nr - 1); } @@ -205,6 +264,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); + BM_mesh_cd_flag_apply(bm, me->cd_flag); + + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD); BM_elem_index_set(v, i); /* set_ok */ @@ -221,9 +286,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) normal_short_to_float_v3(v->no, mvert->no); /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data); + CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true); - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f); + if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f); /* set shapekey data */ if (me->key) { @@ -267,10 +332,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) } /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data); + CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true); + + if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f); + if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f); - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f); - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f); } bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */ @@ -338,11 +404,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) j = 0; BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) { /* Save index of correspsonding MLoop */ - CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data); + CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data, true); } /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data); + CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true); } bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */ @@ -496,6 +562,10 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) BMIter iter, liter; int i, j, ototvert; + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + ototvert = me->totvert; /* new vertex block */ @@ -555,10 +625,6 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT); - - mvert->bweight = bweight ? (char)((*bweight) * 255) : 0; - copy_v3_v3(mvert->co, v->co); normal_float_to_short_v3(mvert->no, v->no); @@ -569,6 +635,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) /* copy over customdat */ CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); + if (cd_vert_bweight_offset != -1) mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); + i++; mvert++; @@ -579,13 +647,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) med = medge; i = 0; BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE); - float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT); - med->v1 = BM_elem_index_get(e->v1); med->v2 = BM_elem_index_get(e->v2); - med->crease = crease ? (char)((*crease) * 255) : 0; - med->bweight = bweight ? (char)((*bweight) * 255) : 0; med->flag = BM_edge_flag_to_mflag(e); @@ -596,6 +659,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) bmesh_quick_edgedraw_flag(med, e); + if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); + i++; med++; BM_CHECK_ELEMENT(e); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h index f9c51584081..55ac39c6745 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.h +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h @@ -34,6 +34,10 @@ struct Mesh; +void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag); +void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag); +char BM_mesh_cd_flag_from_bmesh(BMesh *bm); + void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, int set_key, int act_key_nr); void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, int dotess); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 953e7f4d20c..4545c9bb564 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -158,7 +158,6 @@ float BM_face_calc_area(BMFace *f) BMLoop *l; BMIter iter; float (*verts)[3] = BLI_array_alloca(verts, f->len); - float normal[3]; float area; int i; @@ -173,6 +172,7 @@ float BM_face_calc_area(BMFace *f) area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]); } else { + float normal[3]; calc_poly_normal(normal, verts, f->len); area = area_poly_v3(f->len, verts, normal); } diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index bb013e6428e..538a9058ed5 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -403,6 +403,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker) continue; } + /* saves checking BLI_ghash_haskey below (manifold edges theres a 50% chance) */ + if (f == iwalk->cur) { + continue; + } + if (BLI_ghash_haskey(walker->visithash, f)) { continue; } diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index d20d01af114..663ee463a2c 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) /* sf_edge->tmp.p = e; */ /* UNUSED */ } - BLI_scanfill_calc(&sf_ctx, 0); + BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_HOLES); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { BMFace *f = BM_face_create_quad_tri(bm, diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 759246c38e0..a593e40d850 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1499,7 +1499,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) { BMEdge *bme; BevVert *bv; - BMEdge *bme2, *unflagged_bme; + BMEdge *bme2, *unflagged_bme, *first_bme; BMFace *f; BMIter iter, iter2; EdgeHalf *e; @@ -1511,10 +1511,16 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) * Only bevel selected edges that have exactly two incident faces. */ + if (bp->vertex_only) + first_bme = v->e; + else + first_bme = NULL; BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) { BLI_assert(BM_edge_is_manifold(bme)); nsel++; + if (!first_bme) + first_bme = bme; } ntot++; @@ -1543,7 +1549,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) /* add edges to bv->edges in order that keeps adjacent edges sharing * a face, if possible */ i = 0; - bme = v->e; + + bme = first_bme; BM_BEVEL_EDGE_TAG_ENABLE(bme); e = &bv->edges[0]; e->e = bme; @@ -1557,6 +1564,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) continue; if (!unflagged_bme) unflagged_bme = bme2; + if (!bme->l) + continue; BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) { if (BM_face_edge_share_loop(f, bme)) { found_shared_face = 1; @@ -1591,7 +1600,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) } /* 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].e->l && 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; diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 7c054d84405..794afb3e0d2 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -172,7 +172,7 @@ static int bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_c #endif /* use a small value rather then zero so we don't flip a face in multiple steps - * (first making it zero area, then flipping again)*/ + * (first making it zero area, then flipping again) */ if (dot_v3v3(cross_exist, cross_optim) <= FLT_EPSILON) { //printf("no flip\n"); return TRUE; @@ -441,6 +441,8 @@ static void bm_decim_triangulate_end(BMesh *bm) static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_clear, BMVert *v_other, const float customdata_fac) { + /* disable seam check - the seam check would have to be done per layer, its not really that important */ +//#define USE_SEAM /* these don't need to be updated, since they will get removed when the edge collapses */ BMLoop *l_clear, *l_other; const int is_manifold = BM_edge_is_manifold(l->e); @@ -464,7 +466,9 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle /* now we have both corners of the face 'l->f' */ for (side = 0; side < 2; side++) { +#ifdef USE_SEAM int is_seam = FALSE; +#endif void *src[2]; BMFace *f_exit = is_manifold ? l->radial_next->f : NULL; BMEdge *e_prev = l->e; @@ -501,34 +505,40 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle break; } +#ifdef USE_SEAM /* break out unless we find a match */ is_seam = TRUE; +#endif /* ok. we have a loop. now be smart with it! */ for (i = 0; i < bm->ldata.totlayer; i++) { if (CustomData_layer_has_math(&bm->ldata, i)) { const int offset = bm->ldata.layers[i].offset; const int type = bm->ldata.layers[i].type; - void *cd_src, *cd_iter; - - /* todo, make nicer macros for this */ - cd_src = (char *)src[0] + offset; - // cd_dst = (char *)src[1] + offset; // UNUSED - cd_iter = (char *)l_iter->head.data + offset; + void *cd_src[2] = {(char *)src[0] + offset, + (char *)src[1] + offset}; + void *cd_iter = (char *)l_iter->head.data + offset;; /* detect seams */ - if (CustomData_data_equals(type, cd_src, cd_iter)) { - CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_iter->head.data); + if (CustomData_data_equals(type, cd_src[0], cd_iter)) { + CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i); +#ifdef USE_SEAM is_seam = FALSE; +#endif } } } +#ifdef USE_SEAM if (is_seam) { break; } +#endif } } + +//#undef USE_SEAM + } #endif /* USE_CUSTOMDATA */ diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index c098d6da32b..5b0381f6443 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -58,7 +58,7 @@ private: * @brief The group node this node belongs to. * @note: used to find the links in the current subtree for muting nodes */ - bNode* m_bNodeGroup; + bNode *m_bNodeGroup; public: Node(bNode *editorNode, bool create_sockets = true); @@ -145,8 +145,8 @@ public: */ OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket); - inline void setbNodeGroup(bNode* group) {this->m_bNodeGroup = group;} - inline bNode* getbNodeGroup() {return this->m_bNodeGroup;} + inline void setbNodeGroup(bNode *group) {this->m_bNodeGroup = group;} + inline bNode *getbNodeGroup() {return this->m_bNodeGroup;} protected: void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket); void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 4293e344c65..864d6f08311 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -28,6 +28,10 @@ #include "BKE_node.h" #include "BLI_utildefines.h" +#include "COM_SetValueOperation.h" +#include "COM_SetVectorOperation.h" +#include "COM_SetColorOperation.h" + ImageNode::ImageNode(bNode *editorNode) : Node(editorNode) { /* pass */ @@ -165,6 +169,46 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c graph->addOperation(depthOperation); } } + if (numberOfOutputs > 3) { + /* happens when unlinking image datablock from multilayer node */ + for (int i = 3; i < numberOfOutputs; i++) { + OutputSocket *output = this->getOutputSocket(i); + NodeOperation *operation = NULL; + switch (output->getDataType()) { + case COM_DT_VALUE: + { + SetValueOperation *valueoperation = new SetValueOperation(); + valueoperation->setValue(0.0f); + operation = valueoperation; + break; + } + case COM_DT_VECTOR: + { + SetVectorOperation *vectoroperation = new SetVectorOperation(); + vectoroperation->setX(0.0f); + vectoroperation->setY(0.0f); + vectoroperation->setW(0.0f); + operation = vectoroperation; + break; + } + case COM_DT_COLOR: + { + SetColorOperation *coloroperation = new SetColorOperation(); + coloroperation->setChannel1(0.0f); + coloroperation->setChannel2(0.0f); + coloroperation->setChannel3(0.0f); + coloroperation->setChannel4(0.0f); + operation = coloroperation; + break; + } + } + + if (operation) { + output->relinkConnections(operation->getOutputSocket()); + graph->addOperation(operation); + } + } + } } } diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp index f1c7c616a30..b751c9a6e9f 100644 --- a/source/blender/compositor/nodes/COM_PixelateNode.cpp +++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp @@ -36,8 +36,8 @@ void PixelateNode::convertToOperations(ExecutionSystem *graph, CompositorContext OutputSocket *outputSocket = this->getOutputSocket(0); DataType datatype = inputSocket->getDataType(); if (inputSocket->isConnected()) { - SocketConnection * connection = inputSocket->getConnection(); - OutputSocket* otherOutputSocket = connection->getFromSocket(); + SocketConnection *connection = inputSocket->getConnection(); + OutputSocket *otherOutputSocket = connection->getFromSocket(); datatype = otherOutputSocket->getDataType(); } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 19a97fa0810..a7e84d590b5 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1769,7 +1769,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi"); mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect"); mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound"); - mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6); + mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6); mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside"); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 577113927d1..31f89063f05 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -51,10 +51,10 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2); /* OpenGL stipple defines */ /* OpenGL stipple defines */ -extern unsigned char stipple_halftone[128]; -extern unsigned char stipple_quarttone[128]; -extern unsigned char stipple_diag_stripes_pos[128]; -extern unsigned char stipple_diag_stripes_neg[128]; +extern const unsigned char stipple_halftone[128]; +extern const unsigned char stipple_quarttone[128]; +extern const unsigned char stipple_diag_stripes_pos[128]; +extern const unsigned char stipple_diag_stripes_neg[128]; /** * Draw a lined (non-looping) arc with the given diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 3d13938c204..ac2c47216a6 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -270,13 +270,13 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); int ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d); void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background); + int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, - int draw_background, int colormanage_background, char err_out[256]); + int draw_background, int alpha_mode, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, - int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]); - + int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]); +void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]); struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 080367c4325..292cc4cdca0 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -42,6 +42,7 @@ struct ID; struct Main; struct ListBase; struct ARegion; +struct ARegionType; struct ScrArea; struct wmWindow; struct wmWindowManager; @@ -253,7 +254,8 @@ typedef enum { HISTOGRAM = (48 << 9), WAVEFORM = (49 << 9), VECTORSCOPE = (50 << 9), - PROGRESSBAR = (51 << 9) + PROGRESSBAR = (51 << 9), + SEARCH_MENU_UNLINK = (52 << 9) } eButType; #define BUTTYPE (63 << 9) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 1035f5815f2..29b1a74e859 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -228,7 +228,11 @@ enum { TH_AXIS_X, /* X/Y/Z Axis */ TH_AXIS_Y, - TH_AXIS_Z + TH_AXIS_Z, + + TH_LOW_GRAD, + TH_HIGH_GRAD, + TH_SHOW_BACK_GRAD }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 1d26cbd344b..1dee497ff11 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1605,7 +1605,7 @@ void ui_set_but_val(uiBut *but, double value) int ui_get_but_string_max_length(uiBut *but) { - if (ELEM(but->type, TEX, SEARCH_MENU)) + if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) return but->hardmax; else if (but->type == IDPOIN) return MAX_ID_NAME - 2; @@ -1688,7 +1688,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default) void ui_get_but_string(uiBut *but, char *str, size_t maxlen) { - if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { PropertyType type; const char *buf = NULL; int buf_len; @@ -1742,7 +1742,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen) BLI_strncpy(str, but->poin, maxlen); return; } - else if (but->type == SEARCH_MENU) { + else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* string */ BLI_strncpy(str, but->poin, maxlen); return; @@ -1833,7 +1833,7 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double int ui_set_but_string(bContext *C, uiBut *but, const char *str) { - if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (RNA_property_editable(&but->rnapoin, but->rnaprop)) { PropertyType type; @@ -1890,7 +1890,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str) return 1; } - else if (but->type == SEARCH_MENU) { + else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* string */ BLI_strncpy(but->poin, str, but->hardmax); return 1; @@ -2360,6 +2360,7 @@ void ui_check_but(uiBut *but) case IDPOIN: case TEX: case SEARCH_MENU: + case SEARCH_MENU_UNLINK: if (!but->editstr) { char str[UI_MAX_DRAW_STR]; @@ -2741,7 +2742,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } if ((block->flag & UI_BLOCK_LOOP) || - ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR)) + ELEM9(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK)) { but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 1c9cd92271c..c87bb2a97a1 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -238,6 +238,7 @@ void ui_pan_to_scroll(wmEvent *event, int *type, int *val) *type = WHEELUPMOUSE; else *type = WHEELDOWNMOUSE; + lastdy = 0; } } @@ -1061,6 +1062,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut ui_apply_but_BUT(C, but, data); break; case TEX: + case SEARCH_MENU_UNLINK: case SEARCH_MENU: ui_apply_but_TEX(C, but, data); break; @@ -1168,7 +1170,7 @@ static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonD for (wmd = drags->first; wmd; wmd = wmd->next) { if (wmd->type == WM_DRAG_ID) { /* align these types with UI_but_active_drop_name */ - if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { ID *id = (ID *)wmd->poin; if (but->poin == NULL && but->rnapoin.data == NULL) {} @@ -1269,7 +1271,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } /* text/string and ID data */ - else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + else if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { uiHandleButtonData *active_data = but->active; if (but->poin == NULL && but->rnapoin.data == NULL) { @@ -1288,7 +1290,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen); else BLI_strncpy(active_data->str, buf, active_data->maxlen); - if (but->type == SEARCH_MENU) { + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* else uiSearchboxData.active member is not updated [#26856] */ ui_searchbox_update(C, data->searchbox, but, 1); } @@ -1435,7 +1437,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho /* XXX solve generic */ if (but->type == NUM || but->type == NUMSLI) startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect))); - else if (ELEM(but->type, TEX, SEARCH_MENU)) { + else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { startx += 5; if (but->flag & UI_HAS_ICON) startx += UI_DPI_ICON_SIZE; @@ -1815,7 +1817,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) but->selend = len; /* optional searchbox */ - if (but->type == SEARCH_MENU) { + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { data->searchbox = ui_searchbox_create(C, data->region, but); ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */ } @@ -1861,7 +1863,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa return; for (but = actbut->next; but; but = but->next) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -1870,7 +1872,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } for (but = block->buttons.first; but != actbut; but = but->next) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -1889,7 +1891,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa return; for (but = actbut->prev; but; but = but->prev) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -1898,7 +1900,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } for (but = block->buttons.last; but != actbut; but = but->prev) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -2429,6 +2431,34 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton return WM_UI_HANDLER_CONTINUE; } +static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) +{ + /* unlink icon is on right */ + if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { + ARegion *ar = CTX_wm_region(C); + rcti rect; + int x = event->x, y = event->y; + + ui_window_to_block(ar, but->block, &x, &y); + + BLI_rcti_rctf_copy(&rect, &but->rect); + + rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect)); + if ( BLI_rcti_isect_pt(&rect, x, y) ) { + /* most likely NULL, but let's check, and give it temp zero string */ + if (data->str == NULL) + data->str = MEM_callocN(16, "temp str"); + data->str[0] = 0; + + ui_apply_but_TEX(C, but, data); + button_activate_state(C, but, BUTTON_STATE_EXIT); + + return WM_UI_HANDLER_BREAK; + } + } + return ui_do_but_TEX(C, block, but, data, event); +} + static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) { if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -2717,7 +2747,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton ui_pan_to_scroll(event, &type, &val); /* XXX hardcoded keymap check.... */ - if (type == WHEELDOWNMOUSE && event->alt) { + if (type == MOUSEPAN && event->alt) + retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */ + else if (type == WHEELDOWNMOUSE && event->alt) { mx = but->rect.xmin; click = 1; } @@ -2945,7 +2977,9 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton ui_pan_to_scroll(event, &type, &val); /* XXX hardcoded keymap check.... */ - if (type == WHEELDOWNMOUSE && event->alt) { + if (type == MOUSEPAN && event->alt) + retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */ + else if (type == WHEELDOWNMOUSE && event->alt) { mx = but->rect.xmin; click = 2; } @@ -5133,6 +5167,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) case SEARCH_MENU: retval = ui_do_but_TEX(C, block, but, data, event); break; + case SEARCH_MENU_UNLINK: + retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event); + break; case MENU: case ICONROW: case ICONTEXTROW: @@ -5246,7 +5283,7 @@ int UI_but_active_drop_name(bContext *C) uiBut *but = ui_but_find_activated(ar); if (but) { - if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) + if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) return 1; } @@ -5572,7 +5609,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA copy_v2_fl(data->ungrab_mval, FLT_MAX); #endif - if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) { + if (ELEM3(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* XXX curve is temp */ } else { @@ -6010,19 +6047,18 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) retval = WM_UI_HANDLER_CONTINUE; break; - case WHEELUPMOUSE: - case WHEELDOWNMOUSE: - case MIDDLEMOUSE: - /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */ - if (data->tooltiptimer) { - WM_event_remove_timer(data->wm, data->window, data->tooltiptimer); - data->tooltiptimer = NULL; - } - /* pass on purposedly */ - default: - /* handle button type specific events */ - retval = ui_do_button(C, block, but, event); } + /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */ + case WHEELUPMOUSE: + case WHEELDOWNMOUSE: + case MIDDLEMOUSE: + case MOUSEPAN: + button_timers_tooltip_remove(C, but); + + /* pass on purposedly */ + default: + /* handle button type specific events */ + retval = ui_do_button(C, block, but, event); } } else if (data->state == BUTTON_STATE_WAIT_RELEASE) { @@ -6383,7 +6419,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt) for (bt = block->buttons.first; bt; bt = bt->next) ymax = max_ff(ymax, bt->rect.ymax); - if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) + if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD; } else { @@ -6393,7 +6429,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt) for (bt = block->buttons.first; bt; bt = bt->next) ymin = min_ff(ymin, bt->rect.ymin); - if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) + if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD; } @@ -6436,7 +6472,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle /* if there's an active modal button, don't check events or outside, except for search menu */ but = ui_but_find_activated(ar); - if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU) { + if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK) { /* if a button is activated modal, always reset the start mouse * position of the towards mechanism to avoid loosing focus, * and don't handle events */ @@ -6462,7 +6498,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle if (block->block_event_func && block->block_event_func(C, block, event)) { /* pass */ } /* events not for active search menu button */ - else if (but == NULL || but->type != SEARCH_MENU) { + else if (but == NULL || (but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK)) { switch (event->type) { diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index ebc80d61af3..68780083b97 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -950,8 +950,8 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy { float x1, x2, y1, y2; - if (rgb) glColor4f(alpha*rgb[0], rgb[1], rgb[2], alpha); - else glColor4f(alpha, alpha, alpha, alpha); + if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha); + else glColor4f(alpha, alpha, alpha, alpha); x1 = ix * icongltex.invw; x2 = (ix + ih) * icongltex.invw; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index f4af1f036a3..3b0a1cd3eb5 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1386,7 +1386,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN /* turn button into search button */ if (searchprop) { - but->type = SEARCH_MENU; + but->type = SEARCH_MENU_UNLINK; but->hardmax = MAX2(but->hardmax, 256.0f); but->rnasearchpoin = *searchptr; but->rnasearchprop = searchprop; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 4a8ad5d24a6..ca5e2a1926c 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -466,7 +466,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->totline++; } - if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* full string */ ui_get_but_string(but, buf, sizeof(buf)); if (buf[0]) { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index e4ad3a4f73b..6b44a82a52a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -897,7 +897,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti } } else if (but->block->flag & UI_BLOCK_LOOP) { - if (but->type == SEARCH_MENU) + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) xs = rect->xmin + 4.0f * ofs; else xs = rect->xmin + ofs; @@ -1283,7 +1283,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) { ui_text_clip_right_label(fstyle, but, rect); } - else if (ELEM(but->type, TEX, SEARCH_MENU)) { + else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { ui_text_clip_left(fstyle, but, rect); } else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) { @@ -1331,6 +1331,14 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB else if ((but->flag & UI_TEXT_LEFT)) { rect->xmin += (0.4f * U.widget_unit) / but->block->aspect; } + + /* unlink icon for this button type */ + if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) { + rcti temp = *rect; + + temp.xmin = temp.xmax - BLI_rcti_size_y(rect); + widget_draw_icon(but, ICON_X, 1.0f, &temp); + } /* always draw text for textbutton cursor */ widget_draw_text(fstyle, wcol, but, rect); @@ -3215,7 +3223,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct case TEX: wt = widget_type(UI_WTYPE_NAME); break; - + + case SEARCH_MENU_UNLINK: case SEARCH_MENU: wt = widget_type(UI_WTYPE_NAME); if (but->block->flag & UI_BLOCK_LOOP) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 361bdfacbb2..471193d10d8 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -170,6 +170,16 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo else cp = ts->button; break; + case TH_LOW_GRAD: + cp = ts->gradients.gradient; + break; + case TH_HIGH_GRAD: + cp = ts->gradients.high_gradient; + break; + case TH_SHOW_BACK_GRAD: + cp = &setting; + setting = ts->gradients.show_grad; + break; case TH_TEXT: if (theme_regionid == RGN_TYPE_WINDOW) cp = ts->text; @@ -782,7 +792,10 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255); rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255); - + rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0); + rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 58, 58, 58, 255); + btheme->tv3d.gradients.show_grad = FALSE; + /* space buttons */ /* to have something initialized */ btheme->tbuts = btheme->tv3d; @@ -2116,7 +2129,7 @@ void init_userdef_do_versions(void) } } - if (!MAIN_VERSION_ATLEAST(bmain, 266, 4)) { + if (!MAIN_VERSION_ATLEAST(bmain, 265, 4)) { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */ @@ -2124,7 +2137,14 @@ void init_userdef_do_versions(void) rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */ } } - + + if (!MAIN_VERSION_ATLEAST(bmain, 265, 6)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + copy_v4_v4_char(btheme->tv3d.gradients.high_gradient, btheme->tv3d.back); + } + } + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index d0d631e14a5..41bbed8eb19 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1694,7 +1694,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* draw numbers in the appropriate range */ if (dfac > 0.0f) { - float h = 0.1f*UI_UNIT_Y + (float)(hor.ymin); + float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin); for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) { diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index cc473998340..9236800c16b 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -946,10 +946,10 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event) /* As we have only 1D information (magnify value), feed both axes * with magnify information that is stored in x axis */ - fac = 0.01f * (event->x - event->prevx); + fac = 0.01f * (event->prevx - event->x); dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; if (event->type == MOUSEPAN) - fac = 0.01f * (event->y - event->prevy); + fac = 0.01f * (event->prevy - event->y); dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; RNA_float_set(op->ptr, "deltax", dx); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 590bcd5939e..5e1d954a2ea 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1320,7 +1320,7 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd) { BMIter iter; BMVert *v; - BMesh* bm = kcd->em->bm; + BMesh *bm = kcd->em->bm; float max_xyz = 0.0f; int i; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 48dfe3bf667..38887307a76 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -42,6 +42,7 @@ #include "BKE_displist.h" #include "BKE_report.h" #include "BKE_paint.h" +#include "BKE_mesh.h" #include "BKE_tessmesh.h" #include "IMB_imbuf_types.h" @@ -1370,6 +1371,17 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge /* note, would pass BM_EDGE except we are looping over all edges anyway */ BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */); + switch (scene->toolsettings->edge_mode) { + case EDGE_MODE_TAG_CREASE: + BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_CREASE); + break; + case EDGE_MODE_TAG_BEVEL: + BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_BWEIGHT); + break; + default: + break; + } + BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == FALSE) { BM_elem_flag_disable(e, BM_ELEM_TAG); @@ -2274,7 +2286,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent * BMW_FLAG_TEST_HIDDEN, BMW_NIL_LAY); - e = BMW_begin(&walker, efa); + efa = BMW_begin(&walker, efa); for (; efa; efa = BMW_step(&walker)) { BM_face_select_set(bm, efa, sel); } @@ -2368,7 +2380,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - e = BMW_begin(&walker, efa); + efa = BMW_begin(&walker, efa); for (; efa; efa = BMW_step(&walker)) { BM_face_select_set(bm, efa, TRUE); } @@ -2405,8 +2417,9 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) } } BMW_end(&walker); + + EDBM_selectmode_flush(em); } - EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index e8132f5b82b..b95c8a05353 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -550,7 +550,7 @@ void EDBM_select_more(BMEditMesh *em) BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE); BMO_op_finish(em->bm, &bmop); - EDBM_select_flush(em); + EDBM_selectmode_flush(em); } void EDBM_select_less(BMEditMesh *em) diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 641d1be7a2e..1d13aa36a6b 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -462,7 +462,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes /* copy data from active vertex color layer */ if (layernum) { const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL); - BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst); + BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPCOL, layernum, layernum_dst); } if (active_set || layernum == 0) { CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum); diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index c54ac485be6..fc55b2b5915 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -237,7 +237,7 @@ static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *chann { int i; - channels->timeAtFrame = MEM_callocN((channels->length+1)*sizeof(float), "timeAtFrame channel"); + channels->timeAtFrame = MEM_callocN((channels->length + 1) * sizeof(float), "timeAtFrame channel"); channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1 diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index cbc076b3342..7ba6a92e4be 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -43,6 +43,7 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_world_types.h" #include "BKE_context.h" #include "BKE_global.h" @@ -192,7 +193,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } if ((scene->r.mode & R_OSA) == 0) { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf); } else { @@ -206,7 +207,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) BLI_jitter_init(jit_ofs[0], scene->r.osa); /* first sample buffer, also initializes 'rv3d->persmat' */ - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer); /* skip the first sample */ @@ -216,7 +217,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) (jit_ofs[j][0] * 2.0f) / sizex, (jit_ofs[j][1] * 2.0f) / sizey); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp); add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float)); } @@ -232,7 +233,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender) else { /* shouldnt suddenly give errors mid-render but possible */ char err_out[256] = "unknown"; - ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, FALSE, TRUE, FALSE, err_out); + ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, + IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out); camera = scene->camera; if (ibuf_view) { @@ -243,7 +245,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender) fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out); } } - + + if (scene->r.alphamode == R_ADDSKY) { + float sky_color[3]; + ED_view3d_offscreen_sky_color_get(scene, sky_color); + IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color); + } + /* note on color management: * * OpenGL renders into sRGB colors, but render buffers are expected to be diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 8d748d3ea20..25ad1f61aaf 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -84,6 +84,8 @@ #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" +#include "GPU_extensions.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -710,7 +712,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs else { /* validate owner */ //if (ri->rect == NULL) - // ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender"); + // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender"); //RE_ResultGet32(re, ri->rect); } @@ -884,7 +886,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat ShaderPreview *sp = customdata; ID *id = sp->id; short idtype = GS(id->name); - + if (idtype == ID_IM) { Image *ima = (Image *)id; ImBuf *ibuf = NULL; @@ -1007,8 +1009,27 @@ static void icon_preview_endjob(void *customdata) { IconPreview *ip = customdata; - if (ip->id && GS(ip->id->name) == ID_BR) - WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id); + if (ip->id) { + + if (GS(ip->id->name) == ID_BR) + WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id); +#if 0 + if (GS(ip->id->name) == ID_MA) { + Material *ma = (Material *)ip->id; + PreviewImage *prv_img = ma->preview; + int i; + + /* signal to gpu texture */ + for (i = 0; i < NUM_ICON_SIZES; ++i) { + if (prv_img->gputexture[i]) { + GPU_texture_free(prv_img->gputexture[i]); + prv_img->gputexture[i] = NULL; + WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id); + } + } + } +#endif + } } static void icon_preview_free(void *customdata) @@ -1044,7 +1065,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r /* setup job */ WM_jobs_customdata_set(wm_job, ip, icon_preview_free); - WM_jobs_timer(wm_job, 0.25, NC_MATERIAL, NC_MATERIAL); + WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL); WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob); WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 5af60726f14..cea7b12a27d 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1584,14 +1584,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) if (sa->flag & HEADER_NO_PULLDOWN) { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_RIGHT, - xco, yco, U.widget_unit, U.widget_unit*0.9, + xco, yco, U.widget_unit, U.widget_unit * 0.9f, &(sa->flag), 0, 0, 0, 0, "Show pulldown menus"); } else { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_DOWN, - xco, yco, U.widget_unit, U.widget_unit*0.9, + xco, yco, U.widget_unit, U.widget_unit * 0.9f, &(sa->flag), 0, 0, 0, 0, "Hide pulldown menus"); } diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index d3947432004..f073fdd5125 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -56,7 +56,7 @@ /* ******************************************** */ /* defined in BIF_gl.h */ -GLubyte stipple_halftone[128] = { +const GLubyte stipple_halftone[128] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, @@ -83,7 +83,7 @@ GLubyte stipple_halftone[128] = { * 00000000 */ -GLubyte stipple_quarttone[128] = { +const GLubyte stipple_quarttone[128] = { 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, @@ -94,7 +94,7 @@ GLubyte stipple_quarttone[128] = { 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0}; -GLubyte stipple_diag_stripes_pos[128] = { +const GLubyte stipple_diag_stripes_pos[128] = { 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe, 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8, 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0, @@ -113,7 +113,7 @@ GLubyte stipple_diag_stripes_pos[128] = { 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f}; -GLubyte stipple_diag_stripes_neg[128] = { +const GLubyte stipple_diag_stripes_neg[128] = { 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f, diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index fa8252c824d..d0f8e36e17d 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -6038,7 +6038,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (w > maxsize) w = maxsize; if (h > maxsize) h = maxsize; - ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, FALSE, err_out); + ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out); if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index c30996f03de..dd7412cf3d5 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -391,7 +391,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p double starttime, curtime = time; /* compute brush spacing adapted to brush size */ - spacing = brush->rate; //radius*brush->spacing*0.01f; + spacing = brush->rate; //radius*brush->spacing * 0.01f; /* setup starting time, direction vector and accumulated time */ starttime = painter->accumtime; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 9e702c16e2f..e5d6a1820a2 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -657,8 +657,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf) * grid rather than brush alpha */ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", DKEY, KM_PRESS, KM_SHIFT, 0); set_brush_rc_props(kmi->ptr, "sculpt", "detail_size", NULL, 0); - RNA_string_set(kmi->ptr, "data_path_primary", - "tool_settings.sculpt.detail_size"); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); /* multires switch */ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 54ae2ebf588..2dc4176dde3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -137,6 +137,11 @@ MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob) Mesh *me = (Mesh *)ob->data; ModifierData *md; + if (ob->sculpt && ob->sculpt->bm) { + /* can't combine multires and dynamic topology */ + return NULL; + } + if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) { /* multires can't work without displacement layer */ return NULL; @@ -4585,7 +4590,8 @@ void sculpt_dynamic_topology_disable(bContext *C, CD_DUPLICATE, unode->bm_enter_totpoly); mesh_update_customdata_pointers(me, FALSE); - } else { + } + else { sculptsession_bm_to_me(ob, TRUE); } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 3088243d266..04154a27b74 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -82,7 +82,7 @@ int ED_space_clip_view_clip_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); - if (sc && sc->clip) { + if (sc) { return sc->view == SC_VIEW_CLIP; } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 4e53f34359e..26bae6e3978 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -382,8 +382,8 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) SpaceClip *sc = CTX_wm_space_clip(C); float offset[2]; - offset[0] = (event->x - event->prevx) / sc->zoom; - offset[1] = (event->y - event->prevy) / sc->zoom; + offset[0] = (event->prevx - event->x) / sc->zoom; + offset[1] = (event->prevy - event->y) / sc->zoom; RNA_float_set_array(op->ptr, "offset", offset); @@ -515,10 +515,10 @@ static int view_zoom_exec(bContext *C, wmOperator *op) static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if (event->type == MOUSEZOOM) { + if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { float delta, factor; - delta = event->x - event->prevx + event->y - event->prevy; + delta = event->prevx - event->x + event->prevy - event->y; if (U.uiflag & USER_ZOOM_INVERT) delta *= -1; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index dc7b6d77c9e..9d0421349d7 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -587,6 +587,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 763b18788de..9349abb4d8b 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -28,6 +28,8 @@ * \ingroup spfile */ +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -35,9 +37,6 @@ #include "BKE_report.h" #include "BKE_main.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - #ifdef WIN32 # include "BLI_winstuff.h" #endif diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 21b0ed99f0b..b92430ce0e9 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -217,7 +217,6 @@ void GRAPH_OT_previewrange_set(wmOperatorType *ot) static int graphkeys_viewall(bContext *C, const short do_sel_only, const short include_handles) { bAnimContext ac; - float extra; rctf cur_new; /* get editor data */ @@ -230,13 +229,7 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i &cur_new.ymin, &cur_new.ymax, do_sel_only, include_handles); - extra = 0.1f * BLI_rctf_size_x(&cur_new); - cur_new.xmin -= extra; - cur_new.xmax += extra; - - extra = 0.1f * BLI_rctf_size_y(&cur_new); - cur_new.ymin -= extra; - cur_new.ymax += extra; + BLI_rctf_scale(&cur_new, 1.1f); UI_view2d_smooth_view(C, ac.ar, &cur_new); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 0534b9f4ffd..7b4814d1ab2 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -514,11 +514,15 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, unsigned char *display_buffer; void *cache_handle; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (sima->flag & SI_USE_ALPHA) { fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glRecti(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); } display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); @@ -532,8 +536,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, IMB_display_buffer_release(cache_handle); - if (sima->flag & SI_USE_ALPHA) - glDisable(GL_BLEND); + glDisable(GL_BLEND); } /* reset zoom */ diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index f1662bc254d..eed15425441 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -299,8 +299,8 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) SpaceImage *sima = CTX_wm_space_image(C); float offset[2]; - offset[0] = (event->x - event->prevx) / sima->zoom; - offset[1] = (event->y - event->prevy) / sima->zoom; + offset[0] = (event->prevx - event->x) / sima->zoom; + offset[1] = (event->prevy - event->y) / sima->zoom; RNA_float_set_array(op->ptr, "offset", offset); image_view_pan_exec(C, op); @@ -464,7 +464,7 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); - delta = event->x - event->prevx + event->y - event->prevy; + delta = event->prevx - event->x + event->prevy - event->y; if (U.uiflag & USER_ZOOM_INVERT) delta *= -1; diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index e5f8d6553ed..fc0a7b3b883 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -71,14 +71,14 @@ BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step) static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight) { if (sel[0] <= str_len_draw && sel[1] >= 0) { - int sta = max_ii(sel[0], 0); - int end = min_ii(sel[1], str_len_draw); + const int sta = max_ii(sel[0], 0); + const int end = min_ii(sel[1], str_len_draw); glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipple_halftone); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4ub(255, 255, 255, 96); + glColor4ub(255, 255, 255, 48); glRecti(xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8797cb4a459..981a1775b51 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1932,9 +1932,9 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiItemR(layout, ptr, "type", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE); - switch (RNA_enum_get(ptr, "type")) { + switch (RNA_enum_get(ptr, "mode")) { case CMP_NODE_DILATEERODE_DISTANCE_THRESH: uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE); break; @@ -3271,10 +3271,18 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) } else { glPixelZoom(snode->zoom, snode->zoom); - + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glRecti(x, y, x + ibuf->x * snode->zoom, y + ibuf->y * snode->zoom); + glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); glPixelZoom(1.0f, 1.0f); + + glDisable(GL_BLEND); } } diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index 492ff0dcbd4..a69e73c1489 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -118,6 +118,9 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons cur_new.xmin = cur_new.xmin - width_new / 2.0f; cur_new.xmax = cur_new.xmax + width_new / 2.0f; } + + /* add some padding */ + BLI_rctf_scale(&cur_new, 1.1f); } UI_view2d_smooth_view(C, ar, &cur_new); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index e3db9c23c41..249ba986fd3 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -924,11 +924,18 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq void *cache_handle = NULL; const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); - if (G.is_rendering == FALSE) { + if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { /* stop all running jobs, except screen one. currently previews frustrate Render * needed to make so sequencer's rendering doesn't conflict with compositor */ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE); + + if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { + /* in case of final rendering used for preview, kill all previews, + * otherwise threading conflict will happen in rendering module + */ + WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW); + } } render_size = sseq->render_size; @@ -1051,6 +1058,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_QUADS); if (draw_overlay) { @@ -1082,6 +1093,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glEnd(); glBindTexture(GL_TEXTURE_2D, last_texid); glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); glDeleteTextures(1, &texid); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index 0649edc1ac4..57864854734 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -139,35 +139,38 @@ void draw_motion_path_instance(Scene *scene, short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT); float intensity; /* how faint */ + int frame = sfra + i; + int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */ + /* set color * - more intense for active/selected bones, less intense for unselected bones * - black for before current frame, green for current frame, blue for after current frame * - intensity decreases as distance from current frame increases */ #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min) - if ((sfra + i) < CFRA) { + if (frame < CFRA) { /* black - before cfra */ if (sel) { - // intensity = 0.5f; + /* intensity = 0.5f; */ intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f); } else { - //intensity = 0.8f; + /* intensity = 0.8f; */ intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f); } - UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity); + UI_ThemeColorBlend(TH_WIRE, blend_base, intensity); } - else if ((sfra + i) > CFRA) { + else if (frame > CFRA) { /* blue - after cfra */ if (sel) { - //intensity = 0.5f; + /* intensity = 0.5f; */ intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f); } else { - //intensity = 0.8f; + /* intensity = 0.8f; */ intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f); } - UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity); + UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity); } else { /* green - on cfra */ @@ -232,21 +235,22 @@ void draw_motion_path_instance(Scene *scene, col[3] = 255; for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { + int frame = sfra + i; char numstr[32]; float co[3]; /* only draw framenum if several consecutive highlighted points don't occur on same point */ if (i == 0) { - sprintf(numstr, "%d", (i + sfra)); + sprintf(numstr, " %d", frame); mul_v3_m4v3(co, ob->imat, mpv->co); view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); } - else if ((i > stepsize) && (i < len - stepsize)) { + else if ((i >= stepsize) && (i < len - stepsize)) { bMotionPathVert *mpvP = (mpv - stepsize); bMotionPathVert *mpvN = (mpv + stepsize); if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) { - sprintf(numstr, "%d", (sfra + i)); + sprintf(numstr, " %d", frame); mul_v3_m4v3(co, ob->imat, mpv->co); view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); } @@ -286,12 +290,13 @@ void draw_motion_path_instance(Scene *scene, UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col); col[3] = 255; - glPointSize(4.0f); // XXX perhaps a bit too big + glPointSize(4.0f); glColor3ubv(col); glBegin(GL_POINTS); for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - float mframe = (float)(sfra + i); + int frame = sfra + i; + float mframe = (float)(frame); if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) glVertex3fv(mpv->co); @@ -309,7 +314,7 @@ void draw_motion_path_instance(Scene *scene, if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { char numstr[32]; - sprintf(numstr, "%d", (sfra + i)); + sprintf(numstr, " %d", (sfra + i)); mul_v3_m4v3(co, ob->imat, mpv->co); view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index ebb5fd30666..7ef8dc49a5d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3493,7 +3493,7 @@ static int drawDispListwire(ListBase *dlbase) #if 0 /* (ton) this code crashes for me when resolv is 86 or higher... no clue */ - glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3*nr); + glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr); if (dl->flag & DL_CYCL_V) glDrawArrays(GL_LINE_LOOP, 0, dl->parts); else diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 6a095a8d2b1..ec716284bf3 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -179,32 +179,47 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BMEdge *eed; BMIter iter; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs; - - evedef = eve; - tot++; - add_v3_v3(&median[LOC_X], eve->co); - - vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) { - add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ - totskinradius++; + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + + if (bm->totvertsel) { + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + evedef = eve; + tot++; + add_v3_v3(&median[LOC_X], eve->co); + + /* TODO cd_vert_bweight_offset */ + (void)cd_vert_bweight_offset; + + if (cd_vert_skin_offset != -1) { + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ + totskinradius++; + } } } } - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *f; + if ((cd_edge_bweight_offset != -1) || + (cd_edge_crease_offset != -1)) + { + if (bm->totedgesel) { + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + if (cd_edge_bweight_offset != -1) { + median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset); + } - totedgedata++; - f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - median[M_CREASE] += f ? *f : 0.0f; + if (cd_edge_crease_offset != -1) { + median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset); + } - f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - median[M_WEIGHT] += f ? *f : 0.0f; + totedgedata++; + } + } } } @@ -412,14 +427,26 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float /* Meshes... */ if (meshdata) { if (totedgedata) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + BMesh *bm = em->bm; + + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + + if (cd_edge_crease_offset != -1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); + } + + if (cd_edge_bweight_offset != -1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + } } if (totskinradius) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, @@ -502,91 +529,85 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } if (median[M_CREASE] != 0.0f) { - BMEdge *eed; + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); + BMEdge *eed; if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (crease) { - *crease = sca; - } + BM_ELEM_CD_SET_FLOAT(eed, cd_edge_crease_offset, sca); } } } else if (sca > 0.0f) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (crease) { - *crease *= sca; - CLAMP(*crease, 0.0f, 1.0f); - } + float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); + *crease *= sca; + CLAMP(*crease, 0.0f, 1.0f); } } } else { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (crease) { - *crease = 1.0f + ((1.0f - *crease) * sca); - CLAMP(*crease, 0.0f, 1.0f); - } + float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); + *crease = 1.0f + ((1.0f - *crease) * sca); + CLAMP(*crease, 0.0f, 1.0f); } } } } if (median[M_WEIGHT] != 0.0f) { - BMEdge *eed; + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]); + BMEdge *eed; + + BLI_assert(cd_edge_bweight_offset != -1); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (bweight) { - *bweight = sca; - } + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + *bweight = sca; } } } else if (sca > 0.0f) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (bweight) { - *bweight *= sca; - CLAMP(*bweight, 0.0f, 1.0f); - } + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + *bweight *= sca; + CLAMP(*bweight, 0.0f, 1.0f); } } } else { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (bweight) { - *bweight = 1.0f + ((1.0f - *bweight) * sca); - CLAMP(*bweight, 0.0f, 1.0f); - } + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + *bweight = 1.0f + ((1.0f - *bweight) * sca); + CLAMP(*bweight, 0.0f, 1.0f); } } } } if (median[M_SKIN_X] != 0.0f) { - BMVert *eve; + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); /* That one is not clamped to [0.0, 1.0]. */ float sca = ve_median[M_SKIN_X]; + BMVert *eve; + + BLI_assert(cd_vert_skin_offset != -1); + if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[0] = sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[0] = sca; } } } @@ -594,23 +615,25 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[0] *= sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[0] *= sca; } } } } if (median[M_SKIN_Y] != 0.0f) { - BMVert *eve; + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); /* That one is not clamped to [0.0, 1.0]. */ float sca = ve_median[M_SKIN_Y]; + BMVert *eve; + + BLI_assert(cd_vert_skin_offset != -1); + if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[1] = sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[1] = sca; } } } @@ -618,14 +641,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[1] *= sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[1] *= sca; } } } } - EDBM_mesh_normals_update(em); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = ob->data; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 4ccf26e12b1..67344a9804b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -315,7 +315,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** UI_ThemeColor(TH_GRID); if (unit->system) { - /* Use GRID_MIN_PX*2 for units because very very small grid + /* Use GRID_MIN_PX * 2 for units because very very small grid * items are less useful when dealing with units */ void *usys; int len, i; @@ -381,7 +381,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** drawgrid_draw(ar, wx, wy, x, y, sublines * dx); } } - else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10)) */ + else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */ UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); @@ -599,7 +599,7 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect) float startx = k + 1.0f; /* axis center in screen coordinates, x=y */ float starty = k + 1.0f; float ydisp = 0.0; /* vertical displacement to allow obj info text */ - int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ + int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */ float vec[3]; float dx, dy; @@ -937,7 +937,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) } /* color depends on whether there is a keyframe */ - if (id_frame_has_keyframe((ID *)ob, /*BKE_scene_frame_get(scene)*/ (float)(CFRA), ANIMFILTER_KEYS_LOCAL)) + if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)(CFRA), ANIMFILTER_KEYS_LOCAL)) UI_ThemeColor(TH_VERTEX_SELECT); else UI_ThemeColor(TH_TEXT_HI); @@ -2393,7 +2393,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) invert_m4_m4(rv3d.persinv, rv3d.viewinv); /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ - ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE); GPU_lamp_shadow_buffer_unbind(shadow->lamp); v3d->drawtype = drawtype; @@ -2540,13 +2540,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) /* ED_view3d_draw_offscreen_init should be called before this to initialize * stuff like shadow buffers */ -void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, - int winx, int winy, float viewmat[4][4], float winmat[4][4], - int do_bgpic, int colormanage_background) +void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, + float viewmat[4][4], float winmat[4][4], int do_bgpic) { RegionView3D *rv3d = ar->regiondata; Base *base; - float backcol[3]; int bwinx, bwiny; rcti brect; @@ -2574,34 +2572,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); - /* set background color, fallback on the view background color - * (if active clip is set but frame is failed to load fallback to horizon color as background) */ - if (scene->world) { - /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not - * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc) - * but due to compatibility issues background is being affected display transform, so we can - * emulate behavior of disabled color management - * but this function is also used for sequencer's scene strips which shouldn't be affected by - * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background - * we can drop this flag in cost of some compatibility loss -- background wouldn't be - * color managed in 3d viewport - * same goes to opengl rendering, where color profile should be applied as very final step - */ - - if (colormanage_background) { - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - } - else { - linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); - } - - glClearColor(backcol[0], backcol[1], backcol[2], 0.0f); - } - else { - UI_ThemeClearColor(TH_BACK); - } - + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -2703,10 +2674,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, G.f &= ~G_RENDER_OGL; } +/* get a color used for offscreen sky, returns color in sRGB space */ +void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3]) +{ + if (scene->world) + linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr); + else + UI_GetThemeColor3fv(TH_BACK, sky_color); +} + +static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene) +{ + float sky_color[3]; + + ED_view3d_offscreen_sky_color_get(scene, sky_color); + + if (ibuf->rect_float) + IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color); + else + IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color); +} + /* utility func for ED_view3d_draw_offscreen */ -ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, - int sizex, int sizey, unsigned int flag, int draw_background, - int colormanage_background, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, + int draw_background, int alpha_mode, char err_out[256]) { RegionView3D *rv3d = ar->regiondata; ImBuf *ibuf; @@ -2733,10 +2724,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp); BKE_camera_params_compute_matrix(¶ms); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background); } else { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background); } /* read in pixels & stamp */ @@ -2747,6 +2738,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, else if (ibuf->rect) GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); + if (alpha_mode == R_ADDSKY) + offscreen_imbuf_add_sky(ibuf, scene); + /* unbind */ GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); @@ -2760,9 +2754,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, } /* creates own 3d views, used by the sequencer */ -ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, - unsigned int flag, int drawtype, int use_solid_tex, int draw_background, - int colormanage_background, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype, + int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]) { View3D v3d = {NULL}; ARegion ar = {NULL}; @@ -2805,7 +2798,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag, - draw_background, colormanage_background, err_out); + draw_background, alpha_mode, err_out); // seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty); } @@ -2974,6 +2967,169 @@ static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar) ED_region_info_draw(ar, rv3d->render_engine->text, 1, 0.25); } +/* + * Function to clear the view + */ +static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) +{ + /* clear background */ + if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */ + if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */ + int x, y; + float col_hor[3]; + float col_zen[3]; + +#define VIEWGRAD_RES_X 16 +#define VIEWGRAD_RES_Y 16 + + GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4]; + static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2]; + static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4]; + static char buf_calculated = FALSE; + + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, + &scene->display_settings); + + glClear(GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glShadeModel(GL_SMOOTH); + + /* calculate buffers the first time only */ + if (!buf_calculated) { + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); + + /* -1..1 range */ + grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; + grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; + } + } + + for (x = 0; x < VIEWGRAD_RES_X - 1; x++) { + for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) { + indices[x][y][0] = x * VIEWGRAD_RES_X + y; + indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1; + indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1; + indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y; + } + } + + buf_calculated = TRUE; + } + + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); + const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; + const float z_up[3] = {0.0f, 0.0f, 1.0f}; + float out[3]; + GLubyte *col_ub = grid_col[x][y]; + + float col_fac; + float col_fl[3]; + + ED_view3d_win_to_vector(ar, mval, out); + + if (scene->world->skytype & WO_SKYPAPER) { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f; + } + else { + col_fac = (float)y / (float)VIEWGRAD_RES_Y; + } + } + else { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f; + } + else { + col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI); + } + } + + interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac); + + rgb_float_to_uchar(col_ub, col_fl); + col_ub[3] = 0; + } + } + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, grid_pos); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); + + glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glShadeModel(GL_FLAT); + +#undef VIEWGRAD_RES_X +#undef VIEWGRAD_RES_Y + } + else { /* solid sky */ + float col_hor[3]; + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + + glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + else { + if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + /* only clear depth buffer here */ + glClear(GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + UI_ThemeColor(TH_LOW_GRAD); + glVertex2f(-1.0, -1.0); + glVertex2f(1.0, -1.0); + UI_ThemeColor(TH_HIGH_GRAD); + glVertex2f(1.0, 1.0); + glVertex2f(-1.0, 1.0); + glEnd(); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } + else { + UI_ThemeClearColor(TH_HIGH_GRAD); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } +} + /* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit) { @@ -2981,7 +3137,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); Base *base; - float backcol[3]; unsigned int lay_used; /* shadow buffers, before we setup matrices */ @@ -2994,21 +3149,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const GPU_default_lights(); } - /* clear background */ - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) && scene->world) { - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - - glClearColor(backcol[0], backcol[1], backcol[2], 0.0); - } - else - UI_ThemeClearColor(TH_BACK); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - /* setup view matrices */ view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); + /* clear the background */ + view3d_main_area_clear(scene, v3d, ar); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); if (rv3d->rflag & RV3D_CLIPPING) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e984a3f5cfd..a1e132c6601 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2101,16 +2101,15 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) } else { if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { - /* Bypass Zoom invert flag for track pads (pass FALSE always) */ if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0); } ED_view3d_depth_tag_update(vod->rv3d); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index f8c9497a686..c2e75a1c5d9 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -76,7 +76,8 @@ enum { FLY_MODAL_PRECISION_ENABLE, FLY_MODAL_PRECISION_DISABLE, FLY_MODAL_FREELOOK_ENABLE, - FLY_MODAL_FREELOOK_DISABLE + FLY_MODAL_FREELOOK_DISABLE, + FLY_MODAL_SPEED, /* mousepan typically */ }; @@ -132,6 +133,8 @@ void fly_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE); WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE); + WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); @@ -544,7 +547,22 @@ static void flyEvent(FlyInfo *fly, wmEvent *event) case FLY_MODAL_CONFIRM: fly->state = FLY_CONFIRM; break; - + + /* speed adjusting with mousepan (trackpad) */ + case FLY_MODAL_SPEED: + { + float fac = 0.02f * (event->prevy - event->y); + + /* allowing to brake immediate */ + if (fac > 0.0f && fly->speed < 0.0f) + fly->speed = 0.0f; + else if (fac < 0.0f && fly->speed > 0.0f) + fly->speed = 0.0f; + else + fly->speed += fly->grid * fac; + + break; + } case FLY_MODAL_ACCELERATE: { double time_currwheel; @@ -816,7 +834,7 @@ static int flyApply(bContext *C, FlyInfo *fly) /* scale the mouse movement by this value - scales mouse movement to the view size - * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y) + * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y) * * the mouse moves isn't linear */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 3b443e8bbac..5b5e5206e9c 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -462,7 +462,10 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); else WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - + + if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) + WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); + /* for realtime animation record - send notifiers recognised by animation editors */ // XXX: is this notifier a lame duck? if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) @@ -5262,7 +5265,7 @@ static int createSlideVerts(TransInfo *t) if (dot_v3v3(loop_dir[l_nr], dir) < 0.0f) { swap_v3_v3(sv_array->upvec, sv_array->downvec); SWAP(BMVert, sv_array->vup, sv_array->vdown); - SWAP(BMVert*, sv_array->up, sv_array->down); + SWAP(BMVert *, sv_array->up, sv_array->down); } } @@ -5424,7 +5427,7 @@ void projectSVData(TransInfo *t, int final) } } - + if (!affected) continue; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 12b0341d395..d38bdb178fb 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -127,30 +127,24 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list); /* ************************** Functions *************************** */ -static int trans_data_compare_dist(const void *A, const void *B) +static int trans_data_compare_dist(const void *a, const void *b) { - const TransData *td_A = (const TransData*)A; - const TransData *td_B = (const TransData*)B; + const TransData *td_a = (const TransData *)a; + const TransData *td_b = (const TransData *)b; - if (td_A->dist < td_B->dist) - return -1; - else if (td_A->dist > td_B->dist) - return 1; - - return 0; + if (td_a->dist < td_b->dist) return -1; + else if (td_a->dist > td_b->dist) return 1; + else return 0; } -static int trans_data_compare_rdist(const void *A, const void *B) +static int trans_data_compare_rdist(const void *a, const void *b) { - const TransData *td_A = (const TransData*)A; - const TransData *td_B = (const TransData*)B; + const TransData *td_a = (const TransData *)a; + const TransData *td_b = (const TransData *)b; - if (td_A->rdist < td_B->rdist) - return -1; - else if (td_A->rdist > td_B->rdist) - return 1; - - return 0; + if (td_a->rdist < td_b->rdist) return -1; + else if (td_a->rdist > td_b->rdist) return 1; + else return 0; } void sort_trans_data_dist(TransInfo *t) @@ -295,6 +289,7 @@ static void createTransEdge(TransInfo *t) float mtx[3][3], smtx[3][3]; int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; + int cd_edge_float_offset; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { @@ -318,8 +313,22 @@ static void createTransEdge(TransInfo *t) copy_m3_m4(mtx, t->obedit->obmat); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); + /* create data we need */ + if (t->mode == TFM_BWEIGHT) { + BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_BWEIGHT); + cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); + } + else { //if (t->mode == TFM_CREASE) { + BLI_assert(t->mode == TFM_CREASE); + BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_CREASE); + cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); + } + + BLI_assert(cd_edge_float_offset != -1); + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) { + float *fl_ptr; /* need to set center for center calculations */ mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co); @@ -333,17 +342,10 @@ static void createTransEdge(TransInfo *t) copy_m3_m3(td->mtx, mtx); td->ext = NULL; - if (t->mode == TFM_BWEIGHT) { - float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); - td->val = bweight; - td->ival = bweight ? *bweight : 1.0f; - } - else { - float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); - BLI_assert(t->mode == TFM_CREASE); - td->val = crease; - td->ival = crease ? *crease : 0.0f; - } + + fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset); + td->val = fl_ptr; + td->ival = *fl_ptr; td++; } @@ -1913,8 +1915,8 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx td->val = NULL; td->extra = NULL; if (t->mode == TFM_BWEIGHT) { - td->val = bweight; - td->ival = bweight ? *(bweight) : 1.0f; + td->val = bweight; + td->ival = *bweight; } else if (t->mode == TFM_SKIN_RESIZE) { MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, @@ -1950,6 +1952,7 @@ static void createTransEditVerts(TransInfo *t) int mirror = 0; char *selstate = NULL; short selectmode = ts->selectmode; + int cd_vert_bweight_offset = -1; if (t->flag & T_MIRROR) { EDBM_verts_mirror_cache_begin(em, TRUE); @@ -2031,6 +2034,10 @@ static void createTransEditVerts(TransInfo *t) } } + if (t->mode == TFM_BWEIGHT) { + BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT); + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + } if (propmode) { t->total = count; @@ -2097,11 +2104,10 @@ static void createTransEditVerts(TransInfo *t) } } - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a = 0; eve; eve = BM_iter_step(&iter), a++) { + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (propmode || selstate[a]) { - float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT); + float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL; VertsToTransData(t, tob, tx, em, eve, bweight); if (tx) diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 607640090aa..023f281aea9 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -194,8 +194,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); totarea += BM_face_calc_area(efa); - //totuvarea += tf_area(tf, efa->v4!=0); - totuvarea += uv_poly_area(tf_uv, efa->len); + totuvarea += area_poly_v2(efa->len, tf_uv); if (uvedit_face_visible_test(scene, ima, efa, tf)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -238,8 +237,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); - //uvarea = tf_area(tf, efa->v4!=0) / totuvarea; - uvarea = uv_poly_area(tf_uv, efa->len) / totuvarea; + uvarea = area_poly_v2(efa->len, tf_uv) / totuvarea; if (area < FLT_EPSILON || uvarea < FLT_EPSILON) areadiff = 1.0f; diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 4d52282d540..b6d82451d2f 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -50,7 +50,6 @@ struct BMVert; int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa); /* geometric utilities */ -float uv_poly_area(float uv[][2], int len); void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len); void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 4336eb02752..2194ce28353 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -575,19 +575,6 @@ void uv_poly_center(BMEditMesh *em, BMFace *f, float r_cent[2]) mul_v2_fl(r_cent, 1.0f / (float)f->len); } -float uv_poly_area(float uv[][2], int len) -{ - //BMESH_TODO: make this not suck - //maybe use scanfill? I dunno. - - if (len >= 4) - return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]); - else - return area_tri_v2(uv[0], uv[1], uv[2]); - - return 1.0; -} - void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len) { int i; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 8c3eaa1192f..b1bb5c85e50 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -799,7 +799,7 @@ static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, } -static void stitch_propagate_uv_final_position (UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene* scene) +static void stitch_propagate_uv_final_position(UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene *scene) { StitchPreviewer *preview = state->stitch_preview; @@ -1273,7 +1273,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) UvElement *element = state->selection_stack[i]; stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene); - } else { + } + else { UvEdge *edge = state->selection_stack[i]; stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene); @@ -1391,7 +1392,7 @@ static void stitch_switch_selection_mode(StitchState *state) if (state->mode == STITCH_VERT) { int i; - state->selection_stack = MEM_mallocN(state->total_separate_edges*sizeof(*state->selection_stack), + state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack), "stitch_new_edge_selection_stack"); /* check if both elements of an edge are selected */ @@ -1414,7 +1415,7 @@ static void stitch_switch_selection_mode(StitchState *state) } else { int i; - state->selection_stack = MEM_mallocN(state->total_separate_uvs*sizeof(*state->selection_stack), + state->selection_stack = MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack), "stitch_new_vert_selection_stack"); for (i = 0; i < old_selection_size; i++) { @@ -1501,11 +1502,11 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar else { UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); - glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_stitchable); + glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable); UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); - glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_unstitchable); + glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable); } glPopClientAttrib(); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 850060ef4d5..a19433dbd2f 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -373,8 +373,6 @@ void IMB_rect_from_float(struct ImBuf *ibuf); * Changed part will be stored in buffer. This is expected to be used for texture painting updates */ void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data); void IMB_float_from_rect(struct ImBuf *ibuf); -/* note, check that the conversion exists, only some are supported */ -float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc); void IMB_color_to_bw(struct ImBuf *ibuf); void IMB_saturation(struct ImBuf *ibuf, float sat); @@ -416,6 +414,9 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float c void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]); +void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]); + /** * * \attention defined in readimage.c diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h index a6f38516a14..9fc075e4e8b 100644 --- a/source/blender/imbuf/IMB_thumbs.h +++ b/source/blender/imbuf/IMB_thumbs.h @@ -58,7 +58,7 @@ typedef enum ThumbSource { } ThumbSource; /* don't generate thumbs for images bigger then this (100mb) */ -#define THUMB_SIZE_MAX (100 * 1024*1024) +#define THUMB_SIZE_MAX (100 * 1024 * 1024) // IB_metadata diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index bcfddfe425a..2c6e46cb664 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -351,9 +351,9 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV if (cache_data->exposure != view_settings->exposure || cache_data->gamma != view_settings->gamma || - cache_data->flag != view_settings->flag || - cache_data->curve_mapping != curve_mapping || - cache_data->curve_mapping_timestamp != curve_mapping_timestamp) + cache_data->flag != view_settings->flag || + cache_data->curve_mapping != curve_mapping || + cache_data->curve_mapping_timestamp != curve_mapping_timestamp) { *cache_handle = NULL; @@ -681,7 +681,7 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin } static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display, - float exposure, float gamma) + float exposure, float gamma) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); OCIO_DisplayTransformRcPtr *dt; @@ -698,7 +698,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie if (exposure != 0.0f) { OCIO_MatrixTransformRcPtr *mt; float gain = powf(2.0f, exposure); - const float scale4f[] = {gain, gain, gain, gain}; + const float scale4f[] = {gain, gain, gain, 1.0f}; float m44[16], offset4[4]; OCIO_matrixTransformScale(m44, offset4, scale4f); @@ -731,7 +731,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie } static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, - const char *to_colorspace) + const char *to_colorspace) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); OCIO_ConstProcessorRcPtr *processor; @@ -1591,14 +1591,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in OCIO_PackedImageDesc *img; img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), - channels * sizeof(float), channels * sizeof(float) * width); + channels * sizeof(float), channels * sizeof(float) * width); if (predivide) OCIO_processorApply_predivide(processor, img); else OCIO_processorApply(processor, img); - OCIO_OCIO_PackedImageDescRelease(img); + OCIO_PackedImageDescRelease(img); } } @@ -2538,14 +2538,14 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo /* apply OCIO processor */ img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), - channels * sizeof(float), channels * sizeof(float) * width); + channels * sizeof(float), channels * sizeof(float) * width); if (predivide) OCIO_processorApply_predivide(cm_processor->processor, img); else OCIO_processorApply(cm_processor->processor, img); - OCIO_OCIO_PackedImageDescRelease(img); + OCIO_PackedImageDescRelease(img); } } diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index f0864f06e6f..730a19d84fd 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -69,7 +69,7 @@ struct ColorBlock private: - Color32 m_color[4*4]; + Color32 m_color[4 * 4]; }; diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index 72a524daba2..11e6d4a5708 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -172,7 +172,7 @@ public: void setUserVersion(int version); void mipmap(Image * img, uint f, uint m); - void* readData(uint &size); + void *readData(uint &size); // void mipmap(FloatImage * img, uint f, uint m); void printInfo() const; diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index f0d8b7cac72..84339b51721 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -659,53 +659,6 @@ void IMB_float_from_rect(ImBuf *ibuf) BLI_unlock_thread(LOCK_COLORMANAGE); } -/* use when you need to get a buffer with a certain profile - * if the return */ - -/* OCIO_TODO: used only by Cineon/DPX exporter which is still broken, so can not guarantee - * this function is working properly - */ -float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc) -{ - int profile_from = IB_PROFILE_LINEAR_RGB; - int profile_to; - - /* determine profile */ - if (profile == IB_PROFILE_NONE) - profile_to = IB_PROFILE_LINEAR_RGB; - else - profile_to = IB_PROFILE_SRGB; - - if (profile_from == profile_to) { - /* simple case, just allocate the buffer and return */ - *alloc = 0; - - if (ibuf->rect_float == NULL) - IMB_float_from_rect(ibuf); - - return ibuf->rect_float; - } - else { - /* conversion is needed, first check */ - float *fbuf = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure"); - *alloc = 1; - - if (ibuf->rect_float == NULL) { - IMB_buffer_float_from_byte(fbuf, (uchar *)ibuf->rect, - profile_to, profile_from, FALSE, - ibuf->x, ibuf->y, ibuf->x, ibuf->x); - IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y); - } - else { - IMB_buffer_float_from_float(fbuf, ibuf->rect_float, - 4, profile_to, profile_from, TRUE, - ibuf->x, ibuf->y, ibuf->x, ibuf->x); - } - - return fbuf; - } -} - /**************************** Color to Grayscale *****************************/ /* no profile conversion */ diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 1eac6236829..59282c9d207 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -327,3 +327,53 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_ MEM_freeN(handles); } + +/* Alpha-under */ + +void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]) +{ + int a = x * y; + float *fp = rect_float; + + while (a--) { + if (fp[3] == 0.0f) { + copy_v3_v3(fp, backcol); + } + else { + float mul = 1.0f - fp[3]; + + fp[0] += mul * backcol[0]; + fp[1] += mul * backcol[1]; + fp[2] += mul * backcol[2]; + } + + fp[3] = 1.0f; + + fp += 4; + } +} + +void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]) +{ + int a = x * y; + unsigned char *cp = rect; + + while (a--) { + if (cp[3] == 0) { + cp[0] = backcol[0] * 255; + cp[1] = backcol[1] * 255; + cp[2] = backcol[2] * 255; + } + else { + int mul = 255 - cp[3]; + + cp[0] += mul * backcol[0] / 255; + cp[1] += mul * backcol[1] / 255; + cp[2] += mul * backcol[2] / 255; + } + + cp[3] = 255; + + cp += 4; + } +} diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 03b23c5137a..da666059601 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -119,7 +119,10 @@ typedef struct Mesh { short texflag, drawflag; short smoothresh, flag; - short subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED; + /* customdata flag, for bevel-weight and crease, which are now optional */ + char cd_flag, pad; + + char subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED; char subsurftype DNA_DEPRECATED; /* only kept for backwards compat, not used anymore */ char editflag; @@ -172,6 +175,11 @@ typedef struct TFace { #define ME_DS_EXPAND 512 #define ME_SCULPT_DYNAMIC_TOPOLOGY 1024 +/* me->cd_flag */ +#define ME_CDFLAG_VERT_BWEIGHT (1 << 0) +#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1) +#define ME_CDFLAG_EDGE_CREASE (1 << 2) + /* me->drawflag, short */ #define ME_DRAWEDGES (1 << 0) #define ME_DRAWFACES (1 << 1) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index af1981ae07d..b85bdecee02 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -167,7 +167,7 @@ typedef struct MIntProperty { int i; } MIntProperty; typedef struct MStringProperty { - char s[256]; + char s[255], s_len; } MStringProperty; typedef struct OrigSpaceFace { diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 89328c33674..559ba446740 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -178,7 +178,7 @@ typedef struct Object { short ipoflag; // xxx deprecated... old animation system short scaflag; /* ui state for game logic */ char scavisflag; /* more display settings for game logic */ - char pad5; + char depsflag; int dupon, dupoff, dupsta, dupend; @@ -530,6 +530,10 @@ typedef struct DupliObject { #define OB_BODY_TYPE_NAVMESH 7 #define OB_BODY_TYPE_CHARACTER 8 +/* ob->depsflag */ +#define OB_DEPS_EXTRA_OB_RECALC 1 +#define OB_DEPS_EXTRA_DATA_RECALC 2 + /* ob->scavisflag */ #define OB_VIS_SENS 1 #define OB_VIS_CONT 2 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index e7f27834c85..96bf4a10dda 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -149,6 +149,13 @@ typedef struct uiPanelColors { int pad; } uiPanelColors; +typedef struct uiGradientColors { + char gradient[4]; + char high_gradient[4]; + int show_grad; + int pad2; +} uiGradientColors; + typedef struct ThemeUI { /* Interface Elements (buttons, menus, icons) */ uiWidgetColors wcol_regular, wcol_tool, wcol_text; @@ -210,7 +217,9 @@ typedef struct ThemeSpace { /* note, cannot use name 'panel' because of DNA mapping old files */ uiPanelColors panelcolors; - + + uiGradientColors gradients; + char shade1[4]; char shade2[4]; @@ -440,6 +449,7 @@ typedef struct UserDef { int ndof_flag; /* flags for 3D mouse */ short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */ + short pad4; float glalphaclip; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 8956e9d9005..af182c467be 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -610,6 +610,7 @@ extern StructRNA RNA_ThemeOutliner; extern StructRNA RNA_ThemeProperties; extern StructRNA RNA_ThemeSequenceEditor; extern StructRNA RNA_ThemeSpaceGeneric; +extern StructRNA RNA_ThemeSpaceGradient; extern StructRNA RNA_ThemeSpaceListGeneric; extern StructRNA RNA_ThemeStyle; extern StructRNA RNA_ThemeTextEditor; diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 9939d0839e6..463e0e04679 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -49,6 +49,7 @@ void RNA_exit(void); /* Struct */ +StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom); StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from); void RNA_def_struct_sdna(StructRNA *srna, const char *structname); void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname); @@ -91,7 +92,6 @@ PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont, const char *ide PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description); void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc); -void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data); PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); @@ -177,6 +177,17 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con void RNA_def_property_srna(PropertyRNA *prop, const char *type); void RNA_def_py_data(PropertyRNA *prop, void *py_data); +void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc); +void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc); +void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc); +void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc); +void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc); +void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc); +void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc); +void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc); + +void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data); + void RNA_def_property_translation_context(PropertyRNA *prop, const char *context); /* Function */ diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index dacb2fee212..c76f9824c73 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -269,7 +269,27 @@ typedef struct EnumPropertyItem { const char *description; } EnumPropertyItem; -/* this is a copy of 'PropEnumItemFunc' defined in rna_internal_types.h */ +/* extended versions with PropertyRNA argument */ +typedef int (*BooleanPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*BooleanPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*BooleanArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*BooleanArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef int (*IntPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*IntPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*IntArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*IntArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef void (*IntPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax); +typedef float (*FloatPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*FloatPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value); +typedef void (*FloatArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values); +typedef void (*FloatArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values); +typedef void (*FloatPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax); +typedef void (*StringPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value); +typedef int (*StringPropertyLengthFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*StringPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value); +typedef int (*EnumPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*EnumPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +/* same as PropEnumItemFunc */ typedef EnumPropertyItem *(*EnumPropertyItemFunc)(struct bContext *C, PointerRNA *ptr, struct PropertyRNA *prop, int *free); typedef struct PropertyRNA PropertyRNA; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index a9cb6cdf77e..0992153560f 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2947,11 +2947,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_BOOLEAN: { BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %s, %d, ", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %d, ", rna_function_string(bprop->get), rna_function_string(bprop->set), rna_function_string(bprop->getarray), rna_function_string(bprop->setarray), + rna_function_string(bprop->get_ex), + rna_function_string(bprop->set_ex), + rna_function_string(bprop->getarray_ex), + rna_function_string(bprop->setarray_ex), bprop->defaultvalue); if (prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); @@ -2961,12 +2965,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_INT: { IntPropertyRNA *iprop = (IntPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %s, %s,\n\t", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,\n\t", rna_function_string(iprop->get), rna_function_string(iprop->set), rna_function_string(iprop->getarray), rna_function_string(iprop->setarray), - rna_function_string(iprop->range)); + rna_function_string(iprop->range), + rna_function_string(iprop->get_ex), + rna_function_string(iprop->set_ex), + rna_function_string(iprop->getarray_ex), + rna_function_string(iprop->setarray_ex), + rna_function_string(iprop->range_ex)); rna_int_print(f, iprop->softmin); fprintf(f, ", "); rna_int_print(f, iprop->softmax); fprintf(f, ", "); rna_int_print(f, iprop->hardmin); fprintf(f, ", "); @@ -2981,12 +2990,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_FLOAT: { FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %s, %s, ", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), - rna_function_string(fprop->range)); + rna_function_string(fprop->range), + rna_function_string(fprop->get_ex), + rna_function_string(fprop->set_ex), + rna_function_string(fprop->getarray_ex), + rna_function_string(fprop->setarray_ex), + rna_function_string(fprop->range_ex)); rna_float_print(f, fprop->softmin); fprintf(f, ", "); rna_float_print(f, fprop->softmax); fprintf(f, ", "); rna_float_print(f, fprop->hardmin); fprintf(f, ", "); @@ -3002,10 +3016,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_STRING: { StringPropertyRNA *sprop = (StringPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %d, ", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), + rna_function_string(sprop->get_ex), + rna_function_string(sprop->length_ex), + rna_function_string(sprop->set_ex), sprop->maxlength); rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n"); break; @@ -3013,10 +3030,12 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_ENUM: { EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, NULL, ", + fprintf(f, "\t%s, %s, %s, %s, %s, NULL, ", rna_function_string(eprop->get), rna_function_string(eprop->set), - rna_function_string(eprop->itemf)); + rna_function_string(eprop->itemf), + rna_function_string(eprop->get_ex), + rna_function_string(eprop->set_ex)); if (eprop->item) fprintf(f, "rna_%s%s_%s_items, ", srna->identifier, strnest, prop->identifier); else diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 092c9eb2b17..18281d4d251 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -257,7 +257,7 @@ StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports, return NULL; } - return RNA_def_struct(&BLENDER_RNA, identifier, "PropertyGroup"); /* XXX */ + return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup); /* XXX */ } StructRNA *rna_PropertyGroup_refine(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 0048e1c60c2..59bcb1506af 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_dynstr.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLF_api.h" #include "BLF_translation.h" @@ -937,6 +938,12 @@ void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, in iprop->range(ptr, hardmin, hardmax, &softmin, &softmax); } + else if (iprop->range_ex) { + *hardmin = INT_MIN; + *hardmax = INT_MAX; + + iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax); + } else { *hardmin = iprop->hardmin; *hardmax = iprop->hardmax; @@ -977,8 +984,17 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, iprop->range(ptr, &hardmin, &hardmax, softmin, softmax); - *softmin = MAX2(*softmin, hardmin); - *softmax = MIN2(*softmax, hardmax); + *softmin = max_ii(*softmin, hardmin); + *softmax = min_ii(*softmax, hardmax); + } + else if (iprop->range_ex) { + hardmin = INT_MIN; + hardmax = INT_MAX; + + iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax); + + *softmin = max_ii(*softmin, hardmin); + *softmax = min_ii(*softmax, hardmax); } *step = iprop->step; @@ -1012,6 +1028,12 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin fprop->range(ptr, hardmin, hardmax, &softmin, &softmax); } + else if (fprop->range_ex) { + *hardmin = -FLT_MAX; + *hardmax = FLT_MAX; + + fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax); + } else { *hardmin = fprop->hardmin; *hardmax = fprop->hardmax; @@ -1056,8 +1078,17 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft fprop->range(ptr, &hardmin, &hardmax, softmin, softmax); - *softmin = MAX2(*softmin, hardmin); - *softmax = MIN2(*softmax, hardmax); + *softmin = max_ff(*softmin, hardmin); + *softmax = min_ff(*softmax, hardmax); + } + else if (fprop->range_ex) { + hardmin = -FLT_MAX; + hardmax = FLT_MAX; + + fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax); + + *softmin = max_ff(*softmin, hardmin); + *softmax = min_ff(*softmax, hardmax); } *step = fprop->step; @@ -1645,6 +1676,8 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop) return IDP_Int(idprop); else if (bprop->get) return bprop->get(ptr); + else if (bprop->get_ex) + return bprop->get_ex(ptr, prop); else return bprop->defaultvalue; } @@ -1667,6 +1700,9 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value) else if (bprop->set) { bprop->set(ptr, value); } + else if (bprop->set_ex) { + bprop->set_ex(ptr, prop, value); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -1697,6 +1733,8 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val values[0] = RNA_property_boolean_get(ptr, prop); else if (bprop->getarray) bprop->getarray(ptr, values); + else if (bprop->getarray_ex) + bprop->getarray_ex(ptr, prop, values); else if (bprop->defaultarray) memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength); else @@ -1747,6 +1785,8 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in RNA_property_boolean_set(ptr, prop, values[0]); else if (bprop->setarray) bprop->setarray(ptr, values); + else if (bprop->setarray_ex) + bprop->setarray_ex(ptr, prop, values); else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -1848,6 +1888,8 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop) return IDP_Int(idprop); else if (iprop->get) return iprop->get(ptr); + else if (iprop->get_ex) + return iprop->get_ex(ptr, prop); else return iprop->defaultvalue; } @@ -1868,6 +1910,8 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value) } else if (iprop->set) iprop->set(ptr, value); + else if (iprop->set_ex) + iprop->set_ex(ptr, prop, value); else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -1900,6 +1944,8 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values) values[0] = RNA_property_int_get(ptr, prop); else if (iprop->getarray) iprop->getarray(ptr, values); + else if (iprop->getarray_ex) + iprop->getarray_ex(ptr, prop, values); else if (iprop->defaultarray) memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength); else @@ -1987,6 +2033,8 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v RNA_property_int_set(ptr, prop, values[0]); else if (iprop->setarray) iprop->setarray(ptr, values); + else if (iprop->setarray_ex) + iprop->setarray_ex(ptr, prop, values); else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -2087,6 +2135,8 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop) } else if (fprop->get) return fprop->get(ptr); + else if (fprop->get_ex) + return fprop->get_ex(ptr, prop); else return fprop->defaultvalue; } @@ -2112,6 +2162,9 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value) else if (fprop->set) { fprop->set(ptr, value); } + else if (fprop->set_ex) { + fprop->set_ex(ptr, prop, value); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -2150,6 +2203,8 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val values[0] = RNA_property_float_get(ptr, prop); else if (fprop->getarray) fprop->getarray(ptr, values); + else if (fprop->getarray_ex) + fprop->getarray_ex(ptr, prop, values); else if (fprop->defaultarray) memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength); else @@ -2249,6 +2304,9 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa else if (fprop->setarray) { fprop->setarray(ptr, values); } + else if (fprop->setarray_ex) { + fprop->setarray_ex(ptr, prop, values); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -2361,6 +2419,9 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value) else if (sprop->get) { sprop->get(ptr, value); } + else if (sprop->get_ex) { + sprop->get_ex(ptr, prop, value); + } else { strcpy(value, sprop->defaultvalue); } @@ -2421,6 +2482,8 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop) } else if (sprop->length) return sprop->length(ptr); + else if (sprop->length_ex) + return sprop->length_ex(ptr, prop); else return strlen(sprop->defaultvalue); } @@ -2439,6 +2502,8 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val } else if (sprop->set) sprop->set(ptr, value); /* set function needs to clamp its self */ + else if (sprop->set_ex) + sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */ else if (prop->flag & PROP_EDITABLE) { IDProperty *group; @@ -2497,6 +2562,8 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop) return IDP_Int(idprop); else if (eprop->get) return eprop->get(ptr); + else if (eprop->get_ex) + return eprop->get_ex(ptr, prop); else return eprop->defaultvalue; } @@ -2515,6 +2582,9 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value) else if (eprop->set) { eprop->set(ptr, value); } + else if (eprop->set_ex) { + eprop->set_ex(ptr, prop, value); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -4034,8 +4104,9 @@ static char *rna_idp_path(PointerRNA *ptr, IDProperty *haystack, IDProperty *nee else { if (iter->type == IDP_GROUP) { /* ensure this is RNA */ - PointerRNA child_ptr = RNA_pointer_get(ptr, iter->name); - if (child_ptr.type) { + PropertyRNA *prop = RNA_struct_find_property(ptr, iter->name); + if (prop && prop->type == PROP_POINTER) { + PointerRNA child_ptr = RNA_property_pointer_get(ptr, prop); link.name = iter->name; link.index = -1; if ((path = rna_idp_path(&child_ptr, iter, needle, &link))) { diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 402d05a20b6..d6ea53f6ab3 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -198,6 +198,8 @@ static void rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type) RNA_struct_free_extension(type, &ksi->ext); RNA_struct_free(&BLENDER_RNA, type); + WM_main_add_notifier(NC_WINDOW, NULL); + /* unlink Blender-side data */ ANIM_keyingset_info_unregister(bmain, ksi); } @@ -234,7 +236,7 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo)); /* set RNA-extensions info */ - ksi->ext.srna = RNA_def_struct(&BLENDER_RNA, ksi->idname, "KeyingSetInfo"); + ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo); ksi->ext.data = data; ksi->ext.call = call; ksi->ext.free = free; @@ -249,6 +251,8 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v /* add and register with other info as needed */ ANIM_keyingset_info_register(ksi); + WM_main_add_notifier(NC_WINDOW, NULL); + /* return the struct-rna added */ return ksi->ext.srna; } @@ -577,7 +581,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_flag(prop, PROP_REGISTER); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); @@ -777,7 +781,7 @@ static void rna_def_keyingset(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 36d5a575ab4..bc4194ebffb 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -462,7 +462,7 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int } } -static EnumPropertyItem* rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) +static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) { Scene *scene = CTX_data_scene(C); EnumPropertyItem *items = NULL; diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 727b1e44931..b94d7eb691f 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -623,13 +623,12 @@ static StructDefRNA *rna_find_def_struct(StructRNA *srna) } /* Struct Definition */ - -StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from) +StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom) { - StructRNA *srna, *srnafrom = NULL; + StructRNA *srna; StructDefRNA *ds = NULL, *dsfrom = NULL; PropertyRNA *prop; - + if (DefRNA.preprocess) { char error[512]; @@ -638,18 +637,6 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * DefRNA.error = 1; } } - - if (from) { - /* find struct to derive from */ - for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next) - if (strcmp(srnafrom->identifier, from) == 0) - break; - - if (!srnafrom) { - fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier); - DefRNA.error = 1; - } - } srna = MEM_callocN(sizeof(StructRNA), "StructRNA"); DefRNA.laststruct = srna; @@ -670,7 +657,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * else srna->base = srnafrom; } - + srna->identifier = identifier; srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */ srna->description = ""; @@ -741,6 +728,28 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * return srna; } +StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from) +{ + StructRNA *srnafrom = NULL; + + /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */ + BLI_assert(DefRNA.preprocess); + + if (from) { + /* find struct to derive from */ + for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next) + if (strcmp(srnafrom->identifier, from) == 0) + break; + + if (!srnafrom) { + fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier); + DefRNA.error = 1; + } + } + + return RNA_def_struct_ptr(brna, identifier, srnafrom); +} + void RNA_def_struct_sdna(StructRNA *srna, const char *structname) { StructDefRNA *ds; @@ -2017,6 +2026,38 @@ void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const ch } } +void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc) +{ + BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop; + + if (getfunc) bprop->get_ex = getfunc; + if (setfunc) bprop->set_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc) +{ + BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop; + + if (getfunc) bprop->getarray_ex = getfunc; + if (setfunc) bprop->setarray_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range) { StructRNA *srna = DefRNA.laststruct; @@ -2049,6 +2090,38 @@ void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char * } } +void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc) +{ + IntPropertyRNA *iprop = (IntPropertyRNA *)prop; + + if (getfunc) iprop->get_ex = getfunc; + if (setfunc) iprop->set_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc) +{ + IntPropertyRNA *iprop = (IntPropertyRNA *)prop; + + if (getfunc) iprop->getarray_ex = getfunc; + if (setfunc) iprop->setarray_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range) { StructRNA *srna = DefRNA.laststruct; @@ -2081,6 +2154,40 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char } } +void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc) +{ + FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; + + if (getfunc) fprop->get_ex = getfunc; + if (setfunc) fprop->set_ex = setfunc; + if (rangefunc) fprop->range_ex = rangefunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc) +{ + FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; + + if (getfunc) fprop->getarray_ex = getfunc; + if (setfunc) fprop->setarray_ex = setfunc; + if (rangefunc) fprop->range_ex = rangefunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item) { StructRNA *srna = DefRNA.laststruct; @@ -2107,6 +2214,29 @@ void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char } } +void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc) +{ + EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; + + if (getfunc) eprop->get_ex = getfunc; + if (setfunc) eprop->set_ex = setfunc; + if (itemfunc) eprop->itemf = itemfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data) +{ + EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; + eprop->py_data = py_data; +} + void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set) { StructRNA *srna = DefRNA.laststruct; @@ -2133,6 +2263,23 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha } } +void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc) +{ + StringPropertyRNA *sprop = (StringPropertyRNA *)prop; + + if (getfunc) sprop->get_ex = getfunc; + if (lengthfunc) sprop->length_ex = lengthfunc; + if (setfunc) sprop->set_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll) { @@ -2447,12 +2594,6 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc) eprop->itemf = itemfunc; } -void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data) -{ - EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; - eprop->py_data = py_data; -} - PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index ccfb83b61e3..43ec09de010 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -30,6 +30,8 @@ #include "DNA_listBase.h" +#include "RNA_types.h" + struct BlenderRNA; struct ContainerRNA; struct StructRNA; @@ -64,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr); typedef int (*EditableFunc)(struct PointerRNA *ptr); typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index); -typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int create); +typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create); typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr); typedef char *(*StructPathFunc)(struct PointerRNA *ptr); @@ -91,7 +93,7 @@ typedef void (*PropEnumSetFunc)(struct PointerRNA *ptr, int value); typedef EnumPropertyItem *(*PropEnumItemFunc)(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr); -typedef StructRNA* (*PropPointerTypeFunc)(struct PointerRNA *ptr); +typedef StructRNA *(*PropPointerTypeFunc)(struct PointerRNA *ptr); typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value); typedef int (*PropPointerPollFunc)(struct PointerRNA *ptr, const PointerRNA value); typedef void (*PropCollectionBeginFunc)(struct CollectionPropertyIterator *iter, struct PointerRNA *ptr); @@ -103,6 +105,27 @@ typedef int (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key, stru typedef int (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key, struct PointerRNA *r_ptr); typedef int (*PropCollectionAssignIntFunc)(struct PointerRNA *ptr, int key, const struct PointerRNA *assign_ptr); +/* extended versions with PropertyRNA argument */ +typedef int (*PropBooleanGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropBooleanSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*PropBooleanArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*PropBooleanArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef int (*PropIntGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropIntSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*PropIntArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*PropIntArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef void (*PropIntRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax); +typedef float (*PropFloatGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropFloatSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value); +typedef void (*PropFloatArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values); +typedef void (*PropFloatArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values); +typedef void (*PropFloatRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax); +typedef void (*PropStringGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value); +typedef int (*PropStringLengthFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropStringSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value); +typedef int (*PropEnumGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); + /* Container - generic abstracted container of RNA properties */ typedef struct ContainerRNA { void *next, *prev; @@ -193,10 +216,14 @@ typedef struct BoolPropertyRNA { PropBooleanGetFunc get; PropBooleanSetFunc set; - PropBooleanArrayGetFunc getarray; PropBooleanArraySetFunc setarray; + PropBooleanGetFuncEx get_ex; + PropBooleanSetFuncEx set_ex; + PropBooleanArrayGetFuncEx getarray_ex; + PropBooleanArraySetFuncEx setarray_ex; + int defaultvalue; const int *defaultarray; } BoolPropertyRNA; @@ -206,12 +233,16 @@ typedef struct IntPropertyRNA { PropIntGetFunc get; PropIntSetFunc set; - PropIntArrayGetFunc getarray; PropIntArraySetFunc setarray; - PropIntRangeFunc range; + PropIntGetFuncEx get_ex; + PropIntSetFuncEx set_ex; + PropIntArrayGetFuncEx getarray_ex; + PropIntArraySetFuncEx setarray_ex; + PropIntRangeFuncEx range_ex; + int softmin, softmax; int hardmin, hardmax; int step; @@ -225,12 +256,16 @@ typedef struct FloatPropertyRNA { PropFloatGetFunc get; PropFloatSetFunc set; - PropFloatArrayGetFunc getarray; PropFloatArraySetFunc setarray; - PropFloatRangeFunc range; + PropFloatGetFuncEx get_ex; + PropFloatSetFuncEx set_ex; + PropFloatArrayGetFuncEx getarray_ex; + PropFloatArraySetFuncEx setarray_ex; + PropFloatRangeFuncEx range_ex; + float softmin, softmax; float hardmin, hardmax; float step; @@ -247,6 +282,10 @@ typedef struct StringPropertyRNA { PropStringLengthFunc length; PropStringSetFunc set; + PropStringGetFuncEx get_ex; + PropStringLengthFuncEx length_ex; + PropStringSetFuncEx set_ex; + int maxlength; /* includes string terminator! */ const char *defaultvalue; @@ -258,6 +297,9 @@ typedef struct EnumPropertyRNA { PropEnumGetFunc get; PropEnumSetFunc set; PropEnumItemFunc itemf; + + PropEnumGetFuncEx get_ex; + PropEnumSetFuncEx set_ex; void *py_data; /* store py callback here */ EnumPropertyItem *item; diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 31e27ebc982..8c8b7b4f637 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1233,6 +1233,26 @@ static char *rna_MeshStringProperty_path(PointerRNA *ptr) return rna_PolyCustomData_data_path(ptr, "layers_string", CD_PROP_STR); } +/* XXX, we dont have propper byte string support yet, so for now use the (bytes + 1) + * bmesh API exposes correct python/bytestring access */ +void rna_MeshStringProperty_s_get(PointerRNA *ptr, char *value) +{ + MStringProperty *ms = (MStringProperty *)ptr->data; + BLI_strncpy(value, ms->s, (int)ms->s_len + 1); +} + +int rna_MeshStringProperty_s_length(PointerRNA *ptr) +{ + MStringProperty *ms = (MStringProperty *)ptr->data; + return (int)ms->s_len + 1; +} + +void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value) +{ + MStringProperty *ms = (MStringProperty *)ptr->data; + BLI_strncpy(ms->s, value, sizeof(ms->s)); +} + static int rna_Mesh_tot_vert_get(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); @@ -2182,6 +2202,7 @@ static void rna_def_mproperties(BlenderRNA *brna) /* low level mesh data access, treat as bytes */ prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING); RNA_def_property_string_sdna(prop, NULL, "s"); + RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set"); RNA_def_property_ui_text(prop, "Value", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } @@ -3010,6 +3031,22 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask"); + + + /* customdata flags */ + prop = RNA_def_property(srna, "use_customdata_vertex_bevel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_BWEIGHT); + RNA_def_property_ui_text(prop, "Store Vertex Bevel Weight", ""); + + prop = RNA_def_property(srna, "use_customdata_edge_bevel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_BWEIGHT); + RNA_def_property_ui_text(prop, "Store Edge Bevel Weight", ""); + + prop = RNA_def_property(srna, "use_customdata_edge_crease", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_CREASE); + RNA_def_property_ui_text(prop, "Store Edge Crease", ""); + + /* readonly editmesh info - use for extrude menu */ prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 18dfd8aa6f9..eecdf13813c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -288,6 +288,47 @@ static const char *rna_Node_get_node_type(StructRNA *type) return ""; } +static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value) +{ + bNode *node = ptr->data; + bNode *parent = value.data; + + if (parent) { + /* XXX only Frame node allowed for now, + * in the future should have a poll function or so to test possible attachment. + */ + if (parent->type != NODE_FRAME) + return; + + /* make sure parent is not attached to the node */ + if (nodeAttachNodeCheck(parent, node)) + return; + } + + nodeDetachNode(node); + if (parent) { + nodeAttachNode(node, parent); + } +} + +static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value) +{ + bNode *node = ptr->data; + bNode *parent = value.data; + + /* XXX only Frame node allowed for now, + * in the future should have a poll function or so to test possible attachment. + */ + if (parent->type != NODE_FRAME) + return FALSE; + + /* make sure parent is not attached to the node */ + if (nodeAttachNodeCheck(parent, node)) + return FALSE; + + return TRUE; +} + static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) { bNodeSocket *sock = (bNodeSocket *)ptr->data; @@ -2480,7 +2521,7 @@ static void def_cmp_dilate_erode(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem type_items[] = { + static EnumPropertyItem mode_items[] = { {CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""}, {CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""}, {CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""}, @@ -2488,10 +2529,10 @@ static void def_cmp_dilate_erode(StructRNA *srna) {0, NULL, 0, NULL, NULL} }; - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, type_items); - RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)"); + RNA_def_property_enum_items(prop, mode_items); + RNA_def_property_ui_text(prop, "Mode", "Growing/shrinking mode"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); @@ -4689,8 +4730,9 @@ static void rna_def_node(BlenderRNA *brna) prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "parent"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_parent_set", NULL, "rna_Node_parent_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Node"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to"); prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 80d74c3a9fe..a617c78019f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2469,6 +2469,15 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship"); RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + /* depsgraph hack */ + prop = RNA_def_property(srna, "extra_recalc_object", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_OB_RECALC); + RNA_def_property_ui_text(prop, "Extra Object Update", "Refresh this object again on frame changes, dependency graph hack"); + + prop = RNA_def_property(srna, "extra_recalc_data", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_DATA_RECALC); + RNA_def_property_ui_text(prop, "Extra Data Update", "Refresh this object's data again on frame changes, dependency graph hack"); + /* duplicates */ prop = RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag"); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index d7115256fe5..40b8d4cce66 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -129,9 +129,6 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int DerivedMesh *derivedFinal = NULL; int uv_from_orco; - int (*orco_index)[4] = NULL; - float (*orco)[3] = NULL; - /* copies object and modifiers (but not the data) */ tmpobj = BKE_object_copy_with_caches(ob); tmpcu = (Curve *)tmpobj->data; @@ -158,38 +155,12 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int tmpobj->derivedFinal = derivedFinal; - uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; - - if (uv_from_orco) { - /* before curve conversion */ - orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj); - } - /* convert object type to mesh */ - BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL); + uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; + BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco); tmpmesh = tmpobj->data; - if (uv_from_orco && orco && orco_index) { - const char *uvname = "Orco"; - /* add UV's */ - MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname); - MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname); - - BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly, - tmpmesh->mloop, mloopuvs, - orco, orco_index); - - (void)mtpoly; - } - - if (orco_index) { - MEM_freeN(orco_index); - } - if (orco) { - MEM_freeN(orco); - } - BKE_displist_free(&dispbase); /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index be3cbfaece3..4a520cdc729 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -492,7 +492,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { if (num != DMCACHE_NOTFOUND) { MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no); + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no); mc += num * 4; psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol); @@ -517,7 +517,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) { if (cpa->num != DMCACHE_NOTFOUND) { MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); mc += cpa->num * 4; psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol); @@ -543,7 +543,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { if (num != DMCACHE_NOTFOUND) { MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); mc += num * 4; psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol); @@ -1545,9 +1545,9 @@ static void rna_def_fluid_settings(BlenderRNA *brna) /* Double density relaxation */ prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness_k"); - RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is"); + RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is (speed of sound)"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "repulsion", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 93c5b45e642..5931440b422 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -196,7 +196,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo et = MEM_callocN(sizeof(RenderEngineType), "python render engine"); memcpy(et, &dummyet, sizeof(dummyet)); - et->ext.srna = RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine"); + et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine); et->ext.data = data; et->ext.call = call; et->ext.free = free; @@ -415,7 +415,7 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP); - prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->name"); RNA_def_property_flag(prop, PROP_REGISTER); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 8d99cecd9fa..f4059bc5846 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -278,9 +278,11 @@ EnumPropertyItem image_color_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +#ifdef RNA_RUNTIME #define IMAGE_COLOR_MODE_BW image_color_mode_items[0] #define IMAGE_COLOR_MODE_RGB image_color_mode_items[1] #define IMAGE_COLOR_MODE_RGBA image_color_mode_items[2] +#endif EnumPropertyItem image_color_depth_items[] = { /* 1 (monochrome) not used */ diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 17edf2944aa..cc1895541df 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -222,7 +222,7 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU if (ob->sculpt) { ob->sculpt->bm_smooth_shading = (scene->toolsettings->sculpt->flags & - SCULPT_DYNTOPO_SMOOTH_SHADING); + SCULPT_DYNTOPO_SMOOTH_SHADING); } } } diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 69d35a3c2f0..386263c784e 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -82,14 +82,14 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, BKE_report(reports, RPT_ERROR, error_msg); } -static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start_frame, +static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int frame_start, int channel, int type, const char *file) { Sequence *seq; Strip *strip; StripElem *se; - seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel); + seq = BKE_sequence_alloc(ed->seqbasep, frame_start, channel); seq->type = type; BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2); @@ -113,12 +113,12 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, const char *name, MovieClip *clip, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIECLIP, clip->name); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIECLIP, clip->name); seq->clip = clip; seq->len = BKE_movieclip_get_duration(clip); id_us_plus((ID *)clip); @@ -132,12 +132,12 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed, const char *name, Mask *mask, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MASK, mask->id.name); seq->mask = mask; seq->len = BKE_mask_get_duration(mask); id_us_plus((ID *)mask); @@ -151,15 +151,15 @@ static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed, static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, const char *name, Scene *sce_seq, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SCENE, NULL); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SCENE, NULL); seq->scene = sce_seq; seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; - seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); + seq->scene_sound = sound_scene_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0); id_us_plus((ID *)sce_seq); BKE_sequence_calc_disp(scene, seq); @@ -171,12 +171,12 @@ static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *reports, const char *name, const char *file, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_IMAGE, file); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_IMAGE, file); seq->len = 1; if (seq->strip->stripdata->name[0] == '\0') { @@ -195,12 +195,11 @@ static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *report static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *reports, const char *name, const char *file, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - /* OCIO_TODO: support configurable color spaces for strips */ struct anim *an = openanim(file, IB_rect, 0, NULL); if (an == NULL) { @@ -208,7 +207,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIE, file); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file); seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN); @@ -222,7 +221,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report #ifdef WITH_AUDASPACE static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, ReportList *reports, - const char *name, const char *file, int channel, int start_frame) + const char *name, const char *file, int channel, int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; @@ -234,11 +233,11 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SOUND_RAM, sound->name); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SOUND_RAM, sound->name); seq->sound = sound; seq->len = ceil((double)sound_get_length(sound) * FPS); - seq->scene_sound = sound_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); + seq->scene_sound = sound_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0); BKE_sequence_calc_disp(scene, seq); @@ -249,7 +248,7 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor #else /* WITH_AUDASPACE */ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports, const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), - int UNUSED(start_frame)) + int UNUSED(frame_start)) { BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support"); return NULL; @@ -258,7 +257,7 @@ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Ma static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *reports, const char *name, int type, int channel, - int start_frame, int end_frame, + int frame_start, int frame_end, Sequence *seq1, Sequence *seq2, Sequence *seq3) { Scene *scene = (Scene *)id; @@ -268,7 +267,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor switch (num_inputs) { case 0: - if (end_frame <= start_frame) { + if (frame_end <= frame_start) { BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set"); return NULL; } @@ -298,7 +297,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, type, NULL); + seq = alloc_generic_sequence(ed, name, frame_start, channel, type, NULL); sh = BKE_sequence_get_effect(seq); @@ -310,7 +309,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor if (!seq1) { /* effect has no deps */ seq->len = 1; - BKE_sequence_tx_set_final_right(seq, end_frame); + BKE_sequence_tx_set_final_right(seq, frame_end); } seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; @@ -488,7 +487,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -505,7 +504,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -522,7 +521,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -539,7 +538,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -556,7 +555,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -573,7 +572,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -590,12 +589,13 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); + /* don't use MAXFRAME since it makes importer scripts fail */ RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", - "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + parm = RNA_def_int(func, "frame_start", 0, INT_MIN, INT_MAX, "", + "The start frame for the new sequence", INT_MIN, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "", - "The end frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_int(func, "frame_end", 0, INT_MIN, INT_MAX, "", + "The end frame for the new sequence", INT_MIN, INT_MAX); RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect"); RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect"); RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect"); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 7cc57947671..cd646f4849c 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -402,39 +402,52 @@ static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, P /* API */ -static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) +static MovieTrackingTrack *add_track_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, const char *name, int frame) { - int a, width, height; + int width, height; MovieClipUser user = {0}; + MovieTrackingTrack *track; user.framenr = 1; BKE_movieclip_get_size(clip, &user, &width, &height); - for (a = 0; a < number; a++) - BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height); + track = BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height); + + if (name && name[0]) { + BLI_strncpy(track->name, name, sizeof(track->name)); + BKE_tracking_track_unique_name(tracksbase, track); + } + + return track; } -static void rna_trackingTracks_add(ID *id, MovieTracking *tracking, int frame, int number) +static MovieTrackingTrack *rna_trackingTracks_new(ID *id, MovieTracking *tracking, const char *name, int frame) { MovieClip *clip = (MovieClip *) id; + MovieTrackingTrack *track; - add_tracks_to_base(clip, tracking, &tracking->tracks, frame, number); + track = add_track_to_base(clip, tracking, &tracking->tracks, name, frame); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, clip); + + return track; } -static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number) +static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, int frame) { MovieClip *clip = (MovieClip *) id; ListBase *tracksbase = &object->tracks; + MovieTrackingTrack *track; if (object->flag & TRACKING_OBJECT_CAMERA) tracksbase = &clip->tracking.tracks; - add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number); + track = add_track_to_base(clip, &clip->tracking, tracksbase, name, frame); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); + + return track; } static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name) @@ -475,6 +488,14 @@ static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack marker.framenr = framenr; copy_v2_v2(marker.pos, co); + /* a bit arbitrary, but better than creating markers with zero pattern + * which is forbidden actually + */ + copy_v2_v2(marker.pattern_corners[0], track->markers[0].pattern_corners[0]); + copy_v2_v2(marker.pattern_corners[1], track->markers[0].pattern_corners[1]); + copy_v2_v2(marker.pattern_corners[2], track->markers[0].pattern_corners[2]); + copy_v2_v2(marker.pattern_corners[3], track->markers[0].pattern_corners[3]); + new_marker = BKE_tracking_marker_insert(track, &marker); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); @@ -1318,16 +1339,19 @@ static void rna_def_trackingTracks(BlenderRNA *brna) StructRNA *srna; FunctionRNA *func; PropertyRNA *prop; + PropertyRNA *parm; srna = RNA_def_struct(brna, "MovieTrackingTracks", NULL); RNA_def_struct_sdna(srna, "MovieTracking"); RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); - func = RNA_def_function(srna, "add", "rna_trackingTracks_add"); + func = RNA_def_function(srna, "new", "rna_trackingTracks_new"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); - RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); - RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); + RNA_def_function_ui_description(func, "Create new motion track in this movie clip"); + RNA_def_string(func, "name", "", 0, "", "Name of new track"); + RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add track on", MINFRAME, MAXFRAME); + parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track"); + RNA_def_function_return(func, parm); /* active track */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); @@ -1342,16 +1366,19 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna) StructRNA *srna; FunctionRNA *func; PropertyRNA *prop; + PropertyRNA *parm; srna = RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL); RNA_def_struct_sdna(srna, "MovieTrackingObject"); RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); - func = RNA_def_function(srna, "add", "rna_trackingObject_tracks_add"); + func = RNA_def_function(srna, "new", "rna_trackingObject_tracks_new"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); + RNA_def_function_ui_description(func, "create new motion track in this movie clip"); + RNA_def_string(func, "name", "", 0, "", "Name of new track"); RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); - RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); + parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track"); + RNA_def_function_return(func, parm); /* active track */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 14789a437b7..00124a82dd1 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -165,7 +165,7 @@ static void panel_draw_header(const bContext *C, Panel *pnl) RNA_parameter_list_free(&list); } -static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) +static void rna_Panel_unregister(Main *bmain, StructRNA *type) { ARegionType *art; PanelType *pt = RNA_struct_blender_type_get(type); @@ -181,7 +181,7 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -225,7 +225,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat pt = MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); - pt->ext.srna = RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); + pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel); pt->ext.data = data; pt->ext.call = call; pt->ext.free = free; @@ -251,7 +251,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat BLI_addtail(&art->paneltypes, pt); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return pt->ext.srna; } @@ -303,7 +303,7 @@ static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -338,7 +338,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist"); memcpy(ult, &dummyult, sizeof(dummyult)); - ult->ext.srna = RNA_def_struct(&BLENDER_RNA, ult->idname, "UIList"); + ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList); ult->ext.data = data; ult->ext.call = call; ult->ext.free = free; @@ -350,7 +350,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da WM_uilisttype_add(ult); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return ult->ext.srna; } @@ -397,7 +397,7 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -439,7 +439,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da ht = MEM_callocN(sizeof(HeaderType), "python buttons header"); memcpy(ht, &dummyht, sizeof(dummyht)); - ht->ext.srna = RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); + ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header); ht->ext.data = data; ht->ext.call = call; ht->ext.free = free; @@ -450,7 +450,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da BLI_addtail(&art->headertypes, ht); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return ht->ext.srna; } @@ -520,7 +520,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static char _menu_descr[RNA_DYN_DESCR_MAX]; @@ -572,7 +572,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data mt->description = buf; } - mt->ext.srna = RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); + mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu); mt->ext.data = data; mt->ext.call = call; mt->ext.free = free; @@ -585,7 +585,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data WM_menutype_add(mt); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return mt->ext.srna; } @@ -1000,7 +1000,7 @@ static void rna_def_menu(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Label", "The menu label"); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set"); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7474ff40e32..f53b67c0e92 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -345,6 +345,11 @@ static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data); } +static PointerRNA rna_Theme_space_gradient_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGradient, ptr->data); +} + static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceListGeneric, ptr->data); @@ -471,7 +476,7 @@ static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -509,7 +514,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void memcpy(apt, &dummyapt, sizeof(dummyapt)); BKE_addon_pref_type_add(apt); - apt->ext.srna = RNA_def_struct(&BLENDER_RNA, identifier, "AddonPreferences"); + apt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_AddonPreferences); apt->ext.data = data; apt->ext.call = call; apt->ext.free = free; @@ -518,7 +523,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void // apt->draw = (have_function[0]) ? header_draw : NULL; /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return apt->ext.srna; } @@ -758,6 +763,32 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_userdef_update"); } +static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ThemeGradientColors", NULL); + RNA_def_struct_sdna(srna, "uiGradientColors"); + RNA_def_struct_clear_flag(srna, STRUCT_UNDO); + RNA_def_struct_ui_text(srna, "Theme Background Color", "Theme settings for background colors and gradient"); + + prop = RNA_def_property(srna, "show_grad", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Use Gradient", + "Do a gradient for the background of the viewport working area"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Gradient Low", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "high_gradient", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Gradient High/Off", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +} + static void rna_def_userdef_theme_ui(BlenderRNA *brna) { StructRNA *srna; @@ -766,7 +797,8 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) rna_def_userdef_theme_ui_wcol(brna); rna_def_userdef_theme_ui_wcol_state(brna); rna_def_userdef_theme_ui_panel(brna); - + rna_def_userdef_theme_ui_gradient(brna); + srna = RNA_def_struct(brna, "ThemeUserInterface", NULL); RNA_def_struct_sdna(srna, "ThemeUI"); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); @@ -976,6 +1008,83 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna) /* } */ } +static void rna_def_userdef_theme_space_gradient(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ThemeSpaceGradient", NULL); + RNA_def_struct_sdna(srna, "ThemeSpace"); + RNA_def_struct_ui_text(srna, "Theme Space Settings", ""); + + /* window */ + prop = RNA_def_property(srna, "title", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Title", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* header */ + prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Header", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "header_text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Header Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Header Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* panel settings */ + prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Panel Colors", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* gradient/background settings */ + prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Gradient Colors", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* buttons */ +/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */ + prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Region Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Region Text Titles", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Region Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Region Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +/* } */ +} + /* list / channels */ static void rna_def_userdef_theme_space_list_generic(BlenderRNA *brna) { @@ -1018,6 +1127,17 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna) RNA_def_property_ui_text(prop, "Theme Space", "Settings for space"); } +static void rna_def_userdef_theme_spaces_gradient(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "space", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "ThemeSpaceGradient"); + RNA_def_property_pointer_funcs(prop, "rna_Theme_space_gradient_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Theme Space", "Settings for space"); +} + static void rna_def_userdef_theme_spaces_list_main(StructRNA *srna) { PropertyRNA *prop; @@ -1236,7 +1356,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme 3D View", "Theme settings for the 3D View"); - rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_gradient(srna); prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -2550,6 +2670,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna) rna_def_userdef_theme_ui(brna); rna_def_userdef_theme_space_generic(brna); + rna_def_userdef_theme_space_gradient(brna); rna_def_userdef_theme_space_list_generic(brna); rna_def_userdef_theme_space_view3d(brna); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f123b564f8d..f416d3403ad 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1138,7 +1138,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * * for now just remove from dir(bpy.types) */ /* create a new operator type */ - dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); + dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator); RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */ dummyot.ext.data = data; dummyot.ext.call = call; @@ -1219,7 +1219,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v * for now just remove from dir(bpy.types) */ /* create a new operator type */ - dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); + dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator); dummyot.ext.data = data; dummyot.ext.call = call; dummyot.ext.free = free; @@ -1340,7 +1340,7 @@ static void rna_def_operator(BlenderRNA *brna) /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */ RNA_def_property_flag(prop, PROP_REGISTER); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set"); @@ -1407,7 +1407,7 @@ static void rna_def_macro_operator(BlenderRNA *brna) /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */ RNA_def_property_flag(prop, PROP_REGISTER); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set"); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index a84b1124d44..7a94566c6ee 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -529,7 +529,7 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "zenr"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Zenith Color", "Color at the zenith"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); prop = RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "ambr"); @@ -554,17 +554,17 @@ void RNA_def_world(BlenderRNA *brna) prop = RNA_def_property(srna, "use_sky_blend", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYBLEND); RNA_def_property_ui_text(prop, "Blend Sky", "Render background with natural progression from horizon to zenith"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); prop = RNA_def_property(srna, "use_sky_paper", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYPAPER); RNA_def_property_ui_text(prop, "Paper Sky", "Flatten blend or texture coordinates"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); prop = RNA_def_property(srna, "use_sky_real", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYREAL); RNA_def_property_ui_text(prop, "Real Sky", "Render background with a real horizon, relative to the camera angle"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); /* nested structs */ prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index ff88cd97197..1021620e04f 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -274,7 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1); /* will the screw be closed? - * Note! smaller then FLT_EPSILON*100 gives problems with float precision so its never closed. */ + * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) { diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 9bd45d2b759..13cb11d1301 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -66,7 +66,7 @@ void BPY_python_end(void); /* 2.5 UI Scripts */ int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports); -int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump); +int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump); void BPY_text_free_code(struct Text *text); void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date void BPY_modules_load_user(struct bContext *C); diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index ded35363287..32315195072 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -523,7 +523,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec * * \note Don't throw any exceptions and should always return a valid (PyObject *). */ -static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) +static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) { PyObject *item = NULL; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index f39e170c481..37376cc7610 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1631,6 +1631,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self) } +PyDoc_STRVAR(bpy_bmface_normal_flip_doc, +".. method:: normal_flip()\n" +"\n" +" Reverses winding of a face, which flips its normal.\n" +); +static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self) +{ + BPY_BM_CHECK_OBJ(self); + + BM_face_normal_flip(self->bm, self->f); + + Py_RETURN_NONE; +} + + /* Loop * ---- */ @@ -2439,6 +2454,7 @@ static struct PyMethodDef bpy_bmface_methods[] = { {"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc}, {"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc}, + {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index fd31f3c40cc..4a8f8d49f35 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) case CD_PROP_STR: { MStringProperty *mstring = value; - ret = PyBytes_FromStringAndSize(mstring->s, BLI_strnlen(mstring->s, sizeof(mstring->s))); + ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len); break; } case CD_MTEXPOLY: @@ -1067,13 +1067,17 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj case CD_PROP_STR: { MStringProperty *mstring = value; - const char *tmp_val = PyBytes_AsString(py_value); - if (UNLIKELY(tmp_val == NULL)) { + char *tmp_val; + Py_ssize_t tmp_val_len; + if (UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) { PyErr_Format(PyExc_TypeError, "expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name); ret = -1; } else { - BLI_strncpy(mstring->s, tmp_val, min_ii(PyBytes_Size(py_value), sizeof(mstring->s))); + if (tmp_val_len > sizeof(mstring->s)) + tmp_val_len = sizeof(mstring->s); + memcpy(mstring->s, tmp_val, tmp_val_len); + mstring->s_len = tmp_val_len; } break; } diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 1592ec52b4c..56cdf677ccb 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -48,9 +48,9 @@ struct Text; void bpy_import_init(PyObject *builtins); -PyObject* bpy_text_import(struct Text *text); -PyObject* bpy_text_import_name(const char *name, int *found); -PyObject* bpy_text_reimport(PyObject *module, int *found); +PyObject *bpy_text_import(struct Text *text); +PyObject *bpy_text_import_name(const char *name, int *found); +PyObject *bpy_text_reimport(PyObject *module, int *found); /* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */ void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text); diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 9a064923736..56d9e2ac0dd 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -33,6 +33,8 @@ #include <Python.h> #include <frameobject.h> +#include "BLI_utildefines.h" /* for bool */ + #include "py_capi_utils.h" /* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */ @@ -44,7 +46,7 @@ /* array utility function */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, - const PyTypeObject *type, const short is_double, const char *error_prefix) + const PyTypeObject *type, const bool is_double, const char *error_prefix) { PyObject *value_fast; Py_ssize_t value_len; @@ -112,6 +114,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, return 0; } +/* array utility function */ +PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const bool is_double, const char *error_prefix) +{ + PyObject *tuple; + int i; + + tuple = PyTuple_New(length); + + /* for each type */ + if (type == &PyFloat_Type) { + if (is_double) { + const double *array_double = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i])); + } + } + else { + const float *array_float = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i])); + } + } + } + else if (type == &PyLong_Type) { + /* could use is_double for 'long int' but no use now */ + const int *array_int = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i])); + } + } + else if (type == &PyBool_Type) { + const int *array_bool = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i])); + } + } + else { + Py_DECREF(tuple); + PyErr_Format(PyExc_TypeError, + "%s: internal error %s is invalid", + error_prefix, type->tp_name); + return NULL; + } + + return tuple; +} + /* for debugging */ void PyC_ObSpit(const char *name, PyObject *var) diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index db582bd7086..239858032de 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -38,7 +38,9 @@ PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *f void PyC_FileAndNum(const char **filename, int *lineno); void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, - const PyTypeObject *type, const short is_double, const char *error_prefix); + const PyTypeObject *type, const bool is_double, const char *error_prefix); +PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const bool is_double, const char *error_prefix); /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index c4d8f8ee9b8..1f8385288bd 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -35,19 +35,19 @@ #include "RNA_types.h" #include "RNA_access.h" -#include "bpy.h" -#include "bpy_util.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BKE_bpath.h" +#include "BLI_utildefines.h" + +#include "bpy.h" +#include "bpy_util.h" #include "bpy_rna.h" #include "bpy_app.h" #include "bpy_props.h" #include "bpy_library.h" #include "bpy_operator.h" -#include "BLI_path_util.h" -#include "BLI_string.h" -#include "BKE_bpath.h" -#include "BLI_utildefines.h" - #include "BKE_main.h" #include "BKE_global.h" /* XXX, G.main only */ #include "BKE_blender.h" @@ -98,7 +98,7 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), cons PyObject *item = PyUnicode_DecodeFSDefault(path_src); PyList_Append(list, item); Py_DECREF(item); - return FALSE; /* never edits the path */ + return false; /* never edits the path */ } PyDoc_STRVAR(bpy_blend_paths_doc, @@ -120,9 +120,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec int flag = 0; PyObject *list; - int absolute = FALSE; - int packed = FALSE; - int local = FALSE; + int absolute = false; + int packed = false; + int local = false; static const char *kwlist[] = {"absolute", "packed", "local", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths", @@ -209,7 +209,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj return NULL; } - path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE); + path = BLI_get_folder_version(folder_id, (major * 100) + minor, false); return PyUnicode_DecodeFSDefault(path ? path : ""); } diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 784ce2f93e0..65568e9a0c1 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -182,7 +182,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos const int flag = GET_INT_FROM_POINTER(closure); const int param = PyObject_IsTrue(value); - if (param < 0) { + if (param == -1) { PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False"); return -1; } diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c index 5ae2a11710a..3bf3dec3872 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.c +++ b/source/blender/python/intern/bpy_app_ffmpeg.c @@ -41,16 +41,16 @@ static PyTypeObject BlenderAppFFmpegType; #define DEF_FFMPEG_LIB_VERSION(lib) \ {(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \ - {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}, + {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")} static PyStructSequence_Field app_ffmpeg_info_fields[] = { {(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")}, - DEF_FFMPEG_LIB_VERSION(avcodec) - DEF_FFMPEG_LIB_VERSION(avdevice) - DEF_FFMPEG_LIB_VERSION(avformat) - DEF_FFMPEG_LIB_VERSION(avutil) - DEF_FFMPEG_LIB_VERSION(swscale) + DEF_FFMPEG_LIB_VERSION(avcodec), + DEF_FFMPEG_LIB_VERSION(avdevice), + DEF_FFMPEG_LIB_VERSION(avformat), + DEF_FFMPEG_LIB_VERSION(avutil), + DEF_FFMPEG_LIB_VERSION(swscale), {NULL} }; diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 9a79616c23b..c49794ad37a 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -122,7 +122,7 @@ static void bpy_pydriver_update_dict(const float evaltime) void BPY_driver_reset(void) { PyGILState_STATE gilstate; - int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + bool use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) gilstate = PyGILState_Ensure(); @@ -175,7 +175,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */ PyObject *expr_code; PyGILState_STATE gilstate; - int use_gil; + bool use_gil; DriverVar *dvar; double result = 0.0; /* default return */ @@ -193,7 +193,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) return 0.0f; } - use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) gilstate = PyGILState_Ensure(); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 7bce8673943..e9fa00c7868 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -39,6 +39,15 @@ #include "MEM_guardedalloc.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_string.h" +#include "BLI_string_utf8.h" +#include "BLI_utildefines.h" +#include "BLI_threads.h" + #include "RNA_types.h" #include "bpy.h" @@ -52,15 +61,6 @@ #include "DNA_space_types.h" #include "DNA_text_types.h" -#include "BLI_path_util.h" -#include "BLI_fileops.h" -#include "BLI_listbase.h" -#include "BLI_math_base.h" -#include "BLI_string.h" -#include "BLI_string_utf8.h" -#include "BLI_utildefines.h" -#include "BLI_threads.h" - #include "BKE_context.h" #include "BKE_text.h" #include "BKE_main.h" @@ -166,7 +166,7 @@ void BPY_text_free_code(Text *text) { if (text->compiled) { PyGILState_STATE gilstate; - int use_gil = !PYC_INTERPRETER_ACTIVE; + bool use_gil = !PYC_INTERPRETER_ACTIVE; if (use_gil) gilstate = PyGILState_Ensure(); @@ -378,8 +378,8 @@ static void python_script_error_jump_text(struct Text *text) python_script_error_jump(text->id.name + 2, &lineno, &offset); if (lineno != -1) { /* select the line with the error */ - txt_move_to(text, lineno - 1, INT_MAX, FALSE); - txt_move_to(text, lineno - 1, offset, TRUE); + txt_move_to(text, lineno - 1, INT_MAX, false); + txt_move_to(text, lineno - 1, offset, true); } } @@ -397,7 +397,7 @@ typedef struct { #endif static int python_script_exec(bContext *C, const char *fn, struct Text *text, - struct ReportList *reports, const short do_jump) + struct ReportList *reports, const bool do_jump) { Main *bmain_old = CTX_data_main(C); PyObject *main_mod = NULL; @@ -514,11 +514,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, /* Can run a file or text block */ int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports) { - return python_script_exec(C, filepath, NULL, reports, FALSE); + return python_script_exec(C, filepath, NULL, reports, false); } -int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump) +int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump) { return python_script_exec(C, NULL, text, reports, do_jump); } @@ -719,12 +719,12 @@ void BPY_modules_load_user(bContext *C) int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) { PyGILState_STATE gilstate; - int use_gil = !PYC_INTERPRETER_ACTIVE; + bool use_gil = !PYC_INTERPRETER_ACTIVE; PyObject *pyctx; PyObject *item; PointerRNA *ptr = NULL; - int done = FALSE; + bool done = false; if (use_gil) gilstate = PyGILState_Ensure(); @@ -743,7 +743,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * //result->ptr = ((BPy_StructRNA *)item)->ptr; CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); - done = TRUE; + done = true; } else if (PySequence_Check(item)) { PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion"); @@ -774,7 +774,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * } Py_DECREF(seq_fast); - done = TRUE; + done = true; } } diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index 13d8cedf907..d1d33a01e55 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -31,13 +31,13 @@ #include <Python.h> +#include "BLI_utildefines.h" + #include "bpy_util.h" #include "bpy.h" /* own include */ #include "WM_api.h" -#include "BLI_utildefines.h" - static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw)) { /* close down enough of blender at least not to crash */ diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 7571fe0f75e..ec6322a1a11 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -244,7 +244,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args)) self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports); if (self->blo_handle == NULL) { - if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) { + if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) { PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath); diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 55ef217e781..ee885684e03 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -35,6 +35,9 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" +#include "BLI_string.h" + #include "BPY_extern.h" #include "bpy_operator.h" #include "bpy_operator_wrap.h" @@ -42,9 +45,6 @@ #include "bpy_util.h" #include "../generic/bpy_internal_import.h" -#include "BLI_utildefines.h" -#include "BLI_string.h" - #include "RNA_access.h" #include "RNA_enum_types.h" @@ -85,7 +85,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) return NULL; - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -147,7 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) /* note that context is an int, python does the conversion in this case */ int context = WM_OP_EXEC_DEFAULT; - int is_undo = FALSE; + int is_undo = false; /* XXX Todo, work out a better solution for passing on context, * could make a tuple from self and pack the name and Context into it... */ @@ -164,7 +164,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -209,7 +209,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) CTX_py_dict_set(C, (void *)context_dict); Py_XINCREF(context_dict); /* so we done loose it */ - if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) { + if (WM_operator_poll_context((bContext *)C, ot, context) == false) { const char *msg = CTX_wm_operator_poll_msg_get(C); PyErr_Format(PyExc_RuntimeError, "Operator bpy.ops.%.200s.poll() %.200s", @@ -248,7 +248,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) } #endif - error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE); + error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false); /* operator output is nice to have in the terminal/console too */ if (reports->list.first) { @@ -328,7 +328,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args)) return NULL; - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -392,7 +392,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument"); return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname); return NULL; @@ -408,7 +408,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = TRUE; + pyrna->freeptr = true; #endif return (PyObject *)pyrna; } @@ -425,7 +425,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value) PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument"); return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname); return NULL; @@ -444,7 +444,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value) pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = TRUE; + pyrna->freeptr = true; #endif op->ptr = &pyrna->ptr; diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 1caec294aa0..cb2e12ba996 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -112,7 +112,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) return NULL; - if (WM_operatortype_find(opname, TRUE) == NULL) { + if (WM_operatortype_find(opname, true) == NULL) { PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname); @@ -123,7 +123,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) srna = srna_from_self(macro, "Macro Define:"); macroname = RNA_struct_identifier(srna); - ot = WM_operatortype_find(macroname, TRUE); + ot = WM_operatortype_find(macroname, true); if (!ot) { PyErr_Format(PyExc_ValueError, diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c index 8df7ed2364f..1d554b60bbe 100644 --- a/source/blender/python/intern/bpy_path.c +++ b/source/blender/python/intern/bpy_path.c @@ -28,6 +28,8 @@ #include <Python.h> +#include "BLI_utildefines.h" + #include "bpy_path.h" #include "../generic/py_capi_utils.h" diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 57ddee0c8c0..f3fa0c9a0a9 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -33,12 +33,12 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" + #include "bpy_props.h" #include "bpy_rna.h" #include "bpy_util.h" -#include "BLI_utildefines.h" - #include "BKE_idprop.h" #include "RNA_access.h" @@ -50,9 +50,11 @@ #include "../generic/py_capi_utils.h" /* initial definition of callback slots we'll probably have more then 1 */ -#define BPY_DATA_CB_SLOT_SIZE 1 +#define BPY_DATA_CB_SLOT_SIZE 3 #define BPY_DATA_CB_SLOT_UPDATE 0 +#define BPY_DATA_CB_SLOT_GET 1 +#define BPY_DATA_CB_SLOT_SET 2 extern BPy_StructRNA *bpy_context_module; @@ -197,7 +199,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } bpy_context_set(C, &gilstate); @@ -230,25 +232,1260 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc bpy_context_clear(C, &gilstate); if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); + } +} + +static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = false; + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = false; + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); } + + return value; } -static int bpy_prop_callback_check(PyObject *py_func, int argcount) +static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = false; + } + else { + if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = false; + + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = 0.0f; + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = 0; + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return value; +} + +static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0; + } + else { + if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0; + + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + float value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = 0.0f; + } + else { + value = PyFloat_AsDouble(ret); + + if (value == -1.0f && PyErr_Occurred()) { + printf_func_error(py_func); + value = 0.0f; + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return value; +} + +static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0.0f; + } + else { + if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0.0f; + + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value[0] = '\0'; + } + else if (!PyUnicode_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "return value must be a string, not %.200s", + Py_TYPE(ret)->tp_name); + printf_func_error(py_func); + value[0] = '\0'; + Py_DECREF(ret); + } + else { + Py_ssize_t length; + const char *buffer = _PyUnicode_AsStringAndSize(ret, &length); + memcpy(value, buffer, length + 1); + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int length; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + length = 0; + } + else if (!PyUnicode_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "return value must be a string, not %.200s", + Py_TYPE(ret)->tp_name); + printf_func_error(py_func); + length = 0; + Py_DECREF(ret); + } + else { + Py_ssize_t length_ssize_t = 0; + _PyUnicode_AsStringAndSize(ret, &length_ssize_t); + length = length_ssize_t; + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return length; +} + +static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + PyObject *py_value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_value = PyUnicode_FromString(value); + if (!py_value) { + PyErr_SetString(PyExc_ValueError, "the return value must be a string"); + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_value); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = RNA_property_enum_get_default(ptr, prop); + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = RNA_property_enum_get_default(ptr, prop); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return value; +} + +static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +/* utility function we need for parsing int's in an if statement */ +static int py_long_as_int(PyObject *py_long, int *r_int) +{ + if (PyLong_CheckExact(py_long)) { + *r_int = (int)PyLong_AS_LONG(py_long); + return 0; + } + else { + return -1; + } +} + +#if 0 +/* copies orig to buf, then sets orig to buf, returns copy length */ +static size_t strswapbufcpy(char *buf, const char **orig) +{ + const char *src = *orig; + char *dst = buf; + size_t i = 0; + *orig = buf; + while ((*dst = *src)) { dst++; src++; i++; } + return i + 1; /* include '\0' */ +} +#endif + +static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) +{ + EnumPropertyItem *items; + PyObject *item; + const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); + Py_ssize_t totbuf = 0; + int i; + short def_used = 0; + const char *def_cmp = NULL; + + if (is_enum_flag) { + if (seq_len > RNA_ENUM_BITFLAG_SIZE) { + PyErr_SetString(PyExc_TypeError, + "EnumProperty(...): maximum " + STRINGIFY(RNA_ENUM_BITFLAG_SIZE) + " members for a ENUM_FLAG type property"); + return NULL; + } + if (def && !PySet_Check(def)) { + PyErr_Format(PyExc_TypeError, + "EnumProperty(...): default option must be a 'set' " + "type when ENUM_FLAG is enabled, not a '%.200s'", + Py_TYPE(def)->tp_name); + return NULL; + } + } + else { + if (def) { + def_cmp = _PyUnicode_AsString(def); + if (def_cmp == NULL) { + PyErr_Format(PyExc_TypeError, + "EnumProperty(...): default option must be a 'str' " + "type when ENUM_FLAG is disabled, not a '%.200s'", + Py_TYPE(def)->tp_name); + return NULL; + } + } + } + + /* blank value */ + *defvalue = 0; + + items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); + + for (i = 0; i < seq_len; i++) { + EnumPropertyItem tmp = {0, "", 0, "", ""}; + Py_ssize_t item_size; + Py_ssize_t id_str_size; + Py_ssize_t name_str_size; + Py_ssize_t desc_str_size; + + item = PySequence_Fast_GET_ITEM(seq_fast, i); + + if ((PyTuple_CheckExact(item)) && + (item_size = PyTuple_GET_SIZE(item)) && + (item_size == 3 || item_size == 4) && + (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && + (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && + (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && + /* TODO, number isn't ensured to be unique from the script author */ + (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) + { + if (is_enum_flag) { + if (item_size < 4) { + tmp.value = 1 << i; + } + + if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { + *defvalue |= tmp.value; + def_used++; + } + } + else { + if (item_size < 4) { + tmp.value = i; + } + + if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) { + *defvalue = tmp.value; + def_used++; /* only ever 1 */ + } + } + + items[i] = tmp; + + /* calculate combine string length */ + totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */ + } + else { + MEM_freeN(items); + PyErr_SetString(PyExc_TypeError, + "EnumProperty(...): expected a tuple containing " + "(identifier, name, description) and optionally a " + "unique number"); + return NULL; + } + + } + + if (is_enum_flag) { + /* strict check that all set members were used */ + if (def && def_used != PySet_GET_SIZE(def)) { + MEM_freeN(items); + + PyErr_Format(PyExc_TypeError, + "EnumProperty(..., default={...}): set has %d unused member(s)", + PySet_GET_SIZE(def) - def_used); + return NULL; + } + } + else { + if (def && def_used == 0) { + MEM_freeN(items); + + PyErr_Format(PyExc_TypeError, + "EnumProperty(..., default=\'%s\'): not found in enum members", + def_cmp); + return NULL; + } + } + + /* disabled duplicating strings because the array can still be freed and + * the strings from it referenced, for now we can't support dynamically + * created strings from python. */ +#if 0 + /* this would all work perfectly _but_ the python strings may be freed + * immediately after use, so we need to duplicate them, ugh. + * annoying because it works most of the time without this. */ + { + EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), + "enum_items_from_py2"); + EnumPropertyItem *items_ptr = items_dup; + char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1)); + memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1)); + for (i = 0; i < seq_len; i++, items_ptr++) { + buf += strswapbufcpy(buf, &items_ptr->identifier); + buf += strswapbufcpy(buf, &items_ptr->name); + buf += strswapbufcpy(buf, &items_ptr->description); + } + MEM_freeN(items); + items = items_dup; + } + /* end string duplication */ +#endif + + return items; +} + +static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) +{ + PyGILState_STATE gilstate; + + PyObject *py_func = RNA_property_enum_py_data_get(prop); + PyObject *self = NULL; + PyObject *args; + PyObject *items; /* returned from the function call */ + + EnumPropertyItem *eitems = NULL; + int err = 0; + + bpy_context_set(C, &gilstate); + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + /* now get the context */ + PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); + Py_INCREF(bpy_context_module); + + items = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (items == NULL) { + err = -1; + } + else { + PyObject *items_fast; + int defvalue_dummy = 0; + + if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " + "return value from the callback was not a sequence"))) + { + err = -1; + } + else { + eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, + (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0); + + Py_DECREF(items_fast); + + if (!eitems) { + err = -1; + } + } + + Py_DECREF(items); + } + + if (err != -1) { /* worked */ + *free = 1; + } + else { + printf_func_error(py_func); + + eitems = DummyRNA_NULL_items; + } + + + bpy_context_clear(C, &gilstate); + return eitems; +} + +static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount) { if (py_func && py_func != Py_None) { if (!PyFunction_Check(py_func)) { PyErr_Format(PyExc_TypeError, - "update keyword: expected a function type, not a %.200s", - Py_TYPE(py_func)->tp_name); + "%s keyword: expected a function type, not a %.200s", + keyword, Py_TYPE(py_func)->tp_name); return -1; } else { PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); if (f_code->co_argcount != argcount) { PyErr_Format(PyExc_TypeError, - "update keyword: expected a function taking %d arguments, not %d", - argcount, f_code->co_argcount); + "%s keyword: expected a function taking %d arguments, not %d", + keyword, argcount, f_code->co_argcount); return -1; } } @@ -257,32 +1494,215 @@ static int bpy_prop_callback_check(PyObject *py_func, int argcount) return 0; } +static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop) +{ + PyObject **py_data = RNA_property_py_data_get(prop); + if (!py_data) { + py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); + RNA_def_py_data(prop, py_data); + } + return py_data; +} -static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb) +static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb) { /* assume this is already checked for type and arg length */ if (update_cb && update_cb != Py_None) { - PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); + PyObject **py_data = bpy_prop_py_data_get(prop); + RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb; - RNA_def_py_data(prop, py_data); RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE); } +} - return 0; +static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + BooleanPropertyGetFunc rna_get_cb = NULL; + BooleanPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_boolean_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_boolean_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb); } -/* utility function we need for parsing int's in an if statement */ -static int py_long_as_int(PyObject *py_long, int *r_int) +static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) { - if (PyLong_CheckExact(py_long)) { - *r_int = (int)PyLong_AS_LONG(py_long); - return 0; + BooleanArrayPropertyGetFunc rna_get_cb = NULL; + BooleanArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_boolean_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; } - else { - return -1; + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_boolean_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + IntPropertyGetFunc rna_get_cb = NULL; + IntPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_int_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_int_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + IntArrayPropertyGetFunc rna_get_cb = NULL; + IntArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_int_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_int_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + FloatPropertyGetFunc rna_get_cb = NULL; + FloatPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_float_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_float_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + FloatArrayPropertyGetFunc rna_get_cb = NULL; + FloatArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_float_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_float_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + StringPropertyGetFunc rna_get_cb = NULL; + StringPropertyLengthFunc rna_length_cb = NULL; + StringPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_string_get_cb; + rna_length_cb = bpy_prop_string_length_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_string_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb) +{ + EnumPropertyGetFunc rna_get_cb = NULL; + EnumPropertyItemFunc rna_itemf_cb = NULL; + EnumPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_enum_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_enum_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + if (itemf_cb && itemf_cb != Py_None) { + rna_itemf_cb = bpy_prop_enum_itemf_cb; + RNA_def_property_enum_py_data(prop, (void *)itemf_cb); + + /* watch out!, if a user is tricky they can probably crash blender + * if they manage to free the callback, take care! */ + /* Py_INCREF(itemf_cb); */ + } + + RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb); } /* this define runs at the start of each function and deals with @@ -386,7 +1806,9 @@ PyDoc_STRVAR(BPy_BoolProperty_doc, "default=False, " "options={'ANIMATABLE'}, " "subtype='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new boolean property definition.\n" "\n" @@ -406,7 +1828,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "update", NULL}; + "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int def = 0; @@ -416,20 +1838,28 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiO!sO:BoolProperty", + "s#|ssiO!sOOO:BoolProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -443,7 +1873,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_boolean(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } @@ -457,7 +1888,9 @@ PyDoc_STRVAR(BPy_BoolVectorProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "size=3, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new vector boolean property definition.\n" "\n" @@ -483,7 +1916,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "size", "update", NULL}; + "options", "subtype", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int def[PYRNA_STACK_ARRAY] = {0}; @@ -495,13 +1928,15 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOO!siO:BoolVectorProperty", + "s#|ssOO!siOOO:BoolVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -515,10 +1950,16 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") == -1) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -534,7 +1975,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } @@ -550,7 +1992,9 @@ PyDoc_STRVAR(BPy_IntProperty_doc, "step=1, " "options={'ANIMATABLE'}, " "subtype='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new int property definition.\n" "\n" @@ -571,7 +2015,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "update", NULL}; + "step", "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; @@ -581,21 +2025,29 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiiiiiiO!sO:IntProperty", + "s#|ssiiiiiiO!sOOO:IntProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -611,7 +2063,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_int(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -626,7 +2079,9 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "size=3, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new vector int property definition.\n" "\n" @@ -653,7 +2108,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "size", "update", NULL}; + "step", "options", "subtype", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; @@ -666,15 +2121,17 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOiiiiiO!siO:IntVectorProperty", + "s#|ssOiiiiiO!siOOO:IntVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, &size, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -688,10 +2145,16 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") == -1) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -708,7 +2171,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_int_array(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -726,7 +2190,9 @@ PyDoc_STRVAR(BPy_FloatProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "unit='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new float property definition.\n" "\n" @@ -748,7 +2214,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", "unit", "update", NULL}; + "step", "precision", "options", "subtype", + "unit", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; @@ -761,15 +2228,17 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) char *pyunit = NULL; int unit = PROP_UNIT_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssffffffiO!ssO:FloatProperty", + "s#|ssffffffiO!ssOOO:FloatProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -781,7 +2250,13 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -797,7 +2272,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_float(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -814,7 +2290,9 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "size=3, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new vector float property definition.\n" "\n" @@ -842,7 +2320,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", "unit", "size", "update", NULL}; + "step", "precision", "options", "subtype", + "unit", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3; @@ -857,15 +2336,17 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec char *pyunit = NULL; int unit = PROP_UNIT_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOfffffiO!ssiO:FloatVectorProperty", + "s#|ssOfffffiO!ssiOOO:FloatVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit, &size, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -884,10 +2365,16 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") == -1) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -904,7 +2391,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_float_array(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -917,7 +2405,9 @@ PyDoc_STRVAR(BPy_StringProperty_doc, "maxlen=0, " "options={'ANIMATABLE'}, " "subtype='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new string property definition.\n" "\n" @@ -937,7 +2427,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", - "maxlen", "options", "subtype", "update", NULL}; + "maxlen", "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = "", *def = ""; int id_len; int maxlen = 0; @@ -947,20 +2437,28 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|sssiO!sO:StringProperty", + "s#|sssiO!sOOO:StringProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -975,246 +2473,22 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_string(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; } -#if 0 -/* copies orig to buf, then sets orig to buf, returns copy length */ -static size_t strswapbufcpy(char *buf, const char **orig) -{ - const char *src = *orig; - char *dst = buf; - size_t i = 0; - *orig = buf; - while ((*dst = *src)) { dst++; src++; i++; } - return i + 1; /* include '\0' */ -} -#endif - -static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) -{ - EnumPropertyItem *items; - PyObject *item; - const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); - Py_ssize_t totbuf = 0; - int i; - short def_used = 0; - const char *def_cmp = NULL; - - if (is_enum_flag) { - if (seq_len > RNA_ENUM_BITFLAG_SIZE) { - PyErr_SetString(PyExc_TypeError, - "EnumProperty(...): maximum " - STRINGIFY(RNA_ENUM_BITFLAG_SIZE) - " members for a ENUM_FLAG type property"); - return NULL; - } - if (def && !PySet_Check(def)) { - PyErr_Format(PyExc_TypeError, - "EnumProperty(...): default option must be a 'set' " - "type when ENUM_FLAG is enabled, not a '%.200s'", - Py_TYPE(def)->tp_name); - return NULL; - } - } - else { - if (def) { - def_cmp = _PyUnicode_AsString(def); - if (def_cmp == NULL) { - PyErr_Format(PyExc_TypeError, - "EnumProperty(...): default option must be a 'str' " - "type when ENUM_FLAG is disabled, not a '%.200s'", - Py_TYPE(def)->tp_name); - return NULL; - } - } - } - - /* blank value */ - *defvalue = 0; - - items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); - - for (i = 0; i < seq_len; i++) { - EnumPropertyItem tmp = {0, "", 0, "", ""}; - Py_ssize_t item_size; - Py_ssize_t id_str_size; - Py_ssize_t name_str_size; - Py_ssize_t desc_str_size; - - item = PySequence_Fast_GET_ITEM(seq_fast, i); - - if ((PyTuple_CheckExact(item)) && - (item_size = PyTuple_GET_SIZE(item)) && - (item_size == 3 || item_size == 4) && - (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && - (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && - (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && - /* TODO, number isn't ensured to be unique from the script author */ - (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) - { - if (is_enum_flag) { - if (item_size < 4) { - tmp.value = 1 << i; - } - - if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { - *defvalue |= tmp.value; - def_used++; - } - } - else { - if (item_size < 4) { - tmp.value = i; - } - - if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) { - *defvalue = tmp.value; - def_used++; /* only ever 1 */ - } - } - - items[i] = tmp; - - /* calculate combine string length */ - totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */ - } - else { - MEM_freeN(items); - PyErr_SetString(PyExc_TypeError, - "EnumProperty(...): expected a tuple containing " - "(identifier, name, description) and optionally a " - "unique number"); - return NULL; - } - - } - - if (is_enum_flag) { - /* strict check that all set members were used */ - if (def && def_used != PySet_GET_SIZE(def)) { - MEM_freeN(items); - - PyErr_Format(PyExc_TypeError, - "EnumProperty(..., default={...}): set has %d unused member(s)", - PySet_GET_SIZE(def) - def_used); - return NULL; - } - } - else { - if (def && def_used == 0) { - MEM_freeN(items); - - PyErr_Format(PyExc_TypeError, - "EnumProperty(..., default=\'%s\'): not found in enum members", - def_cmp); - return NULL; - } - } - - /* disabled duplicating strings because the array can still be freed and - * the strings from it referenced, for now we can't support dynamically - * created strings from python. */ -#if 0 - /* this would all work perfectly _but_ the python strings may be freed - * immediately after use, so we need to duplicate them, ugh. - * annoying because it works most of the time without this. */ - { - EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), - "enum_items_from_py2"); - EnumPropertyItem *items_ptr = items_dup; - char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1)); - memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1)); - for (i = 0; i < seq_len; i++, items_ptr++) { - buf += strswapbufcpy(buf, &items_ptr->identifier); - buf += strswapbufcpy(buf, &items_ptr->name); - buf += strswapbufcpy(buf, &items_ptr->description); - } - MEM_freeN(items); - items = items_dup; - } - /* end string duplication */ -#endif - - return items; -} - -static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) -{ - PyGILState_STATE gilstate; - - PyObject *py_func = RNA_property_enum_py_data_get(prop); - PyObject *self = NULL; - PyObject *args; - PyObject *items; /* returned from the function call */ - - EnumPropertyItem *eitems = NULL; - int err = 0; - - bpy_context_set(C, &gilstate); - - args = PyTuple_New(2); - self = pyrna_struct_as_instance(ptr); - PyTuple_SET_ITEM(args, 0, self); - - /* now get the context */ - PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); - Py_INCREF(bpy_context_module); - - items = PyObject_CallObject(py_func, args); - - Py_DECREF(args); - - if (items == NULL) { - err = -1; - } - else { - PyObject *items_fast; - int defvalue_dummy = 0; - - if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " - "return value from the callback was not a sequence"))) - { - err = -1; - } - else { - eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, - (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0); - - Py_DECREF(items_fast); - - if (!eitems) { - err = -1; - } - } - - Py_DECREF(items); - } - - if (err != -1) { /* worked */ - *free = 1; - } - else { - printf_func_error(py_func); - - eitems = DummyRNA_NULL_items; - } - - - bpy_context_clear(C, &gilstate); - return eitems; -} - PyDoc_STRVAR(BPy_EnumProperty_doc, ".. function:: EnumProperty(items, " "name=\"\", " "description=\"\", " "default=\"\", " "options={'ANIMATABLE'}, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new enumerator property definition.\n" "\n" @@ -1246,7 +2520,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "items", "name", "description", "default", - "options", "update", NULL}; + "options", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; PyObject *def = NULL; int id_len; @@ -1256,22 +2530,30 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; - short is_itemf = FALSE; + bool is_itemf = false; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#O|ssOO!O:EnumProperty", + "s#O|ssOO!OOO:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -1292,7 +2574,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - is_itemf = TRUE; + is_itemf = true; eitems = DummyRNA_NULL_items; } else { @@ -1314,25 +2596,17 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description); else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); - if (is_itemf) { - RNA_def_enum_funcs(prop, bpy_props_enum_itemf); - RNA_def_enum_py_data(prop, (void *)items); - - /* watch out!, if a user is tricky they can probably crash blender - * if they manage to free the callback, take care! */ - /* Py_INCREF(items); */ - } - if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL)); RNA_def_property_duplicate_pointers(srna, prop); - if (is_itemf == FALSE) { + if (is_itemf == false) { /* note: this must be postponed until after #RNA_def_property_duplicate_pointers * otherwise if this is a generator it may free the strings before we copy them */ Py_DECREF(items_fast); @@ -1424,7 +2698,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if (!ptype) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { return NULL; } @@ -1435,7 +2709,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index bc245ecda5c..94f262f57f5 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -37,6 +37,12 @@ #include "RNA_types.h" +#include "BLI_dynstr.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_math_rotation.h" +#include "BLI_utildefines.h" + #include "BPY_extern.h" #include "bpy_rna.h" @@ -50,12 +56,6 @@ # include "MEM_guardedalloc.h" #endif -#include "BLI_dynstr.h" -#include "BLI_string.h" -#include "BLI_listbase.h" -#include "BLI_math_rotation.h" -#include "BLI_utildefines.h" - #ifdef USE_PYRNA_INVALIDATE_WEAKREF # include "BLI_ghash.h" #endif @@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id) } #ifdef USE_PEDANTIC_WRITE -static short rna_disallow_writes = FALSE; +static bool rna_disallow_writes = false; -static int rna_id_write_error(PointerRNA *ptr, PyObject *key) +static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) { ID *id = ptr->id.data; if (id) { @@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key) "%.200s, %.200s datablock, error setting %.200s.%.200s", id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname); - return TRUE; + return true; } } - return FALSE; + return false; } #endif /* USE_PEDANTIC_WRITE */ #ifdef USE_PEDANTIC_WRITE -int pyrna_write_check(void) +bool pyrna_write_check(void) { return !rna_disallow_writes; } -void pyrna_write_set(int val) +void pyrna_write_set(bool val) { rna_disallow_writes = !val; } #else /* USE_PEDANTIC_WRITE */ -int pyrna_write_check(void) +bool pyrna_write_check(void) { - return TRUE; + return true; } -void pyrna_write_set(int UNUSED(val)) +void pyrna_write_set(bool UNUSED(val)) { /* nothing */ } @@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0); Py_DECREF(ret); /* the matrix owns now */ ret = mat_cb; /* return the matrix instead */ } @@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0); Py_DECREF(ret); /* the matrix owns now */ ret = mat_cb; /* return the matrix instead */ } @@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { EnumPropertyItem *item; const char *result; - int free = FALSE; + int free = false; RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if (item) { @@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_ return -1; } - if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) { + if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { return -1; } @@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj { EnumPropertyItem *item; int ret; - int free = FALSE; + int free = false; *r_value = 0; @@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) } else { EnumPropertyItem *enum_item; - int free = FALSE; + int free = false; /* don't throw error here, can't trust blender 100% to give the * right values, python code should not generate error for that */ @@ -1682,13 +1682,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb /* type checkins is done by each function */ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { /* set of enum items, concatenate all values with OR */ - if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) { + if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { return -1; } } else { /* simple enum string */ - if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) { + if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { return -1; } } @@ -1777,7 +1777,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb } else { BPy_StructRNA *param = (BPy_StructRNA *)value; - int raise_error = FALSE; + bool raise_error = false; if (data) { if (flag & PROP_RNAPTR) { @@ -1804,7 +1804,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb *((void **)data) = param->ptr.data; } else { - raise_error = TRUE; + raise_error = true; } } else { @@ -2195,7 +2195,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel else { PyObject *keylib = PyTuple_GET_ITEM(key, 1); Library *lib; - int found = FALSE; + bool found = false; if (keylib == Py_None) { lib = NULL; @@ -2232,7 +2232,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel { ID *id = itemptr.data; /* always an ID */ if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) { - found = TRUE; + found = true; if (r_ptr) { *r_ptr = itemptr; } @@ -2242,7 +2242,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel RNA_PROP_END; /* we may want to fail silently as with collection.get() */ - if ((found == FALSE) && err_not_found) { + if ((found == false) && err_not_found) { /* only runs for getitem access so use fixed string */ PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); @@ -2255,7 +2255,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel } static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key, - const char *err_prefix, const short err_not_found) + const char *err_prefix, const bool err_not_found) { PointerRNA ptr; const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr); @@ -2448,7 +2448,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject else if (PyTuple_Check(key)) { /* special case, for ID datablocks we */ return pyrna_prop_collection_subscript_str_lib_pair(self, key, - "bpy_prop_collection[id, lib]", TRUE); + "bpy_prop_collection[id, lib]", true); } else { PyErr_Format(PyExc_TypeError, @@ -2865,7 +2865,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) if (PyTuple_Check(key)) { /* special case, for ID datablocks we */ return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, - "(id, lib) in bpy_prop_collection", FALSE, NULL); + "(id, lib) in bpy_prop_collection", false, NULL); } else { @@ -4205,7 +4205,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args } else if (PyTuple_Check(key_ob)) { PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, - "bpy_prop_collection.get((id, lib))", FALSE); + "bpy_prop_collection.get((id, lib))", false); if (ret) { return ret; } @@ -4267,12 +4267,12 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr, /* values to assign */ - RawPropertyType *raw_type, int *attr_tot, int *attr_signed) + RawPropertyType *raw_type, int *attr_tot, bool *attr_signed) { PropertyRNA *prop; *raw_type = PROP_RAW_UNSET; *attr_tot = 0; - *attr_signed = FALSE; + *attr_signed = false; /* note: this is fail with zero length lists, so don't let this get caled in that case */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) @@ -4280,7 +4280,7 @@ static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr, prop = RNA_struct_find_property(&itemptr, attr); *raw_type = RNA_property_raw_type(prop); *attr_tot = RNA_property_array_length(&itemptr, prop); - *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE; + *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? false : true; break; } RNA_PROP_END; @@ -4291,7 +4291,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, /* values to assign */ const char **attr, PyObject **seq, int *tot, int *size, - RawPropertyType *raw_type, int *attr_tot, int *attr_signed + RawPropertyType *raw_type, int *attr_tot, bool *attr_signed ) { #if 0 @@ -4299,7 +4299,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, int target_tot; #endif - *size = *attr_tot = *attr_signed = FALSE; + *size = *attr_tot = 0; + *attr_signed = false; *raw_type = PROP_RAW_UNSET; if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) { @@ -4344,7 +4345,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, return 0; } -static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) +static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) { char f = format ? *format : 'B'; /* B is assumed when not set */ @@ -4372,16 +4373,18 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) { PyObject *item = NULL; - int i = 0, ok = 0, buffer_is_compat; + int i = 0, ok = 0; + bool buffer_is_compat; void *array = NULL; /* get/set both take the same args currently */ const char *attr; PyObject *seq; - int tot, size, attr_tot, attr_signed; + int tot, size, attr_tot; + bool attr_signed; RawPropertyType raw_type; - if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) + if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1) return NULL; if (tot == 0) @@ -4390,7 +4393,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) if (set) { /* get the array from python */ - buffer_is_compat = FALSE; + buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); @@ -4441,7 +4444,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) } } else { - buffer_is_compat = FALSE; + buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); @@ -4945,7 +4948,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ParameterIterator iter; PropertyRNA *parm; PyObject *ret, *item; - int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg; + int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0; + bool kw_arg; PropertyRNA *pret_single = NULL; void *retdata_single = NULL; @@ -5026,7 +5030,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject if (i < pyargs_len) { item = PyTuple_GET_ITEM(args, i); - kw_arg = FALSE; + kw_arg = false; } else if (kw != NULL) { #if 0 @@ -5037,7 +5041,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject if (item) kw_tot++; /* make sure invalid keywords are not given */ - kw_arg = TRUE; + kw_arg = true; } i++; /* current argument */ @@ -5074,7 +5078,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject char error_prefix[512]; PyErr_Clear(); /* re-raise */ - if (kw_arg == TRUE) + if (kw_arg == true) BLI_snprintf(error_prefix, sizeof(error_prefix), "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", RNA_struct_identifier(self_ptr->type), @@ -5109,12 +5113,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject DynStr *good_args = BLI_dynstr_new(); const char *arg_name, *bad_args_str, *good_args_str; - int found = FALSE, first = TRUE; + bool found = false, first = true; while (PyDict_Next(kw, &pos, &key, &value)) { arg_name = _PyUnicode_AsString(key); - found = FALSE; + found = false; if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/ PyErr_Clear(); @@ -5125,22 +5129,22 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) { - found = TRUE; + found = true; break; } } RNA_parameter_list_end(&iter); - if (found == FALSE) { + if (found == false) { BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name); - first = FALSE; + first = false; } } } /* list good args */ - first = TRUE; + first = true; RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { @@ -5149,7 +5153,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject continue; BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); - first = FALSE; + first = false; } RNA_parameter_list_end(&iter); @@ -5179,7 +5183,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject BKE_reports_init(&reports, RPT_STORE); RNA_function_call(C, &reports, self_ptr, self_func, &parms); - err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE)); + err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); /* return value */ if (err != -1) { @@ -5242,7 +5246,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure) PyObject *ret; char *args; - args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE); + args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true); ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s", RNA_struct_identifier(self->ptr.type), @@ -5974,7 +5978,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self) { - if (self->iter.valid == FALSE) { + if (self->iter.valid == false) { PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop"); return NULL; } @@ -6052,7 +6056,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) FunctionRNA *func = (FunctionRNA *)link; const int flag = RNA_function_flag(func); if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */ - (flag & FUNC_REGISTER) == FALSE) /* is not for registration */ + (flag & FUNC_REGISTER) == false) /* is not for registration */ { /* we may want to set the type of this later */ PyObject *func_py = pyrna_func_to_py(&func_ptr, func); @@ -6262,7 +6266,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) pyrna->ptr = *ptr; #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = FALSE; + pyrna->freeptr = false; #endif #ifdef USE_PYRNA_STRUCT_REFERENCE @@ -6342,15 +6346,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id) } } -int pyrna_id_FromPyObject(PyObject *obj, ID **id) +bool pyrna_id_FromPyObject(PyObject *obj, ID **id) { if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) { *id = ((BPy_StructRNA *)obj)->ptr.id.data; - return TRUE; + return true; } else { *id = NULL; - return FALSE; + return false; } } @@ -6561,7 +6565,7 @@ PyObject *BPY_rna_types(void) return (PyObject *)self; } -StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix) +StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix) { BPy_StructRNA *py_srna = NULL; StructRNA *srna; @@ -6635,7 +6639,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Clear(); - srna = pyrna_struct_as_srna(self, 0, error_prefix); + srna = pyrna_struct_as_srna(self, false, error_prefix); if (!PyErr_Occurred()) { PyErr_Restore(error_type, error_value, error_traceback); @@ -7051,7 +7055,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param if (py_class->tp_init) { #ifdef USE_PEDANTIC_WRITE const int prev_write = rna_disallow_writes; - rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */ + rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */ #endif /* true in most cases even when the class its self doesn't define an __init__ function. */ @@ -7070,7 +7074,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #else const int prev_write = rna_disallow_writes; - rna_disallow_writes = TRUE; + rna_disallow_writes = true; /* 'almost' all the time calling the class isn't needed. * We could just do... */ @@ -7146,7 +7150,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes = is_readonly ? TRUE : FALSE; + rna_disallow_writes = is_readonly ? true : false; #endif /* *** Main Caller *** */ @@ -7155,7 +7159,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param /* *** Done Calling *** */ #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes = FALSE; + rna_disallow_writes = false; #endif RNA_parameter_list_end(&iter); @@ -7420,7 +7424,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } /* warning: gets parent classes srna, only for the register function */ - srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):"); + srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); if (srna == NULL) return NULL; @@ -7456,7 +7460,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class srna_new = reg(CTX_data_main(C), &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; /* python errors validating are not converted into reports so the check above will fail. @@ -7563,7 +7567,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla return NULL; } - srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):"); + srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):"); if (srna == NULL) return NULL; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index edd2ada0539..424452ef6fe 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -115,7 +115,7 @@ typedef struct { #endif /* !USE_PYRNA_STRUCT_REFERENCE */ #ifdef PYRNA_FREE_SUPPORT - int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ + bool freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ #endif /* PYRNA_FREE_SUPPORT */ } BPy_StructRNA; @@ -164,7 +164,7 @@ typedef struct { #define BPy_BaseTypeRNA BPy_PropertyRNA StructRNA *srna_from_self(PyObject *self, const char *error_prefix); -StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix); +StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix); void BPY_rna_init(void); PyObject *BPY_rna_module(void); @@ -178,7 +178,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop); /* extern'd by other modules which don't deal closely with RNA */ PyObject *pyrna_id_CreatePyObject(struct ID *id); -int pyrna_id_FromPyObject(PyObject *obj, struct ID **id); +bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id); /* operators also need this to set args */ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix); @@ -205,8 +205,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop); int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value); -int pyrna_write_check(void); -void pyrna_write_set(int val); +bool pyrna_write_check(void); +void pyrna_write_set(bool val); void pyrna_invalidate(BPy_DummyPointerRNA *self); int pyrna_struct_validity_check(BPy_StructRNA *pysrna); diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 0acfc36bb4e..a19f8e2d8ed 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -160,14 +160,14 @@ static int pyrna_struct_keyframe_parse( return -1; } - if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0) + if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1) return -1; if (*cfra == FLT_MAX) *cfra = CTX_data_scene(BPy_GetContext())->r.cfra; /* flag may be null (no option currently for remove keyframes e.g.). */ - if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) < 0)) + if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1)) return -1; return 0; /* success */ @@ -222,7 +222,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; return PyBool_FromLong(result); @@ -271,7 +271,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; return PyBool_FromLong(result); @@ -301,7 +301,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index)) return NULL; - if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) { + if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) { return NULL; } else { @@ -313,7 +313,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; if (result) { @@ -377,7 +377,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index)) return NULL; - if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) { + if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) { return NULL; } else { @@ -390,7 +390,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL); diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index adb4ae6a2c6..1043f68dbdb 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -32,12 +32,12 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" + #include "bpy_rna.h" #include "bpy_rna_callback.h" #include "bpy_util.h" -#include "BLI_utildefines.h" - #include "DNA_space_types.h" #include "DNA_screen_types.h" @@ -101,7 +101,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args) if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) { if (cb_event_str) { - if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } } @@ -194,7 +194,7 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) } cls = PyTuple_GET_ITEM(args, 0); - if (!(srna = pyrna_struct_as_srna(cls, FALSE, "handler_add"))) { + if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) { return NULL; } cb_func = PyTuple_GET_ITEM(args, 1); @@ -212,10 +212,10 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) return NULL; } - if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } - else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") < 0) { + else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) { return NULL; } else { @@ -257,7 +257,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar } cls = PyTuple_GET_ITEM(args, 0); - if (!(srna = pyrna_struct_as_srna(cls, FALSE, "callback_remove"))) { + if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) { return NULL; } py_handle = PyTuple_GET_ITEM(args, 1); @@ -278,7 +278,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar customdata = ED_region_draw_cb_customdata(handle); Py_DECREF((PyObject *)customdata); - if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") < 0) { + if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) { return NULL; } else { diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index b7994eeccdc..b0b0f346944 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -29,9 +29,13 @@ #include <Python.h> -#include "bpy_util.h" +#include "BLI_utildefines.h" #include "BLI_dynstr.h" + +#include "bpy_util.h" + #include "MEM_guardedalloc.h" + #include "BKE_report.h" #include "BKE_context.h" @@ -59,13 +63,13 @@ char *BPy_enum_as_string(EnumPropertyItem *item) return cstring; } -short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear) +short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear) { char *report_str; report_str = BKE_reports_string(reports, RPT_ERROR); - if (clear) { + if (clear == true) { BKE_reports_clear(reports); } diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index b5f679b741f..b007e123cfc 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -39,7 +39,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item); #define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL} /* error reporting */ -short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear); +short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear); short BPy_errors_to_report(struct ReportList *reports); /* TODO - find a better solution! */ diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index 6935c908ee4..4a8a06134c8 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -61,8 +61,8 @@ #import <QTKit/QTKit.h> #include <AudioToolbox/AudioToolbox.h> -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) || !__LP64__ -#error 64 bit build & OSX 10.5 minimum are needed for QTKit +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040 +#error OSX 10.5 minimum is needed for QTKit #endif #include "quicktime_import.h" @@ -557,7 +557,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R [qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute]; [qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute]; - qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000); + qtexport->frameDuration = QTMakeTime(rd->frs_sec_base * 1000, rd->frs_sec * 1000); /* specifying the codec attributes : try to retrieve them from render data first*/ if (rd->qtcodecsettings.codecType) { diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index d773cdc8f3a..55323c05278 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -65,14 +65,14 @@ void filepath_qt(char *string, struct RenderData *rd); void quicktime_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); //used by RNA for defaults values init, if needed /*Video codec type*/ int quicktime_get_num_videocodecs(void); -QuicktimeCodecTypeDesc* quicktime_get_videocodecType_desc(int indexValue); +QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue); int quicktime_rnatmpvalue_from_videocodectype(int codecType); int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue); #ifdef USE_QTKIT /*Audio codec type*/ int quicktime_get_num_audiocodecs(void); -QuicktimeCodecTypeDesc* quicktime_get_audiocodecType_desc(int indexValue); +QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue); int quicktime_rnatmpvalue_from_audiocodectype(int codecType); int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue); #endif diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 148e3417ea9..658ab9dc091 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -1015,7 +1015,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) vec2[2] = oz1 - dda_lambda * doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - //is->dist = (u1+dda_lambda*(u2-u1))*o_lambda; + //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda; if (testnode(oc, is, no, ocval) ) found = 1; diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index b8784685836..091ba9589d7 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -952,7 +952,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) RayFace *face; CCGElem **grid_data; CCGKey key; - int num_grids, grid_size, face_side, num_faces; + int num_grids, grid_size /*, face_side */, num_faces; int i; num_grids = hidm->getNumGrids(hidm); @@ -960,7 +960,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) grid_data = hidm->getGridData(hidm); hidm->getGridKey(hidm, &key); - face_side = (grid_size << 1) - 1; + /* face_side = (grid_size << 1) - 1; */ /* UNUSED */ num_faces = num_grids * (grid_size - 1) * (grid_size - 1); raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 43bada3b383..e37b24b13a4 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -45,6 +45,16 @@ #include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_rect.h" +#include "BLI_listbase.h" +#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" + #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_camera.h" #include "BKE_global.h" @@ -57,16 +67,6 @@ #include "BKE_sequencer.h" #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ -#include "BLI_math.h" -#include "BLI_rect.h" -#include "BLI_listbase.h" -#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" - #include "PIL_time.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 0587b097f36..62919297e73 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -35,11 +35,6 @@ #include "MEM_guardedalloc.h" -#include "BKE_image.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_report.h" - #include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" @@ -48,6 +43,11 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_report.h" + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 2e1b23435e5..a0267cd65b7 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -4148,8 +4148,17 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas } if (addpassflag & SCE_PASS_INDEXMA) { ObjectRen *obr = R.objectinstance[zrow[totface-1].obi].obr; - VlakRen *vr = obr->vlaknodes->vlak; - Material *mat = vr->mat; + Material *mat = NULL; + + if (zrow[totface-1].segment == -1) { + if (obr->vlaknodes) + mat = obr->vlaknodes->vlak->mat; + } + else { + if (obr->strandbuf) + mat = obr->strandbuf->ma; + } + if (mat) { for (a= 0; a<totfullsample; a++) add_transp_material_index(rlpp[a], od, mat); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index eee4b5a3a57..eb1aad75a88 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -204,9 +204,9 @@ void WM_operator_stack_clear(struct wmWindowManager *wm); struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet); struct GHashIterator *WM_operatortype_iter(void); -void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*)); -void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata); -void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata); +void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *)); +void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata); +void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata); int WM_operatortype_remove(const char *idname); struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index a6b3efd30bf..48cad9e020b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1345,6 +1345,15 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve } } } + else { + /* modal keymap checking returns handled events fine, but all hardcoded modal + handling typically swallows all events (OPERATOR_RUNNING_MODAL). + This bypass just disables support for double clicks in hardcoded modal handlers */ + if (event->val == KM_DBL_CLICK) { + event->prevval = event->val; + event->val = KM_PRESS; + } + } } /* bad hacking event system... better restore event type for checking of KM_CLICK for example */ @@ -1357,6 +1366,8 @@ static void wm_event_modalmap_end(wmEvent *event) event->val = event->prevval; event->prevval = 0; } + else if (event->prevval == KM_DBL_CLICK) + event->val = KM_DBL_CLICK; } @@ -2792,6 +2803,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U switch (pd->subtype) { case GHOST_kTrackpadEventMagnify: event.type = MOUSEZOOM; + pd->deltaX = -pd->deltaX; + pd->deltaY = -pd->deltaY; break; case GHOST_kTrackpadEventRotate: event.type = MOUSEROTATE; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 61699c94567..550a9f83cff 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -740,11 +740,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out); + IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, FALSE, FALSE, err_out); + IB_rect, FALSE, R_ADDSKY, err_out); } if (ibuf) { diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index bfcd4b1e955..b2c3c935553 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -151,7 +151,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *)) wmOperatorType *ot; ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); /* Set the default i18n context now, so that opfunc can redefine it if needed! */ RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT); opfunc(ot); @@ -173,7 +173,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void * wmOperatorType *ot; ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); /* Set the default i18n context now, so that opfunc can redefine it if needed! */ RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT); opfunc(ot, userdata); @@ -360,7 +360,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam } ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); ot->idname = idname; ot->name = name; @@ -390,7 +390,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *), wmOperatorType *ot; ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); ot->flag = OPTYPE_MACRO; ot->exec = wm_macro_exec; @@ -1558,7 +1558,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); /* XXX splash scales with pixelsize, should become widget-units */ - but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize *282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ + but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ uiButSetFunc(but, wm_block_splash_close, block, NULL); uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index ec94501c8be..9e0f8613a1a 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -701,6 +701,14 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr case GHOST_kEventWindowDeactivate: wm_event_add_ghostevent(wm, win, type, time, data); win->active = 0; /* XXX */ + + /* clear modifiers for inactive windows */ + win->eventstate->alt = 0; + win->eventstate->ctrl = 0; + win->eventstate->shift = 0; + win->eventstate->oskey = 0; + win->eventstate->keymodifier = 0; + break; case GHOST_kEventWindowActivate: { diff --git a/source/creator/creator.c b/source/creator/creator.c index d678df33ad0..55a24971c61 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -40,6 +40,17 @@ # include <xmmintrin.h> #endif +/* crash handler */ +#ifdef WIN32 +# include <process.h> /* getpid */ +#else +# include <unistd.h> /* getpid */ +#endif +/* for backtrace */ +#ifndef WIN32 +# include <execinfo.h> +#endif + #ifdef WIN32 # include <Windows.h> # include "utfconv.h" @@ -48,6 +59,7 @@ #include <stdlib.h> #include <stddef.h> #include <string.h> +#include <errno.h> /* This little block needed for linking to Blender... */ @@ -161,6 +173,8 @@ static int print_version(int argc, const char **argv, void *data); /* Initialize callbacks for the modules that need them */ static void setCallbacks(void); +static bool use_crash_handler = true; + #ifndef WITH_PYTHON_MODULE /* set breakpoints here when running in debug mode, useful to catch floating point errors */ @@ -250,6 +264,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data) printf("Misc Options:\n"); BLI_argsPrintArgDoc(ba, "--debug"); BLI_argsPrintArgDoc(ba, "--debug-fpe"); + BLI_argsPrintArgDoc(ba, "--disable-crash-handler"); #ifdef WITH_FFMPEG BLI_argsPrintArgDoc(ba, "--debug-ffmpeg"); @@ -354,6 +369,12 @@ static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNU return 0; } +static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) +{ + use_crash_handler = false; + return 0; +} + static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { G.background = 1; @@ -427,6 +448,102 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat return 0; } +static void blender_crash_handler_backtrace(FILE *fp) +{ +#ifndef WIN32 +#define SIZE 100 + void *buffer[SIZE]; + int nptrs; + char **strings; + int i; + + fputs("\n# backtrace\n", fp); + + /* include a backtrace for good measure */ + nptrs = backtrace(buffer, SIZE); + strings = backtrace_symbols(buffer, nptrs); + for (i = 0; i < nptrs; i++) { + fputs(strings[i], fp); + fputc('\n', fp); + } + + free(strings); +#undef SIZE +#else /* WIN32 */ + /* TODO */ + (void)fp; +#endif +} +static void blender_crash_handler(int signum) +{ + +#if 0 + { + char fname[FILE_MAX]; + + if (!G.main->name[0]) { + BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend"); + } + else { + BLI_strncpy(fname, G.main->name, sizeof(fname)); + BLI_replace_extension(fname, sizeof(fname), ".crash.blend"); + } + + printf("Writing: %s\n", fname); + fflush(stdout); + + BKE_undo_save_file(fname); + } +#endif + + FILE *fp; + char header[512]; + wmWindowManager *wm = G.main->wm.first; + + char fname[FILE_MAX]; + + if (!G.main->name[0]) { + BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt"); + } + else { + BLI_strncpy(fname, G.main->name, sizeof(fname)); + BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); + } + + printf("Writing: %s\n", fname); + fflush(stdout); + + BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT); + + /* open the crash log */ + errno = 0; + fp = BLI_fopen(fname, "wb"); + if (fp == NULL) { + fprintf(stderr, "Unable to save '%s': %s\n", + fname, errno ? strerror(errno) : "Unknown error opening file"); + } + else { + if (wm) { + BKE_report_write_file_fp(fp, &wm->reports, header); + } + + blender_crash_handler_backtrace(fp); + + fclose(fp); + } + + + /* really crash */ + signal(signum, SIG_DFL); +#ifndef WIN32 + kill(getpid(), signum); +#else + /* force crash on windows for now */ + *((void **)NULL) = NULL; +#endif +} + + static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { G.factory_startup = 1; @@ -1126,6 +1243,8 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL); BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL); + BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL); + #undef PY_ENABLE_AUTO #undef PY_DISABLE_AUTO @@ -1310,6 +1429,10 @@ int main(int argc, const char **argv) BLI_argsParse(ba, 1, NULL, NULL); #endif + if (use_crash_handler) { + /* after parsing args */ + signal(SIGSEGV, blender_crash_handler); + } /* after level 1 args, this is so playanim skips RNA init */ RNA_init(); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index a4c4253754e..9267b2b9fed 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -650,11 +650,10 @@ static bool ConvertMaterial( material->texname[i] = material->img[i]->id.name; material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0; // ----------------------- - if ( mttmp->tex->imaflag &TEX_USEALPHA ) { + if (material->img[i] && (material->img[i]->flag & IMA_IGNORE_ALPHA) == 0) material->flag[i] |= USEALPHA; - } // ----------------------- - else if ( mttmp->tex->imaflag &TEX_CALCALPHA ) { + if ( mttmp->tex->imaflag &TEX_CALCALPHA ) { material->flag[i] |= CALCALPHA; } else if (mttmp->tex->flag &TEX_NEGALPHA) { diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index b7fbe958c86..dce62ad189a 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -307,8 +307,11 @@ int SCA_Joystick::pGetAxis(int axisnum, int udlr) int SCA_Joystick::pAxisTest(int axisnum) { #ifdef WITH_SDL - short i1 = m_axis_array[(axisnum * 2)]; - short i2 = m_axis_array[(axisnum * 2) + 1]; + /* Use ints instead of shorts here to avoid problems when we get -32768. + * When we take the negative of that later, we should get 32768, which is greater + * than what a short can hold. In other words, abs(MIN_SHORT) > MAX_SHRT. */ + int i1 = m_axis_array[(axisnum * 2)]; + int i2 = m_axis_array[(axisnum * 2) + 1]; /* long winded way to do: * return max_ff(absf(i1), absf(i2)) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index c7f6954fd6c..eec45669e04 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -42,7 +42,6 @@ typedef unsigned __int64 uint_ptr; typedef unsigned long uint_ptr; #endif -#define KX_INERTIA_INFINITE 10000 #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" #include "KX_GameObject.h" diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index f0d5d5c6685..87683f8b57b 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -83,7 +83,7 @@ // not valid, skip rendering this frame. //#define NZC_GUARDED_OUTPUT #define DEFAULT_LOGIC_TIC_RATE 60.0 -#define DEFAULT_PHYSICS_TIC_RATE 60.0 +//#define DEFAULT_PHYSICS_TIC_RATE 60.0 #ifdef FREE_WINDOWS /* XXX mingw64 (gcc 4.7.0) defines a macro for DrawText that translates to DrawTextA. Not good */ #ifdef DrawText diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 02995a53954..6b3f745b899 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -198,7 +198,7 @@ static PyObject *gp_OrigPythonSysModules= NULL; /* Macro for building the keyboard translation */ //#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromLong(SCA_IInputDevice::KX_##name)) -#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item) +//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item) /* For the defines for types from logic bricks, we do stuff explicitly... */ #define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name2)); Py_DECREF(item) |