Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2017-09-29 19:55:00 +10:00
commit e3fe8128e4
56 changed files with 836 additions and 578 deletions

@ -494,7 +494,12 @@ endif()
# Experimental support of C11 and C++11 # Experimental support of C11 and C++11
# #
# We default options to whatever default standard in the current compiler. # We default options to whatever default standard in the current compiler.
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11)) if(APPLE)
set(_c11_init ON)
set(_cxx11_init ON)
set(WITH_C11 ON)
set(WITH_CXX11 ON)
elseif(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11))
set(_c11_init ON) set(_c11_init ON)
else() else()
set(_c11_init OFF) set(_c11_init OFF)

@ -419,11 +419,17 @@ icons: .FORCE
"$(BLENDER_DIR)/release/datafiles/prvicons_update.py" "$(BLENDER_DIR)/release/datafiles/prvicons_update.py"
update: .FORCE update: .FORCE
if [ "$(OS_NCASE)" == "darwin" ] && [ ! -d "../lib/$(OS_NCASE)" ]; then \
svn checkout https://svn.blender.org/svnroot/bf-blender/trunk/lib/$(OS_NCASE) ../lib/$(OS_NCASE) ; \
fi
if [ -d "../lib" ]; then \ if [ -d "../lib" ]; then \
svn cleanup ../lib/* ; \
svn update ../lib/* ; \ svn update ../lib/* ; \
fi fi
git pull --rebase git pull --rebase
git submodule update --remote git submodule update --init --recursive
git submodule foreach git checkout master
git submodule foreach git pull --rebase origin master
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------

@ -246,8 +246,6 @@ def git_submodules_update():
def lib_svn_step(dir): def lib_svn_step(dir):
name = "lib svn" name = "lib svn"
if dir == "darwin":
name = "C++11 lib svn"
return SVN(name=name, return SVN(name=name,
baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir,
codebase='lib svn', codebase='lib svn',
@ -277,9 +275,6 @@ def generic_builder(id, libdir='', branch='', rsync=False):
f = BuildFactory() f = BuildFactory()
if libdir != '': if libdir != '':
f.addStep(lib_svn_step(libdir)) f.addStep(lib_svn_step(libdir))
# Special trick to make sure we always have all the libs.
if libdir.startswith("darwin"):
f.addStep(lib_svn_step("darwin"))
for submodule in ('blender-translations', for submodule in ('blender-translations',
'blender-addons', 'blender-addons',
@ -312,7 +307,7 @@ def generic_builder(id, libdir='', branch='', rsync=False):
# Builders # Builders
add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin-9.x.universal', generic_builder, hour=1) add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin', generic_builder, hour=1)
add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=2) add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=2)
add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=1) add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=1)
add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=1) add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=1)

@ -30,11 +30,7 @@ macro(find_package_wrapper)
endmacro() endmacro()
if(NOT DEFINED LIBDIR) if(NOT DEFINED LIBDIR)
if(WITH_CXX11) set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
else()
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-9.x.universal)
endif()
else() else()
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}") message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
endif() endif()
@ -95,11 +91,7 @@ if(WITH_PYTHON)
# normally cached but not since we include them with blender # normally cached but not since we include them with blender
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}m") set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}m")
set(PYTHON_EXECUTABLE "${LIBDIR}/python/bin/python${PYTHON_VERSION}m") set(PYTHON_EXECUTABLE "${LIBDIR}/python/bin/python${PYTHON_VERSION}m")
if(WITH_CXX11) set(PYTHON_LIBRARY ${LIBDIR}/python/lib/libpython${PYTHON_VERSION}m.a)
set(PYTHON_LIBRARY ${LIBDIR}/python/lib/libpython${PYTHON_VERSION}m.a)
else()
set(PYTHON_LIBRARY python${PYTHON_VERSION}m)
endif()
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}") set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
# set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled # set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
else() else()
@ -150,11 +142,7 @@ if(WITH_IMAGE_OPENEXR)
set(OPENEXR ${LIBDIR}/openexr) set(OPENEXR ${LIBDIR}/openexr)
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include) set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR}/include/OpenEXR) set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR}/include/OpenEXR)
if(WITH_CXX11) set(OPENEXR_POSTFIX -2_2)
set(OPENEXR_POSTFIX -2_2)
else()
set(OPENEXR_POSTFIX)
endif()
set(OPENEXR_LIBRARIES set(OPENEXR_LIBRARIES
Iex${OPENEXR_POSTFIX} Iex${OPENEXR_POSTFIX}
Half Half
@ -171,20 +159,16 @@ if(WITH_CODEC_FFMPEG)
avcodec avdevice avformat avutil avcodec avdevice avformat avutil
mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg
) )
if(WITH_CXX11) set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} schroedinger orc vpx webp swresample)
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} schroedinger orc vpx webp swresample)
endif()
set(FFMPEG_LIBPATH ${FFMPEG}/lib) set(FFMPEG_LIBPATH ${FFMPEG}/lib)
endif() endif()
if(WITH_OPENJPEG OR WITH_CODEC_FFMPEG) if(WITH_OPENJPEG OR WITH_CODEC_FFMPEG)
# use openjpeg from libdir that is linked into ffmpeg # use openjpeg from libdir that is linked into ffmpeg
if(WITH_CXX11) set(OPENJPEG ${LIBDIR}/openjpeg)
set(OPENJPEG ${LIBDIR}/openjpeg) set(WITH_SYSTEM_OPENJPEG ON)
set(WITH_SYSTEM_OPENJPEG ON) set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include)
set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include) set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/libopenjpeg.a)
set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/libopenjpeg.a)
endif()
endif() endif()
find_library(SYSTEMSTUBS_LIBRARY find_library(SYSTEMSTUBS_LIBRARY
@ -202,11 +186,7 @@ set(PLATFORM_LINKFLAGS
"-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio" "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio"
) )
if(WITH_CXX11) list(APPEND PLATFORM_LINKLIBS c++)
list(APPEND PLATFORM_LINKLIBS c++)
else()
list(APPEND PLATFORM_LINKLIBS stdc++)
endif()
if(WITH_JACK) if(WITH_JACK)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework jackmp") set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework jackmp")
@ -257,11 +237,7 @@ if(WITH_SDL)
set(SDL_INCLUDE_DIR ${SDL}/include) set(SDL_INCLUDE_DIR ${SDL}/include)
set(SDL_LIBRARY SDL2) set(SDL_LIBRARY SDL2)
set(SDL_LIBPATH ${SDL}/lib) set(SDL_LIBPATH ${SDL}/lib)
if(WITH_CXX11) set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework ForceFeedback")
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework ForceFeedback")
else()
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -lazy_framework ForceFeedback")
endif()
endif() endif()
set(PNG "${LIBDIR}/png") set(PNG "${LIBDIR}/png")
@ -282,11 +258,7 @@ endif()
if(WITH_BOOST) if(WITH_BOOST)
set(BOOST ${LIBDIR}/boost) set(BOOST ${LIBDIR}/boost)
set(BOOST_INCLUDE_DIR ${BOOST}/include) set(BOOST_INCLUDE_DIR ${BOOST}/include)
if(WITH_CXX11) set(BOOST_POSTFIX)
set(BOOST_POSTFIX)
else()
set(BOOST_POSTFIX -mt)
endif()
set(BOOST_LIBRARIES set(BOOST_LIBRARIES
boost_date_time${BOOST_POSTFIX} boost_date_time${BOOST_POSTFIX}
boost_filesystem${BOOST_POSTFIX} boost_filesystem${BOOST_POSTFIX}
@ -323,9 +295,7 @@ if(WITH_OPENIMAGEIO)
${OPENEXR_LIBRARIES} ${OPENEXR_LIBRARIES}
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
) )
if(WITH_CXX11) set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${LIBDIR}/ffmpeg/lib/libwebp.a)
set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${LIBDIR}/ffmpeg/lib/libwebp.a)
endif()
set(OPENIMAGEIO_LIBPATH set(OPENIMAGEIO_LIBPATH
${OPENIMAGEIO}/lib ${OPENIMAGEIO}/lib
${JPEG_LIBPATH} ${JPEG_LIBPATH}
@ -463,10 +433,8 @@ set(PLATFORM_LINKFLAGS
"${PLATFORM_LINKFLAGS} -Xlinker -unexported_symbols_list -Xlinker ${CMAKE_SOURCE_DIR}/source/creator/osx_locals.map" "${PLATFORM_LINKFLAGS} -Xlinker -unexported_symbols_list -Xlinker ${CMAKE_SOURCE_DIR}/source/creator/osx_locals.map"
) )
if(WITH_CXX11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -stdlib=libc++")
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -stdlib=libc++")
endif()
# Suppress ranlib "has no symbols" warnings (workaround for T48250) # Suppress ranlib "has no symbols" warnings (workaround for T48250)
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")

@ -101,21 +101,14 @@ if(OSX_SYSTEM MATCHES 10.9)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT})
endif() endif()
if(WITH_CXX11) # 10.9 is our min. target, if you use higher sdk, weak linking happens
# 10.9 is our min. target, if you use higher sdk, weak linking happens if(CMAKE_OSX_DEPLOYMENT_TARGET)
if(CMAKE_OSX_DEPLOYMENT_TARGET) if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.9)
if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.9) message(STATUS "Setting deployment target to 10.9, lower versions are incompatible with WITH_CXX11")
message(STATUS "Setting deployment target to 10.9, lower versions are incompatible with WITH_CXX11")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
endif()
else()
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
endif() endif()
else() else()
if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
# 10.6 is our min. target, if you use higher sdk, weak linking happens
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE)
endif()
endif() endif()
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode") if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")

@ -400,10 +400,6 @@ if(CMAKE_COMPILER_IS_GNUCC)
# CLang is the same as GCC for now. # CLang is the same as GCC for now.
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
# Solaris CC
elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro")
set(PLATFORM_CFLAGS "-pipe -features=extensions -fPIC -D__FUNCTION__=__func__")
# Intel C++ Compiler # Intel C++ Compiler
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
# think these next two are broken # think these next two are broken

@ -181,7 +181,6 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
if(use_light_pass) { if(use_light_pass) {
L->indirect = make_float3(0.0f, 0.0f, 0.0f); L->indirect = make_float3(0.0f, 0.0f, 0.0f);
L->direct_throughput = make_float3(0.0f, 0.0f, 0.0f);
L->direct_emission = make_float3(0.0f, 0.0f, 0.0f); L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f); L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
@ -202,18 +201,19 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f); L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f); L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
L->transparent = 0.0f; L->transparent = 0.0f;
L->emission = make_float3(0.0f, 0.0f, 0.0f); L->emission = make_float3(0.0f, 0.0f, 0.0f);
L->background = make_float3(0.0f, 0.0f, 0.0f); L->background = make_float3(0.0f, 0.0f, 0.0f);
L->ao = make_float3(0.0f, 0.0f, 0.0f); L->ao = make_float3(0.0f, 0.0f, 0.0f);
L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f); L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
L->mist = 0.0f; L->mist = 0.0f;
L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
L->state.direct = make_float3(0.0f, 0.0f, 0.0f);
} }
else else
#endif #endif
@ -245,26 +245,34 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
#endif #endif
} }
ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space float3 *throughput, ccl_device_inline void path_radiance_bsdf_bounce(
BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label) KernelGlobals *kg,
PathRadianceState *L_state,
ccl_addr_space float3 *throughput,
BsdfEval *bsdf_eval,
float bsdf_pdf, int bounce, int bsdf_label)
{ {
float inverse_pdf = 1.0f/bsdf_pdf; float inverse_pdf = 1.0f/bsdf_pdf;
#ifdef __PASSES__ #ifdef __PASSES__
if(L->use_light_pass) { if(kernel_data.film.use_light_pass) {
if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) { if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
/* first on directly visible surface */ /* first on directly visible surface */
float3 value = *throughput*inverse_pdf; float3 value = *throughput*inverse_pdf;
L->path_diffuse = bsdf_eval->diffuse*value; L_state->diffuse = bsdf_eval->diffuse*value;
L->path_glossy = bsdf_eval->glossy*value; L_state->glossy = bsdf_eval->glossy*value;
L->path_transmission = bsdf_eval->transmission*value; L_state->transmission = bsdf_eval->transmission*value;
L->path_subsurface = bsdf_eval->subsurface*value; L_state->subsurface = bsdf_eval->subsurface*value;
L->path_scatter = bsdf_eval->scatter*value; L_state->scatter = bsdf_eval->scatter*value;
*throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter; *throughput = L_state->diffuse +
L_state->glossy +
L_state->transmission +
L_state->subsurface +
L_state->scatter;
L->direct_throughput = *throughput; L_state->direct = *throughput;
} }
else { else {
/* transparent bounce before first hit, or indirectly visible through BSDF */ /* transparent bounce before first hit, or indirectly visible through BSDF */
@ -493,19 +501,19 @@ ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
* only a single throughput further along the path, here we recover just * only a single throughput further along the path, here we recover just
* the indirect path that is not influenced by any particular BSDF type */ * the indirect path that is not influenced by any particular BSDF type */
if(L->use_light_pass) { if(L->use_light_pass) {
L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput); L->direct_emission = safe_divide_color(L->direct_emission, L->state.direct);
L->direct_diffuse += L->path_diffuse*L->direct_emission; L->direct_diffuse += L->state.diffuse*L->direct_emission;
L->direct_glossy += L->path_glossy*L->direct_emission; L->direct_glossy += L->state.glossy*L->direct_emission;
L->direct_transmission += L->path_transmission*L->direct_emission; L->direct_transmission += L->state.transmission*L->direct_emission;
L->direct_subsurface += L->path_subsurface*L->direct_emission; L->direct_subsurface += L->state.subsurface*L->direct_emission;
L->direct_scatter += L->path_scatter*L->direct_emission; L->direct_scatter += L->state.scatter*L->direct_emission;
L->indirect = safe_divide_color(L->indirect, L->direct_throughput); L->indirect = safe_divide_color(L->indirect, L->state.direct);
L->indirect_diffuse += L->path_diffuse*L->indirect; L->indirect_diffuse += L->state.diffuse*L->indirect;
L->indirect_glossy += L->path_glossy*L->indirect; L->indirect_glossy += L->state.glossy*L->indirect;
L->indirect_transmission += L->path_transmission*L->indirect; L->indirect_transmission += L->state.transmission*L->indirect;
L->indirect_subsurface += L->path_subsurface*L->indirect; L->indirect_subsurface += L->state.subsurface*L->indirect;
L->indirect_scatter += L->path_scatter*L->indirect; L->indirect_scatter += L->state.scatter*L->indirect;
} }
#endif #endif
} }
@ -514,11 +522,11 @@ ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
{ {
#ifdef __PASSES__ #ifdef __PASSES__
if(L->use_light_pass) { if(L->use_light_pass) {
L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f); L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->path_glossy = make_float3(0.0f, 0.0f, 0.0f); L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
L->path_transmission = make_float3(0.0f, 0.0f, 0.0f); L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f); L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->path_scatter = make_float3(0.0f, 0.0f, 0.0f); L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
L->direct_emission = make_float3(0.0f, 0.0f, 0.0f); L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
L->indirect = make_float3(0.0f, 0.0f, 0.0f); L->indirect = make_float3(0.0f, 0.0f, 0.0f);
@ -531,11 +539,7 @@ ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
{ {
#ifdef __PASSES__ #ifdef __PASSES__
if(L->use_light_pass) { if(L->use_light_pass) {
L->path_diffuse = L_src->path_diffuse; L->state = L_src->state;
L->path_glossy = L_src->path_glossy;
L->path_transmission = L_src->path_transmission;
L->path_subsurface = L_src->path_subsurface;
L->path_scatter = L_src->path_scatter;
L->direct_emission = L_src->direct_emission; L->direct_emission = L_src->direct_emission;
L->indirect = L_src->indirect; L->indirect = L_src->indirect;

@ -103,7 +103,6 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
throughput, throughput,
&state, &state,
&L_sample); &L_sample);
kernel_path_subsurface_accum_indirect(&ss_indirect, &L_sample);
} }
is_sss_sample = true; is_sss_sample = true;
} }
@ -114,7 +113,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) { if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample); kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
if(kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample, &ray)) { if(kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
#ifdef __LAMP_MIS__ #ifdef __LAMP_MIS__
state.ray_t = 0.0f; state.ray_t = 0.0f;
#endif #endif

@ -222,7 +222,7 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
kernel_volume_decoupled_free(kg, &volume_segment); kernel_volume_decoupled_free(kg, &volume_segment);
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray)) if(kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
return VOLUME_PATH_SCATTERED; return VOLUME_PATH_SCATTERED;
else else
return VOLUME_PATH_MISSED; return VOLUME_PATH_MISSED;
@ -244,7 +244,7 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L); kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
/* indirect light bounce */ /* indirect light bounce */
if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray)) if(kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
return VOLUME_PATH_SCATTERED; return VOLUME_PATH_SCATTERED;
else else
return VOLUME_PATH_MISSED; return VOLUME_PATH_MISSED;
@ -519,7 +519,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
} }
#endif /* defined(__EMISSION__) */ #endif /* defined(__EMISSION__) */
if(!kernel_path_surface_bounce(kg, sd, &throughput, state, L, ray)) if(!kernel_path_surface_bounce(kg, sd, &throughput, state, &L->state, ray))
break; break;
} }
} }
@ -648,13 +648,11 @@ ccl_device_forceinline void kernel_path_integrate(
kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L); kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L);
/* compute direct lighting and next bounce */ /* compute direct lighting and next bounce */
if(!kernel_path_surface_bounce(kg, &sd, &throughput, state, L, ray)) if(!kernel_path_surface_bounce(kg, &sd, &throughput, state, &L->state, ray))
break; break;
} }
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
kernel_path_subsurface_accum_indirect(&ss_indirect, L);
/* Trace indirect subsurface rays by restarting the loop. this uses less /* Trace indirect subsurface rays by restarting the loop. this uses less
* stack memory than invoking kernel_path_indirect. * stack memory than invoking kernel_path_indirect.
*/ */

