diff options
75 files changed, 764 insertions, 338 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e623d587bc..891539e0b34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -673,8 +673,11 @@ if(NOT WITH_BOOST) elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_AUDASPACE OR WITH_INTERNATIONAL OR WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_MOD_BOOLEAN) # Keep enabled else() - # Enabled but we don't need it - set(WITH_BOOST OFF) + # New dependency graph needs either Boost or C++11 for function bindings. + if(NOT USE_CPP11) + # Enabled but we don't need it + set(WITH_BOOST OFF) + endif() endif() # auto enable openimageio for cycles @@ -1285,6 +1288,10 @@ elseif(WIN32) set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib") + # Ignore meaningless for us linker warnings. + set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /ignore:4049 /ignore:4217 /ignore:4221") + set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") + # MSVC only, Mingw doesnt need if(CMAKE_CL_64) set(PLATFORM_LINKFLAGS "/MACHINE:X64 /OPT:NOREF ${PLATFORM_LINKFLAGS}") @@ -2169,7 +2176,7 @@ elseif(APPLE) set(OPENVDB_INCLUDE_DIRS ${OPENVDB}/include) set(TBB_INCLUDE_DIRS ${LIBDIR}/tbb/include) set(TBB_LIBRARIES ${LIBDIR}/tbb/lib/libtbb.a) - set(OPENVDB_LIBRARIES openvdb ${TBB_LIBRARIES}) + set(OPENVDB_LIBRARIES openvdb blosc ${TBB_LIBRARIES}) set(OPENVDB_LIBPATH ${LIBDIR}/openvdb/lib) set(OPENVDB_DEFINITIONS) endif() diff --git a/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst b/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst index 17f54031ec3..ece2a65af71 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst @@ -89,6 +89,15 @@ base class --- :class:`PyObjectPlus` :return: the material's shader :rtype: :class:`BL_Shader` + .. method:: getTextureBindcode(textureslot) + + Returns the material's texture OpenGL bind code/id/number/name. + + :arg textureslot: Specifies the texture slot number + :type textureslot: integer + :return: the material's texture OpenGL bind code/id/number/name + :rtype: integer + .. attribute:: alpha The material's alpha transparency. diff --git a/extern/carve/include/carve/mesh_simplify.hpp b/extern/carve/include/carve/mesh_simplify.hpp index 40c90eb763d..9c7371b3df5 100644 --- a/extern/carve/include/carve/mesh_simplify.hpp +++ b/extern/carve/include/carve/mesh_simplify.hpp @@ -1341,9 +1341,9 @@ namespace carve { carve::geom::vector<3> v_best = vert->v; double d_best = 0.0; - for (size_t axes = 0; axes < 8; ++axes) { + for (int axes = 0; axes < 8; ++axes) { carve::geom::vector<3> v = vert->v; - for (size_t N = 0; N < 3; ++N) { + for (int N = 0; N < 3; ++N) { if (constraint & (1 << N)) continue; if (axes & (1<<N)) { v.v[N] = ceil(v.v[N] / grid) * grid; @@ -1471,9 +1471,9 @@ namespace carve { std::vector<heapval_t> heap; point_enumerator_t(vector_t _origin, int _base, int _n_dp) : origin(_origin), rounding_fac(pow((double)_base, _n_dp)), last(-1.0, _origin), heap() { - for (size_t i = 0; i < (1 << 3); ++i) { + for (int i = 0; i < (1 << 3); ++i) { vector_t t = origin; - for (size_t j = 0; j < 3; ++j) { + for (int j = 0; j < 3; ++j) { if (i & (1U << j)) { t[j] = ceil(t[j] * rounding_fac) / rounding_fac; } else { diff --git a/extern/gflags/src/windows_port.h b/extern/gflags/src/windows_port.h index 8b870ecb138..1f546996783 100644 --- a/extern/gflags/src/windows_port.h +++ b/extern/gflags/src/windows_port.h @@ -69,8 +69,10 @@ extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size, extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size, const char *format, va_list ap); #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) +#if defined(_MSC_VER) && (_MSC_VER < 1400) #define va_copy(dst, src) (dst) = (src) #endif +#endif #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */ #ifdef _MSC_VER @@ -109,7 +111,7 @@ inline void setenv(const char* name, const char* value, int) { #define unlink _unlink #endif -#if !(defined(_MSC_VER) && _MSC_VER >= 1900) +#if !(defined(_MSC_VER) && _MSC_VER >= 1400) #define PRId32 "d" #define PRIu32 "u" #define PRId64 "I64d" diff --git a/extern/glog/src/config_freebsd.h b/extern/glog/src/config_freebsd.h index afa4262b022..d97b7e16c61 100644 --- a/extern/glog/src/config_freebsd.h +++ b/extern/glog/src/config_freebsd.h @@ -14,7 +14,7 @@ #define HAVE_DLFCN_H /* Define to 1 if you have the <execinfo.h> header file. */ -#define HAVE_EXECINFO_H +/* #undef HAVE_EXECINFO_H */ /* Define if you have the `fcntl' function */ #define HAVE_FCNTL @@ -26,10 +26,10 @@ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `pthread' library (-lpthread). */ -/* #undef HAVE_LIBPTHREAD */ +#define HAVE_LIBPTHREAD /* Define to 1 if you have the <libunwind.h> header file. */ -#define HAVE_LIBUNWIND_H +/* #undef HAVE_LIBUNWIND_H */ /* define if you have google gflags library */ #define HAVE_LIB_GFLAGS @@ -65,13 +65,13 @@ #define HAVE_PWRITE /* define if the compiler implements pthread_rwlock_* */ -/* #undef HAVE_RWLOCK */ +#define HAVE_RWLOCK 1 /* Define if you have the 'sigaction' function */ #define HAVE_SIGACTION /* Define if you have the `sigaltstack' function */ -/* #undef HAVE_SIGALTSTACK */ +#define HAVE_SIGALTSTACK 1 /* Define to 1 if you have the <stdint.h> header file. */ #define HAVE_STDINT_H 1 @@ -86,7 +86,7 @@ #define HAVE_STRING_H /* Define to 1 if you have the <syscall.h> header file. */ -#define HAVE_SYSCALL_H +/* #undef HAVE_SYSCALL_H */ /* Define to 1 if you have the <syslog.h> header file. */ #define HAVE_SYSLOG_H @@ -104,7 +104,7 @@ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the <sys/ucontext.h> header file. */ -/* #undef HAVE_SYS_UCONTEXT_H */ +#define HAVE_SYS_UCONTEXT_H /* Define to 1 if you have the <sys/utsname.h> header file. */ #define HAVE_SYS_UTSNAME_H @@ -166,7 +166,7 @@ #define SIZEOF_VOID_P 8 /* Define to 1 if you have the ANSI C header files. */ -/* #undef STDC_HEADERS */ +#define STDC_HEADERS 1 /* the namespace where STL code like vector<> is defined */ #define STL_NAMESPACE std @@ -184,3 +184,9 @@ #define _START_GOOGLE_NAMESPACE_ namespace google { #define GOOGLE_GLOG_DLL_DECL + +/* isn't getting defined by configure script when clang compilers are used + and cuases compilation errors in stactrace/unwind modules */ +#ifdef __clang__ +# define NO_FRAME_POINTER +#endif diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 29eca865384..5f5a3609ded 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -378,6 +378,7 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi /* Reject invalid value */ if(!isfinite(sum)) { + kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!"); L_sum = make_float3(0.0f, 0.0f, 0.0f); L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f); @@ -445,8 +446,10 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi /* Reject invalid value */ float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z); - if(!isfinite(sum)) + if(!isfinite(sum)) { + kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!"); L_sum = make_float3(0.0f, 0.0f, 0.0f); + } return L_sum; } diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index 7314af35eb9..8e7a2c1b62b 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -16,8 +16,6 @@ CCL_NAMESPACE_BEGIN -#undef USE_BAKE_JITTER - #ifndef __NO_BAKING__ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng, @@ -150,7 +148,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian #if defined(__EMISSION__) /* direct light */ if(kernel_data.integrator.use_direct_light) { - bool all = kernel_data.integrator.sample_all_lights_direct; + int all = kernel_data.integrator.sample_all_lights_direct; kernel_branched_path_surface_connect_light(kg, &rng, sd, &state, throughput, 1.0f, &L_sample, all); } @@ -180,15 +178,16 @@ ccl_device bool is_aa_pass(ShaderEvalType type) /* this helps with AA but it's not the real solution as it does not AA the geometry * but it's better than nothing, thus committed */ -ccl_device_inline float bake_clamp_mirror_repeat(float u) +ccl_device_inline float bake_clamp_mirror_repeat(float u, float max) { /* use mirror repeat (like opengl texture) so that if the barycentric * coordinate goes past the end of the triangle it is not always clamped * to the same value, gives ugly patterns */ + u /= max; float fu = floorf(u); u = u - fu; - return (((int)fu) & 1)? 1.0f - u: u; + return ((((int)fu) & 1)? 1.0f - u: u) * max; } ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg, @@ -282,7 +281,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, /* random number generator */ RNG rng = cmj_hash(offset + i, kernel_data.integrator.seed); -#ifdef USE_BAKE_JITTER float filter_x, filter_y; if(sample == 0) { filter_x = filter_y = 0.5f; @@ -293,10 +291,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, /* subpixel u/v offset */ if(sample > 0) { - u = bake_clamp_mirror_repeat(u + dudx*(filter_x - 0.5f) + dudy*(filter_y - 0.5f)); - v = bake_clamp_mirror_repeat(v + dvdx*(filter_x - 0.5f) + dvdy*(filter_y - 0.5f)); + u = bake_clamp_mirror_repeat(u + dudx*(filter_x - 0.5f) + dudy*(filter_y - 0.5f), 1.0f); + v = bake_clamp_mirror_repeat(v + dvdx*(filter_x - 0.5f) + dvdy*(filter_y - 0.5f), 1.0f - u); } -#endif /* triangle */ int shader; diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 650e3b047f0..732c6e2fc21 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -141,7 +141,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED; if(volume_segment.closure_flag & SD_SCATTER) { - bool all = kernel_data.integrator.sample_all_lights_indirect; + int all = kernel_data.integrator.sample_all_lights_indirect; /* direct light sampling */ kernel_branched_path_volume_connect_light(kg, @@ -374,7 +374,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #if defined(__EMISSION__) && defined(__BRANCHED_PATH__) if(kernel_data.integrator.use_direct_light) { - bool all = kernel_data.integrator.sample_all_lights_indirect; + int all = kernel_data.integrator.sample_all_lights_indirect; kernel_branched_path_surface_connect_light(kg, rng, &sd, @@ -705,7 +705,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED; if(volume_segment.closure_flag & SD_SCATTER) { - bool all = false; + int all = false; /* direct light sampling */ kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 7c685e3b191..13ae4cf669b 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -194,7 +194,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, #ifdef __EMISSION__ /* direct light */ if(kernel_data.integrator.use_direct_light) { - bool all = kernel_data.integrator.sample_all_lights_direct; + int all = kernel_data.integrator.sample_all_lights_direct; kernel_branched_path_surface_connect_light( kg, rng, @@ -297,7 +297,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in if(volume_segment.closure_flag & SD_SCATTER) { volume_segment.sampling_method = volume_stack_sampling_method(kg, state.volume_stack); - bool all = kernel_data.integrator.sample_all_lights_direct; + int all = kernel_data.integrator.sample_all_lights_direct; kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L, all, &volume_ray, &volume_segment); @@ -517,7 +517,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in #ifdef __EMISSION__ /* direct light */ if(kernel_data.integrator.use_direct_light) { - bool all = kernel_data.integrator.sample_all_lights_direct; + int all = kernel_data.integrator.sample_all_lights_direct; kernel_branched_path_surface_connect_light(kg, rng, &sd, &hit_state, throughput, 1.0f, &L, all); } diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index 6e94cc5762e..f2204a524fd 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -19,8 +19,8 @@ CCL_NAMESPACE_BEGIN #if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) /* branched path tracing: connect path directly to position on one or more lights and add it to L */ -ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RNG *rng, - ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, bool sample_all_lights) +ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RNG *rng, + ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, int sample_all_lights) { #ifdef __EMISSION__ /* sample illumination from lights to find path contribution */ diff --git a/intern/cycles/kernel/svm/svm_light_path.h b/intern/cycles/kernel/svm/svm_light_path.h index 94c9fddfab8..f35ea05048b 100644 --- a/intern/cycles/kernel/svm/svm_light_path.h +++ b/intern/cycles/kernel/svm/svm_light_path.h @@ -62,7 +62,10 @@ ccl_device void svm_node_light_falloff(ShaderData *sd, float *stack, uint4 node) if(smooth > 0.0f) { float squared = ccl_fetch(sd, ray_length)*ccl_fetch(sd, ray_length); - strength *= squared/(smooth + squared); + /* Distant lamps set the ray length to FLT_MAX, which causes squared to overflow. */ + if(isfinite(squared)) { + strength *= squared/(smooth + squared); + } } stack_store_float(stack, out_offset, strength); diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index f3fd1b31e31..cdbc37fd32c 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -24,10 +24,6 @@ #ifndef __KERNEL_OPENCL__ -#ifdef _MSC_VER -# define _USE_MATH_DEFINES -#endif - #include <float.h> #include <math.h> #include <stdio.h> diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index 78115b325df..bcfa24b06a8 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -447,7 +447,7 @@ AVRational av_get_r_frame_rate_compat(const AVStream *stream) #endif /* Since FFmpeg-1.1 this constant have AV_ prefix. */ -#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 13, 100) +#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 3, 100) # define AV_PIX_FMT_BGR32 PIX_FMT_BGR32 # define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P # define AV_PIX_FMT_BGRA PIX_FMT_BGRA diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp index 65d5e650251..252ea775329 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp @@ -34,6 +34,7 @@ #include "GHOST_DisplayManagerWin32.h" #include "GHOST_Debug.h" +#undef _WIN32_WINNT #define _WIN32_WINNT 0x501 // require Windows XP or newer #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h index b63d20bfcbd..5685a57eba8 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.h +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h @@ -37,6 +37,7 @@ #error WIN32 only! #endif // WIN32 +#undef _WIN32_WINNT #define _WIN32_WINNT 0x501 // require Windows XP or newer #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 0a8837294db..3085fde610b 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -38,7 +38,8 @@ #endif // WIN32 #ifndef __MINGW64__ -#define _WIN32_WINNT 0x501 // require Windows XP or newer +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x501 // require Windows XP or newer #endif #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/intern/ghost/intern/GHOST_TaskbarWin32.h b/intern/ghost/intern/GHOST_TaskbarWin32.h index 04196701fe9..6fcff297237 100644 --- a/intern/ghost/intern/GHOST_TaskbarWin32.h +++ b/intern/ghost/intern/GHOST_TaskbarWin32.h @@ -9,7 +9,8 @@ #endif // WIN32 #ifndef __MINGW64__ -#define _WIN32_WINNT 0x501 // require Windows XP or newer +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x501 // require Windows XP or newer #endif #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index bf5590077ef..82536a74159 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -29,7 +29,14 @@ #include <sstream> #include <string.h> +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4251 4275) +#endif #include <OpenColorIO/OpenColorIO.h> +#ifdef _MSC_VER +# pragma warning(pop) +#endif using namespace OCIO_NAMESPACE; diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 42bd20d2eb1..bf91ea143da 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -39,7 +39,15 @@ #include "glew-mx.h" +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4251 4275) +#endif #include <OpenColorIO/OpenColorIO.h> +#ifdef _MSC_VER +# pragma warning(pop) +#endif + using namespace OCIO_NAMESPACE; diff --git a/release/environment-macosx b/release/environment-macosx deleted file mode 100644 index d41d5ec485f..00000000000 --- a/release/environment-macosx +++ /dev/null @@ -1,18 +0,0 @@ -# This is a Blender Environment Variable config file. -# -# Comment lines start with "#", other lines will be split at the "=" -# and the part before will be used as env var name and the part after -# as env var value. The value can make reference to previous or -# prelaunch variables with "${}" and the content will be replaced. -# Once set, values of variables will not be overwritten. -# -# BLENDER_SHARE should be /Library/Application Support/Blender for typical installs. -# BLENDER_VERSION will be set by the program before processing this file. -BLENDER_USER_BASE=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION} -BLENDER_SYSTEM_BASE=${BLENDER_SHARE}/${BLENDER_VERSION} -BLENDER_USER_DATAFILES=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/datafiles -BLENDER_SYSTEM_DATAFILES=${BLENDER_SHARE}/${BLENDER_VERSION}/datafiles -BLENDER_USER_PY=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/py -BLENDER_SYSTEM_PY=${BLENDER_SHARE}/${BLENDER_VERSION}/py -BLENDER_USER_PLUGINS=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/plugins -BLENDER_SYSTEM_PLUGINS=${BLENDER_SHARE}/${BLENDER_VERSION}/plugins diff --git a/release/environment-mswindows b/release/environment-mswindows deleted file mode 100644 index 41308533e0b..00000000000 --- a/release/environment-mswindows +++ /dev/null @@ -1,18 +0,0 @@ -# This is a Blender Environment Variable config file. -# -# Comment lines start with "#", other lines will be split at the "=" -# and the part before will be used as env var name and the part after -# as env var value. The value can make reference to previous or -# prelaunch variables with "%%" and the content will be replaced. -# Once set, values of variables will not be overwritten. -# -# BLENDER_SHARE should be COMMON_APPDATA\\Blender Foundation\\Blender for typical installs. -# BLENDER_VERSION will be set by the program before processing this file. -BLENDER_USER_BASE=%USERPROFILE%\\Blender Foundation\\Blender\\%BLENDER_VERSION% -BLENDER_SYSTEM_BASE=%BLENDER_SHARE%\\%BLENDER_VERSION% -BLENDER_USER_DATAFILES=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\datafiles -BLENDER_SYSTEM_DATAFILES=%BLENDER_SHARE%\\%BLENDER_VERSION%\\datafiles -BLENDER_USER_PY=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\py -BLENDER_SYSTEM_PY=%BLENDER_SHARE%\\%BLENDER_VERSION%\\py -BLENDER_USER_PLUGINS=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\plugins -BLENDER_SYSTEM_PLUGINS=%BLENDER_SHARE%\\%BLENDER_VERSION%\\plugins diff --git a/release/environment-unix b/release/environment-unix deleted file mode 100644 index 8a13c288306..00000000000 --- a/release/environment-unix +++ /dev/null @@ -1,18 +0,0 @@ -# This is a Blender Environment Variable config file. -# -# Comment lines start with "#", other lines will be split at the "=" -# and the part before will be used as env var name and the part after -# as env var value. The value can make reference to previous or -# prelaunch variables with "${}" and the content will be replaced. -# Once set, values of variables will not be overwritten. -# -# BLENDER_SHARE should be /usr/share/blender for typical distro installs. -# BLENDER_VERSION will be set by the program before processing this file. -BLENDER_USER_BASE=${HOME}/.blender/${BLENDER_VERSION} -BLENDER_SYSTEM_BASE=${BLENDER_SHARE}/${BLENDER_VERSION} -BLENDER_USER_DATAFILES=${HOME}/.blender/${BLENDER_VERSION}/datafiles -BLENDER_SYSTEM_DATAFILES=${BLENDER_SHARE}/${BLENDER_VERSION}/datafiles -BLENDER_USER_PY=${HOME}/.blender/${BLENDER_VERSION}/py -BLENDER_SYSTEM_PY=${BLENDER_SHARE}/${BLENDER_VERSION}/py -BLENDER_USER_PLUGINS=${HOME}/.blender/${BLENDER_VERSION}/plugins -BLENDER_SYSTEM_PLUGINS=${BLENDER_SHARE}/${BLENDER_VERSION}/plugins diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py index 21d1959a037..2ca7a7997a5 100644 --- a/release/scripts/modules/rna_keymap_ui.py +++ b/release/scripts/modules/rna_keymap_ui.py @@ -70,7 +70,7 @@ def draw_km(display_keymaps, kc, km, children, layout, level): col = _indented_layout(layout, level) - row = col.row() + row = col.row(align=True) row.prop(km, "show_expanded_children", text="", emboss=False) row.label(text=km.name, text_ctxt=i18n_contexts.id_windowmanager) @@ -89,7 +89,7 @@ def draw_km(display_keymaps, kc, km, children, layout, level): # Put the Parent key map's entries in a 'global' sub-category # equal in hierarchy to the other children categories subcol = _indented_layout(col, level + 1) - subrow = subcol.row() + subrow = subcol.row(align=True) subrow.prop(km, "show_expanded_items", text="", emboss=False) subrow.label(text=iface_("%s (Global)") % km.name, translate=False) else: @@ -97,25 +97,25 @@ def draw_km(display_keymaps, kc, km, children, layout, level): # Key Map items if km.show_expanded_items: + kmi_level = level + 3 if children else level + 1 for kmi in km.keymap_items: - draw_kmi(display_keymaps, kc, km, kmi, col, level + 1) + draw_kmi(display_keymaps, kc, km, kmi, col, kmi_level) # "Add New" at end of keymap item list - col = _indented_layout(col, level + 1) - subcol = col.split(percentage=0.2).column() + subcol = _indented_layout(col, kmi_level) + subcol = subcol.split(percentage=0.2).column() subcol.operator("wm.keyitem_add", text="Add New", text_ctxt=i18n_contexts.id_windowmanager, icon='ZOOMIN') - col.separator() + col.separator() # Child key maps if children: - subcol = col.column() - row = subcol.row() - for entry in children: draw_entry(display_keymaps, entry, col, level + 1) + col.separator() + def draw_kmi(display_keymaps, kc, km, kmi, layout, level): map_type = kmi.map_type @@ -128,7 +128,7 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level): else: box = col.column() - split = box.split(percentage=0.05) + split = box.split(percentage=0.01) # header bar row = split.row() diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index f3575f26890..05817216a54 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -108,10 +108,40 @@ class ANIM_OT_keying_set_export(Operator): - id.bl_rna.name gives a name suitable for UI, with a capitalised first letter, but we need the plural form that's all lower case + - special handling is needed for "nested" ID-blocks + (e.g. nodetree in Material) """ - - idtype_list = ksp.id.bl_rna.name.lower() + "s" - id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name) + if ksp.id.bl_rna.identifier.startswith("ShaderNodeTree"): + # Find material or lamp using this node tree... + id_bpy_path = "bpy.data.nodes[\"%s\"]" + found = False + + for mat in bpy.data.materials: + if mat.node_tree == ksp.id: + id_bpy_path = "bpy.data.materials[\"%s\"].node_tree" % (mat.name) + found = True + break; + + if not found: + for lamp in bpy.data.lamps: + if lamp.node_tree == ksp.id: + id_bpy_path = "bpy.data.lamps[\"%s\"].node_tree" % (lamp.name) + found = True + break; + + if not found: + self.report({'WARN'}, "Could not find material or lamp using Shader Node Tree - %s" % (ksp.id)) + elif ksp.id.bl_rna.identifier.startswith("CompositorNodeTree"): + # Find compositor nodetree using this node tree... + for scene in bpy.data.scenes: + if scene.node_tree == ksp.id: + id_bpy_path = "bpy.data.scenes[\"%s\"].node_tree" % (scene.name) + break; + else: + self.report({'WARN'}, "Could not find scene using Compositor Node Tree - %s" % (ksp.id)) + else: + idtype_list = ksp.id.bl_rna.name.lower() + "s" + id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name) # shorthand ID for the ID-block (as used in the script) short_id = "id_%d" % len(id_to_paths_cache) diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index d29cd18053f..10b4e24efd9 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -208,19 +208,18 @@ class IMAGE_MT_image(Menu): layout.menu("IMAGE_MT_image_invert") if not show_render: - layout.separator() - if not ima.packed_file: + layout.separator() layout.operator("image.pack") # only for dirty && specific image types, perhaps # this could be done in operator poll too if ima.is_dirty: if ima.source in {'FILE', 'GENERATED'} and ima.type != 'OPEN_EXR_MULTILAYER': + if ima.packed_file: + layout.separator() layout.operator("image.pack", text="Pack As PNG").as_png = True - layout.separator() - class IMAGE_MT_image_invert(Menu): bl_label = "Invert" diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index e6302ff7bdc..163458ee0fd 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -559,8 +559,33 @@ class USERPREF_PT_theme(Panel): bl_region_type = 'WINDOW' bl_options = {'HIDE_HEADER'} + # not essential, hard-coded UI delimiters for the theme layout + ui_delimiters = { + 'VIEW_3D': { + "text_grease_pencil", + "text_keyframe", + "speaker", + "freestyle_face_mark", + "split_normal", + "bone_solid", + "paint_curve_pivot", + }, + 'GRAPH_EDITOR': { + "handle_vertex_select", + }, + 'IMAGE_EDITOR': { + "paint_curve_pivot", + }, + 'NODE_EDITOR': { + "layout_node", + }, + 'CLIP_EDITOR': { + "handle_vertex_select", + } + } + @staticmethod - def _theme_generic(split, themedata): + def _theme_generic(split, themedata, theme_area): col = split.column() @@ -587,13 +612,30 @@ class USERPREF_PT_theme(Panel): props_type.setdefault((prop.type, prop.subtype), []).append(prop) + th_delimiters = USERPREF_PT_theme.ui_delimiters.get(theme_area) for props_type, props_ls in sorted(props_type.items()): if props_type[0] == 'POINTER': for i, prop in enumerate(props_ls): theme_generic_recurse(getattr(data, prop.identifier)) else: - for i, prop in enumerate(props_ls): - colsub_pair[i % 2].row().prop(data, prop.identifier) + if th_delimiters is None: + # simple, no delimiters + for i, prop in enumerate(props_ls): + colsub_pair[i % 2].row().prop(data, prop.identifier) + else: + # add hard coded delimiters + i = 0 + for prop in props_ls: + colsub = colsub_pair[i] + colsub.row().prop(data, prop.identifier) + i = (i + 1) % 2 + if prop.identifier in th_delimiters: + if i: + colsub = colsub_pair[1] + colsub.row().label("") + colsub_pair[0].row().label("") + colsub_pair[1].row().label("") + i = 0 theme_generic_recurse(themedata) @@ -864,7 +906,7 @@ class USERPREF_PT_theme(Panel): col.label(text="Widget Label:") self._ui_font_style(col, style.widget_label) else: - self._theme_generic(split, getattr(theme, theme.theme_area.lower())) + self._theme_generic(split, getattr(theme, theme.theme_area.lower()), theme.theme_area) class USERPREF_PT_file(Panel): diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 1c13e42f70d..41726e41176 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -113,6 +113,10 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) gc->max_glyph_height = (int)(((float)font->face->size->metrics.height) / 64.0f); } + /* can happen with size 1 fonts */ + CLAMP_MIN(gc->max_glyph_width, 1); + CLAMP_MIN(gc->max_glyph_height, 1); + gc->p2_width = 0; gc->p2_height = 0; diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index fd566f34f2e..c663458963c 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -32,6 +32,7 @@ struct ImBuf; struct ImagePool; struct Main; struct Scene; +struct UnifiedPaintSettings; // enum CurveMappingPreset; @@ -60,8 +61,9 @@ int BKE_brush_clone_image_set_nr(struct Brush *brush, int nr); int BKE_brush_clone_image_delete(struct Brush *brush); /* jitter */ -void BKE_brush_jitter_pos(const struct Scene *scene, struct Brush *brush, - const float pos[2], float jitterpos[2]); +void BKE_brush_jitter_pos( + const struct Scene *scene, struct Brush *brush, + const float pos[2], float jitterpos[2]); void BKE_brush_randomize_texture_coords(struct UnifiedPaintSettings *ups, bool mask); /* brush curve */ @@ -70,10 +72,12 @@ float BKE_brush_curve_strength_clamped(struct Brush *br, float p, const float le float BKE_brush_curve_strength(struct Brush *br, float p, const float len); /* sampling */ -float BKE_brush_sample_tex_3D(const Scene *scene, struct Brush *br, const float point[3], - float rgba[4], const int thread, struct ImagePool *pool); -float BKE_brush_sample_masktex(const Scene *scene, struct Brush *br, const float point[2], - const int thread, struct ImagePool *pool); +float BKE_brush_sample_tex_3D( + const struct Scene *scene, struct Brush *br, const float point[3], + float rgba[4], const int thread, struct ImagePool *pool); +float BKE_brush_sample_masktex( + const struct Scene *scene, struct Brush *br, const float point[2], + const int thread, struct ImagePool *pool); /* texture */ unsigned int *BKE_brush_gen_texture_cache(struct Brush *br, int half_side, bool use_secondary); @@ -94,9 +98,9 @@ float BKE_brush_unprojected_radius_get(const struct Scene *scene, const struct B void BKE_brush_unprojected_radius_set(struct Scene *scene, struct Brush *brush, float value); float BKE_brush_alpha_get(const struct Scene *scene, const struct Brush *brush); -void BKE_brush_alpha_set(Scene *scene, struct Brush *brush, float alpha); -float BKE_brush_weight_get(const Scene *scene, const struct Brush *brush); -void BKE_brush_weight_set(const Scene *scene, struct Brush *brush, float value); +void BKE_brush_alpha_set(struct Scene *scene, struct Brush *brush, float alpha); +float BKE_brush_weight_get(const struct Scene *scene, const struct Brush *brush); +void BKE_brush_weight_set(const struct Scene *scene, struct Brush *brush, float value); int BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush); int BKE_brush_use_alpha_pressure(const struct Scene *scene, const struct Brush *brush); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 00c84976516..49b380f9a9b 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1500,7 +1500,7 @@ static void cdDM_buffer_copy_uv_texpaint( } } - MEM_freeN(uv_base); + MEM_freeN((void*)uv_base); } /* treat varray_ as an array of MCol, four MCol's per face */ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 8985dd372a6..730d5a93758 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -71,6 +71,7 @@ #include "BKE_action.h" #include "BKE_fcurve.h" #include "BKE_global.h" +#include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_nla.h" @@ -330,7 +331,7 @@ static const char *constraint_adrcodes_to_paths(int adrcode, int *array_index) * NOTE: as we don't have access to the keyblock where the data comes from (for now), * we'll just use numerical indices for now... */ -static char *shapekey_adrcodes_to_paths(int adrcode, int *UNUSED(array_index)) +static char *shapekey_adrcodes_to_paths(ID *id, int adrcode, int *UNUSED(array_index)) { static char buf[128]; @@ -340,8 +341,19 @@ static char *shapekey_adrcodes_to_paths(int adrcode, int *UNUSED(array_index)) BLI_strncpy(buf, "eval_time", sizeof(buf)); } else { + /* Find the name of the ShapeKey (i.e. KeyBlock) to look for */ + Key *key = (Key *)id; + KeyBlock *kb = BKE_keyblock_from_key(key, adrcode); + /* setting that we alter is the "value" (i.e. keyblock.curval) */ - BLI_snprintf(buf, sizeof(buf), "key_blocks[%d].value", adrcode); + if (kb) { + /* Use the keyblock name, escaped, so that path lookups for this will work */ + BLI_snprintf(buf, sizeof(buf), "key_blocks[\"%s\"].value", kb->name); + } + else { + /* Fallback - Use the adrcode as index directly, so that this can be manually fixed */ + BLI_snprintf(buf, sizeof(buf), "key_blocks[%d].value", adrcode); + } } return buf; } @@ -799,13 +811,14 @@ static const char *particle_adrcodes_to_paths(int adrcode, int *array_index) /* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path * Input: + * - id - the datablock that the curve's IPO block is attached to and/or which the new paths will start from * - blocktype, adrcode - determines setting to get * - actname, constname,seq - used to build path * Output: * - array_index - index in property's array (if applicable) to use * - return - the allocated path... */ -static char *get_rna_access(int blocktype, int adrcode, char actname[], char constname[], Sequence *seq, int *array_index) +static char *get_rna_access(ID *id, int blocktype, int adrcode, char actname[], char constname[], Sequence *seq, int *array_index) { DynStr *path = BLI_dynstr_new(); const char *propname = NULL; @@ -828,7 +841,7 @@ static char *get_rna_access(int blocktype, int adrcode, char actname[], char con break; case ID_KE: /* shapekeys */ - propname = shapekey_adrcodes_to_paths(adrcode, &dummy_index); + propname = shapekey_adrcodes_to_paths(id, adrcode, &dummy_index); break; case ID_CO: /* constraint */ @@ -1274,7 +1287,7 @@ static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *i /* get rna-path * - we will need to set the 'disabled' flag if no path is able to be made (for now) */ - fcu->rna_path = get_rna_access(icu->blocktype, icu->adrcode, actname, constname, seq, &fcu->array_index); + fcu->rna_path = get_rna_access(id, icu->blocktype, icu->adrcode, actname, constname, seq, &fcu->array_index); if (fcu->rna_path == NULL) fcu->flag |= FCURVE_DISABLED; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 811fbf5e5f0..c06f776f6d0 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -209,11 +209,6 @@ void id_us_min(ID *id) if (id) { const int limit = ID_FAKE_USERS(id); - if ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER) && !(id->tag & LIB_TAG_EXTRAUSER_SET)) { - /* We need an extra user here, but never actually incremented user count for it so far, do it now. */ - id_us_ensure_real(id); - } - if (id->us <= limit) { printf("ID user decrement error: %s (from '%s'): %d <= %d\n", id->name, id->lib ? id->lib->filepath : "[Main]", id->us, limit); @@ -225,6 +220,11 @@ void id_us_min(ID *id) else { id->us--; } + + if ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER)) { + /* We need an extra user here, but never actually incremented user count for it so far, do it now. */ + id_us_ensure_real(id); + } } } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 48fd34e38f4..3c6498e0236 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2530,13 +2530,15 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene, const char *name, char *r /* begin of extension */ index_act = BLI_str_rpartition(name, delims, rext, &suf_act); + if (*rext == NULL) + return; BLI_assert(index_act > 0); UNUSED_VARS_NDEBUG(index_act); for (srv = scene->r.views.first; srv; srv = srv->next) { if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) { size_t len = strlen(srv->suffix); - if (STREQLEN(*rext - len, srv->suffix, len)) { + if (strlen(*rext) >= len && STREQLEN(*rext - len, srv->suffix, len)) { BLI_strncpy(rprefix, name, strlen(name) - strlen(*rext) - len + 1); break; } diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index 9503da6e53e..f13e8cb2ae8 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -39,6 +39,14 @@ extern "C" { #endif +#define _GHASH_INTERNAL_ATTR +#ifndef GHASH_INTERNAL_API +# ifdef __GNUC__ +# undef _GHASH_INTERNAL_ATTR +# define _GHASH_INTERNAL_ATTR __attribute__ ((deprecated)) +# endif +#endif + typedef unsigned int (*GHashHashFP) (const void *key); /** returns false when equal */ typedef bool (*GHashCmpFP) (const void *a, const void *b); @@ -55,6 +63,12 @@ typedef struct GHashIterator { unsigned int curBucket; } GHashIterator; +typedef struct GHashIterState { + unsigned int curr_bucket _GHASH_INTERNAL_ATTR; +} GHashIterState; + + + enum { GHASH_FLAG_ALLOW_DUPES = (1 << 0), /* Only checked for in debug mode */ GHASH_FLAG_ALLOW_SHRINK = (1 << 1), /* Allow to shrink buckets' size. */ @@ -87,6 +101,7 @@ void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP va const unsigned int nentries_reserve); void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) ATTR_WARN_UNUSED_RESULT; bool BLI_ghash_haskey(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT; +bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); unsigned int BLI_ghash_size(GHash *gh) ATTR_WARN_UNUSED_RESULT; void BLI_ghash_flag_set(GHash *gh, unsigned int flag); void BLI_ghash_flag_clear(GHash *gh, unsigned int flag); @@ -208,6 +223,8 @@ typedef GHashCmpFP GSetCmpFP; typedef GHashKeyFreeFP GSetKeyFreeFP; typedef GHashKeyCopyFP GSetKeyCopyFP; +typedef GHashIterState GSetIterState; + /* so we can cast but compiler sees as different */ typedef struct GSetIterator { GHashIterator _ghi @@ -229,6 +246,7 @@ void BLI_gset_insert(GSet *gh, void *key); bool BLI_gset_add(GSet *gs, void *key); bool BLI_gset_reinsert(GSet *gh, void *key, GSetKeyFreeFP keyfreefp); bool BLI_gset_haskey(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT; +bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp); void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const unsigned int nentries_reserve); diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 29b07b37932..21b0a5860af 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -167,6 +167,31 @@ BLI_INLINE unsigned int ghash_bucket_index(GHash *gh, const unsigned int hash) } /** + * Find the index of next used bucket, starting from \a curr_bucket (\a gh is assumed non-empty). + */ +BLI_INLINE unsigned int ghash_find_next_bucket_index(GHash *gh, unsigned int curr_bucket) +{ + if (curr_bucket >= gh->nbuckets) { + curr_bucket = 0; + } + if (gh->buckets[curr_bucket]) { + return curr_bucket; + } + for (; curr_bucket < gh->nbuckets; curr_bucket++) { + if (gh->buckets[curr_bucket]) { + return curr_bucket; + } + } + for (curr_bucket = 0; curr_bucket < gh->nbuckets; curr_bucket++) { + if (gh->buckets[curr_bucket]) { + return curr_bucket; + } + } + BLI_assert(0); + return 0; +} + +/** * Expand buckets to the next size up or down. */ static void ghash_buckets_resize(GHash *gh, const unsigned int nbuckets) @@ -572,6 +597,29 @@ static Entry *ghash_remove_ex( } /** + * Remove a random entry and return it (or NULL if empty), caller must free from gh->entrypool. + */ +static Entry *ghash_pop(GHash *gh, GHashIterState *state) +{ + unsigned int curr_bucket = state->curr_bucket; + if (gh->nentries == 0) { + return NULL; + } + + /* Note: using first_bucket_index here allows us to avoid potential huge number of loops over buckets, + * in case we are poping from a large ghash with few items in it... */ + curr_bucket = ghash_find_next_bucket_index(gh, curr_bucket); + + Entry *e = gh->buckets[curr_bucket]; + BLI_assert(e); + + ghash_remove_ex(gh, e->key, NULL, NULL, curr_bucket); + + state->curr_bucket = curr_bucket; + return e; +} + +/** * Run free callbacks for freeing entries. */ static void ghash_free_cb( @@ -865,6 +913,35 @@ bool BLI_ghash_haskey(GHash *gh, const void *key) } /** + * Remove a random entry from \a ghp, returning true if a key/value pair could be removed, false otherwise. + * + * \param r_key: The removed key. + * \param r_val: The removed value. + * \param state: Used for efficient removal. + * \return true if there was somethjing to pop, false if ghash was already empty. + */ +bool BLI_ghash_pop( + GHash *gh, GHashIterState *state, + void **r_key, void **r_val) +{ + GHashEntry *e = (GHashEntry *)ghash_pop(gh, state); + + BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET)); + + if (e) { + *r_key = e->e.key; + *r_val = e->val; + + BLI_mempool_free(gh->entrypool, e); + return true; + } + else { + *r_key = *r_val = NULL; + return false; + } +} + +/** * Reset \a gh clearing all entries. * * \param keyfreefp Optional callback to free the key. @@ -1335,6 +1412,31 @@ bool BLI_gset_haskey(GSet *gs, const void *key) return (ghash_lookup_entry((GHash *)gs, key) != NULL); } +/** + * Remove a random entry from \a gsp, returning true if a key could be removed, false otherwise. + * + * \param r_key: The removed key. + * \param state: Used for efficient removal. + * \return true if there was somethjing to pop, false if gset was already empty. + */ +bool BLI_gset_pop( + GSet *gs, GSetIterState *state, + void **r_key) +{ + GSetEntry *e = (GSetEntry *)ghash_pop((GHash *)gs, (GHashIterState *)state); + + if (e) { + *r_key = e->key; + + BLI_mempool_free(((GHash *)gs)->entrypool, e); + return true; + } + else { + *r_key = NULL; + return false; + } +} + void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const unsigned int nentries_reserve) { diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 1348d7e6d43..15e95a05425 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -133,6 +133,7 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype); #include "LightExporter.h" #include "MaterialExporter.h" +#include <errno.h> char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) { @@ -160,7 +161,7 @@ static COLLADABU::NativeString make_temp_filepath(const char *name, const char * const char *tempdir = BKE_tempdir_session(); if (name == NULL) { - name = tmpnam(NULL); + name = "untitled"; } BLI_make_file_string(NULL, tempfile, tempdir, name); @@ -178,7 +179,7 @@ static COLLADABU::NativeString make_temp_filepath(const char *name, const char * // COLLADA allows this through multiple <channel>s in <animation>. // For this to work, we need to know objects that use a certain action. -void DocumentExporter::exportCurrentScene(Scene *sce) +int DocumentExporter::exportCurrentScene(Scene *sce) { PointerRNA sceneptr, unit_settings; PropertyRNA *system; /* unused , *scale; */ @@ -188,8 +189,6 @@ void DocumentExporter::exportCurrentScene(Scene *sce) COLLADABU::NativeString native_filename = make_temp_filepath(NULL, ".dae"); COLLADASW::StreamWriter *writer = new COLLADASW::StreamWriter(native_filename); - fprintf(stdout, "Collada export: %s\n", this->export_settings->filepath); - // open <collada> writer->startDocument(); @@ -330,8 +329,13 @@ void DocumentExporter::exportCurrentScene(Scene *sce) delete writer; // Finally move the created document into place - BLI_rename(native_filename.c_str(), this->export_settings->filepath); - + fprintf(stdout, "Collada export to: %s\n", this->export_settings->filepath); + int status = BLI_rename(native_filename.c_str(), this->export_settings->filepath); + if (status != 0) { + status = BLI_copy(native_filename.c_str(), this->export_settings->filepath); + BLI_delete(native_filename.c_str(), false, false); + } + return status; } void DocumentExporter::exportScenes(const char *filename) diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h index 84c0610282e..6e3c1ecd7cd 100644 --- a/source/blender/collada/DocumentExporter.h +++ b/source/blender/collada/DocumentExporter.h @@ -39,7 +39,7 @@ class DocumentExporter { public: DocumentExporter(const ExportSettings *export_settings); - void exportCurrentScene(Scene *sce); + int exportCurrentScene(Scene *sce); void exportScenes(const char *filename); private: const ExportSettings *export_settings; diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 4ca21869ec2..b1cbc01a9a6 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -133,11 +133,11 @@ int collada_export(Scene *sce, } DocumentExporter exporter(&export_settings); - exporter.exportCurrentScene(sce); + int status = exporter.exportCurrentScene(sce); BLI_linklist_free(export_settings.export_set, NULL); - return export_count; + return (status) ? -1:export_count; } /* end extern C */ diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 6ad8be719ce..35e5ec98e57 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -542,7 +542,7 @@ list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR}/operations ) -if(MSVC) +if(MSVC AND NOT CMAKE_CL_64) set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2") endif() diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index f9e2dd87d05..a8e34543e08 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -259,6 +259,12 @@ public: float u = x; float v = y; this->wrap_pixel(u, v, extend_x, extend_y); + if ((extend_x != COM_MB_REPEAT && (u < 0.0f || u >= this->m_width)) || + (extend_y != COM_MB_REPEAT && (v < 0.0f || v >= this->m_height))) + { + zero_v4(result); + return; + } BLI_bilinear_interpolation_wrap_fl( this->m_buffer, result, this->m_width, this->m_height, this->m_num_channels, u, v, extend_x == COM_MB_REPEAT, extend_y == COM_MB_REPEAT); diff --git a/source/blender/datatoc/CMakeLists.txt b/source/blender/datatoc/CMakeLists.txt index 4c35a941757..0f123fbf9f0 100644 --- a/source/blender/datatoc/CMakeLists.txt +++ b/source/blender/datatoc/CMakeLists.txt @@ -51,6 +51,9 @@ if(NOT WITH_HEADLESS) ../blenlib/intern/winstuff_dir.c ../../../intern/utfconv/utfconv.c ) + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}") endif() include_directories(${PNG_INCLUDE_DIRS}) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 05e9b893e65..95354bc5e8a 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4259,6 +4259,13 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle UI_block_emboss_set(block, UI_EMBOSS_NONE); } + else { + /* Cannot get property/cannot or rename for some reason, so clear rename index + * so that this doesn't hang around, and the name can be drawn normally - T47492 + */ + ac->ads->renameIndex = 0; + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL); + } } /* step 5) draw mute+protection toggles + (sliders) ....................... */ diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index cb331554a8f..f143ea478c6 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -32,6 +32,7 @@ #define __ED_UTIL_H__ struct bContext; +struct SpaceLink; struct wmOperator; struct wmOperatorType; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 574c6d93cbf..11dc88d615d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -776,6 +776,7 @@ void UI_popup_handlers_remove_all(struct bContext *C, struct ListBase *handlers) void UI_init(void); void UI_init_userdef(void); void UI_reinit_font(void); +void UI_reinit_gl_state(void); void UI_exit(void); /* Layout diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 9d6ae110a32..8fbc545cb77 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1734,3 +1734,14 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha glDisable(GL_BLEND); } +/** + * Reset GL state (keep minimal). + * + * \note Blender's internal code doesn't assume these are reset, + * but external callbacks may depend on their state. + */ +void UI_reinit_gl_state(void) +{ + glLineWidth(1.0f); + glPointSize(1.0f); +} diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index d8f33dced13..d4c976fb544 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -175,6 +175,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "Export file is empty"); return OPERATOR_CANCELLED; } + else if (export_count < 0) { + BKE_report(op->reports, RPT_WARNING, "Error during export (see Console)"); + return OPERATOR_CANCELLED; + } else { char buff[100]; sprintf(buff, "Exported %d Objects", export_count); diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c index 2c173a20eac..69588928253 100644 --- a/source/blender/editors/mesh/editmesh_intersect.c +++ b/source/blender/editors/mesh/editmesh_intersect.c @@ -761,7 +761,7 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op)) BM_mesh_elem_index_ensure(bm, BM_FACE); { - BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, NULL); + BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, false); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BM_elem_index_set(e, -1); /* set_dirty */ diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index c29840cc654..b8693639673 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3934,10 +3934,10 @@ static void project_paint_end(ProjPaintState *ps) /* must be set for non-shared */ BLI_assert(ps->dm_mloopuv || ps->is_shared_user); if (ps->dm_mloopuv) - MEM_freeN(ps->dm_mloopuv); + MEM_freeN((void *)ps->dm_mloopuv); if (ps->do_layer_clone) - MEM_freeN(ps->dm_mloopuv_clone); + MEM_freeN((void *)ps->dm_mloopuv_clone); if (ps->thread_tot > 1) { BLI_spin_end(ps->tile_lock); MEM_freeN((void *)ps->tile_lock); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 574d3f6f2c9..f2813b2a8d3 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -244,10 +244,12 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) { /* if channel is mapped in NLA, apply correction */ if (adt) { + ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP); ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP); } else { + ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */ ked.f1 = rectf.xmin; ked.f2 = rectf.xmax; } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 01f0d1ae54f..590bf5d702e 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -249,8 +249,10 @@ void ED_region_draw_cb_draw(const bContext *C, ARegion *ar, int type) RegionDrawCB *rdc; for (rdc = ar->type->drawcalls.first; rdc; rdc = rdc->next) { - if (rdc->type == type) + if (rdc->type == type) { + UI_reinit_gl_state(); rdc->draw(C, ar, rdc->customdata); + } } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index a130436770a..ed207e2da02 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -441,9 +441,14 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp for (line = text->lines.first; line; line = line->next) { struct ResultBLF info; - BLF_position(fontid, x, y, 0); - BLF_draw_ex(fontid, line->line, line->len, &info); - y -= line_spacing * info.lines; + if (line->line[0]) { + BLF_position(fontid, x, y, 0); + BLF_draw_ex(fontid, line->line, line->len, &info); + y -= line_spacing * info.lines; + } + else { + y -= line_spacing; + } if (y < y_min) { break; } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index b57f95db4e6..5c58e9b720c 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -253,7 +253,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) if (wgroup->adt) { LinkData *ld, *ldn = NULL; bAction *waction; - + /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action); @@ -271,6 +271,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) /* free temp action too */ if (waction) { BKE_libblock_free(G.main, waction); + wgroup->adt->action = NULL; } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index b1e47ad9ef4..e783f444563 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4443,6 +4443,9 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, if (ob->type == OB_MBALL) { /* mball always smooth shaded */ glShadeModel(GL_SMOOTH); } + + /* track current material, -1 for none (needed for lines) */ + short col = -1; DispList *dl = lb->first; while (dl) { @@ -4452,6 +4455,11 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, switch (dl->type) { case DL_SEGM: if (ob->type == OB_SURF) { + if (col != -1) { + GPU_object_material_unbind(); + col = -1; + } + if ((dflag & DRAW_CONSTCOLOR) == 0) glColor3ubv(ob_wire_col); @@ -4466,6 +4474,11 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, break; case DL_POLY: if (ob->type == OB_SURF) { + if (col != -1) { + GPU_object_material_unbind(); + col = -1; + } + /* for some reason glDrawArrays crashes here in half of the platforms (not osx) */ //glVertexPointer(3, GL_FLOAT, 0, dl->verts); //glDrawArrays(GL_LINE_LOOP, 0, dl->nr); @@ -4479,7 +4492,10 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, case DL_SURF: if (dl->index) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); + if (col != dl->col) { + GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); + col = dl->col; + } if (dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); @@ -4493,7 +4509,10 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, break; case DL_INDEX3: - GPU_object_material_bind(dl->col + 1, (use_glsl) ? &gattribs : NULL); + if (col != dl->col) { + GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); + col = dl->col; + } glVertexPointer(3, GL_FLOAT, 0, dl->verts); @@ -4513,7 +4532,10 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, break; case DL_INDEX4: - GPU_object_material_bind(dl->col + 1, (use_glsl) ? &gattribs : NULL); + if (col != dl->col) { + GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); + col = dl->col; + } glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, 0, dl->verts); @@ -4530,7 +4552,9 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, glShadeModel(GL_FLAT); glFrontFace(GL_CCW); - GPU_object_material_unbind(); + if (col != -1) { + GPU_object_material_unbind(); + } } static void drawCurveDMWired(Object *ob) @@ -7133,7 +7157,6 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, RegionView3D *rv3d = ar->regiondata; Object *ob = base->object; - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(0); if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { @@ -7156,24 +7179,33 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) { + glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); if (dm) { draw_mesh_object_outline(v3d, ob, dm); } else { - drawDispListwire(&ob->curve_cache->disp, ob->type); + /* don't show outline on 'wire' with surfaces, + * don't show interior tessellation with curves */ + drawDispListwire_ex( + &ob->curve_cache->disp, + (ob->type == OB_SURF) ? + (DL_INDEX3 | DL_INDEX4 | DL_SURF) : (DL_SEGM | DL_POLY)); } } } else if (ob->type == OB_MBALL) { if (BKE_mball_is_basis(ob)) { if ((base->flag & OB_FROMDUPLI) == 0) { + glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); drawDispListwire(&ob->curve_cache->disp, ob->type); } } } else if (ob->type == OB_ARMATURE) { - if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) + if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) { + glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); draw_armature(scene, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true); + } } glDepthMask(1); diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 9bb4e050ae6..e07831358d6 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -477,6 +477,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) /* At this point, our value has changed, try to interpret it with python (if str is not empty!). */ if (n->str[0]) { + const float val_prev = n->val[idx]; #ifdef WITH_PYTHON Scene *sce = CTX_data_scene(C); double val; @@ -514,6 +515,11 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) if (n->val_flag[idx] & NUM_INVERSE) { n->val[idx] = 1.0f / n->val[idx]; } + + if (UNLIKELY(!isfinite(n->val[idx]))) { + n->val[idx] = val_prev; + n->val_flag[idx] |= NUM_INVALID; + } } /* REDRAW SINCE NUMBERS HAVE CHANGED */ diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index e1495b617f8..59f9cd16908 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -4166,6 +4166,7 @@ static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts, while (nverts > 2) { float minangle = FLT_MAX; + float minshape = FLT_MAX; int i, mini = 0; /* find corner with smallest angle */ @@ -4181,8 +4182,20 @@ static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts, if (normal && (dot_v3v3(n, normal) < 0.0f)) angle = (float)(2.0 * M_PI) - angle; - if (angle < minangle) { + float other_angle = p_vec_angle(co[v2], co[v0], co[v1]); + float shape = fabsf((float)M_PI - angle - 2.0f * other_angle); + + if (fabsf(angle - minangle) < 0.01f) { + /* for nearly equal angles, try to get well shaped triangles */ + if (shape < minshape) { + minangle = angle; + minshape = shape; + mini = i; + } + } + else if (angle < minangle) { minangle = angle; + minshape = shape; mini = i; } } diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index 537cde9ac5c..f4763883489 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -72,18 +72,16 @@ # endif /* _WIN32 || __APPLE__ */ #endif /* WITH_QUICKTIME */ -#ifdef WITH_FFMPEG -# include <libavformat/avformat.h> -# include <libavcodec/avcodec.h> -# include <libswscale/swscale.h> -#endif - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "IMB_allocimbuf.h" - +#ifdef WITH_FFMPEG +# include <libavformat/avformat.h> +# include <libavcodec/avcodec.h> +# include <libswscale/swscale.h> +#endif /* actually hard coded endianness */ #define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index a32cf401f70..1b4ce4225d6 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -85,22 +85,21 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_colormanagement.h" +#include "IMB_colormanagement_intern.h" + #include "IMB_anim.h" #include "IMB_indexer.h" #ifdef WITH_FFMPEG -#include <libavformat/avformat.h> -#include <libavcodec/avcodec.h> -#include <libavutil/rational.h> -#include <libswscale/swscale.h> - -#include "ffmpeg_compat.h" +# include <libavformat/avformat.h> +# include <libavcodec/avcodec.h> +# include <libavutil/rational.h> +# include <libswscale/swscale.h> +# include "ffmpeg_compat.h" #endif //WITH_FFMPEG -#include "IMB_colormanagement.h" -#include "IMB_colormanagement_intern.h" - int ismovie(const char *UNUSED(filepath)) { return 0; diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp index 0a2e8742ba8..11bf45418d6 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp +++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp @@ -31,11 +31,6 @@ #include <set> -#include <openimageio_api.h> -#include <OpenImageIO/imageio.h> - -OIIO_NAMESPACE_USING - #if defined(WIN32) && !defined(FREE_WINDOWS) #include "utfconv.h" #endif @@ -53,7 +48,12 @@ extern "C" #include "IMB_colormanagement_intern.h" } -using namespace std; +#include <openimageio_api.h> +#include <OpenImageIO/imageio.h> + +OIIO_NAMESPACE_USING + +using std::string; typedef unsigned char uchar; diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 40b5a1a914c..47fa4c1de0c 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -422,14 +422,14 @@ static bool imb_save_openexr_half( OutputFile file(file_stream, header); /* we store first everything in half array */ - RGBAZ *pixels = new RGBAZ[height * width * totviews]; + std::vector<RGBAZ> pixels(height * width * totviews); int xstride = sizeof(RGBAZ); int ystride = xstride * width; for (view_id = 0; view_id < totviews; view_id ++) { ImBuf *view_ibuf = is_multiview ? getbuffer(ibuf->userdata, view_id) : ibuf; const size_t offset = view_id * width * height; - RGBAZ *to = pixels + offset; + RGBAZ *to = &pixels[offset]; /* TODO (dfelinto) * In some cases we get NULL ibufs, it needs investigation, meanwhile prevent crash @@ -487,8 +487,6 @@ static bool imb_save_openexr_half( file.setFrameBuffer(frameBuffer); file.writePixels(height); - - delete[] pixels; } catch (const std::exception& exc) { diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 6a36048acd7..f4c6fdf42f5 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1593,11 +1593,18 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) rna_def_userdef_theme_spaces_gradient(srna); + /* General Viewport options */ + prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "clipping_border_3d", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Clipping Border", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Wire", ""); @@ -1608,32 +1615,18 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Wire Edit", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - rna_def_userdef_theme_spaces_gpencil(srna); - prop = RNA_def_property(srna, "lamp", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 4); - RNA_def_property_ui_text(prop, "Lamp", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* Grease Pencil */ - prop = RNA_def_property(srna, "speaker", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Speaker", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop = RNA_def_property(srna, "camera", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Camera", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + rna_def_userdef_theme_spaces_gpencil(srna); - prop = RNA_def_property(srna, "view_overlay", PROP_FLOAT, PROP_COLOR_GAMMA); + prop = RNA_def_property(srna, "text_grease_pencil", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "time_gp_keyframe"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "View Overlay", ""); + RNA_def_property_ui_text(prop, "Grease Pencil Keyframe", "Color for indicating Grease Pencil keyframes"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "empty", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Empty", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* Object specific options */ prop = RNA_def_property(srna, "object_selected", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "select"); @@ -1659,14 +1652,42 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object Grouped Active", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "transform", PROP_FLOAT, PROP_COLOR_GAMMA); + prop = RNA_def_property(srna, "text_keyframe", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "time_keyframe"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Transform", ""); + RNA_def_property_ui_text(prop, "Object Keyframe", "Color for indicating Object keyframes"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + + /* Object type options */ + + prop = RNA_def_property(srna, "camera", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Camera", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "empty", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Empty", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "lamp", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Lamp", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "speaker", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Speaker", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* Mesh Object specific */ + rna_def_userdef_theme_spaces_vertex(srna); rna_def_userdef_theme_spaces_edge(srna); rna_def_userdef_theme_spaces_face(srna); + + /* Mesh Object specific curves*/ + rna_def_userdef_theme_spaces_curves(srna, true, true, true, false); prop = RNA_def_property(srna, "extra_edge_len", PROP_FLOAT, PROP_COLOR_GAMMA); @@ -1710,10 +1731,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Split Normal", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "bone_solid", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Bone Solid", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* Armature Object specific */ prop = RNA_def_property(srna, "bone_pose", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1725,16 +1743,12 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bone Pose Active", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "cframe"); + prop = RNA_def_property(srna, "bone_solid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Current Frame", ""); + RNA_def_property_ui_text(prop, "Bone Solid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "outline_width", PROP_INT, PROP_NONE); - RNA_def_property_range(prop, 1, 5); - RNA_def_property_ui_text(prop, "Outline Width", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* misc */ prop = RNA_def_property(srna, "bundle_solid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "bundle_solid"); @@ -1753,24 +1767,29 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Skin Root", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "clipping_border_3d", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 4); - RNA_def_property_ui_text(prop, "Clipping Border", ""); + prop = RNA_def_property(srna, "view_overlay", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "View Overlay", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "text_keyframe", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "time_keyframe"); + prop = RNA_def_property(srna, "transform", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Keyframe", "Color for indicating Object keyframes"); + RNA_def_property_ui_text(prop, "Transform", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "text_grease_pencil", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "time_gp_keyframe"); + prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Grease Pencil", "Color for indicating Grease Pencil keyframes"); + RNA_def_property_ui_text(prop, "Current Frame", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); rna_def_userdef_theme_spaces_paint_curves(srna); + + prop = RNA_def_property(srna, "outline_width", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 1, 5); + RNA_def_property_ui_text(prop, "Outline Width", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + } diff --git a/source/blender/render/intern/include/renderpipeline.h b/source/blender/render/intern/include/renderpipeline.h index a831ab3c29c..c5d6e3b44b1 100644 --- a/source/blender/render/intern/include/renderpipeline.h +++ b/source/blender/render/intern/include/renderpipeline.h @@ -41,6 +41,7 @@ struct RenderResult; struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr); float panorama_pixel_rot(struct Render *re); void render_update_anim_renderdata(struct Render *re, struct RenderData *rd); +void render_copy_renderdata(struct RenderData *to, struct RenderData *from); #endif /* __RENDERPIPELINE_H__ */ diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index 11dcc9d9e80..27867eadbb4 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -82,6 +82,10 @@ void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3); void calc_R_ref(struct ShadeInput *shi); +void barycentric_differentials_from_position( + const float co[3], const float v1[3], const float v2[3], const float v3[3], + const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials, + float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v); /* shadeoutput. */ void shade_lamp_loop(struct ShadeInput *shi, struct ShadeResult *shr); diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index 21460c701e6..4101acf7990 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -84,6 +84,7 @@ /* local include */ #include "render_types.h" +#include "shading.h" #include "zbuf.h" /* Remove when Cycles moves from MFace to MLoopTri */ @@ -263,31 +264,14 @@ static void calc_point_from_barycentric_extrusion( } /** - * This function returns the barycentric u,v of a face for a coordinate. The face is defined by its index. - */ -static void calc_barycentric_from_point( - TriTessFace *triangles, const int index, const float co[3], - int *r_primitive_id, float r_uv[2]) -{ - TriTessFace *triangle = &triangles[index]; - resolve_tri_uv_v3(r_uv, co, - triangle->mverts[0]->co, - triangle->mverts[1]->co, - triangle->mverts[2]->co); - *r_primitive_id = index; -} - -/** * This function populates pixel_array and returns TRUE if things are correct */ static bool cast_ray_highpoly( - BVHTreeFromMesh *treeData, TriTessFace *triangles[], BakePixel *pixel_array, BakeHighPolyData *highpoly, - const float co[3], const float dir[3], const int pixel_id, const int tot_highpoly, - const float du_dx, const float du_dy, const float dv_dx, const float dv_dy) + BVHTreeFromMesh *treeData, TriTessFace *triangle_low, TriTessFace *triangles[], + BakePixel *pixel_array_low, BakePixel *pixel_array, float mat_low[4][4], BakeHighPolyData *highpoly, + const float co[3], const float dir[3], const int pixel_id, const int tot_highpoly) { int i; - int primitive_id = -1; - float uv[2]; int hit_mesh = -1; float hit_distance = FLT_MAX; @@ -333,17 +317,54 @@ static bool cast_ray_highpoly( } if (hit_mesh != -1) { - calc_barycentric_from_point(triangles[hit_mesh], hits[hit_mesh].index, hits[hit_mesh].co, &primitive_id, uv); - pixel_array[pixel_id].primitive_id = primitive_id; - pixel_array[pixel_id].object_id = hit_mesh; - copy_v2_v2(pixel_array[pixel_id].uv, uv); - - /* the differentials are relative to the UV/image space, so the highpoly differentials - * are the same as the low poly differentials */ - pixel_array[pixel_id].du_dx = du_dx; - pixel_array[pixel_id].du_dy = du_dy; - pixel_array[pixel_id].dv_dx = dv_dx; - pixel_array[pixel_id].dv_dy = dv_dy; + int primitive_id_high = hits[hit_mesh].index; + TriTessFace *triangle_high = &triangles[hit_mesh][primitive_id_high]; + BakePixel *pixel_low = &pixel_array_low[pixel_id]; + BakePixel *pixel_high = &pixel_array[pixel_id]; + + pixel_high->primitive_id = primitive_id_high; + pixel_high->object_id = hit_mesh; + + /* ray direction in high poly object space */ + float dir_high[3]; + mul_v3_mat3_m4v3(dir_high, highpoly[hit_mesh].imat, dir); + normalize_v3(dir_high); + + /* compute position differentials on low poly object */ + float duco_low[3], dvco_low[3], dxco[3], dyco[3]; + sub_v3_v3v3(duco_low, triangle_low->mverts[0]->co, triangle_low->mverts[2]->co); + sub_v3_v3v3(dvco_low, triangle_low->mverts[1]->co, triangle_low->mverts[2]->co); + + mul_v3_v3fl(dxco, duco_low, pixel_low->du_dx); + madd_v3_v3fl(dxco, dvco_low, pixel_low->dv_dx); + mul_v3_v3fl(dyco, duco_low, pixel_low->du_dy); + madd_v3_v3fl(dyco, dvco_low, pixel_low->dv_dy); + + /* transform from low poly to to high poly object space */ + mul_mat3_m4_v3(mat_low, dxco); + mul_mat3_m4_v3(mat_low, dyco); + mul_mat3_m4_v3(highpoly[hit_mesh].imat, dxco); + mul_mat3_m4_v3(highpoly[hit_mesh].imat, dyco); + + /* transfer position differentials */ + float tmp[3]; + mul_v3_v3fl(tmp, dir_high, 1.0f/dot_v3v3(dir_high, triangle_high->normal)); + madd_v3_v3fl(dxco, tmp, -dot_v3v3(dxco, triangle_high->normal)); + madd_v3_v3fl(dyco, tmp, -dot_v3v3(dyco, triangle_high->normal)); + + /* compute barycentric differentials from position differentials */ + barycentric_differentials_from_position( + hits[hit_mesh].co, triangle_high->mverts[0]->co, + triangle_high->mverts[1]->co, triangle_high->mverts[2]->co, + dxco, dyco, triangle_high->normal, true, + &pixel_high->uv[0], &pixel_high->uv[1], + &pixel_high->du_dx, &pixel_high->dv_dx, + &pixel_high->du_dy, &pixel_high->dv_dy); + + /* verify we have valid uvs */ + BLI_assert(pixel_high->uv[0] >= -1e-3f && + pixel_high->uv[1] >= -1e-3f && + pixel_high->uv[0] + pixel_high->uv[1] <= 1.0f + 1e-3f); } else { pixel_array[pixel_id].primitive_id = -1; @@ -385,8 +406,6 @@ static TriTessFace *mesh_calc_tri_tessface( int i; MVert *mvert; TSpace *tspace; - float *precomputed_normals = NULL; - bool calculate_normal; const int tottri = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *looptri; @@ -408,9 +427,6 @@ static TriTessFace *mesh_calc_tri_tessface( DM_ensure_normals(dm); DM_calc_loop_tangents(dm); - precomputed_normals = dm->getPolyDataArray(dm, CD_NORMAL); - calculate_normal = precomputed_normals ? false : true; - tspace = dm->getLoopDataArray(dm, CD_TANGENT); BLI_assert(tspace); } @@ -421,6 +437,10 @@ static TriTessFace *mesh_calc_tri_tessface( me->totloop, me->totpoly, looptri); + + const float *precomputed_normals = dm ? dm->getPolyDataArray(dm, CD_NORMAL) : NULL; + const bool calculate_normal = precomputed_normals ? false : true; + for (i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; const MPoly *mp = &me->mpoly[lt->poly]; @@ -441,17 +461,17 @@ static TriTessFace *mesh_calc_tri_tessface( triangles[i].tspace[0] = &tspace[lt->tri[0]]; triangles[i].tspace[1] = &tspace[lt->tri[1]]; triangles[i].tspace[2] = &tspace[lt->tri[2]]; + } - if (calculate_normal) { - if (lt->poly != mpoly_prev) { - BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no); - mpoly_prev = lt->poly; - } - copy_v3_v3(triangles[i].normal, no); - } - else { - copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]); + if (calculate_normal) { + if (lt->poly != mpoly_prev) { + BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no); + mpoly_prev = lt->poly; } + copy_v3_v3(triangles[i].normal, no); + } + else { + copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]); } } @@ -546,9 +566,9 @@ bool RE_bake_pixels_populate_from_objects( } /* cast ray */ - if (!cast_ray_highpoly(treeData, tris_high, pixel_array_to, highpoly, co, dir, i, tot_highpoly, - pixel_array_from[i].du_dx, pixel_array_from[i].du_dy, - pixel_array_from[i].dv_dx, pixel_array_from[i].dv_dy)) { + if (!cast_ray_highpoly(treeData, &tris_low[primitive_id], tris_high, + pixel_array_from, pixel_array_to, mat_low, + highpoly, co, dir, i, tot_highpoly)) { /* if it fails mask out the original pixel array */ pixel_array_from[i].primitive_id = -1; } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 1e5e9025dcd..64fd56715c7 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3131,9 +3131,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) copy_m3_m4(imat, ob->imat); negative_scale= is_negative_m4(mat); - if (me->totvert==0) - return; - need_orco= 0; for (a=1; a<=ob->totcol; a++) { ma= give_render_material(re, ob, a); @@ -3194,6 +3191,14 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) dm= mesh_create_derived_render(re->scene, ob, mask); if (dm==NULL) return; /* in case duplicated object fails? */ + mvert= dm->getVertArray(dm); + totvert= dm->getNumVerts(dm); + + if (totvert == 0) { + dm->release(dm); + return; + } + if (mask & CD_MASK_ORCO) { orco = get_object_orco(re, ob); if (!orco) { @@ -3205,9 +3210,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) } } - mvert= dm->getVertArray(dm); - totvert= dm->getNumVerts(dm); - /* attempt to autsmooth on original mesh, only without subsurf */ if (do_autosmooth && me->totvert==totvert && me->totface==dm->getNumTessFaces(dm)) use_original_normals= true; @@ -5871,11 +5873,7 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, re->lay= lay; /* renderdata setup and exceptions */ - BLI_freelistN(&re->r.layers); - BLI_freelistN(&re->r.views); - re->r = scene->r; - BLI_duplicatelist(&re->r.layers, &scene->r.layers); - BLI_duplicatelist(&re->r.views, &scene->r.views); + render_copy_renderdata(&re->r, &scene->r); RE_init_threadcount(re); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index d70cc4b1ee0..b1afb86e5af 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -56,7 +56,8 @@ /* this module */ #include "render_types.h" #include "envmap.h" -#include "renderdatabase.h" +#include "renderdatabase.h" +#include "renderpipeline.h" #include "texture.h" #include "zbuf.h" @@ -138,7 +139,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) envre->flag = re->flag; /* set up renderdata */ - envre->r = re->r; + render_copy_renderdata(&envre->r, &re->r); envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); BLI_listbase_clear(&envre->r.layers); BLI_listbase_clear(&envre->r.views); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 094c4de1f55..2804e2d7638 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -452,18 +452,9 @@ RenderData *RE_engine_get_render_data(Render *re) /* Bake */ void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene) { - curvemapping_free_data(&re->r.mblur_shutter_curve); - re->scene = scene; re->main = bmain; - re->r = scene->r; - - /* prevent crash when freeing the scene - * but it potentially leaves unfreed memory blocks - * not sure how to fix this yet -- dfelinto */ - BLI_listbase_clear(&re->r.layers); - BLI_listbase_clear(&re->r.views); - curvemapping_copy_data(&re->r.mblur_shutter_curve, &scene->r.mblur_shutter_curve); + render_copy_renderdata(&re->r, &scene->r); } bool RE_bake_has_engine(Render *re) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 59b9da9b2a6..6fef581e0ed 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -684,6 +684,19 @@ static void re_init_resolution(Render *re, Render *source, re->clipcrop = 1.0f + 2.0f / (float)(re->winx > re->winy ? re->winy : re->winx); } +void render_copy_renderdata(RenderData *to, RenderData *from) +{ + BLI_freelistN(&to->layers); + BLI_freelistN(&to->views); + curvemapping_free_data(&to->mblur_shutter_curve); + + *to = *from; + + BLI_duplicatelist(&to->layers, &from->layers); + BLI_duplicatelist(&to->views, &from->views); + curvemapping_copy_data(&to->mblur_shutter_curve, &from->mblur_shutter_curve); +} + /* what doesn't change during entire render sequence */ /* disprect is optional, if NULL it assumes full window render */ void RE_InitState(Render *re, Render *source, RenderData *rd, @@ -697,13 +710,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->i.starttime = PIL_check_seconds_timer(); /* copy render data and render layers for thread safety */ - BLI_freelistN(&re->r.layers); - BLI_freelistN(&re->r.views); - curvemapping_free_data(&re->r.mblur_shutter_curve); - re->r = *rd; - BLI_duplicatelist(&re->r.layers, &rd->layers); - BLI_duplicatelist(&re->r.views, &rd->views); - curvemapping_copy_data(&re->r.mblur_shutter_curve, &rd->mblur_shutter_curve); + render_copy_renderdata(&re->r, rd); if (source) { /* reuse border flags from source renderer */ diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 05097bb8004..e60a5a70a7f 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -705,6 +705,35 @@ void shade_input_set_viewco(ShadeInput *shi, float x, float y, float xs, float y shade_input_calc_viewco(shi, xs, ys, z, shi->view, dxyview, shi->co, dxco, dyco); } +void barycentric_differentials_from_position( + const float co[3], const float v1[3], const float v2[3], const float v3[3], + const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials, + float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v) +{ + /* find most stable axis to project */ + int axis1, axis2; + axis_dominant_v3(&axis1, &axis2, facenor); + + /* compute u,v and derivatives */ + float t00 = v3[axis1] - v1[axis1]; + float t01 = v3[axis2] - v1[axis2]; + float t10 = v3[axis1] - v2[axis1]; + float t11 = v3[axis2] - v2[axis2]; + + float detsh = (t00 * t11 - t10 * t01); + detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f; + t00 *= detsh; t01 *= detsh; + t10 *= detsh; t11 *= detsh; + + *u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10; + *v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01; + if (differentials) { + *dx_u = dxco[axis1] * t11 - dxco[axis2] * t10; + *dx_v = dxco[axis2] * t00 - dxco[axis1] * t01; + *dy_u = dyco[axis1] * t11 - dyco[axis2] * t10; + *dy_v = dyco[axis2] * t00 - dyco[axis1] * t01; + } +} /* calculate U and V, for scanline (silly render face u and v are in range -1 to 0) */ void shade_input_set_uv(ShadeInput *shi) { @@ -746,30 +775,12 @@ void shade_input_set_uv(ShadeInput *shi) } } else { - /* most of this could become re-used for faces */ - float detsh, t00, t10, t01, t11; - int axis1, axis2; - - /* find most stable axis to project */ - axis_dominant_v3(&axis1, &axis2, shi->facenor); + barycentric_differentials_from_position( + shi->co, v1, v2, v3, shi->dxco, shi->dyco, shi->facenor, shi->osatex, + &shi->u, &shi->v, &shi->dx_u, &shi->dx_v, &shi->dy_u, &shi->dy_v); - /* compute u,v and derivatives */ - t00 = v3[axis1] - v1[axis1]; t01 = v3[axis2] - v1[axis2]; - t10 = v3[axis1] - v2[axis1]; t11 = v3[axis2] - v2[axis2]; - - detsh = (t00 * t11 - t10 * t01); - detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f; - t00 *= detsh; t01 *= detsh; - t10 *= detsh; t11 *= detsh; - - shi->u = (shi->co[axis1] - v3[axis1]) * t11 - (shi->co[axis2] - v3[axis2]) * t10; - shi->v = (shi->co[axis2] - v3[axis2]) * t00 - (shi->co[axis1] - v3[axis1]) * t01; - if (shi->osatex) { - shi->dx_u = shi->dxco[axis1] * t11 - shi->dxco[axis2] * t10; - shi->dx_v = shi->dxco[axis2] * t00 - shi->dxco[axis1] * t01; - shi->dy_u = shi->dyco[axis1] * t11 - shi->dyco[axis2] * t10; - shi->dy_v = shi->dyco[axis2] * t00 - shi->dyco[axis1] * t01; - } + shi->u = -shi->u; + shi->v = -shi->v; /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */ CLAMP(shi->u, -2.0f, 1.0f); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index f509aa03399..0acd18126d9 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -26,7 +26,7 @@ #ifndef __WM_API_H__ #define __WM_API_H__ -/** \file WM_api.h +/** \file blender/windowmanager/WM_api.h * \ingroup wm * * \page wmpage windowmanager diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index 079ade0fbe3..a6413369a8f 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -26,7 +26,7 @@ #ifndef __WM_KEYMAP_H__ #define __WM_KEYMAP_H__ -/** \file WM_keymap.h +/** \file blender/windowmanager/WM_keymap.h * \ingroup wm */ diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index aa4b0c37efd..74b26d1fd4f 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -624,13 +624,13 @@ elseif(WIN32) # MinGW TODO: This bit of Python configuration diverges from MSVC if(NOT CMAKE_COMPILER_IS_GNUCC) install( - FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.dll ${LIBDIR}/python/lib/sqlite3.dll + FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.dll DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel ) install( - FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll ${LIBDIR}/python/lib/sqlite3_d.dll + FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll DESTINATION "." CONFIGURATIONS Debug ) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 1d185d52dc8..476fbd29b8b 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -972,6 +972,7 @@ PyMethodDef KX_BlenderMaterial::Methods[] = { KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ), KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ), + KX_PYMETHODTABLE( KX_BlenderMaterial, getTextureBindcode ), KX_PYMETHODTABLE( KX_BlenderMaterial, setBlending ), {NULL,NULL} //Sentinel }; @@ -1325,4 +1326,20 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( bge.logic.sr return NULL; } +KX_PYMETHODDEF_DOC(KX_BlenderMaterial, getTextureBindcode, "getTextureBindcode(texslot)") +{ + unsigned int texslot; + if (!PyArg_ParseTuple(args, "i:texslot", &texslot)) { + PyErr_SetString(PyExc_ValueError, "material.getTextureBindcode(texslot): KX_BlenderMaterial, expected an int."); + return NULL; + } + Image *ima = getImage(texslot); + if (ima) { + unsigned int *bindcode = ima->bindcode; + return PyLong_FromLong(*bindcode); + } + PyErr_SetString(PyExc_ValueError, "material.getTextureBindcode(texslot): KX_BlenderMaterial, invalid texture slot."); + return NULL; +} + #endif // WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index df089cb7f99..a3d10c0a89d 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -133,6 +133,7 @@ public: KX_PYMETHOD_DOC(KX_BlenderMaterial, getMaterialIndex); KX_PYMETHOD_DOC(KX_BlenderMaterial, getTexture); KX_PYMETHOD_DOC(KX_BlenderMaterial, setTexture); + KX_PYMETHOD_DOC(KX_BlenderMaterial, getTextureBindcode); KX_PYMETHOD_DOC(KX_BlenderMaterial, setBlending); #endif /* WITH_PYTHON */ diff --git a/source/gameengine/VideoTexture/PyTypeList.h b/source/gameengine/VideoTexture/PyTypeList.h index a8716e72e14..ce0eb81e656 100644 --- a/source/gameengine/VideoTexture/PyTypeList.h +++ b/source/gameengine/VideoTexture/PyTypeList.h @@ -66,7 +66,11 @@ public: protected: /// pointer to list of types +#if (__cplusplus > 199711L) /* || (defined(_MSC_VER) && _MSC_VER >= 1800) */ + std::unique_ptr<PyTypeListType> m_list; +#else std::auto_ptr<PyTypeListType> m_list; +#endif }; diff --git a/tests/gtests/blenlib/BLI_ghash_performance_test.cc b/tests/gtests/blenlib/BLI_ghash_performance_test.cc index 817f0b3d10a..709302db021 100644 --- a/tests/gtests/blenlib/BLI_ghash_performance_test.cc +++ b/tests/gtests/blenlib/BLI_ghash_performance_test.cc @@ -196,6 +196,21 @@ static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr TIMEIT_END(int_lookup); } + { + void *k, *v; + + TIMEIT_START(int_pop); + + GHashIterState pop_state = {0}; + + while (BLI_ghash_pop(ghash, &pop_state, &k, &v)) { + EXPECT_EQ(k, v); + } + + TIMEIT_END(int_pop); + } + EXPECT_EQ(0, BLI_ghash_size(ghash)); + BLI_ghash_free(ghash, NULL, NULL); printf("========== ENDED %s ==========\n\n", id); diff --git a/tests/gtests/blenlib/BLI_ghash_test.cc b/tests/gtests/blenlib/BLI_ghash_test.cc index 5fe43d14cbe..ffbe5f5547f 100644 --- a/tests/gtests/blenlib/BLI_ghash_test.cc +++ b/tests/gtests/blenlib/BLI_ghash_test.cc @@ -156,3 +156,45 @@ TEST(ghash, Copy) BLI_ghash_free(ghash, NULL, NULL); BLI_ghash_free(ghash_copy, NULL, NULL); } + +/* Check pop. */ +TEST(ghash, Pop) +{ + GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__); + unsigned int keys[TESTCASE_SIZE], *k; + int i; + + BLI_ghash_flag_set(ghash, GHASH_FLAG_ALLOW_SHRINK); + init_keys(keys, 30); + + for (i = TESTCASE_SIZE, k = keys; i--; k++) { + BLI_ghash_insert(ghash, SET_UINT_IN_POINTER(*k), SET_UINT_IN_POINTER(*k)); + } + + EXPECT_EQ(TESTCASE_SIZE, BLI_ghash_size(ghash)); + + GHashIterState pop_state = {0}; + + for (i = TESTCASE_SIZE / 2; i--; ) { + void *k, *v; + bool success = BLI_ghash_pop(ghash, &pop_state, &k, &v); + EXPECT_EQ(k, v); + EXPECT_EQ(success, true); + + if (i % 2) { + BLI_ghash_insert(ghash, SET_UINT_IN_POINTER(i * 4), SET_UINT_IN_POINTER(i * 4)); + } + } + + EXPECT_EQ((TESTCASE_SIZE - TESTCASE_SIZE / 2 + TESTCASE_SIZE / 4), BLI_ghash_size(ghash)); + + { + void *k, *v; + while (BLI_ghash_pop(ghash, &pop_state, &k, &v)) { + EXPECT_EQ(k, v); + } + } + EXPECT_EQ(0, BLI_ghash_size(ghash)); + + BLI_ghash_free(ghash, NULL, NULL); +} |