@ -128,7 +128,7 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
num_samples, num_samples,
&tp, &tp,
&ps, &ps,
L, &L->state,
&bsdf_ray, &bsdf_ray,
sum_sample_weight)) sum_sample_weight))
{ {
@ -350,7 +350,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
&sd, &sd,
&tp, &tp,
&ps, &ps,
L, &L->state,
&pray)) &pray))
{ {
kernel_path_indirect(kg, kernel_path_indirect(kg,
@ -405,7 +405,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
&sd, &sd,
&tp, &tp,
&ps, &ps,
L, &L->state,
&pray)) &pray))
{ {
kernel_path_indirect(kg, kernel_path_indirect(kg,

@ -43,7 +43,7 @@ bool kernel_path_subsurface_scatter(
* the second one should be converted to a diffuse BSDF to * the second one should be converted to a diffuse BSDF to
* avoid this. * avoid this.
*/ */
kernel_assert(!ss_indirect->tracing); kernel_assert(!(state->flag & PATH_RAY_DIFFUSE_ANCESTOR));
uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb); uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
@ -56,7 +56,7 @@ bool kernel_path_subsurface_scatter(
bssrdf_u, bssrdf_v, bssrdf_u, bssrdf_v,
false); false);
# ifdef __VOLUME__ # ifdef __VOLUME__
ss_indirect->need_update_volume_stack = bool need_update_volume_stack =
kernel_data.integrator.use_volumes && kernel_data.integrator.use_volumes &&
sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME; sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
# endif /* __VOLUME__ */ # endif /* __VOLUME__ */
@ -75,28 +75,25 @@ bool kernel_path_subsurface_scatter(
sc, sc,
false); false);
kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L);
ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays]; ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays];
ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays]; ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays];
ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays]; ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays];
PathRadiance *hit_L = &ss_indirect->L[ss_indirect->num_rays]; PathRadianceState *hit_L_state = &ss_indirect->L_state[ss_indirect->num_rays];
*hit_state = *state; *hit_state = *state;
*hit_ray = *ray; *hit_ray = *ray;
*hit_tp = *throughput; *hit_tp = *throughput;
*hit_L_state = L->state;
hit_state->rng_offset += PRNG_BOUNCE_NUM; hit_state->rng_offset += PRNG_BOUNCE_NUM;
path_radiance_init(hit_L, kernel_data.film.use_light_pass);
hit_L->direct_throughput = L->direct_throughput;
path_radiance_copy_indirect(hit_L, L);
kernel_path_surface_connect_light(kg, sd, emission_sd, *hit_tp, state, hit_L);
if(kernel_path_surface_bounce(kg, if(kernel_path_surface_bounce(kg,
sd, sd,
hit_tp, hit_tp,
hit_state, hit_state,
hit_L, hit_L_state,
hit_ray)) hit_ray))
{ {
# ifdef __LAMP_MIS__ # ifdef __LAMP_MIS__
@ -104,7 +101,7 @@ bool kernel_path_subsurface_scatter(
# endif /* __LAMP_MIS__ */ # endif /* __LAMP_MIS__ */
# ifdef __VOLUME__ # ifdef __VOLUME__
if(ss_indirect->need_update_volume_stack) { if(need_update_volume_stack) {
Ray volume_ray = *ray; Ray volume_ray = *ray;
/* Setup ray from previous surface point to the new one. */ /* Setup ray from previous surface point to the new one. */
volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, volume_ray.D = normalize_len(hit_ray->P - volume_ray.P,
@ -117,12 +114,8 @@ bool kernel_path_subsurface_scatter(
hit_state->volume_stack); hit_state->volume_stack);
} }
# endif /* __VOLUME__ */ # endif /* __VOLUME__ */
path_radiance_reset_indirect(L);
ss_indirect->num_rays++; ss_indirect->num_rays++;
} }
else {
path_radiance_accum_sample(L, hit_L);
}
} }
return true; return true;
} }
@ -132,23 +125,9 @@ bool kernel_path_subsurface_scatter(
ccl_device_inline void kernel_path_subsurface_init_indirect( ccl_device_inline void kernel_path_subsurface_init_indirect(
ccl_addr_space SubsurfaceIndirectRays *ss_indirect) ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
{ {
ss_indirect->tracing = false;
ss_indirect->num_rays = 0; ss_indirect->num_rays = 0;
} }
ccl_device void kernel_path_subsurface_accum_indirect(
ccl_addr_space SubsurfaceIndirectRays *ss_indirect,
PathRadiance *L)
{
if(ss_indirect->tracing) {
path_radiance_sum_indirect(L);
path_radiance_accum_sample(&ss_indirect->direct_L, L);
if(ss_indirect->num_rays == 0) {
*L = ss_indirect->direct_L;
}
}
}
ccl_device void kernel_path_subsurface_setup_indirect( ccl_device void kernel_path_subsurface_setup_indirect(
KernelGlobals *kg, KernelGlobals *kg,
ccl_addr_space SubsurfaceIndirectRays *ss_indirect, ccl_addr_space SubsurfaceIndirectRays *ss_indirect,
@ -157,20 +136,15 @@ ccl_device void kernel_path_subsurface_setup_indirect(
PathRadiance *L, PathRadiance *L,
ccl_addr_space float3 *throughput) ccl_addr_space float3 *throughput)
{ {
if(!ss_indirect->tracing) {
ss_indirect->direct_L = *L;
}
ss_indirect->tracing = true;
/* Setup state, ray and throughput for indirect SSS rays. */ /* Setup state, ray and throughput for indirect SSS rays. */
ss_indirect->num_rays--; ss_indirect->num_rays--;
ccl_addr_space Ray *indirect_ray = &ss_indirect->rays[ss_indirect->num_rays]; path_radiance_sum_indirect(L);
PathRadiance *indirect_L = &ss_indirect->L[ss_indirect->num_rays]; path_radiance_reset_indirect(L);
*state = ss_indirect->state[ss_indirect->num_rays]; *state = ss_indirect->state[ss_indirect->num_rays];
*ray = *indirect_ray; *ray = ss_indirect->rays[ss_indirect->num_rays];
*L = *indirect_L; L->state = ss_indirect->L_state[ss_indirect->num_rays];
*throughput = ss_indirect->throughputs[ss_indirect->num_rays]; *throughput = ss_indirect->throughputs[ss_indirect->num_rays];
state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM; state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM;

@ -150,7 +150,7 @@ ccl_device bool kernel_branched_path_surface_bounce(
int num_samples, int num_samples,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
PathRadiance *L, PathRadianceState *L_state,
ccl_addr_space Ray *ray, ccl_addr_space Ray *ray,
float sum_sample_weight) float sum_sample_weight)
{ {
@ -170,7 +170,7 @@ ccl_device bool kernel_branched_path_surface_bounce(
return false; return false;
/* modify throughput */ /* modify throughput */
path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label); path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
#ifdef __DENOISING_FEATURES__ #ifdef __DENOISING_FEATURES__
state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples); state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples);
@ -271,7 +271,7 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
ShaderData *sd, ShaderData *sd,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
PathRadiance *L, PathRadianceState *L_state,
ccl_addr_space Ray *ray) ccl_addr_space Ray *ray)
{ {
/* no BSDF? we can stop here */ /* no BSDF? we can stop here */
@ -292,7 +292,7 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
return false; return false;
/* modify throughput */ /* modify throughput */
path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label); path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
/* set labels */ /* set labels */
if(!(label & LABEL_TRANSPARENT)) { if(!(label & LABEL_TRANSPARENT)) {

@ -68,7 +68,7 @@ bool kernel_path_volume_bounce(
ShaderData *sd, ShaderData *sd,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
PathRadiance *L, PathRadianceState *L_state,
ccl_addr_space Ray *ray) ccl_addr_space Ray *ray)
{ {
/* sample phase function */ /* sample phase function */
@ -87,7 +87,7 @@ bool kernel_path_volume_bounce(
return false; return false;
/* modify throughput */ /* modify throughput */
path_radiance_bsdf_bounce(L, throughput, &phase_eval, phase_pdf, state->bounce, label); path_radiance_bsdf_bounce(kg, L_state, throughput, &phase_eval, phase_pdf, state->bounce, label);
/* set labels */ /* set labels */
state->ray_pdf = phase_pdf; state->ray_pdf = phase_pdf;

@ -466,6 +466,18 @@ typedef struct DebugData {
} DebugData; } DebugData;
#endif #endif
typedef ccl_addr_space struct PathRadianceState {
#ifdef __PASSES__
float3 diffuse;
float3 glossy;
float3 transmission;
float3 subsurface;
float3 scatter;
float3 direct;
#endif
} PathRadianceState;
typedef ccl_addr_space struct PathRadiance { typedef ccl_addr_space struct PathRadiance {
#ifdef __PASSES__ #ifdef __PASSES__
int use_light_pass; int use_light_pass;
@ -478,7 +490,6 @@ typedef ccl_addr_space struct PathRadiance {
float3 ao; float3 ao;
float3 indirect; float3 indirect;
float3 direct_throughput;
float3 direct_emission; float3 direct_emission;
float3 color_diffuse; float3 color_diffuse;
@ -499,16 +510,12 @@ typedef ccl_addr_space struct PathRadiance {
float3 indirect_subsurface; float3 indirect_subsurface;
float3 indirect_scatter; float3 indirect_scatter;
float3 path_diffuse;
float3 path_glossy;
float3 path_transmission;
float3 path_subsurface;
float3 path_scatter;
float4 shadow; float4 shadow;
float mist; float mist;
#endif #endif
PathRadianceState state;
#ifdef __SHADOW_TRICKS__ #ifdef __SHADOW_TRICKS__
/* Total light reachable across the path, ignoring shadow blocked queries. */ /* Total light reachable across the path, ignoring shadow blocked queries. */
float3 path_total; float3 path_total;
@ -1032,8 +1039,7 @@ typedef struct PathState {
/* Subsurface */ /* Subsurface */
/* Struct to gather multiple SSS hits. */ /* Struct to gather multiple SSS hits. */
typedef struct SubsurfaceIntersection typedef struct SubsurfaceIntersection {
{
Ray ray; Ray ray;
float3 weight[BSSRDF_MAX_HITS]; float3 weight[BSSRDF_MAX_HITS];
@ -1043,17 +1049,14 @@ typedef struct SubsurfaceIntersection
} SubsurfaceIntersection; } SubsurfaceIntersection;
/* Struct to gather SSS indirect rays and delay tracing them. */ /* Struct to gather SSS indirect rays and delay tracing them. */
typedef struct SubsurfaceIndirectRays typedef struct SubsurfaceIndirectRays {
{
bool need_update_volume_stack;
bool tracing;
PathState state[BSSRDF_MAX_HITS]; PathState state[BSSRDF_MAX_HITS];
struct PathRadiance direct_L;
int num_rays; int num_rays;
struct Ray rays[BSSRDF_MAX_HITS]; struct Ray rays[BSSRDF_MAX_HITS];
float3 throughputs[BSSRDF_MAX_HITS]; float3 throughputs[BSSRDF_MAX_HITS];
struct PathRadiance L[BSSRDF_MAX_HITS]; struct PathRadianceState L_state[BSSRDF_MAX_HITS];
} SubsurfaceIndirectRays; } SubsurfaceIndirectRays;
/* Constant Kernel Data /* Constant Kernel Data

@ -87,7 +87,6 @@ ccl_device_inline bool kernel_split_branched_indirect_start_shared(KernelGlobals
PathRadiance *inactive_L = &kernel_split_state.path_radiance[inactive_ray]; PathRadiance *inactive_L = &kernel_split_state.path_radiance[inactive_ray];
path_radiance_init(inactive_L, kernel_data.film.use_light_pass); path_radiance_init(inactive_L, kernel_data.film.use_light_pass);
inactive_L->direct_throughput = L->direct_throughput;
path_radiance_copy_indirect(inactive_L, L); path_radiance_copy_indirect(inactive_L, L);
ray_state[inactive_ray] = RAY_REGENERATED; ray_state[inactive_ray] = RAY_REGENERATED;
@ -176,7 +175,7 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(
num_samples, num_samples,
tp, tp,
ps, ps,
L, &L->state,
bsdf_ray, bsdf_ray,
sum_sample_weight)) sum_sample_weight))
{ {

@ -65,7 +65,7 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K
kernel_path_volume_connect_light(kg, sd, emission_sd, *tp, &branched_state->path_state, L); kernel_path_volume_connect_light(kg, sd, emission_sd, *tp, &branched_state->path_state, L);
/* indirect light bounce */ /* indirect light bounce */
if(!kernel_path_volume_bounce(kg, sd, tp, ps, L, pray)) { if(!kernel_path_volume_bounce(kg, sd, tp, ps, &L->state, pray)) {
continue; continue;
} }
@ -170,7 +170,7 @@ ccl_device void kernel_do_volume(KernelGlobals *kg)
kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L); kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
/* indirect light bounce */ /* indirect light bounce */
if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray)) { if(kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray)) {
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED); ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
} }
else { else {

@ -54,7 +54,6 @@ ccl_device void kernel_indirect_subsurface(KernelGlobals *kg)
#endif #endif
if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) { if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
ccl_addr_space SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index]; ccl_addr_space SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
kernel_path_subsurface_accum_indirect(ss_indirect, L);
/* Trace indirect subsurface rays by restarting the loop. this uses less /* Trace indirect subsurface rays by restarting the loop. this uses less
* stack memory than invoking kernel_path_indirect. * stack memory than invoking kernel_path_indirect.

@ -134,7 +134,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
#endif #endif
/* Compute direct lighting and next bounce. */ /* Compute direct lighting and next bounce. */
if(!kernel_path_surface_bounce(kg, sd, throughput, state, L, ray)) { if(!kernel_path_surface_bounce(kg, sd, throughput, state, &L->state, ray)) {
kernel_split_path_end(kg, ray_index); kernel_split_path_end(kg, ray_index);
} }
#ifdef __BRANCHED_PATH__ #ifdef __BRANCHED_PATH__

@ -930,7 +930,7 @@ void Session::update_status_time(bool show_pause, bool show_done)
const bool rendering_finished = (tile == num_tiles); const bool rendering_finished = (tile == num_tiles);
const bool is_last_tile = (tile + 1) == num_tiles; const bool is_last_tile = (tile + 1) == num_tiles;
substatus = string_printf("Path Tracing Tile %d/%d", tile, num_tiles); substatus = string_printf("Rendered %d/%d Tiles", tile, num_tiles);
if(!rendering_finished && (device->show_samples() || (is_cpu && is_last_tile))) { if(!rendering_finished && (device->show_samples() || (is_cpu && is_last_tile))) {
/* Some devices automatically support showing the sample number: /* Some devices automatically support showing the sample number:

@ -193,16 +193,6 @@ void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
} }
else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) { else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0)); sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0));
#if defined(__sun__) || defined(__sun)
}
else if (key == 268828432) { /* solaris keyboards are messed up */
/* This should really test XK_F11 but that doesn't work */
strcpy(str, "F11");
}
else if (key == 268828433) { /* solaris keyboards are messed up */
/* This should really test XK_F12 but that doesn't work */
strcpy(str, "F12");
#endif
} }
else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) { else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) {
sprintf(str, "F%d", key - GHOST_kKeyF1 + 1); sprintf(str, "F%d", key - GHOST_kKeyF1 + 1);

@ -1254,27 +1254,6 @@ 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) GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
{ {
NSEvent *event = (NSEvent *)eventPtr; NSEvent *event = (NSEvent *)eventPtr;
@ -1459,7 +1438,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
double dx; double dx;
double dy; double dy;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
/* with 10.7 nice scrolling deltas are supported */ /* with 10.7 nice scrolling deltas are supported */
dx = [event scrollingDeltaX]; dx = [event scrollingDeltaX];
dy = [event scrollingDeltaY]; dy = [event scrollingDeltaY];
@ -1469,29 +1447,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
dx = [event deltaX]; dx = [event deltaX];
dy = [event deltaY]; dy = [event deltaY];
} }
#else
/* trying to pretend you have nice scrolls... */
dx = [event deltaX];
dy = -[event deltaY];
const double deltaMax = 50.0;
if ((dx == 0) && (dy == 0)) break;
/* Quadratic acceleration */
dx = dx*(fabs(dx) + 0.5);
if (dx < 0.0) dx -= 0.5;
else dx += 0.5;
if (dx < -deltaMax) dx = -deltaMax;
else if (dx > deltaMax) dx = deltaMax;
dy = dy*(fabs(dy) + 0.5);
if (dy < 0.0) dy -= 0.5;
else dy += 0.5;
if (dy < -deltaMax) dy= -deltaMax;
else if (dy > deltaMax) dy= deltaMax;
dy = -dy;
#endif
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy)); pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));

@ -1601,26 +1601,6 @@ convertXKey(KeySym key)
} }
else if ((key >= XK_F1) && (key <= XK_F24)) { else if ((key >= XK_F1) && (key <= XK_F24)) {
type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1)); type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1));
#if defined(__sun) || defined(__sun__)
/* This is a bit of a hack, but it looks like sun
* Used F11 and friends for its special keys Stop,again etc..
* So this little patch enables F11 and F12 to work as expected
* following link has documentation on it:
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4734408
* also from /usr/include/X11/Sunkeysym.h
* #define SunXK_F36 0x1005FF10 // Labeled F11
* #define SunXK_F37 0x1005FF11 // Labeled F12
*
* mein@cs.umn.edu
*/
}
else if (key == 268828432) {
type = GHOST_kKeyF11;
}
else if (key == 268828433) {
type = GHOST_kKeyF12;
#endif
} }
else { else {
switch (key) { switch (key) {
@ -1714,19 +1694,6 @@ convertXKey(KeySym key)
GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast); GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast);
#endif #endif
#endif #endif
/* some extra sun cruft (NICE KEYBOARD!) */
#ifdef __sun__
GXMAP(type, 0xffde, GHOST_kKeyNumpad1);
GXMAP(type, 0xffe0, GHOST_kKeyNumpad3);
GXMAP(type, 0xffdc, GHOST_kKeyNumpad5);
GXMAP(type, 0xffd8, GHOST_kKeyNumpad7);
GXMAP(type, 0xffda, GHOST_kKeyNumpad9);
GXMAP(type, 0xffd6, GHOST_kKeyNumpadSlash);
GXMAP(type, 0xffd7, GHOST_kKeyNumpadAsterisk);
#endif
default: default:
type = GHOST_kKeyUnknown; type = GHOST_kKeyUnknown;
break; break;

@ -303,8 +303,6 @@ protected:
GHOST_TabletData m_tablet; GHOST_TabletData m_tablet;
bool m_lionStyleFullScreen;
bool m_immediateDraw; bool m_immediateDraw;
bool m_debug_context; // for debug messages during context setup bool m_debug_context; // for debug messages during context setup
}; };

@ -43,14 +43,6 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
/* Lion style fullscreen support when building with the 10.6 SDK */
enum {
NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7,
NSFullScreenWindowMask = 1 << 14
};
#endif
#pragma mark Cocoa window delegate object #pragma mark Cocoa window delegate object
@interface CocoaWindowDelegate : NSObject @interface CocoaWindowDelegate : NSObject
@ -511,14 +503,6 @@ enum {
#pragma mark initialization / finalization #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
GHOST_WindowCocoa::GHOST_WindowCocoa( GHOST_WindowCocoa::GHOST_WindowCocoa(
GHOST_SystemCocoa *systemCocoa, GHOST_SystemCocoa *systemCocoa,
const STR_String& title, const STR_String& title,
@ -537,7 +521,6 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
m_systemCocoa = systemCocoa; m_systemCocoa = systemCocoa;
m_fullScreen = false; m_fullScreen = false;
m_immediateDraw = false; m_immediateDraw = false;
m_lionStyleFullScreen = false;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@ -613,16 +596,6 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
if (state == GHOST_kWindowStateFullScreen) if (state == GHOST_kWindowStateFullScreen)
setState(GHOST_kWindowStateFullScreen); setState(GHOST_kWindowStateFullScreen);
// Starting with 10.9 (darwin 13.x.x), we can use Lion fullscreen,
// since it now has better multi-monitor support
// if the screens are spawned, additional screens get useless,
// so we only use lionStyleFullScreen when screens have separate spaces
if ([NSScreen respondsToSelector:@selector(screensHaveSeparateSpaces)] && [NSScreen screensHaveSeparateSpaces]) {
// implies we are on >= OSX 10.9
m_lionStyleFullScreen = true;
}
[pool drain]; [pool drain];
} }
@ -760,28 +733,18 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (!m_fullScreen) { NSRect screenSize = [[m_window screen] visibleFrame];
NSRect screenSize = [[m_window screen] visibleFrame];
//Max window contents as screen size (excluding title bar...) //Max window contents as screen size (excluding title bar...)
NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)]; styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
rect = [m_window contentRectForFrameRect:[m_window frame]]; rect = [m_window contentRectForFrameRect:[m_window frame]];
bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y);
bounds.m_l = rect.origin.x -contentRect.origin.x; bounds.m_l = rect.origin.x -contentRect.origin.x;
bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width;
bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y);
}
else {
NSRect screenSize = [[m_window screen] frame];
bounds.m_b = screenSize.origin.y + screenSize.size.height;
bounds.m_l = screenSize.origin.x;
bounds.m_r = screenSize.origin.x + screenSize.size.width;
bounds.m_t = screenSize.origin.y;
}
[pool drain]; [pool drain];
} }
@ -856,9 +819,6 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const
state = GHOST_kWindowStateNormal; state = GHOST_kWindowStateNormal;
} }
} }
else if (m_fullScreen) {
state = GHOST_kWindowStateFullScreen;
}
else if ([m_window isMiniaturized]) { else if ([m_window isMiniaturized]) {
state = GHOST_kWindowStateMinimized; state = GHOST_kWindowStateMinimized;
} }
@ -940,15 +900,12 @@ NSScreen* GHOST_WindowCocoa::getScreen()
/* called for event, when window leaves monitor to another */ /* called for event, when window leaves monitor to another */
void GHOST_WindowCocoa::setNativePixelSize(void) void GHOST_WindowCocoa::setNativePixelSize(void)
{ {
/* make sure 10.6 keeps running */ NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; GHOST_Rect rect;
getClientBounds(rect);
GHOST_Rect rect;
getClientBounds(rect);
m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth(); m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth();
}
} }
/** /**
@ -973,35 +930,8 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
{ {
NSUInteger masks = [m_window styleMask]; NSUInteger masks = [m_window styleMask];
if (!m_fullScreen && !(masks & NSFullScreenWindowMask)) { if (!(masks & NSFullScreenWindowMask)) {
if (m_lionStyleFullScreen) { [m_window toggleFullScreen:nil];
[m_window toggleFullScreen:nil];
break;
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/* This status change needs to be done before Cocoa call to enter fullscreen mode
* to give window delegate hint not to forward its deactivation to ghost wm that
* doesn't know view/window difference. */
m_fullScreen = true;
/* Disable toggle for Lion style fullscreen */
[m_window setCollectionBehavior:NSWindowCollectionBehaviorDefault];
//10.6 provides Cocoa functions to autoshow menu bar, and to change a window style
//Hide menu & dock if on primary screen. else only menu
if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) {
[NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
}
//Make window borderless and enlarge it
[m_window setStyleMask:NSBorderlessWindowMask];
[m_window setFrame:[[m_window screen] frame] display:YES];
[m_window makeFirstResponder:m_openGLView];
//Tell WM of view new size
m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
[pool drain];
} }
break; break;
} }
@ -1014,26 +944,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
// Lion style fullscreen // Lion style fullscreen
[m_window toggleFullScreen:nil]; [m_window toggleFullScreen:nil];
} }
else if (m_fullScreen) {
m_fullScreen = false;
/* Enable toggle for into Lion style fullscreen */
[m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
//Exit fullscreen
//Show again menu & dock if needed
if ([[m_window screen] isEqual:[NSScreen mainScreen]]) {
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
}
//Make window normal and resize it
[m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
[m_window setFrame:[[m_window screen] visibleFrame] display:YES];
//TODO for 10.6 only : window title is forgotten after the style change
[m_window makeFirstResponder:m_openGLView];
//Tell WM of view new size
m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
}
else if ([m_window isMiniaturized]) else if ([m_window isMiniaturized])
[m_window deminiaturize:nil]; [m_window deminiaturize:nil];
else if ([m_window isZoomed]) else if ([m_window isZoomed])
@ -1164,7 +1074,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
return GHOST_kSuccess; return GHOST_kSuccess;
} }
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
static void postNotification() static void postNotification()
{ {
NSUserNotification *notification = [[NSUserNotification alloc] init]; NSUserNotification *notification = [[NSUserNotification alloc] init];
@ -1174,7 +1083,6 @@ static void postNotification()
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
[notification release]; [notification release];
} }
#endif
GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
{ {
@ -1189,15 +1097,13 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
[dockIcon unlockFocus]; [dockIcon unlockFocus];
[NSApp setApplicationIconImage:dockIcon]; [NSApp setApplicationIconImage:dockIcon];
// We use notifications to inform the user when the progress reached 100%
// With OSX 10.8 and later, we can use notifications to inform the user when the progress reached 100% // Atm. just fire this when the progressbar ends, the behavior is controlled
// Atm. just fire this when the progressbar ends, the behavior is controlled in the NotificationCenter // in the NotificationCenter If Blender is not frontmost window, a message
// If Blender is not frontmost window, a message pops up with sound, in any case an entry in notifications // pops up with sound, in any case an entry in notifications
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) { if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) {
postNotification(); postNotification();
} }
#endif
[dockIcon release]; [dockIcon release];

@ -59,10 +59,6 @@
//For DPI value //For DPI value
#include <X11/Xresource.h> #include <X11/Xresource.h>
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
# include <strings.h>
#endif
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>

@ -225,7 +225,7 @@ public: \
MEM_freeN(mem); \ MEM_freeN(mem); \
} \ } \
#if defined __GNUC__ || defined __sun #if defined __GNUC__
# define OBJECT_GUARDED_NEW(type, args ...) \ # define OBJECT_GUARDED_NEW(type, args ...) \
new(MEM_mallocN(sizeof(type), __func__)) type(args) new(MEM_mallocN(sizeof(type), __func__)) type(args)
#else #else

@ -37,9 +37,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
# include <strings.h>
#endif
#include "STR_String.h" #include "STR_String.h"
/*------------------------------------------------------------------------------------------------- /*-------------------------------------------------------------------------------------------------

@ -55,7 +55,7 @@ class VIEW3D_HT_header(Header):
# Occlude geometry # Occlude geometry
if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
(mode == 'WEIGHT_PAINT')): (mode in {'WEIGHT_PAINT', 'VERTEX_PAINT'})):
row.prop(view, "use_occlude_geometry", text="") row.prop(view, "use_occlude_geometry", text="")
# Proportional editing # Proportional editing
@ -170,7 +170,7 @@ class VIEW3D_MT_editor_menus(Menu):
mesh = obj.data mesh = obj.data
if mesh.use_paint_mask: if mesh.use_paint_mask:
layout.menu("VIEW3D_MT_select_paint_mask") layout.menu("VIEW3D_MT_select_paint_mask")
elif mesh.use_paint_mask_vertex and mode_string == 'PAINT_WEIGHT': elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
layout.menu("VIEW3D_MT_select_paint_mask_vertex") layout.menu("VIEW3D_MT_select_paint_mask_vertex")
elif mode_string != 'SCULPT': elif mode_string != 'SCULPT':
layout.menu("VIEW3D_MT_select_%s" % mode_string.lower()) layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
@ -1778,6 +1778,7 @@ class VIEW3D_MT_paint_vertex(Menu):
layout.operator("paint.vertex_color_set") layout.operator("paint.vertex_color_set")
layout.operator("paint.vertex_color_smooth") layout.operator("paint.vertex_color_smooth")
layout.operator("paint.vertex_color_dirt") layout.operator("paint.vertex_color_dirt")
layout.operator("paint.vertex_color_from_weight")
layout.separator() layout.separator()

@ -1168,6 +1168,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
# row.prop(brush, "use_pressure_jitter", toggle=True, text="") # row.prop(brush, "use_pressure_jitter", toggle=True, text="")
col.separator() col.separator()
col.prop(brush, "vertex_tool", text="Blend") col.prop(brush, "vertex_tool", text="Blend")
col.prop(brush, "use_accumulate")
col.prop(brush, "use_alpha")
col.separator() col.separator()
col.template_ID(settings, "palette", new="palette.new") col.template_ID(settings, "palette", new="palette.new")

@ -222,6 +222,7 @@ typedef struct SculptSession {
/* For non-airbrush painting to re-apply from the original (MLoop aligned). */ /* For non-airbrush painting to re-apply from the original (MLoop aligned). */
unsigned int *previous_color; unsigned int *previous_color;
unsigned int *previous_accum;
} vpaint; } vpaint;
struct { struct {

@ -641,8 +641,18 @@ static void cdDM_drawMappedFaces(
/* avoid buffer problems in following code */ /* avoid buffer problems in following code */
} }
else if (setDrawOptions == NULL) { else if (setDrawOptions == NULL) {
const bool show_alpha = true;
if (show_alpha) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
/* just draw the entire face array */ /* just draw the entire face array */
GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tot_tri_elem); GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tot_tri_elem);
if (show_alpha) {
glDisable(GL_BLEND);
}
} }
else { else {
for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
@ -1405,8 +1415,8 @@ static void cdDM_buffer_copy_mcol(
for (i = 0; i < totpoly; i++, mpoly++) { for (i = 0; i < totpoly; i++, mpoly++) {
for (j = 0; j < mpoly->totloop; j++) { for (j = 0; j < mpoly->totloop; j++) {
copy_v3_v3_uchar(&varray[start], &mloopcol[mpoly->loopstart + j].r); copy_v4_v4_uchar(&varray[start], &mloopcol[mpoly->loopstart + j].r);
start += 3; start += 4;
} }
} }
} }

@ -469,7 +469,7 @@ bool BKE_paint_select_vert_test(Object *ob)
(ob->type == OB_MESH) && (ob->type == OB_MESH) &&
(ob->data != NULL) && (ob->data != NULL) &&
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
(ob->mode & OB_MODE_WEIGHT_PAINT) (ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT)
); );
} }
@ -683,6 +683,7 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
gmap = &ss->mode.vpaint.gmap; gmap = &ss->mode.vpaint.gmap;
MEM_SAFE_FREE(ss->mode.vpaint.previous_color); MEM_SAFE_FREE(ss->mode.vpaint.previous_color);
MEM_SAFE_FREE(ss->mode.vpaint.previous_accum);
} }
else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) { else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) {
gmap = &ss->mode.wpaint.gmap; gmap = &ss->mode.wpaint.gmap;
@ -740,7 +741,10 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
*/ */
BKE_object_free_derived_caches(object); BKE_object_free_derived_caches(object);
MEM_SAFE_FREE(object->sculpt->pbvh); if (object->sculpt->pbvh) {
BKE_pbvh_free(object->sculpt->pbvh);
object->sculpt->pbvh = NULL;
}
sculptsession_bm_to_me_update_data_only(object, false); sculptsession_bm_to_me_update_data_only(object, false);

@ -28,7 +28,7 @@
extern "C" { extern "C" {
#endif #endif
#if defined WIN32 && !defined _LIBC || defined __sun #if defined WIN32 && !defined _LIBC
#if defined(__cplusplus) || (defined(__STDC__) && __STDC__) #if defined(__cplusplus) || (defined(__STDC__) && __STDC__)
#undef __P #undef __P
@ -53,7 +53,7 @@ extern "C" {
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ #define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ #define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined(_GNU_SOURCE) || defined(__SUNPRO_C) #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined(_GNU_SOURCE)
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ #define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ #define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ #define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
@ -72,7 +72,7 @@ extern int fnmatch __P((const char *__pattern, const char *__string,
# define _GNU_SOURCE # define _GNU_SOURCE
# endif # endif
# include <fnmatch.h> # include <fnmatch.h>
#endif /* defined WIN32 && !defined _LIBC || defined __sun */ #endif /* defined WIN32 && !defined _LIBC */
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -37,14 +37,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) || defined(__sun) #if defined(__NetBSD__) || defined(__DragonFly__)
/* Other modern unix os's should probably use this also */ /* Other modern unix os's should probably use this also */
# include <sys/statvfs.h> # include <sys/statvfs.h>
# define USE_STATFS_STATVFS # define USE_STATFS_STATVFS
#elif (defined(__sparc) || defined(__sparc__)) && !defined(__FreeBSD__) && !defined(__linux__)
# include <sys/statfs.h>
/* 4 argument version (not common) */
# define USE_STATFS_4ARGS
#endif #endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)

@ -1653,6 +1653,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
} }
} }
{
Brush *br;
br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Average");
if (!br) {
br = BKE_brush_add(main, "Average", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
br->vertexpaint_tool = PAINT_BLEND_AVERAGE;
br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
}
br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Smear");
if (!br) {
br = BKE_brush_add(main, "Smear", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
br->vertexpaint_tool = PAINT_BLEND_SMEAR;
br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
}
}
FOREACH_NODETREE(main, ntree, id) { FOREACH_NODETREE(main, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) { if (ntree->type == NTREE_COMPOSIT) {
do_versions_compositor_render_passes(ntree); do_versions_compositor_render_passes(ntree);

@ -41,7 +41,7 @@
/* macro which inserts the function name */ /* macro which inserts the function name */
#if defined __GNUC__ || defined __sun #if defined __GNUC__
# define ERRMSG(format, args...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, ##args); errtot++; } (void)0 # define ERRMSG(format, args...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, ##args); errtot++; } (void)0
#else #else
# define ERRMSG(format, ...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, __VA_ARGS__); errtot++; } (void)0 # define ERRMSG(format, ...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, __VA_ARGS__); errtot++; } (void)0

@ -480,12 +480,13 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
source.setAccessorCount(me->totloop); source.setAccessorCount(me->totloop);
source.setAccessorStride(3); source.setAccessorStride(4);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList(); COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("R"); param.push_back("R");
param.push_back("G"); param.push_back("G");
param.push_back("B"); param.push_back("B");
param.push_back("A");
source.prepareToAppendValues(); source.prepareToAppendValues();
@ -495,9 +496,10 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
MLoopCol *mlc = mloopcol + mpoly->loopstart; MLoopCol *mlc = mloopcol + mpoly->loopstart;
for (int j = 0; j < mpoly->totloop; j++, mlc++) { for (int j = 0; j < mpoly->totloop; j++, mlc++) {
source.appendValues( source.appendValues(
mlc->r / 255.0f, mlc->r / 255.0f,
mlc->g / 255.0f, mlc->g / 255.0f,
mlc->b / 255.0f mlc->b / 255.0f,
mlc->a / 255.0f
); );
} }
} }

@ -283,6 +283,7 @@ bool ED_mesh_uv_texture_remove_active(struct Mesh *me);
bool ED_mesh_uv_texture_remove_named(struct Mesh *me, const char *name); bool ED_mesh_uv_texture_remove_named(struct Mesh *me, const char *name);
void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me); void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me);
void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum); void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum);
bool ED_mesh_color_ensure(struct Mesh *me, const char *name);
int ED_mesh_color_add(struct Mesh *me, const char *name, const bool active_set); int ED_mesh_color_add(struct Mesh *me, const char *name, const bool active_set);
bool ED_mesh_color_remove_index(struct Mesh *me, const int n); bool ED_mesh_color_remove_index(struct Mesh *me, const int n);
bool ED_mesh_color_remove_active(struct Mesh *me); bool ED_mesh_color_remove_active(struct Mesh *me);

@ -440,6 +440,20 @@ int ED_mesh_color_add(Mesh *me, const char *name, const bool active_set)
return layernum; return layernum;
} }
bool ED_mesh_color_ensure(struct Mesh *me, const char *name)
{
BLI_assert(me->edit_btmesh == NULL);
if (!me->mloopcol && me->totloop) {
CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name);
BKE_mesh_update_customdata_pointers(me, true);
}
DEG_id_tag_update(&me->id, 0);
return (me->mloopcol != NULL);
}
bool ED_mesh_color_remove_index(Mesh *me, const int n) bool ED_mesh_color_remove_index(Mesh *me, const int n)
{ {
CustomData *ldata = GET_CD_DATA(me, ldata); CustomData *ldata = GET_CD_DATA(me, ldata);

@ -53,6 +53,7 @@ set(SRC
paint_undo.c paint_undo.c
paint_utils.c paint_utils.c
paint_vertex.c paint_vertex.c
paint_vertex_color_ops.c
paint_vertex_proj.c paint_vertex_proj.c
sculpt.c sculpt.c
sculpt_undo.c sculpt_undo.c

@ -123,6 +123,8 @@ void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp); unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp);
/* paint_vertex_color_ops.c */
void PAINT_OT_vertex_color_from_weight(struct wmOperatorType *ot);
/* paint_vertex_proj.c */ /* paint_vertex_proj.c */
struct VertProjHandle; struct VertProjHandle;

@ -1349,6 +1349,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_vertex_color_hsv); WM_operatortype_append(PAINT_OT_vertex_color_hsv);
WM_operatortype_append(PAINT_OT_vertex_color_invert); WM_operatortype_append(PAINT_OT_vertex_color_invert);
WM_operatortype_append(PAINT_OT_vertex_color_levels); WM_operatortype_append(PAINT_OT_vertex_color_levels);
WM_operatortype_append(PAINT_OT_vertex_color_from_weight);
/* face-select */ /* face-select */
WM_operatortype_append(PAINT_OT_face_select_linked); WM_operatortype_append(PAINT_OT_face_select_linked);

@ -84,6 +84,8 @@
#include "sculpt_intern.h" #include "sculpt_intern.h"
#include "paint_intern.h" /* own include */ #include "paint_intern.h" /* own include */
#define EPS_SATURATION 0.0005f
/* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */ /* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */
struct VPaintAverageAccum { struct VPaintAverageAccum {
uint len; uint len;
@ -257,29 +259,6 @@ static void do_shared_vertexcol(Mesh *me, bool *mlooptag)
MEM_freeN(scol); MEM_freeN(scol);
} }
static bool make_vertexcol(Object *ob) /* single ob */
{
Mesh *me;
if (ID_IS_LINKED_DATABLOCK(ob) ||
((me = BKE_mesh_from_object(ob)) == NULL) ||
(me->totpoly == 0) ||
(me->edit_btmesh))
{
return false;
}
/* copies from shadedisplist to mcol */
if (!me->mloopcol && me->totloop) {
CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop);
BKE_mesh_update_customdata_pointers(me, true);
}
DEG_id_tag_update(&me->id, 0);
return (me->mloopcol != NULL);
}
/* mirror_vgroup is set to -1 when invalid */ /* mirror_vgroup is set to -1 when invalid */
static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
{ {
@ -343,12 +322,13 @@ bool ED_vpaint_fill(Object *ob, uint paintcol)
int i, j; int i, j;
if (((me = BKE_mesh_from_object(ob)) == NULL) || if (((me = BKE_mesh_from_object(ob)) == NULL) ||
(me->mloopcol == NULL && (make_vertexcol(ob) == false))) (ED_mesh_color_ensure(me, NULL) == false))
{ {
return false; return false;
} }
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
mp = me->mpoly; mp = me->mpoly;
for (i = 0; i < me->totpoly; i++, mp++) { for (i = 0; i < me->totpoly; i++, mp++) {
@ -357,9 +337,16 @@ bool ED_vpaint_fill(Object *ob, uint paintcol)
if (use_face_sel && !(mp->flag & ME_FACE_SEL)) if (use_face_sel && !(mp->flag & ME_FACE_SEL))
continue; continue;
for (j = 0; j < mp->totloop; j++, lcol++) { j = 0;
*(int *)lcol = paintcol; do {
} uint vidx = me->mloop[mp->loopstart + j].v;
if (!(use_vert_sel && !(me->mvert[vidx].flag & SELECT))) {
*(int *)lcol = paintcol;
}
lcol++;
j++;
} while (j < mp->totloop);
} }
/* remove stale me->mcol, will be added later */ /* remove stale me->mcol, will be added later */
@ -466,7 +453,7 @@ bool ED_vpaint_smooth(Object *ob)
bool *mlooptag; bool *mlooptag;
if (((me = BKE_mesh_from_object(ob)) == NULL) || if (((me = BKE_mesh_from_object(ob)) == NULL) ||
(me->mloopcol == NULL && (make_vertexcol(ob) == false))) (ED_mesh_color_ensure(me, NULL) == false))
{ {
return false; return false;
} }
@ -513,7 +500,7 @@ bool ED_vpaint_color_transform(
const MPoly *mp; const MPoly *mp;
if (((me = BKE_mesh_from_object(ob)) == NULL) || if (((me = BKE_mesh_from_object(ob)) == NULL) ||
(me->mloopcol == NULL && (make_vertexcol(ob) == false))) (ED_mesh_color_ensure(me, NULL) == false))
{ {
return false; return false;
} }
@ -613,15 +600,17 @@ BLI_INLINE uint mcol_blend(uint col1, uint col2, int fac)
int r1 = cp1[0] * cp1[0]; int r1 = cp1[0] * cp1[0];
int g1 = cp1[1] * cp1[1]; int g1 = cp1[1] * cp1[1];
int b1 = cp1[2] * cp1[2]; int b1 = cp1[2] * cp1[2];
int a1 = cp1[3] * cp1[3];
int r2 = cp2[0] * cp2[0]; int r2 = cp2[0] * cp2[0];
int g2 = cp2[1] * cp2[1]; int g2 = cp2[1] * cp2[1];
int b2 = cp2[2] * cp2[2]; int b2 = cp2[2] * cp2[2];
int a2 = cp2[3] * cp2[3];
cp[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255))); cp[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255)));
cp[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255))); cp[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255)));
cp[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255))); cp[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255)));
cp[3] = 255; cp[3] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * a1 + fac * a2), 255)));
return col; return col;
} }
@ -646,7 +635,8 @@ BLI_INLINE uint mcol_add(uint col1, uint col2, int fac)
cp[1] = (temp > 254) ? 255 : temp; cp[1] = (temp > 254) ? 255 : temp;
temp = cp1[2] + divide_round_i((fac * cp2[2]), 255); temp = cp1[2] + divide_round_i((fac * cp2[2]), 255);
cp[2] = (temp > 254) ? 255 : temp; cp[2] = (temp > 254) ? 255 : temp;
cp[3] = 255; temp = cp1[3] + divide_round_i((fac * cp2[3]), 255);
cp[3] = (temp > 254) ? 255 : temp;
return col; return col;
} }
@ -671,7 +661,8 @@ BLI_INLINE uint mcol_sub(uint col1, uint col2, int fac)
cp[1] = (temp < 0) ? 0 : temp; cp[1] = (temp < 0) ? 0 : temp;
temp = cp1[2] - divide_round_i((fac * cp2[2]), 255); temp = cp1[2] - divide_round_i((fac * cp2[2]), 255);
cp[2] = (temp < 0) ? 0 : temp; cp[2] = (temp < 0) ? 0 : temp;
cp[3] = 255; temp = cp1[3] - divide_round_i((fac * cp2[3]), 255);
cp[3] = (temp < 0) ? 0 : temp;
return col; return col;
} }
@ -696,7 +687,7 @@ BLI_INLINE uint mcol_mul(uint col1, uint col2, int fac)
cp[0] = divide_round_i(mfac * cp1[0] * 255 + fac * cp2[0] * cp1[0], 255 * 255); cp[0] = divide_round_i(mfac * cp1[0] * 255 + fac * cp2[0] * cp1[0], 255 * 255);
cp[1] = divide_round_i(mfac * cp1[1] * 255 + fac * cp2[1] * cp1[1], 255 * 255); cp[1] = divide_round_i(mfac * cp1[1] * 255 + fac * cp2[1] * cp1[1], 255 * 255);
cp[2] = divide_round_i(mfac * cp1[2] * 255 + fac * cp2[2] * cp1[2], 255 * 255); cp[2] = divide_round_i(mfac * cp1[2] * 255 + fac * cp2[2] * cp1[2], 255 * 255);
cp[3] = 255; cp[3] = divide_round_i(mfac * cp1[3] * 255 + fac * cp2[3] * cp1[3], 255 * 255);
return col; return col;
} }
@ -729,7 +720,7 @@ BLI_INLINE uint mcol_lighten(uint col1, uint col2, int fac)
cp[0] = divide_round_i(mfac * cp1[0] + fac * cp2[0], 255); cp[0] = divide_round_i(mfac * cp1[0] + fac * cp2[0], 255);
cp[1] = divide_round_i(mfac * cp1[1] + fac * cp2[1], 255); cp[1] = divide_round_i(mfac * cp1[1] + fac * cp2[1], 255);
cp[2] = divide_round_i(mfac * cp1[2] + fac * cp2[2], 255); cp[2] = divide_round_i(mfac * cp1[2] + fac * cp2[2], 255);
cp[3] = 255; cp[3] = divide_round_i(mfac * cp1[3] + fac * cp2[3], 255);
return col; return col;
} }
@ -762,24 +753,373 @@ BLI_INLINE uint mcol_darken(uint col1, uint col2, int fac)
cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255); cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255);
cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255); cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255);
cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255); cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255);
cp[3] = 255; cp[3] = divide_round_i((mfac * cp1[3] + fac * cp2[3]), 255);
return col; return col;
} }
BLI_INLINE uint mcol_colordodge(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac,temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
temp = (cp2[0] == 255) ? 255 : min_ii((cp1[0] * 225) / (255 - cp2[0]), 255);
cp[0] = (mfac * cp1[0] + temp * fac) / 255;
temp = (cp2[1] == 255) ? 255 : min_ii((cp1[1] * 225) / (255 - cp2[1]), 255);
cp[1] = (mfac * cp1[1] + temp * fac) / 255;
temp = (cp2[2] == 255) ? 255 : min_ii((cp1[2] * 225 )/ (255 - cp2[2]), 255);
cp[2] = (mfac * cp1[2] + temp * fac) / 255;
temp = (cp2[3] == 255) ? 255 : min_ii((cp1[3] * 225) / (255 - cp2[3]), 255);
cp[3] = (mfac * cp1[3] + temp * fac) / 255;
return col;
}
BLI_INLINE uint mcol_difference(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac, temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
temp = abs(cp1[0] - cp2[0]);
cp[0] = (mfac * cp1[0] + temp * fac) / 255;
temp = abs(cp1[1] - cp2[1]);
cp[1] = (mfac * cp1[1] + temp * fac) / 255;
temp = abs(cp1[2] - cp2[2]);
cp[2] = (mfac * cp1[2] + temp * fac) / 255;
temp = abs(cp1[3] - cp2[3]);
cp[3] = (mfac * cp1[3] + temp * fac) / 255;
return col;
}
BLI_INLINE uint mcol_screen(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac, temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
temp = max_ii(255 - (((255 - cp1[0]) * (255 - cp2[0])) / 255), 0);
cp[0] = (mfac * cp1[0] + temp * fac) / 255;
temp = max_ii(255 - (((255 - cp1[1]) * (255 - cp2[1])) / 255), 0);
cp[1] = (mfac * cp1[1] + temp * fac) / 255;
temp = max_ii(255 - (((255 - cp1[2]) * (255 - cp2[2])) / 255), 0);
cp[2] = (mfac * cp1[2] + temp * fac) / 255;
temp = max_ii(255 - (((255 - cp1[3]) * (255 - cp2[3])) / 255), 0);
cp[3] = (mfac * cp1[3] + temp * fac) / 255;
return col;
}
BLI_INLINE uint mcol_hardlight(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac, temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
int i = 0;
for (i = 0; i < 4; i++) {
if (cp2[i] > 127) {
temp = 255 - ((255 - 2 * (cp2[i] - 127)) * (255 - cp1[i]) / 255);
}
else {
temp = (2 * cp2[i] * cp1[i]) >> 8;
}
cp[i] = min_ii((mfac * cp1[i] + temp * fac) / 255, 255);
}
return col;
}
BLI_INLINE uint mcol_overlay(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac, temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
int i = 0;
for (i = 0; i < 4; i++) {
if (cp1[i] > 127) {
temp = 255 - ((255 - 2 * (cp1[i] - 127)) * (255 - cp2[i]) / 255);
}
else {
temp = (2 * cp2[i] * cp1[i]) >> 8;
}
cp[i] = min_ii((mfac * cp1[i] + temp * fac) / 255, 255);
}
return col;
}
BLI_INLINE uint mcol_softlight(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac, temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
int i = 0;
for (i = 0; i < 4; i++) {
if (cp1[i] < 127) {
temp = ((2 * ((cp2[i] / 2) + 64)) * cp1[i]) / 255;
}
else {
temp = 255 - (2 * (255 - ((cp2[i] / 2) + 64)) * (255 - cp1[i]) / 255);
}
cp[i] = (temp * fac + cp1[i] * mfac) / 255;
}
return col;
}
BLI_INLINE uint mcol_exclusion(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac, temp;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
int i = 0;
for (i = 0; i < 4; i++) {
temp = 127 - ((2 * (cp1[i] - 127) * (cp2[i] - 127)) / 255);
cp[i] = (temp * fac + cp1[i] * mfac) / 255;
}
return col;
}
BLI_INLINE uint mcol_luminosity(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
float h1, s1, v1;
float h2, s2, v2;
float r, g, b;
rgb_to_hsv(cp1[0] / 255.0f, cp1[1] / 255.0f, cp1[2] / 255.0f, &h1, &s1, &v1);
rgb_to_hsv(cp2[0] / 255.0f, cp2[1] / 255.0f, cp2[2] / 255.0f, &h2, &s2, &v2);
v1 = v2;
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
cp[0] = ((int)(r * 255.0f) * fac + mfac * cp1[0]) / 255;
cp[1] = ((int)(g * 255.0f) * fac + mfac * cp1[1]) / 255;
cp[2] = ((int)(b * 255.0f) * fac + mfac * cp1[2]) / 255;
cp[3] = ((int)(cp2[3]) * fac + mfac * cp1[3]) / 255;
return col;
}
BLI_INLINE uint mcol_saturation(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
float h1, s1, v1;
float h2, s2, v2;
float r, g, b;
rgb_to_hsv(cp1[0] / 255.0f, cp1[1] / 255.0f, cp1[2] / 255.0f, &h1, &s1, &v1);
rgb_to_hsv(cp2[0] / 255.0f, cp2[1] / 255.0f, cp2[2] / 255.0f, &h2, &s2, &v2);
if (s1 > EPS_SATURATION) {
s1 = s2;
}
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
cp[0] = ((int)(r * 255.0f) * fac + mfac * cp1[0]) / 255;
cp[1] = ((int)(g * 255.0f) * fac + mfac * cp1[1]) / 255;
cp[2] = ((int)(b * 255.0f) * fac + mfac * cp1[2]) / 255;
return col;
}
BLI_INLINE uint mcol_hue(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac;
uint col = 0;
if (fac == 0) {
return col1;
}
mfac = 255 - fac;
cp1 = (uchar *)&col1;
cp2 = (uchar *)&col2;
cp = (uchar *)&col;
float h1, s1, v1;
float h2, s2, v2;
float r, g, b;
rgb_to_hsv(cp1[0] / 255.0f, cp1[1] / 255.0f, cp1[2] / 255.0f, &h1, &s1, &v1);
rgb_to_hsv(cp2[0] / 255.0f, cp2[1] / 255.0f, cp2[2] / 255.0f, &h2, &s2, &v2);
h1 = h2;
hsv_to_rgb(h1, s1, v1, &r, &g, &b);
cp[0] = ((int)(r * 255.0f) * fac + mfac * cp1[0]) / 255;
cp[1] = ((int)(g * 255.0f) * fac + mfac * cp1[1]) / 255;
cp[2] = ((int)(b * 255.0f) * fac + mfac * cp1[2]) / 255;
cp[3] = ((int)(cp2[3]) * fac + mfac * cp1[3]) / 255;
return col;
}
BLI_INLINE uint mcol_alpha_add(uint col1, int fac)
{
uchar *cp1, *cp;
int temp;
uint col = 0;
if (fac == 0) {
return col1;
}
cp1 = (uchar *)&col1;
cp = (uchar *)&col;
temp = cp1[3] + fac;
cp[3] = (temp > 254) ? 255 : temp;
return col;
}
BLI_INLINE uint mcol_alpha_sub(uint col1, int fac)
{
uchar *cp1, *cp;
int temp;
uint col = 0;
if (fac == 0) {
return col1;
}
cp1 = (uchar *)&col1;
cp = (uchar *)&col;
temp = cp1[3] - fac;
cp[3] = temp < 0 ? 0 : temp;
return col;
}
/* wpaint has 'wpaint_blend_tool' */ /* wpaint has 'wpaint_blend_tool' */
static uint vpaint_blend_tool(const int tool, const uint col, static uint vpaint_blend_tool(
const uint paintcol, const int alpha_i) const int tool, const uint col,
const uint paintcol, const int alpha_i)
{ {
switch (tool) { switch (tool) {
case PAINT_BLEND_MIX: case PAINT_BLEND_MIX:
case PAINT_BLEND_BLUR: return mcol_blend(col, paintcol, alpha_i); case PAINT_BLEND_BLUR: return mcol_blend(col, paintcol, alpha_i);
case PAINT_BLEND_AVERAGE: return mcol_blend(col, paintcol, alpha_i); case PAINT_BLEND_AVERAGE: return mcol_blend(col, paintcol, alpha_i);
case PAINT_BLEND_SMEAR: return mcol_blend(col, paintcol, alpha_i); case PAINT_BLEND_SMEAR: return mcol_blend(col, paintcol, alpha_i);
case PAINT_BLEND_ADD: return mcol_add(col, paintcol, alpha_i); case PAINT_BLEND_ADD: return mcol_add(col, paintcol, alpha_i);
case PAINT_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i); case PAINT_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i);
case PAINT_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i); case PAINT_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i);
case PAINT_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i); case PAINT_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i);
case PAINT_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i); case PAINT_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i);
case PAINT_BLEND_COLORDODGE: return mcol_colordodge(col, paintcol, alpha_i);
case PAINT_BLEND_DIFFERENCE: return mcol_difference(col, paintcol, alpha_i);
case PAINT_BLEND_SCREEN: return mcol_screen(col, paintcol, alpha_i);
case PAINT_BLEND_HARDLIGHT: return mcol_hardlight(col, paintcol, alpha_i);
case PAINT_BLEND_OVERLAY: return mcol_overlay(col, paintcol, alpha_i);
case PAINT_BLEND_SOFTLIGHT: return mcol_softlight(col, paintcol, alpha_i);
case PAINT_BLEND_EXCLUSION: return mcol_exclusion(col, paintcol, alpha_i);
case PAINT_BLEND_LUMINOCITY: return mcol_luminosity(col, paintcol, alpha_i);
case PAINT_BLEND_SATURATION: return mcol_saturation(col, paintcol, alpha_i);
case PAINT_BLEND_HUE: return mcol_hue(col, paintcol, alpha_i);
/* non-color */
case PAINT_BLEND_ALPHA_SUB: return mcol_alpha_sub(col, alpha_i);
case PAINT_BLEND_ALPHA_ADD: return mcol_alpha_add(col, alpha_i);
default: default:
BLI_assert(0); BLI_assert(0);
return 0; return 0;
@ -788,27 +1128,27 @@ static uint vpaint_blend_tool(const int tool, const uint col,
/* wpaint has 'wpaint_blend' */ /* wpaint has 'wpaint_blend' */
static uint vpaint_blend( static uint vpaint_blend(
VPaint *vp, uint col, uint colorig, VPaint *vp, uint color_curr, uint color_orig,
const uint paintcol, const int alpha_i, uint color_paint, const int alpha_i,
/* pre scaled from [0-1] --> [0-255] */ /* pre scaled from [0-1] --> [0-255] */
const int brush_alpha_value_i) const int brush_alpha_value_i)
{ {
Brush *brush = BKE_paint_brush(&vp->paint); Brush *brush = BKE_paint_brush(&vp->paint);
const int tool = brush->vertexpaint_tool; const int tool = brush->vertexpaint_tool;
col = vpaint_blend_tool(tool, col, paintcol, alpha_i); uint color_blend = vpaint_blend_tool(tool, color_curr, color_paint, alpha_i);
/* if no spray, clip color adding with colorig & orig alpha */ /* if no spray, clip color adding with colorig & orig alpha */
if ((vp->flag & VP_SPRAY) == 0) { if ((vp->flag & VP_SPRAY) == 0) {
uint testcol, a; uint color_test, a;
char *cp, *ct, *co; char *cp, *ct, *co;
testcol = vpaint_blend_tool(tool, colorig, paintcol, brush_alpha_value_i); color_test = vpaint_blend_tool(tool, color_orig, color_paint, brush_alpha_value_i);
cp = (char *)&col; cp = (char *)&color_blend;
ct = (char *)&testcol; ct = (char *)&color_test;
co = (char *)&colorig; co = (char *)&color_orig;
for (a = 0; a < 4; a++) { for (a = 0; a < 4; a++) {
if (ct[a] < co[a]) { if (ct[a] < co[a]) {
if (cp[a] < ct[a]) cp[a] = ct[a]; if (cp[a] < ct[a]) cp[a] = ct[a];
@ -821,7 +1161,16 @@ static uint vpaint_blend(
} }
} }
return col; if ((brush->flag & BRUSH_LOCK_ALPHA) &&
!ELEM(tool, PAINT_BLEND_ALPHA_SUB, PAINT_BLEND_ALPHA_ADD))
{
char *cp, *cc;
cp = (char *)&color_blend;
cc = (char *)&color_curr;
cp[3] = cc[3];
}
return color_blend;
} }
@ -1739,12 +2088,15 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
{ {
/* Create maps */ /* Create maps */
struct SculptVertexPaintGeomMap *gmap = NULL; struct SculptVertexPaintGeomMap *gmap = NULL;
const Brush *brush = NULL;
if (ob->mode == OB_MODE_VERTEX_PAINT) { if (ob->mode == OB_MODE_VERTEX_PAINT) {
gmap = &ob->sculpt->mode.vpaint.gmap; gmap = &ob->sculpt->mode.vpaint.gmap;
brush = BKE_paint_brush(&ts->vpaint->paint);
ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT; ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT;
} }
else if (ob->mode == OB_MODE_WEIGHT_PAINT) { else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
gmap = &ob->sculpt->mode.wpaint.gmap; gmap = &ob->sculpt->mode.wpaint.gmap;
brush = BKE_paint_brush(&ts->wpaint->paint);
ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT; ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT;
} }
else { else {
@ -1781,6 +2133,16 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
else { else {
MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color); MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color);
} }
if (brush && brush->flag & BRUSH_ACCUMULATE) {
if (ob->sculpt->mode.vpaint.previous_accum == NULL) {
ob->sculpt->mode.vpaint.previous_accum =
MEM_callocN(me->totloop * sizeof(uint), "previous_color");
}
}
else {
MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_accum);
}
} }
else if (ob->mode == OB_MODE_WEIGHT_PAINT) { else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
if ((ts->wpaint->flag & VP_SPRAY) == 0) { if ((ts->wpaint->flag & VP_SPRAY) == 0) {
@ -3116,6 +3478,9 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
BKE_mesh_flush_select_from_polys(me); BKE_mesh_flush_select_from_polys(me);
} }
else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
BKE_mesh_flush_select_from_verts(me);
}
/* If the cache is not released by a cancel or a done, free it now. */ /* If the cache is not released by a cancel or a done, free it now. */
if (ob->sculpt->cache) { if (ob->sculpt->cache) {
@ -3134,9 +3499,7 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
ob->mode |= mode_flag; ob->mode |= mode_flag;
if (me->mloopcol == NULL) { ED_mesh_color_ensure(me, NULL);
make_vertexcol(ob);
}
if (vp == NULL) if (vp == NULL)
vp = scene->toolsettings->vpaint = new_vpaint(0); vp = scene->toolsettings->vpaint = new_vpaint(0);
@ -3250,8 +3613,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
if (me == NULL || me->totpoly == 0) if (me == NULL || me->totpoly == 0)
return false; return false;
if (me->mloopcol == NULL) ED_mesh_color_ensure(me, NULL);
make_vertexcol(ob);
if (me->mloopcol == NULL) if (me->mloopcol == NULL)
return false; return false;
@ -3316,8 +3678,7 @@ static void do_vpaint_brush_calc_average_color_cb_ex(
StrokeCache *cache = ss->cache; StrokeCache *cache = ss->cache;
uint *lcol = data->lcol; uint *lcol = data->lcol;
char *col; char *col;
const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
struct VPaintAverageAccum *accum = (struct VPaintAverageAccum *)data->custom_data + n; struct VPaintAverageAccum *accum = (struct VPaintAverageAccum *)data->custom_data + n;
accum->len = 0; accum->len = 0;
@ -3336,7 +3697,7 @@ static void do_vpaint_brush_calc_average_color_cb_ex(
if (BKE_brush_curve_strength(data->brush, test.dist, cache->radius) > 0.0) { if (BKE_brush_curve_strength(data->brush, test.dist, cache->radius) > 0.0) {
/* If the vertex is selected for painting. */ /* If the vertex is selected for painting. */
const MVert *mv = &data->me->mvert[v_index]; const MVert *mv = &data->me->mvert[v_index];
if (!use_face_sel || mv->flag & SELECT) { if (!use_vert_sel || mv->flag & SELECT) {
accum->len += gmap->vert_to_loop[v_index].count; accum->len += gmap->vert_to_loop[v_index].count;
/* if a vertex is within the brush region, then add it's color to the blend. */ /* if a vertex is within the brush region, then add it's color to the blend. */
for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) { for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) {
@ -3388,12 +3749,13 @@ static void do_vpaint_brush_draw_task_cb_ex(
Scene *scene = CTX_data_scene(data->C); Scene *scene = CTX_data_scene(data->C);
float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
SculptBrushTest test; SculptBrushTest test;
sculpt_brush_test_init(ss, &test); sculpt_brush_test_init(ss, &test);
/* For each vertex*/ /* For each vertex */
PBVHVertexIter vd; PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{ {
@ -3407,7 +3769,7 @@ static void do_vpaint_brush_draw_task_cb_ex(
const MVert *mv = &data->me->mvert[v_index]; const MVert *mv = &data->me->mvert[v_index];
/* If the vertex is selected for painting. */ /* If the vertex is selected for painting. */
if (!use_face_sel || mv->flag & SELECT) { if (!use_vert_sel || mv->flag & SELECT) {
/* Calc the dot prod. between ray norm on surf and current vert /* Calc the dot prod. between ray norm on surf and current vert
* (ie splash prevention factor), and only paint front facing verts. */ * (ie splash prevention factor), and only paint front facing verts. */
const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0; const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
@ -3437,9 +3799,16 @@ static void do_vpaint_brush_draw_task_cb_ex(
} }
color_orig = ss->mode.vpaint.previous_color[l_index]; color_orig = ss->mode.vpaint.previous_color[l_index];
} }
const float final_alpha = float final_alpha =
255 * brush_fade * brush_strength * view_dot * 255 * brush_fade * brush_strength * view_dot *
tex_alpha * brush_alpha_pressure * grid_alpha; tex_alpha * brush_alpha_pressure * grid_alpha;
if (brush->flag & BRUSH_ACCUMULATE) {
float mask_accum = ss->mode.vpaint.previous_accum[l_index];
final_alpha = min_ff(final_alpha + mask_accum, 255.0f);
ss->mode.vpaint.previous_accum[l_index] = final_alpha;
}
/* Mix the new color with the original based on final_alpha. */ /* Mix the new color with the original based on final_alpha. */
lcol[l_index] = vpaint_blend( lcol[l_index] = vpaint_blend(
data->vp, lcol[l_index], color_orig, color_final, data->vp, lcol[l_index], color_orig, color_final,
@ -3468,6 +3837,7 @@ static void do_vpaint_brush_blur_task_cb_ex(
uint *lcol = data->lcol; uint *lcol = data->lcol;
float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
SculptBrushTest test; SculptBrushTest test;
@ -3480,7 +3850,7 @@ static void do_vpaint_brush_blur_task_cb_ex(
/* Test to see if the vertex coordinates are within the spherical brush region. */ /* Test to see if the vertex coordinates are within the spherical brush region. */
if (sculpt_brush_test(&test, vd.co)) { if (sculpt_brush_test(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop cooresponds to the current grid. /* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
Otherwise, take the current vert. */ * Otherwise, take the current vert. */
const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f; const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
const MVert *mv = &data->me->mvert[v_index]; const MVert *mv = &data->me->mvert[v_index];
@ -3490,7 +3860,7 @@ static void do_vpaint_brush_blur_task_cb_ex(
const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius); const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius);
/* If the vertex is selected for painting. */ /* If the vertex is selected for painting. */
if (!use_face_sel || mv->flag & SELECT) { if (!use_vert_sel || mv->flag & SELECT) {
/* Get the average poly color */ /* Get the average poly color */
uint color_final = 0; uint color_final = 0;
int total_hit_loops = 0; int total_hit_loops = 0;
@ -3568,6 +3938,7 @@ static void do_vpaint_brush_smear_task_cb_ex(
float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
float brush_dir[3]; float brush_dir[3];
const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
sub_v3_v3v3(brush_dir, cache->location, cache->last_location); sub_v3_v3v3(brush_dir, cache->location, cache->last_location);
@ -3583,15 +3954,15 @@ static void do_vpaint_brush_smear_task_cb_ex(
/* Test to see if the vertex coordinates are within the spherical brush region. */ /* Test to see if the vertex coordinates are within the spherical brush region. */
if (sculpt_brush_test(&test, vd.co)) { if (sculpt_brush_test(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop cooresponds to the current grid. /* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
Otherwise, take the current vert. */ * Otherwise, take the current vert. */
const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f; const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
const MVert *mv_curr = &data->me->mvert[v_index]; const MVert *mv_curr = &data->me->mvert[v_index];
/* if the vertex is selected for painting. */ /* if the vertex is selected for painting. */
if (!use_face_sel || mv_curr->flag & SELECT) { if (!use_vert_sel || mv_curr->flag & SELECT) {
/* Calc the dot prod. between ray norm on surf and current vert /* Calc the dot prod. between ray norm on surf and current vert
(ie splash prevention factor), and only paint front facing verts. */ * (ie splash prevention factor), and only paint front facing verts. */
const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0; const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
if (view_dot > 0.0f) { if (view_dot > 0.0f) {
const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius); const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius);

@ -0,0 +1,112 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/sculpt_paint/paint_vertex_color_ops.c
* \ingroup edsculpt
*/
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "BKE_context.h"
#include "BKE_mesh.h"
#include "BKE_deform.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
#include "paint_intern.h" /* own include */
static int vertex_weight_paint_mode_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
Mesh *me = BKE_mesh_from_object(ob);
return (ob && (ob->mode == OB_MODE_VERTEX_PAINT || ob->mode == OB_MODE_WEIGHT_PAINT)) &&
(me && me->totpoly && me->dvert);
}
static bool vertex_paint_from_weight(bContext *C)
{
Object *ob = CTX_data_active_object(C);
Mesh *me;
const MPoly *mp;
int vgroup_active;
if (((me = BKE_mesh_from_object(ob)) == NULL ||
(ED_mesh_color_ensure(me, NULL)) == false))
{
return false;
}
/* TODO: respect selection. */
mp = me->mpoly;
vgroup_active = ob->actdef - 1;
for (int i = 0; i < me->totpoly; i++, mp++) {
MLoopCol *lcol = &me->mloopcol[mp->loopstart];
uint j = 0;
do{
uint vidx = me->mloop[mp->loopstart + j].v;
const float weight = defvert_find_weight(&me->dvert[vidx], vgroup_active);
const uchar grayscale = weight * 255;
lcol->r = grayscale;
lcol->b = grayscale;
lcol->g = grayscale;
lcol++;
j++;
} while (j < mp->totloop);
}
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return true;
}
static int vertex_paint_from_weight_exec(bContext *C, wmOperator *UNUSED(op))
{
if (vertex_paint_from_weight(C)) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_from_weight(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Vertex Color from Weight";
ot->idname = "PAINT_OT_vertex_color_from_weight";
ot->description = "Converts active weight into greyscale vertex colors";
/* api callback */
ot->exec = vertex_paint_from_weight_exec;
ot->poll = vertex_weight_paint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* TODO: invert, alpha */
}

@ -192,14 +192,14 @@ typedef struct {
bool original; bool original;
} SculptSearchSphereData; } SculptSearchSphereData;
void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test); void sculpt_brush_test_init(struct SculptSession *ss, SculptBrushTest *test);
bool sculpt_brush_test(SculptBrushTest *test, const float co[3]); bool sculpt_brush_test(SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3]); bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3]); bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]); bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]);
bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v); bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v);
float tex_strength( float tex_strength(
SculptSession *ss, struct Brush *br, struct SculptSession *ss, struct Brush *br,
const float point[3], const float point[3],
const float len, const float len,
const short vno[3], const short vno[3],

@ -9792,8 +9792,8 @@ void draw_object_backbufsel(
else { else {
Mesh *me = ob->data; Mesh *me = ob->data;
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
/* currently vertex select only supports weight paint */ /* currently vertex select supports weight paint and vertex paint*/
(ob->mode & OB_MODE_WEIGHT_PAINT)) ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
{ {
bbs_mesh_solid_verts(eval_ctx, scene, ob); bbs_mesh_solid_verts(eval_ctx, scene, ob);
} }

@ -314,7 +314,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
PointerRNA meshptr; PointerRNA meshptr;
RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr); RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
if (ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT)) { if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
} }
else { else {

@ -4780,7 +4780,7 @@ void flushTransGraphData(TransInfo *t)
/* if int-values only, truncate to integers */ /* if int-values only, truncate to integers */
if (td->flag & TD_INTVALUES) if (td->flag & TD_INTVALUES)
td2d->loc2d[1] = floorf(td2d->loc[1] + 0.5f); td2d->loc2d[1] = floorf(td2d->loc[1] * inv_unit_scale - tdg->offset + 0.5f);
else else
td2d->loc2d[1] = td2d->loc[1] * inv_unit_scale - tdg->offset; td2d->loc2d[1] = td2d->loc[1] * inv_unit_scale - tdg->offset;

@ -84,7 +84,7 @@ static const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
/* normal */ /* normal */
{GL_ARRAY_BUFFER, 4}, /* we copy 3 shorts per normal but we add a fourth for alignment */ {GL_ARRAY_BUFFER, 4}, /* we copy 3 shorts per normal but we add a fourth for alignment */
/* mcol */ /* mcol */
{GL_ARRAY_BUFFER, 3}, {GL_ARRAY_BUFFER, 4},
/* uv */ /* uv */
{GL_ARRAY_BUFFER, 2}, {GL_ARRAY_BUFFER, 2},
/* uv for texpaint */ /* uv for texpaint */
@ -691,7 +691,7 @@ void GPU_color_setup(DerivedMesh *dm, int colType)
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->colors->id); glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->colors->id);
glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
GLStates |= GPU_BUFFER_COLOR_STATE; GLStates |= GPU_BUFFER_COLOR_STATE;
} }

@ -49,7 +49,7 @@
#include "IMB_imbuf.h" #include "IMB_imbuf.h"
#ifdef DEBUG_MESSAGES #ifdef DEBUG_MESSAGES
# if defined __GNUC__ || defined __sun # if defined __GNUC__
# define PRINT(format, args ...) printf(format, ##args) # define PRINT(format, args ...) printf(format, ##args)
# else # else
# define PRINT(format, ...) printf(__VA_ARGS__) # define PRINT(format, ...) printf(__VA_ARGS__)

@ -318,6 +318,18 @@ enum {
PAINT_BLEND_DARKEN = 6, PAINT_BLEND_DARKEN = 6,
PAINT_BLEND_AVERAGE = 7, PAINT_BLEND_AVERAGE = 7,
PAINT_BLEND_SMEAR = 8, PAINT_BLEND_SMEAR = 8,
PAINT_BLEND_COLORDODGE = 9,
PAINT_BLEND_DIFFERENCE = 10,
PAINT_BLEND_SCREEN = 11,
PAINT_BLEND_HARDLIGHT = 12,
PAINT_BLEND_OVERLAY = 13,
PAINT_BLEND_SOFTLIGHT = 14,
PAINT_BLEND_EXCLUSION = 15,
PAINT_BLEND_LUMINOCITY = 16,
PAINT_BLEND_SATURATION = 17,
PAINT_BLEND_HUE = 18,
PAINT_BLEND_ALPHA_SUB = 19,
PAINT_BLEND_ALPHA_ADD = 20,
}; };
typedef enum { typedef enum {

@ -1219,7 +1219,7 @@ StructRNA *ID_code_to_RNA_type(short idcode);
} (void)0 } (void)0
/* macro which inserts the function name */ /* macro which inserts the function name */
#if defined __GNUC__ || defined __sun #if defined __GNUC__
# define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args) # define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args)
#else #else
# define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__) # define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__)

@ -94,8 +94,21 @@ EnumPropertyItem rna_enum_brush_vertex_tool_items[] = {
{PAINT_BLEND_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", "Blur the color with surrounding values"}, {PAINT_BLEND_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", "Blur the color with surrounding values"},
{PAINT_BLEND_LIGHTEN, "LIGHTEN", ICON_BRUSH_LIGHTEN, "Lighten", "Use lighten blending mode while painting"}, {PAINT_BLEND_LIGHTEN, "LIGHTEN", ICON_BRUSH_LIGHTEN, "Lighten", "Use lighten blending mode while painting"},
{PAINT_BLEND_DARKEN, "DARKEN", ICON_BRUSH_DARKEN, "Darken", "Use darken blending mode while painting"}, {PAINT_BLEND_DARKEN, "DARKEN", ICON_BRUSH_DARKEN, "Darken", "Use darken blending mode while painting"},
{PAINT_BLEND_AVERAGE, "AVERAGE", ICON_BRUSH_BLUR, "Average", "Use average blending mode while painting" }, {PAINT_BLEND_AVERAGE, "AVERAGE", ICON_BRUSH_BLUR, "Average", "Use average blending mode while painting"},
{PAINT_BLEND_SMEAR, "SMEAR", ICON_BRUSH_BLUR, "Smear", "Use smear blending mode while painting" }, {PAINT_BLEND_SMEAR, "SMEAR", ICON_BRUSH_BLUR, "Smear", "Use smear blending mode while painting"},
{PAINT_BLEND_COLORDODGE, "COLORDODGE", ICON_BRUSH_BLUR, "Color Dodge", "Use color dodge blending mode while painting" },
{PAINT_BLEND_DIFFERENCE, "DIFFERENCE", ICON_BRUSH_BLUR, "Difference", "Use difference blending mode while painting"},
{PAINT_BLEND_SCREEN, "SCREEN", ICON_BRUSH_BLUR, "Screen", "Use screen blending mode while painting"},
{PAINT_BLEND_HARDLIGHT, "HARDLIGHT", ICON_BRUSH_BLUR, "Hardlight", "Use hardlight blending mode while painting"},
{PAINT_BLEND_OVERLAY, "OVERLAY", ICON_BRUSH_BLUR, "Overlay", "Use overlay blending mode while painting"},
{PAINT_BLEND_SOFTLIGHT, "SOFTLIGHT", ICON_BRUSH_BLUR, "Softlight", "Use softlight blending mode while painting"},
{PAINT_BLEND_EXCLUSION, "EXCLUSION", ICON_BRUSH_BLUR, "Exclusion", "Use exclusion blending mode while painting"},
{PAINT_BLEND_LUMINOCITY, "LUMINOCITY", ICON_BRUSH_BLUR, "Luminocity", "Use luminocity blending mode while painting"},
{PAINT_BLEND_SATURATION, "SATURATION", ICON_BRUSH_BLUR, "Saturation", "Use saturation blending mode while painting"},
{PAINT_BLEND_HUE, "HUE", ICON_BRUSH_BLUR, "Hue", "Use hue blending mode while painting"},
{PAINT_BLEND_ALPHA_SUB, "ERASE_ALPHA", 0, "Erase Alpha", "Erase alpha while painting"},
{PAINT_BLEND_ALPHA_ADD, "ADD_ALPHA", 0, "Add Alpha", "Add alpha while painting"},
{0, NULL, 0, NULL, NULL} {0, NULL, 0, NULL, NULL}
}; };
@ -1266,7 +1279,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Restore Mesh", "Allow a single dot to be carefully positioned"); RNA_def_property_ui_text(prop, "Restore Mesh", "Allow a single dot to be carefully positioned");
RNA_def_property_update(prop, 0, "rna_Brush_update"); RNA_def_property_update(prop, 0, "rna_Brush_update");
/* only for projection paint, TODO, other paint modes */ /* only for projection paint & vertex paint, TODO, other paint modes */
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_LOCK_ALPHA); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_LOCK_ALPHA);
RNA_def_property_ui_text(prop, "Alpha", "When this is disabled, lock alpha while painting"); RNA_def_property_ui_text(prop, "Alpha", "When this is disabled, lock alpha while painting");

@ -608,12 +608,14 @@ static void rna_MeshColor_color1_set(PointerRNA *ptr, const float *values)
(&mcol[0].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[0].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f);
(&mcol[0].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[0].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f);
(&mcol[0].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); (&mcol[0].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f);
(&mcol[0].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f);
} }
static void rna_MeshColor_color2_get(PointerRNA *ptr, float *values) static void rna_MeshColor_color2_get(PointerRNA *ptr, float *values)
{ {
MCol *mcol = (MCol *)ptr->data; MCol *mcol = (MCol *)ptr->data;
values[3] = (&mcol[1].r)[3] / 255.0f;
values[2] = (&mcol[1].r)[0] / 255.0f; values[2] = (&mcol[1].r)[0] / 255.0f;
values[1] = (&mcol[1].r)[1] / 255.0f; values[1] = (&mcol[1].r)[1] / 255.0f;
values[0] = (&mcol[1].r)[2] / 255.0f; values[0] = (&mcol[1].r)[2] / 255.0f;
@ -626,12 +628,14 @@ static void rna_MeshColor_color2_set(PointerRNA *ptr, const float *values)
(&mcol[1].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[1].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f);
(&mcol[1].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[1].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f);
(&mcol[1].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); (&mcol[1].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f);
(&mcol[1].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f);
} }
static void rna_MeshColor_color3_get(PointerRNA *ptr, float *values) static void rna_MeshColor_color3_get(PointerRNA *ptr, float *values)
{ {
MCol *mcol = (MCol *)ptr->data; MCol *mcol = (MCol *)ptr->data;
values[3] = (&mcol[2].r)[3] / 255.0f;
values[2] = (&mcol[2].r)[0] / 255.0f; values[2] = (&mcol[2].r)[0] / 255.0f;
values[1] = (&mcol[2].r)[1] / 255.0f; values[1] = (&mcol[2].r)[1] / 255.0f;
values[0] = (&mcol[2].r)[2] / 255.0f; values[0] = (&mcol[2].r)[2] / 255.0f;
@ -644,6 +648,7 @@ static void rna_MeshColor_color3_set(PointerRNA *ptr, const float *values)
(&mcol[2].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[2].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f);
(&mcol[2].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[2].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f);
(&mcol[2].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); (&mcol[2].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f);
(&mcol[2].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f);
} }
static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values) static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values)
@ -653,6 +658,7 @@ static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values)
values[2] = (&mcol[3].r)[0] / 255.0f; values[2] = (&mcol[3].r)[0] / 255.0f;
values[1] = (&mcol[3].r)[1] / 255.0f; values[1] = (&mcol[3].r)[1] / 255.0f;
values[0] = (&mcol[3].r)[2] / 255.0f; values[0] = (&mcol[3].r)[2] / 255.0f;
values[3] = (&mcol[3].r)[3] / 255.0f;
} }
static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values) static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values)
@ -662,6 +668,7 @@ static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values)
(&mcol[3].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[3].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f);
(&mcol[3].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[3].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f);
(&mcol[3].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); (&mcol[3].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f);
(&mcol[3].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f);
} }
static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values) static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values)
@ -671,6 +678,7 @@ static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values)
values[0] = (&mcol->r)[0] / 255.0f; values[0] = (&mcol->r)[0] / 255.0f;
values[1] = (&mcol->r)[1] / 255.0f; values[1] = (&mcol->r)[1] / 255.0f;
values[2] = (&mcol->r)[2] / 255.0f; values[2] = (&mcol->r)[2] / 255.0f;
values[3] = (&mcol->r)[3] / 255.0f;
} }
static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values) static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values)
@ -680,6 +688,7 @@ static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values)
(&mcol->r)[0] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol->r)[0] = round_fl_to_uchar_clamp(values[0] * 255.0f);
(&mcol->r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol->r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f);
(&mcol->r)[2] = round_fl_to_uchar_clamp(values[2] * 255.0f); (&mcol->r)[2] = round_fl_to_uchar_clamp(values[2] * 255.0f);
(&mcol->r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f);
} }
static int rna_Mesh_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info)) static int rna_Mesh_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info))
@ -2454,28 +2463,28 @@ static void rna_def_mcol(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_MeshColor_path"); RNA_def_struct_path_func(srna, "rna_MeshColor_path");
prop = RNA_def_property(srna, "color1", PROP_FLOAT, PROP_COLOR); prop = RNA_def_property(srna, "color1", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3); RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color1_get", "rna_MeshColor_color1_set", NULL); RNA_def_property_float_funcs(prop, "rna_MeshColor_color1_get", "rna_MeshColor_color1_set", NULL);
RNA_def_property_ui_text(prop, "Color 1", ""); RNA_def_property_ui_text(prop, "Color 1", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "color2", PROP_FLOAT, PROP_COLOR); prop = RNA_def_property(srna, "color2", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3); RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color2_get", "rna_MeshColor_color2_set", NULL); RNA_def_property_float_funcs(prop, "rna_MeshColor_color2_get", "rna_MeshColor_color2_set", NULL);
RNA_def_property_ui_text(prop, "Color 2", ""); RNA_def_property_ui_text(prop, "Color 2", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "color3", PROP_FLOAT, PROP_COLOR); prop = RNA_def_property(srna, "color3", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3); RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color3_get", "rna_MeshColor_color3_set", NULL); RNA_def_property_float_funcs(prop, "rna_MeshColor_color3_get", "rna_MeshColor_color3_set", NULL);
RNA_def_property_ui_text(prop, "Color 3", ""); RNA_def_property_ui_text(prop, "Color 3", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "color4", PROP_FLOAT, PROP_COLOR); prop = RNA_def_property(srna, "color4", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3); RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color4_get", "rna_MeshColor_color4_set", NULL); RNA_def_property_float_funcs(prop, "rna_MeshColor_color4_get", "rna_MeshColor_color4_set", NULL);
RNA_def_property_ui_text(prop, "Color 4", ""); RNA_def_property_ui_text(prop, "Color 4", "");
@ -2525,7 +2534,7 @@ static void rna_def_mloopcol(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_MeshColor_path"); RNA_def_struct_path_func(srna, "rna_MeshColor_path");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3); RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshLoopColor_color_get", "rna_MeshLoopColor_color_set", NULL); RNA_def_property_float_funcs(prop, "rna_MeshLoopColor_color_get", "rna_MeshLoopColor_color_set", NULL);
RNA_def_property_ui_text(prop, "Color", ""); RNA_def_property_ui_text(prop, "Color", "");

@ -921,49 +921,11 @@ elseif(APPLE)
# python # python
if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK) if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
if(WITH_CXX11) # Copy the python libs into the install directory
# Copy the python libs into the install directory install_dir(
install_dir( ${PYTHON_LIBPATH}
${PYTHON_LIBPATH} ${TARGETDIR_VER}/python/lib
${TARGETDIR_VER}/python/lib )
)
else()
# the python zip is first extracted as part of the build process,
# and then later installed as part of make install. this is much
# quicker, and means we can easily exclude files on copy
# Not needed for PYTHON_MODULE or WEB_PLUGIN due uses Pyhon framework
# use a hash of the .zip path to handle switching between different
# lib directories without needing a clean build
string(SHA1 PYTHON_ZIP_HASH ${LIBDIR}/release/${PYTHON_ZIP})
set(PYTHON_EXTRACT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_ZIP_HASH}/python)
add_custom_target(
extractpyzip
DEPENDS ${PYTHON_EXTRACT_DIR})
set(PYTHON_ZIP "python_${CMAKE_OSX_ARCHITECTURES}.zip")
add_custom_command(
OUTPUT ${PYTHON_EXTRACT_DIR}
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PYTHON_EXTRACT_DIR}/"
COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_EXTRACT_DIR}/"
COMMAND ${CMAKE_COMMAND} -E chdir "${PYTHON_EXTRACT_DIR}/"
${CMAKE_COMMAND} -E tar xzfv "${LIBDIR}/release/${PYTHON_ZIP}"
DEPENDS ${LIBDIR}/release/${PYTHON_ZIP})
add_dependencies(blender extractpyzip)
# copy extracted python files
install_dir(
${PYTHON_EXTRACT_DIR}
\${TARGETDIR_VER}
)
# copy site-packages files
install_dir(
${LIBDIR}/release/site-packages
\${TARGETDIR_VER}/python/lib/python${PYTHON_VERSION}
)
endif()
install(DIRECTORY ${LIBDIR}/python/bin install(DIRECTORY ${LIBDIR}/python/bin
DESTINATION ${TARGETDIR_VER}/python DESTINATION ${TARGETDIR_VER}/python
@ -1018,27 +980,11 @@ elseif(APPLE)
# python # python
if(WITH_PYTHON AND NOT WITH_PYTHON_FRAMEWORK) if(WITH_PYTHON AND NOT WITH_PYTHON_FRAMEWORK)
if(WITH_CXX11) # Copy the python libs into the install directory
# Copy the python libs into the install directory install_dir(
install_dir( ${PYTHON_LIBPATH}
${PYTHON_LIBPATH} ${PLAYER_TARGETDIR_VER}/python/lib
${PLAYER_TARGETDIR_VER}/python/lib )
)
else()
add_custom_command(
OUTPUT ${PYTHON_EXTRACT_DIR}
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PYTHON_EXTRACT_DIR}/"
COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_EXTRACT_DIR}/"
COMMAND ${CMAKE_COMMAND} -E chdir "${PYTHON_EXTRACT_DIR}/"
${CMAKE_COMMAND} -E tar xzfv "${LIBDIR}/release/${PYTHON_ZIP}"
DEPENDS ${LIBDIR}/release/${PYTHON_ZIP})
# copy extracted python files
install_dir(
${PYTHON_EXTRACT_DIR}
\${PLAYER_TARGETDIR_VER}
)
endif()
endif() endif()
endif() endif()

@ -40,11 +40,6 @@
# ifdef _XOPEN_SOURCE # ifdef _XOPEN_SOURCE
# undef _XOPEN_SOURCE # undef _XOPEN_SOURCE
# endif # endif
# if defined(__sun) || defined(sun)
# if defined(_XPG4)
# undef _XPG4
# endif
# endif
# include <Python.h> # include <Python.h>
extern "C" { extern "C" {