diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2016-12-03 00:14:52 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2016-12-03 00:14:52 +0300 |
commit | 8c8b81dfdb3c0529be4cf4a16a3310e6ec26db0a (patch) | |
tree | 6f2572b1c4bc9cd521d4919415d7a7fd4d467f75 | |
parent | be47582c46f831e5c5f34899185a70c3d8ff78ab (diff) | |
parent | 35d490b3f13c75e9a62cb30f3842ed38a27f6dbc (diff) |
Merge remote-tracking branch 'origin/master' into soc-2016-cycles_denoising
85 files changed, 1214 insertions, 632 deletions
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 573ea4577e2..44334612a3a 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -289,7 +289,7 @@ NO_BUILD=false NO_CONFIRM=false USE_CXX11=false -PYTHON_VERSION="3.5.1" +PYTHON_VERSION="3.5.2" PYTHON_VERSION_MIN="3.5" PYTHON_FORCE_BUILD=false PYTHON_FORCE_REBUILD=false @@ -322,7 +322,7 @@ OPENEXR_FORCE_REBUILD=false OPENEXR_SKIP=false _with_built_openexr=false -OIIO_VERSION="1.6.9" +OIIO_VERSION="1.7.8" OIIO_VERSION_MIN="1.6.0" OIIO_VERSION_MAX="1.9.0" # UNKNOWN currently # Not supported by current OSL... OIIO_FORCE_BUILD=false @@ -337,14 +337,14 @@ LLVM_FORCE_REBUILD=false LLVM_SKIP=false # OSL needs to be compiled for now! -OSL_VERSION="1.7.3" +OSL_VERSION="1.7.5" OSL_VERSION_MIN=$OSL_VERSION OSL_FORCE_BUILD=false OSL_FORCE_REBUILD=false OSL_SKIP=false # OpenSubdiv needs to be compiled for now -OSD_VERSION="3.0.5" +OSD_VERSION="3.1.0" OSD_VERSION_MIN=$OSD_VERSION OSD_FORCE_BUILD=false OSD_FORCE_REBUILD=false @@ -372,7 +372,7 @@ OPENCOLLADA_FORCE_BUILD=false OPENCOLLADA_FORCE_REBUILD=false OPENCOLLADA_SKIP=false -FFMPEG_VERSION="2.8.4" +FFMPEG_VERSION="3.2.1" FFMPEG_VERSION_MIN="2.8.4" FFMPEG_FORCE_BUILD=false FFMPEG_FORCE_REBUILD=false diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index 6b7191cd57b..387e53593b3 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -297,8 +297,8 @@ def generic_builder(id, libdir='', branch='', rsync=False): # Builders add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin-9.x.universal', generic_builder, hour=5) -add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1) -add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2) +# add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1) +# add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2) add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=3) add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=4) add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3) diff --git a/build_files/cmake/platform/platform_win32_msvc.cmake b/build_files/cmake/platform/platform_win32_msvc.cmake index 6ca0568b5fd..96c9ec91d11 100644 --- a/build_files/cmake/platform/platform_win32_msvc.cmake +++ b/build_files/cmake/platform/platform_win32_msvc.cmake @@ -112,7 +112,7 @@ 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}") + set(PLATFORM_LINKFLAGS "/MACHINE:X64 ${PLATFORM_LINKFLAGS}") else() set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}") endif() diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h index 611664a2e8a..1894af6b779 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h @@ -77,7 +77,7 @@ namespace std { void resize(size_type new_size) { resize(new_size, T()); } -#if defined(_VECTOR_) +#if defined(_VECTOR_) && (_MSC_VER<1910) // workaround MSVC std::vector implementation void resize(size_type new_size, const value_type& x) { @@ -110,7 +110,7 @@ namespace std { vector_base::insert(vector_base::end(), new_size - vector_base::size(), x); } #else - // either GCC 4.1 or non-GCC + // either GCC 4.1, MSVC2017 or non-GCC // default implementation which should always work. void resize(size_type new_size, const value_type& x) { diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp index 9c1d4443b06..7d850ac7b5f 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.cpp +++ b/intern/audaspace/FX/AUD_LimiterReader.cpp @@ -110,10 +110,10 @@ void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer) eos = true; } - if(position < m_start * rate) + if(position < int(m_start * rate)) { int len2 = length; - for(int len = m_start * rate - position; + for(int len = int(m_start * rate) - position; len2 == length && !eos; len -= length) { diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 607aafbfa1d..3616b13e751 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -288,7 +288,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). " "Zero disables the test and never ignores lights", min=0.0, max=1.0, - default=0.05, + default=0.01, ) cls.caustics_reflective = BoolProperty( diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index f0ef61bdcad..5c99d4d6915 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -150,8 +150,8 @@ void BlenderSession::create_session() /* setup callbacks for builtin image support */ scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7); - scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3); - scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3); + scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4); + scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4); /* create session */ session = new Session(session_params); @@ -1090,7 +1090,13 @@ int BlenderSession::builtin_image_frame(const string &builtin_name) return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str()); } -void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels) +void BlenderSession::builtin_image_info(const string &builtin_name, + void *builtin_data, + bool &is_float, + int &width, + int &height, + int &depth, + int &channels) { /* empty image */ is_float = false; @@ -1168,60 +1174,67 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti } } -bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels) +bool BlenderSession::builtin_image_pixels(const string &builtin_name, + void *builtin_data, + unsigned char *pixels, + const size_t pixels_size) { - if(!builtin_data) + if(!builtin_data) { return false; + } - int frame = builtin_image_frame(builtin_name); + const int frame = builtin_image_frame(builtin_name); PointerRNA ptr; RNA_id_pointer_create((ID*)builtin_data, &ptr); BL::Image b_image(ptr); - int width = b_image.size()[0]; - int height = b_image.size()[1]; - int channels = b_image.channels(); + const int width = b_image.size()[0]; + const int height = b_image.size()[1]; + const int channels = b_image.channels(); - unsigned char *image_pixels; - image_pixels = image_get_pixels_for_frame(b_image, frame); - size_t num_pixels = ((size_t)width) * height; + unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame); + const size_t num_pixels = ((size_t)width) * height; - if(image_pixels) { - memcpy(pixels, image_pixels, num_pixels * channels * sizeof(unsigned char)); + if(image_pixels && num_pixels * channels == pixels_size) { + memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char)); MEM_freeN(image_pixels); } else { if(channels == 1) { - memset(pixels, 0, num_pixels * sizeof(unsigned char)); + memset(pixels, 0, pixels_size * sizeof(unsigned char)); } else { + const size_t num_pixels_safe = pixels_size / channels; unsigned char *cp = pixels; - for(size_t i = 0; i < num_pixels; i++, cp += channels) { + for(size_t i = 0; i < num_pixels_safe; i++, cp += channels) { cp[0] = 255; cp[1] = 0; cp[2] = 255; - if(channels == 4) + if(channels == 4) { cp[3] = 255; + } } } } - - /* premultiply, byte images are always straight for blender */ + /* Premultiply, byte images are always straight for Blender. */ unsigned char *cp = pixels; for(size_t i = 0; i < num_pixels; i++, cp += channels) { cp[0] = (cp[0] * cp[3]) >> 8; cp[1] = (cp[1] * cp[3]) >> 8; cp[2] = (cp[2] * cp[3]) >> 8; } - return true; } -bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels) +bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, + void *builtin_data, + float *pixels, + const size_t pixels_size) { - if(!builtin_data) + if(!builtin_data) { return false; + } PointerRNA ptr; RNA_id_pointer_create((ID*)builtin_data, &ptr); @@ -1232,16 +1245,16 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void BL::Image b_image(b_id); int frame = builtin_image_frame(builtin_name); - int width = b_image.size()[0]; - int height = b_image.size()[1]; - int channels = b_image.channels(); + const int width = b_image.size()[0]; + const int height = b_image.size()[1]; + const int channels = b_image.channels(); float *image_pixels; image_pixels = image_get_float_pixels_for_frame(b_image, frame); - size_t num_pixels = ((size_t)width) * height; + const size_t num_pixels = ((size_t)width) * height; - if(image_pixels) { - memcpy(pixels, image_pixels, num_pixels * channels * sizeof(float)); + if(image_pixels && num_pixels * channels == pixels_size) { + memcpy(pixels, image_pixels, pixels_size * sizeof(float)); MEM_freeN(image_pixels); } else { @@ -1249,13 +1262,15 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void memset(pixels, 0, num_pixels * sizeof(float)); } else { + const size_t num_pixels_safe = pixels_size / channels; float *fp = pixels; - for(int i = 0; i < num_pixels; i++, fp += channels) { + for(int i = 0; i < num_pixels_safe; i++, fp += channels) { fp[0] = 1.0f; fp[1] = 0.0f; fp[2] = 1.0f; - if(channels == 4) + if(channels == 4) { fp[3] = 1.0f; + } } } } @@ -1267,8 +1282,9 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void BL::Object b_ob(b_id); BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob); - if(!b_domain) + if(!b_domain) { return false; + } int3 resolution = get_int3(b_domain.domain_resolution()); int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1; @@ -1280,10 +1296,10 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void amplify = 1; } - int width = resolution.x * amplify; - int height = resolution.y * amplify; - int depth = resolution.z * amplify; - size_t num_pixels = ((size_t)width) * height * depth; + const int width = resolution.x * amplify; + const int height = resolution.y * amplify; + const int depth = resolution.z * amplify; + const size_t num_pixels = ((size_t)width) * height * depth; if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) { SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length); diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index e579f556836..cf8def676b8 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -152,9 +152,21 @@ protected: void do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight); int builtin_image_frame(const string &builtin_name); - void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels); - bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels); - bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels); + void builtin_image_info(const string &builtin_name, + void *builtin_data, + bool &is_float, + int &width, + int &height, + int &depth, + int &channels); + bool builtin_image_pixels(const string &builtin_name, + void *builtin_data, + unsigned char *pixels, + const size_t pixels_size); + bool builtin_image_float_pixels(const string &builtin_name, + void *builtin_data, + float *pixels, + const size_t pixels_size); /* Update tile manager to reflect resumable render settings. */ void update_resumable_tile_manager(int num_samples); diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h index bede5f45e7e..daaa26dc6ad 100644 --- a/intern/cycles/kernel/closure/bsdf_hair.h +++ b/intern/cycles/kernel/closure/bsdf_hair.h @@ -267,7 +267,10 @@ ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng, *eval = make_float3(*pdf, *pdf, *pdf); - kernel_assert(dot(locy, *omega_in) < 0.0f); + /* TODO(sergey): Should always be negative, but seems some precision issue + * is involved here. + */ + kernel_assert(dot(locy, *omega_in) < 1e-4f); return LABEL_TRANSMIT|LABEL_GLOSSY; } diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index 84aaaab7453..636dbcc71e0 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -255,6 +255,17 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte int ka = max(k0 - 1, v00.x); int kb = min(k1 + 1, v00.x + v00.y - 1); +#ifdef __KERNEL_AVX2__ + avxf P_curve_0_1, P_curve_2_3; + if(type & PRIMITIVE_CURVE) { + P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x); + P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x); + } + else { + int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object; + motion_cardinal_curve_keys_avx(kg, fobject, prim, time, ka, k0, k1, kb, &P_curve_0_1,&P_curve_2_3); + } +#else /* __KERNEL_AVX2__ */ ssef P_curve[4]; if(type & PRIMITIVE_CURVE) { @@ -267,6 +278,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object; motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve); } +#endif /* __KERNEL_AVX2__ */ ssef rd_sgn = set_sign_bit<0, 1, 1, 1>(shuffle<0>(rd_ss)); ssef mul_zxxy = shuffle<2, 0, 0, 1>(vdir) * rd_sgn; @@ -278,6 +290,33 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte ssef htfm1 = shuffle<1, 0, 1, 3>(load1f_first(extract<0>(d_ss)), vdir0); ssef htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0); +#ifdef __KERNEL_AVX2__ + const avxf vPP = _mm256_broadcast_ps(&P.m128); + const avxf htfm00 = avxf(htfm0.m128, htfm0.m128); + const avxf htfm11 = avxf(htfm1.m128, htfm1.m128); + const avxf htfm22 = avxf(htfm2.m128, htfm2.m128); + + const avxf p01 = madd(shuffle<0>(P_curve_0_1 - vPP), + htfm00, + madd(shuffle<1>(P_curve_0_1 - vPP), + htfm11, + shuffle<2>(P_curve_0_1 - vPP) * htfm22)); + const avxf p23 = madd(shuffle<0>(P_curve_2_3 - vPP), + htfm00, + madd(shuffle<1>(P_curve_2_3 - vPP), + htfm11, + shuffle<2>(P_curve_2_3 - vPP)*htfm22)); + + const ssef p0 = _mm256_castps256_ps128(p01); + const ssef p1 = _mm256_extractf128_ps(p01, 1); + const ssef p2 = _mm256_castps256_ps128(p23); + const ssef p3 = _mm256_extractf128_ps(p23, 1); + + const ssef P_curve_1 = _mm256_extractf128_ps(P_curve_0_1, 1); + r_st = ((float4 &)P_curve_1).w; + const ssef P_curve_2 = _mm256_castps256_ps128(P_curve_2_3); + r_en = ((float4 &)P_curve_2).w; +#else /* __KERNEL_AVX2__ */ ssef htfm[] = { htfm0, htfm1, htfm2 }; ssef vP = load4f(P); ssef p0 = transform_point_T3(htfm, P_curve[0] - vP); @@ -285,6 +324,10 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte ssef p2 = transform_point_T3(htfm, P_curve[2] - vP); ssef p3 = transform_point_T3(htfm, P_curve[3] - vP); + r_st = ((float4 &)P_curve[1]).w; + r_en = ((float4 &)P_curve[2]).w; +#endif /* __KERNEL_AVX2__ */ + float fc = 0.71f; ssef vfc = ssef(fc); ssef vfcxp3 = vfc * p3; @@ -294,8 +337,6 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte vcurve_coef[2] = madd(ssef(fc * 2.0f), p0, madd(ssef(fc - 3.0f), p1, msub(ssef(3.0f - 2.0f * fc), p2, vfcxp3))); vcurve_coef[3] = msub(ssef(fc - 2.0f), p2 - p1, msub(vfc, p0, vfcxp3)); - r_st = ((float4 &)P_curve[1]).w; - r_en = ((float4 &)P_curve[2]).w; } #else float3 curve_coef[4]; @@ -383,8 +424,9 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte /* begin loop */ while(!(tree >> (depth))) { - float i_st = tree * resol; - float i_en = i_st + (level * resol); + const float i_st = tree * resol; + const float i_en = i_st + (level * resol); + #ifdef __KERNEL_SSE2__ ssef vi_st = ssef(i_st), vi_en = ssef(i_en); ssef vp_st = madd(madd(madd(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]); @@ -458,13 +500,23 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte if(flags & CURVE_KN_RIBBONS) { float3 tg = (p_en - p_st); +#ifdef __KERNEL_SSE__ + const float3 tg_sq = tg * tg; + float w = tg_sq.x + tg_sq.y; +#else float w = tg.x * tg.x + tg.y * tg.y; +#endif if(w == 0) { tree++; level = tree & -tree; continue; } +#ifdef __KERNEL_SSE__ + const float3 p_sttg = p_st * tg; + w = -(p_sttg.x + p_sttg.y) / w; +#else w = -(p_st.x * tg.x + p_st.y * tg.y) / w; +#endif w = saturate(w); /* compute u on the curve segment */ @@ -496,7 +548,13 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte if(difl != 0.0f) { mw_extension = min(difl * fabsf(bmaxz), extmax); r_ext = mw_extension + r_curr; +#ifdef __KERNEL_SSE__ + const float3 p_curr_sq = p_curr * p_curr; + const float3 dxxx = _mm_sqrt_ss(_mm_hadd_ps(p_curr_sq.m128, p_curr_sq.m128)); + float d = dxxx.x; +#else float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y); +#endif float d0 = d - r_curr; float d1 = d + r_curr; float inv_mw_extension = 1.0f/mw_extension; diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h index 6de5aa7ea99..80b33fad68b 100644 --- a/intern/cycles/kernel/geom/geom_motion_curve.h +++ b/intern/cycles/kernel/geom/geom_motion_curve.h @@ -118,7 +118,12 @@ ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg, in } /* return 2 curve key locations */ -ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, int object, int prim, float time, int k0, int k1, int k2, int k3, float4 keys[4]) +ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, + int object, + int prim, + float time, + int k0, int k1, int k2, int k3, + float4 keys[4]) { /* get motion info */ int numsteps, numkeys; @@ -147,6 +152,65 @@ ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, int object, keys[3] = (1.0f - t)*keys[3] + t*next_keys[3]; } +#ifdef __KERNEL_AVX2__ +/* Similar to above, but returns keys as pair of two AVX registers with each + * holding two float4. + */ +ccl_device_inline void motion_cardinal_curve_keys_avx(KernelGlobals *kg, + int object, + int prim, + float time, + int k0, int k1, + int k2, int k3, + avxf *out_keys_0_1, + avxf *out_keys_2_3) +{ + /* Get motion info. */ + int numsteps, numkeys; + object_motion_info(kg, object, &numsteps, NULL, &numkeys); + + /* Figure out which steps we need to fetch and their interpolation factor. */ + int maxstep = numsteps * 2; + int step = min((int)(time*maxstep), maxstep - 1); + float t = time*maxstep - step; + + /* Find attribute. */ + AttributeElement elem; + int offset = find_attribute_curve_motion(kg, + object, + ATTR_STD_MOTION_VERTEX_POSITION, + &elem); + kernel_assert(offset != ATTR_STD_NOT_FOUND); + + /* Fetch key coordinates. */ + float4 next_keys[4]; + float4 keys[4]; + motion_cardinal_curve_keys_for_step(kg, + offset, + numkeys, + numsteps, + step, + k0, k1, k2, k3, + keys); + motion_cardinal_curve_keys_for_step(kg, + offset, + numkeys, + numsteps, + step + 1, + k0, k1, k2, k3, + next_keys); + + const avxf keys_0_1 = avxf(keys[0].m128, keys[1].m128); + const avxf keys_2_3 = avxf(keys[2].m128, keys[3].m128); + const avxf next_keys_0_1 = avxf(next_keys[0].m128, next_keys[1].m128); + const avxf next_keys_2_3 = avxf(next_keys[2].m128, next_keys[3].m128); + + /* Interpolate between steps. */ + *out_keys_0_1 = (1.0f - t) * keys_0_1 + t*next_keys_0_1; + *out_keys_2_3 = (1.0f - t) * keys_2_3 + t*next_keys_2_3; +} +#endif + #endif CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h index aec7bc33acd..67546131746 100644 --- a/intern/cycles/kernel/kernel_jitter.h +++ b/intern/cycles/kernel/kernel_jitter.h @@ -149,6 +149,15 @@ ccl_device_inline uint cmj_hash(uint i, uint p) return i; } +ccl_device_inline uint cmj_hash_simple(uint i, uint p) +{ + i = (i ^ 61) ^ p; + i += i << 3; + i ^= i >> 4; + i *= 0x27d4eb2d; + return i; +} + ccl_device_inline float cmj_randfloat(uint i, uint p) { return cmj_hash(i, p) * (1.0f / 4294967808.0f); diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 2b767da5041..e773753396f 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -120,13 +120,11 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, ccl_addr_space RNG * /* Cranly-Patterson rotation using rng seed */ float shift; - /* using the same *rng value to offset seems to give correlation issues, - * we could hash it with the dimension but this has a performance impact, - * we need to find a solution for this */ - if(dimension & 1) - shift = (*rng >> 16) * (1.0f/(float)0xFFFF); - else - shift = (*rng & 0xFFFF) * (1.0f/(float)0xFFFF); + /* Hash rng with dimension to solve correlation issues. + * See T38710, T50116. + */ + RNG tmp_rng = cmj_hash_simple(dimension, *rng); + shift = tmp_rng * (1.0f/(float)0xFFFFFFFF); return r + shift - floorf(r + shift); #endif diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index dd7b0d9812d..a07ce6be077 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -582,17 +582,12 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance( ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals *kg, PathState *state, ShaderData *sd, Ray *ray, PathRadiance *L, float3 *throughput, RNG *rng, bool heterogeneous) { - /* workaround to fix correlation bug in T38710, can find better solution - * in random number generator later, for now this is done here to not impact - * performance of rendering without volumes */ - RNG tmp_rng = cmj_hash(*rng, state->rng_offset); - shader_setup_from_volume(kg, sd, ray); if(heterogeneous) - return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput, &tmp_rng); + return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput, rng); else - return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, &tmp_rng, true); + return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, rng, true); } /* Decoupled Volume Sampling diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 11193bf4974..ab830b19c57 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -498,6 +498,7 @@ bool ImageManager::file_load_image(Image *img, pixels = (StorageType*)tex_img.resize(width, height, depth); } bool cmyk = false; + const size_t num_pixels = ((size_t)width) * height * depth; if(in) { StorageType *readpixels = pixels; vector<StorageType> tmppixels; @@ -534,12 +535,14 @@ bool ImageManager::file_load_image(Image *img, if(FileFormat == TypeDesc::FLOAT) { builtin_image_float_pixels_cb(img->filename, img->builtin_data, - (float*)&pixels[0]); + (float*)&pixels[0], + num_pixels * components); } else if(FileFormat == TypeDesc::UINT8) { builtin_image_pixels_cb(img->filename, img->builtin_data, - (uchar*)&pixels[0]); + (uchar*)&pixels[0], + num_pixels * components); } else { /* TODO(dingto): Support half for ImBuf. */ @@ -552,7 +555,6 @@ bool ImageManager::file_load_image(Image *img, type == IMAGE_DATA_TYPE_HALF4 || type == IMAGE_DATA_TYPE_BYTE4); if(is_rgba) { - size_t num_pixels = ((size_t)width) * height * depth; if(cmyk) { /* CMYK */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 3da7338985c..47bbd92347c 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -86,9 +86,25 @@ public: bool need_update; - function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels)> builtin_image_info_cb; - function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb; - function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb; + /* NOTE: Here pixels_size is a size of storage, which equals to + * width * height * depth. + * Use this to avoid some nasty memory corruptions. + */ + function<void(const string &filename, + void *data, + bool &is_float, + int &width, + int &height, + int &depth, + int &channels)> builtin_image_info_cb; + function<bool(const string &filename, + void *data, + unsigned char *pixels, + const size_t pixels_size)> builtin_image_pixels_cb; + function<bool(const string &filename, + void *data, + float *pixels, + const size_t pixels_size)> builtin_image_float_pixels_cb; struct Image { string filename; diff --git a/intern/cycles/util/util_avxf.h b/intern/cycles/util/util_avxf.h index 2db2c4dad1a..2451213963a 100644 --- a/intern/cycles/util/util_avxf.h +++ b/intern/cycles/util/util_avxf.h @@ -180,6 +180,14 @@ __forceinline const avxf nmadd(const avxf& a, const avxf& b, const avxf& c) { } #endif +#ifndef _mm256_set_m128 +# define _mm256_set_m128(/* __m128 */ hi, /* __m128 */ lo) \ + _mm256_insertf128_ps(_mm256_castps128_ps256(lo), (hi), 0x1) +#endif + +#define _mm256_loadu2_m128(/* float const* */ hiaddr, /* float const* */ loaddr) \ + _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr)) + CCL_NAMESPACE_END #endif diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 9c7cc583be9..e5512e2e65f 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -596,8 +596,7 @@ ccl_device_inline float len_squared(const float4& a) ccl_device_inline float3 normalize(const float3& a) { - /* TODO(sergey): Disabled for now, causes crashes in certain cases. */ -#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) && 0 +#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) __m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F)); return _mm_div_ps(a.m128, norm); #else @@ -798,8 +797,7 @@ ccl_device_inline float4 operator-(const float4& a) ccl_device_inline float4 operator*(const float4& a, const float4& b) { - /* TODO(sergey): Disabled for now, causes crashes in certain cases. */ -#if defined(__KERNEL_SSE__) && 0 +#ifdef __KERNEL_SSE__ return _mm_mul_ps(a.m128, b.m128); #else return make_float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w); @@ -847,8 +845,7 @@ ccl_device_inline float4 operator/(const float4& a, const float4& b) ccl_device_inline float4 operator+(const float4& a, const float4& b) { - /* TODO(sergey): Disabled for now, causes crashes in certain cases. */ -#if defined(__KERNEL_SSE__) && 0 +#ifdef __KERNEL_SSE__ return _mm_add_ps(a.m128, b.m128); #else return make_float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index ea5eb3b25b0..a0695f20488 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -74,7 +74,7 @@ ccl_device_inline float3 transform_perspective(const Transform *t, const float3 ccl_device_inline float3 transform_point(const Transform *t, const float3 a) { /* TODO(sergey): Disabled for now, causes crashes in certain cases. */ -#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__) && 0 +#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__) ssef x, y, z, w, aa; aa = a.m128; @@ -103,8 +103,7 @@ ccl_device_inline float3 transform_point(const Transform *t, const float3 a) ccl_device_inline float3 transform_direction(const Transform *t, const float3 a) { - /* TODO(sergey): Disabled for now, causes crashes in certain cases. */ -#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__) && 0 +#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__) ssef x, y, z, w, aa; aa = a.m128; x = _mm_loadu_ps(&t->x.x); diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 2aa950f8278..7d80aa43a40 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -353,7 +353,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32() // Release our reference of the DropTarget and it will delete itself eventually. m_dropTarget->Release(); } - + ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL); ::DestroyWindow(m_hWnd); m_hWnd = 0; } diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index 1124e7fd8ab..87629422013 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -23,18 +23,26 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include <string.h> +#include <algorithm> +#include <cstring> #include "MEM_guardedalloc.h" #include "BLI_math_color.h" +#include "BLI_math_vector.h" #include "ocio_impl.h" +using std::max; + #define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr*)1) -#define PROCESSOR_LINEAR_TO_SRGB ((OCIO_ConstProcessorRcPtr*)1) -#define PROCESSOR_SRGB_TO_LINEAR ((OCIO_ConstProcessorRcPtr*)2) -#define PROCESSOR_UNKNOWN ((OCIO_ConstProcessorRcPtr*)3) +enum TransformType { + TRANSFORM_LINEAR_TO_SRGB, + TRANSFORM_SRGB_TO_LINEAR, + TRANSFORM_MATRIX, + TRANSFORM_EXPONENT, + TRANSFORM_UNKNOWN, +}; #define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr*)1) #define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr*)2) @@ -49,6 +57,145 @@ typedef struct OCIO_PackedImageDescription { long yStrideBytes; } OCIO_PackedImageDescription; +struct FallbackTransform { + FallbackTransform() + : type(TRANSFORM_UNKNOWN), + linear_transform(NULL), + display_transform(NULL) + { + } + + ~FallbackTransform() + { + delete linear_transform; + delete display_transform; + } + + void applyRGB(float *pixel) + { + if (type == TRANSFORM_LINEAR_TO_SRGB) { + applyLinearRGB(pixel); + linearrgb_to_srgb_v3_v3(pixel, pixel); + applyDisplayRGB(pixel); + } + else if (type == TRANSFORM_SRGB_TO_LINEAR) { + srgb_to_linearrgb_v3_v3(pixel, pixel); + } + else if (type == TRANSFORM_EXPONENT) { + pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]); + pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]); + pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]); + } + else if (type == TRANSFORM_MATRIX) { + float r = pixel[0]; + float g = pixel[1]; + float b = pixel[2]; + pixel[0] = r*matrix[0] + g*matrix[1] + b*matrix[2]; + pixel[1] = r*matrix[4] + g*matrix[5] + b*matrix[6]; + pixel[2] = r*matrix[8] + g*matrix[9] + b*matrix[10]; + pixel[0] += offset[0]; + pixel[1] += offset[1]; + pixel[2] += offset[2]; + } + } + + void applyRGBA(float *pixel) + { + if (type == TRANSFORM_LINEAR_TO_SRGB) { + applyLinearRGBA(pixel); + linearrgb_to_srgb_v4(pixel, pixel); + applyDisplayRGBA(pixel); + } + else if (type == TRANSFORM_SRGB_TO_LINEAR) { + srgb_to_linearrgb_v4(pixel, pixel); + } + else if (type == TRANSFORM_EXPONENT) { + pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]); + pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]); + pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]); + pixel[3] = powf(max(0.0f, pixel[3]), exponent[3]); + } + else if (type == TRANSFORM_MATRIX) { + float r = pixel[0]; + float g = pixel[1]; + float b = pixel[2]; + float a = pixel[3]; + pixel[0] = r*matrix[0] + g*matrix[1] + b*matrix[2] + a*matrix[3]; + pixel[1] = r*matrix[4] + g*matrix[5] + b*matrix[6] + a*matrix[7]; + pixel[2] = r*matrix[8] + g*matrix[9] + b*matrix[10] + a*matrix[11]; + pixel[3] = r*matrix[12] + g*matrix[13] + b*matrix[14] + a*matrix[15]; + pixel[0] += offset[0]; + pixel[1] += offset[1]; + pixel[2] += offset[2]; + pixel[3] += offset[3]; + } + } + + void applyLinearRGB(float *pixel) + { + if (linear_transform != NULL) { + linear_transform->applyRGB(pixel); + } + } + + void applyLinearRGBA(float *pixel) + { + if (linear_transform != NULL) { + linear_transform->applyRGBA(pixel); + } + } + + void applyDisplayRGB(float *pixel) + { + if (display_transform != NULL) { + display_transform->applyRGB(pixel); + } + } + + void applyDisplayRGBA(float *pixel) + { + if (display_transform != NULL) { + display_transform->applyRGBA(pixel); + } + } + + TransformType type; + FallbackTransform *linear_transform; + FallbackTransform *display_transform; + /* Exponent transform. */ + float exponent[4]; + /* Matrix transform. */ + float matrix[16]; + float offset[4]; + + MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor"); +}; + +struct FallbackProcessor { + FallbackProcessor() + : transform(NULL) + { + } + + ~FallbackProcessor() { + delete transform; + } + + void applyRGB(float *pixel) + { + transform->applyRGB(pixel); + } + + void applyRGBA(float *pixel) + { + transform->applyRGBA(pixel); + } + + FallbackTransform *transform; + + MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor"); +}; + OCIO_ConstConfigRcPtr *FallbackImpl::getCurrentConfig(void) { return CONFIG_DEFAULT; @@ -77,7 +224,8 @@ int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/) return 2; } -const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int index) +const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, + int index) { if (index == 0) return "Linear"; @@ -87,7 +235,8 @@ const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * return NULL; } -OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/, const char *name) +OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/, + const char *name) { if (strcmp(name, "scene_linear") == 0) return COLORSPACE_LINEAR; @@ -109,15 +258,17 @@ OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcP return NULL; } -int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, + const char *name) { OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name); - if (cs == COLORSPACE_LINEAR) + if (cs == COLORSPACE_LINEAR) { return 0; - else if (cs == COLORSPACE_SRGB) + } + else if (cs == COLORSPACE_SRGB) { return 1; - + } return -1; } @@ -131,44 +282,51 @@ int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr * /*config*/) return 1; } -const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, int index) +const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, + int index) { - if (index == 0) + if (index == 0) { return "sRGB"; - + } return NULL; } -const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/) +const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/) { return "Default"; } -int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/) +int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/) { return 1; } -const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, int index) +const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/, int index) { - if (index == 0) + if (index == 0) { return "Default"; - + } return NULL; } -const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, const char * /*view*/) +const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/, + const char * /*view*/) { return "sRGB"; } -void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, float *rgb) +void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, + float *rgb) { - /* Here we simply use the older Blender assumed primaries of - * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute - * force stupid, but only plausible option given no color management - * system in place. - */ + /* Here we simply use the older Blender assumed primaries of + * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute + * force stupid, but only plausible option given no color management + * system in place. + */ rgb[0] = 0.2126f; rgb[1] = 0.7152f; @@ -180,12 +338,14 @@ int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/) return 0; } -const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int /*index*/) +const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, + int /*index*/) { return ""; } -OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/, const char * /*name*/) +OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*name*/) { return NULL; } @@ -213,25 +373,38 @@ void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr * /*cs*/) { } -OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames( + OCIO_ConstConfigRcPtr *config, + const char *srcName, + const char *dstName) { OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName); OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName); - - if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) - return PROCESSOR_LINEAR_TO_SRGB; - else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) - return PROCESSOR_SRGB_TO_LINEAR; - - return 0; + FallbackTransform *transform = new FallbackTransform(); + if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) { + transform->type = TRANSFORM_LINEAR_TO_SRGB; + } + else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) { + transform->type = TRANSFORM_SRGB_TO_LINEAR; + } + else { + transform->type = TRANSFORM_UNKNOWN; + } + FallbackProcessor *processor = new FallbackProcessor(); + processor->transform = transform; + return (OCIO_ConstProcessorRcPtr *)processor; } -OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/, OCIO_ConstTransformRcPtr *tfm) +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/, + OCIO_ConstTransformRcPtr *transform) { - return (OCIO_ConstProcessorRcPtr*)tfm; + FallbackProcessor *processor = new FallbackProcessor(); + processor->transform = (FallbackTransform *)transform; + return (OCIO_ConstProcessorRcPtr *)processor; } -void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, + OCIO_PackedImageDesc *img) { /* OCIO_TODO stride not respected, channels must be 3 or 4 */ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; @@ -253,7 +426,8 @@ void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_Pack } } -void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, + OCIO_PackedImageDesc *img) { /* OCIO_TODO stride not respected, channels must be 3 or 4 */ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; @@ -275,23 +449,20 @@ void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, } } -void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, + float *pixel) { - if (processor == PROCESSOR_LINEAR_TO_SRGB) - linearrgb_to_srgb_v3_v3(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) - srgb_to_linearrgb_v3_v3(pixel, pixel); + ((FallbackProcessor *)processor)->applyRGB(pixel); } -void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, + float *pixel) { - if (processor == PROCESSOR_LINEAR_TO_SRGB) - linearrgb_to_srgb_v4(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) - srgb_to_linearrgb_v4(pixel, pixel); + ((FallbackProcessor *)processor)->applyRGBA(pixel); } -void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, + float *pixel) { if (pixel[3] == 1.0f || pixel[3] == 0.0f) { processorApplyRGBA(processor, pixel); @@ -314,17 +485,19 @@ void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *proces } } -void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr * /*p*/) +void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor) { + delete (FallbackProcessor*)(processor); } const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) { - if (cs == COLORSPACE_LINEAR) + if (cs == COLORSPACE_LINEAR) { return "Linear"; - else if (cs == COLORSPACE_SRGB) + } + else if (cs == COLORSPACE_SRGB) { return "sRGB"; - + } return NULL; } @@ -340,34 +513,47 @@ const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr * /*cs*/ OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void) { - return (OCIO_DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB; + FallbackTransform *transform = new FallbackTransform(); + transform->type = TRANSFORM_LINEAR_TO_SRGB; + return (OCIO_DisplayTransformRcPtr*)transform; } -void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/) +void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*name*/) { } -void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/) +void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*name*/) { } -void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/) +void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*name*/) { } -void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/) +void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, + OCIO_ConstTransformRcPtr *et) { + FallbackTransform *transform = (FallbackTransform *)dt; + transform->display_transform = (FallbackTransform *)et; } -void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/) +void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, + OCIO_ConstTransformRcPtr *et) { + FallbackTransform *transform = (FallbackTransform *)dt; + transform->linear_transform = (FallbackTransform *)et; } -void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*looks*/) +void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*looks*/) { } -void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/, bool /*enabled*/) +void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/, + bool /*enabled*/) { } @@ -375,11 +561,14 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr * /*dt*/) { } -OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) +OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc( + float *data, + long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { - OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription"); - + OCIO_PackedImageDescription *desc = + (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), + "OCIO_PackedImageDescription"); desc->data = data; desc->width = width; desc->height = height; @@ -387,7 +576,6 @@ OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long desc->chanStrideBytes = chanStrideBytes; desc->xStrideBytes = xStrideBytes; desc->yStrideBytes = yStrideBytes; - return (OCIO_PackedImageDesc*)desc; } @@ -398,11 +586,16 @@ void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void) { - return (OCIO_ExponentTransformRcPtr*)PROCESSOR_UNKNOWN; + FallbackTransform *transform = new FallbackTransform(); + transform->type = TRANSFORM_EXPONENT; + return (OCIO_ExponentTransformRcPtr *)transform; } -void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr * /*et*/, const float * /*exponent*/) +void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, + const float *exponent) { + FallbackTransform *transform = (FallbackTransform *)et; + copy_v4_v4(transform->exponent, exponent); } void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/) @@ -411,19 +604,44 @@ void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/ OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void) { - return (OCIO_MatrixTransformRcPtr*)PROCESSOR_UNKNOWN; + FallbackTransform *transform = new FallbackTransform(); + transform->type = TRANSFORM_MATRIX; + return (OCIO_MatrixTransformRcPtr *)transform; } -void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr * /*mt*/, const float * /*m44*/, const float * /*offset4*/) +void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, + const float *m44, + const float *offset4) { + FallbackTransform *transform = (FallbackTransform *)mt; + copy_m4_m4((float (*)[4])transform->matrix, (float (*)[4])m44); + copy_v4_v4(transform->offset, offset4); } void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr * /*mt*/) { } -void FallbackImpl::matrixTransformScale(float * /*m44*/, float * /*offset44*/, const float * /*scale4*/) +void FallbackImpl::matrixTransformScale(float *m44, + float *offset4, + const float *scale4) { + if (scale4 == NULL) { + return; + } + if (m44 != NULL) { + memset(m44, 0, 16*sizeof(float)); + m44[0] = scale4[0]; + m44[5] = scale4[1]; + m44[10] = scale4[2]; + m44[15] = scale4[3]; + } + if (offset4 != NULL) { + offset4[0] = 0.0f; + offset4[1] = 0.0f; + offset4[2] = 0.0f; + offset4[3] = 0.0f; + } } bool FallbackImpl::supportGLSLDraw(void) @@ -431,9 +649,11 @@ bool FallbackImpl::supportGLSLDraw(void) return false; } -bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/, +bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, + OCIO_ConstProcessorRcPtr * /*processor*/, OCIO_CurveMappingSettings * /*curve_mapping_settings*/, - float /*dither*/, bool /*predivide*/) + float /*dither*/, + bool /*predivide*/) { return false; } diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 9de9376312c..5e936076d0e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3053,11 +3053,18 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() layout.menu("VIEW3D_MT_object_animation") # NOTE: provides keyingset access... + layout.menu("VIEW3D_MT_edit_gpencil_interpolate") layout.separator() layout.menu("VIEW3D_MT_edit_gpencil_delete") layout.operator("gpencil.duplicate_move", text="Duplicate") + layout.operator("gpencil.stroke_subdivide", text="Subdivide") + + layout.separator() + + layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...") + layout.operator("gpencil.stroke_flip", text="Flip Direction") layout.separator() @@ -3077,6 +3084,11 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") + layout.operator("gpencil.stroke_change_color", text="Move to Color") + layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") + + layout.separator() + layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...") @@ -3097,6 +3109,20 @@ class VIEW3D_MT_edit_gpencil_transform(Menu): layout.operator("transform.tosphere", text="To Sphere") layout.operator("transform.transform", text="Shrink Fatten").mode = 'GPENCIL_SHRINKFATTEN' + layout.separator() + + layout.operator("gpencil.reproject") + + +class VIEW3D_MT_edit_gpencil_interpolate(Menu): + bl_label = "Interpolate" + + def draw(self, context): + layout = self.layout + + layout.operator("gpencil.interpolate", text="Interpolate") + layout.operator("gpencil.interpolate_sequence", text="Sequence") + # ********** Panel ********** diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc index d5271e3ca31..4f70b2a972c 100644 --- a/source/blender/alembic/intern/abc_camera.cc +++ b/source/blender/alembic/intern/abc_camera.cc @@ -138,11 +138,11 @@ void AbcCameraReader::readObjectData(Main *bmain, float time) bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel); } - const float lens = cam_sample.getFocalLength(); - const float apperture_x = cam_sample.getHorizontalAperture(); - const float apperture_y = cam_sample.getVerticalAperture(); - const float h_film_offset = cam_sample.getHorizontalFilmOffset(); - const float v_film_offset = cam_sample.getVerticalFilmOffset(); + const float lens = static_cast<float>(cam_sample.getFocalLength()); + const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture()); + const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture()); + const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset()); + const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset()); const float film_aspect = apperture_x / apperture_y; bcam->lens = lens; @@ -150,10 +150,10 @@ void AbcCameraReader::readObjectData(Main *bmain, float time) bcam->sensor_y = apperture_y * 10; bcam->shiftx = h_film_offset / apperture_x; bcam->shifty = v_film_offset / apperture_y / film_aspect; - bcam->clipsta = max_ff(0.1f, cam_sample.getNearClippingPlane()); - bcam->clipend = cam_sample.getFarClippingPlane(); - bcam->gpu_dof.focus_distance = cam_sample.getFocusDistance(); - bcam->gpu_dof.fstop = cam_sample.getFStop(); + bcam->clipsta = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane())); + bcam->clipend = static_cast<float>(cam_sample.getFarClippingPlane()); + bcam->gpu_dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance()); + bcam->gpu_dof.fstop = static_cast<float>(cam_sample.getFStop()); m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str()); m_object->data = bcam; diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc index 7e5ea3b1853..4ecb9d944f2 100644 --- a/source/blender/alembic/intern/abc_curves.cc +++ b/source/blender/alembic/intern/abc_curves.cc @@ -361,7 +361,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time) * object directly and create a new DerivedMesh from that. Also we might need to * create new or delete existing NURBS in the curve. */ -DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/) +DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/, const char **/*err_str*/) { ISampleSelector sample_sel(time); const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel); diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h index 979ee8af639..2757d179a47 100644 --- a/source/blender/alembic/intern/abc_curves.h +++ b/source/blender/alembic/intern/abc_curves.h @@ -56,7 +56,7 @@ public: bool valid() const; void readObjectData(Main *bmain, float time); - DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int); + DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int read_flag, const char **err_str); }; /* ************************************************************************** */ diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h index bc42e24eba1..9e671fde386 100644 --- a/source/blender/alembic/intern/abc_customdata.h +++ b/source/blender/alembic/intern/abc_customdata.h @@ -26,6 +26,7 @@ #define __ABC_CUSTOMDATA_H__ #include <Alembic/Abc/All.h> +#include <Alembic/AbcGeom/All.h> struct CustomData; struct MLoop; @@ -65,8 +66,8 @@ struct CDStreamConfig { float weight; float time; - int index; - int ceil_index; + Alembic::AbcGeom::index_t index; + Alembic::AbcGeom::index_t ceil_index; CDStreamConfig() : mloop(NULL) diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index d259721e192..ff8b0442ab6 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -176,13 +176,13 @@ void AbcExporter::getShutterSamples(double step, bool time_relative, /* sample all frame */ if (shutter_open == 0.0 && shutter_close == 1.0) { - for (double t = 0; t < 1.0; t += step) { + for (double t = 0.0; t < 1.0; t += step) { samples.push_back((t + m_settings.frame_start) / time_factor); } } else { /* sample between shutter open & close */ - const int nsamples = std::max((1.0 / step) - 1.0, 1.0); + const int nsamples = static_cast<int>(std::max((1.0 / step) - 1.0, 1.0)); const double time_inc = (shutter_close - shutter_open) / nsamples; for (double t = shutter_open; t <= shutter_close; t += time_inc) { @@ -217,7 +217,7 @@ void AbcExporter::getFrameSet(double step, std::set<double> &frames) getShutterSamples(step, false, shutter_samples); - for (int frame = m_settings.frame_start; frame <= m_settings.frame_end; ++frame) { + for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) { for (int j = 0, e = shutter_samples.size(); j < e; ++j) { frames.insert(frame + shutter_samples[j]); } @@ -238,9 +238,9 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) } Scene *scene = m_scene; - const int fps = FPS; + const double fps = FPS; char buf[16]; - snprintf(buf, 15, "%d", fps); + snprintf(buf, 15, "%f", fps); const std::string str_fps = buf; Alembic::AbcCoreAbstract::MetaData md; @@ -578,7 +578,7 @@ AbcTransformWriter *AbcExporter::getXForm(const std::string &name) void AbcExporter::setCurrentFrame(Main *bmain, double t) { - m_scene->r.cfra = std::floor(t); - m_scene->r.subframe = t - m_scene->r.cfra; + m_scene->r.cfra = static_cast<int>(t); + m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene, m_scene->lay); } diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 5b282e3c5bb..bdd75f93189 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -868,53 +868,6 @@ ABC_INLINE void read_normals_params(AbcMeshData &abc_data, } } -/* ************************************************************************** */ - -AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings) - : AbcObjectReader(object, settings) -{ - m_settings->read_flag |= MOD_MESHSEQ_READ_ALL; - - IPolyMesh ipoly_mesh(m_iobject, kWrapExisting); - m_schema = ipoly_mesh.getSchema(); - - get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time); -} - -bool AbcMeshReader::valid() const -{ - return m_schema.valid(); -} - -void AbcMeshReader::readObjectData(Main *bmain, float time) -{ - Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str()); - - m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str()); - m_object->data = mesh; - - const ISampleSelector sample_sel(time); - - DerivedMesh *dm = CDDM_from_mesh(mesh); - DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL); - - if (ndm != dm) { - dm->release(dm); - } - - DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true); - - if (m_settings->validate_meshes) { - BKE_mesh_validate(mesh, false, false); - } - - readFaceSetsSample(bmain, mesh, 0, sample_sel); - - if (has_animations(m_schema, m_settings)) { - addCacheModifier(); - } -} - static bool check_smooth_poly_flag(DerivedMesh *dm) { MPoly *mpolys = dm->getPolyArray(dm); @@ -962,6 +915,66 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type) return cd_ptr; } +static void get_weight_and_index(CDStreamConfig &config, + Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling, + size_t samples_number) +{ + Alembic::AbcGeom::index_t i0, i1; + + config.weight = get_weight_and_index(config.time, + time_sampling, + samples_number, + i0, + i1); + + config.index = i0; + config.ceil_index = i1; +} + +static void read_mesh_sample(ImportSettings *settings, + const IPolyMeshSchema &schema, + const ISampleSelector &selector, + CDStreamConfig &config, + bool &do_normals) +{ + const IPolyMeshSchema::Sample sample = schema.getValue(selector); + + AbcMeshData abc_mesh_data; + abc_mesh_data.face_counts = sample.getFaceCounts(); + abc_mesh_data.face_indices = sample.getFaceIndices(); + abc_mesh_data.positions = sample.getPositions(); + + read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector); + + do_normals = (abc_mesh_data.face_normals != NULL); + + get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples()); + + if (config.weight != 0.0f) { + Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample; + schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index)); + abc_mesh_data.ceil_positions = ceil_sample.getPositions(); + } + + if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) { + read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector); + } + + if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) { + read_mverts(config, abc_mesh_data); + } + + if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) { + read_mpolys(config, abc_mesh_data); + } + + if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { + read_custom_data(schema.getArbGeomParams(), config, selector); + } + + /* TODO: face sets */ +} + CDStreamConfig get_config(DerivedMesh *dm) { CDStreamConfig config; @@ -978,7 +991,54 @@ CDStreamConfig get_config(DerivedMesh *dm) return config; } -DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag) +/* ************************************************************************** */ + +AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings) + : AbcObjectReader(object, settings) +{ + m_settings->read_flag |= MOD_MESHSEQ_READ_ALL; + + IPolyMesh ipoly_mesh(m_iobject, kWrapExisting); + m_schema = ipoly_mesh.getSchema(); + + get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time); +} + +bool AbcMeshReader::valid() const +{ + return m_schema.valid(); +} + +void AbcMeshReader::readObjectData(Main *bmain, float time) +{ + Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str()); + + m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str()); + m_object->data = mesh; + + const ISampleSelector sample_sel(time); + + DerivedMesh *dm = CDDM_from_mesh(mesh); + DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL); + + if (ndm != dm) { + dm->release(dm); + } + + DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true); + + if (m_settings->validate_meshes) { + BKE_mesh_validate(mesh, false, false); + } + + readFaceSetsSample(bmain, mesh, 0, sample_sel); + + if (has_animations(m_schema, m_settings)) { + addCacheModifier(); + } +} + +DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str) { ISampleSelector sample_sel(time); const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel); @@ -1003,6 +1063,21 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, settings.read_flag |= MOD_MESHSEQ_READ_ALL; } + else { + /* If the face count changed (e.g. by triangulation), only read points. + * This prevents crash from T49813. + * TODO(kevin): perhaps find a better way to do this? */ + if (face_counts->size() != dm->getNumPolys(dm) || + face_indices->size() != dm->getNumLoops(dm)) + { + settings.read_flag = MOD_MESHSEQ_READ_VERT; + + if (err_str) { + *err_str = "Topology has changed, perhaps by triangulating the" + " mesh. Only vertices will be read!"; + } + } + } CDStreamConfig config = get_config(new_dm ? new_dm : dm); config.time = time; @@ -1078,44 +1153,40 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star utils::assign_materials(bmain, m_object, mat_map); } -static void get_weight_and_index(CDStreamConfig &config, - Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling, - size_t samples_number) +/* ************************************************************************** */ + +ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2) { - Alembic::AbcGeom::index_t i0, i1; + for (int i = 0, e = totedge; i < e; ++i) { + MEdge &edge = edges[i]; - config.weight = get_weight_and_index(config.time, - time_sampling, - samples_number, - i0, - i1); + if (edge.v1 == v1 && edge.v2 == v2) { + return &edge; + } + } - config.index = i0; - config.ceil_index = i1; + return NULL; } -void read_mesh_sample(ImportSettings *settings, - const IPolyMeshSchema &schema, - const ISampleSelector &selector, - CDStreamConfig &config, - bool &do_normals) +static void read_subd_sample(ImportSettings *settings, + const ISubDSchema &schema, + const ISampleSelector &selector, + CDStreamConfig &config) { - const IPolyMeshSchema::Sample sample = schema.getValue(selector); + const ISubDSchema::Sample sample = schema.getValue(selector); AbcMeshData abc_mesh_data; abc_mesh_data.face_counts = sample.getFaceCounts(); abc_mesh_data.face_indices = sample.getFaceIndices(); + abc_mesh_data.vertex_normals = N3fArraySamplePtr(); + abc_mesh_data.face_normals = N3fArraySamplePtr(); abc_mesh_data.positions = sample.getPositions(); - read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector); - - do_normals = (abc_mesh_data.face_normals != NULL); - get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples()); if (config.weight != 0.0f) { - Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample; - schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index))); + Alembic::AbcGeom::ISubDSchema::Sample ceil_sample; + schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index)); abc_mesh_data.ceil_positions = ceil_sample.getPositions(); } @@ -1140,19 +1211,6 @@ void read_mesh_sample(ImportSettings *settings, /* ************************************************************************** */ -ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2) -{ - for (int i = 0, e = totedge; i < e; ++i) { - MEdge &edge = edges[i]; - - if (edge.v1 == v1 && edge.v2 == v2) { - return &edge; - } - } - - return NULL; -} - AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings) : AbcObjectReader(object, settings) { @@ -1177,7 +1235,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time) m_object->data = mesh; DerivedMesh *dm = CDDM_from_mesh(mesh); - DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL); + DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL); if (ndm != dm) { dm->release(dm); @@ -1216,48 +1274,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time) } } -void read_subd_sample(ImportSettings *settings, - const ISubDSchema &schema, - const ISampleSelector &selector, - CDStreamConfig &config) -{ - const ISubDSchema::Sample sample = schema.getValue(selector); - - AbcMeshData abc_mesh_data; - abc_mesh_data.face_counts = sample.getFaceCounts(); - abc_mesh_data.face_indices = sample.getFaceIndices(); - abc_mesh_data.vertex_normals = N3fArraySamplePtr(); - abc_mesh_data.face_normals = N3fArraySamplePtr(); - abc_mesh_data.positions = sample.getPositions(); - - get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples()); - - if (config.weight != 0.0f) { - Alembic::AbcGeom::ISubDSchema::Sample ceil_sample; - schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index))); - abc_mesh_data.ceil_positions = ceil_sample.getPositions(); - } - - if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) { - read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector); - } - - if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) { - read_mverts(config, abc_mesh_data); - } - - if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) { - read_mpolys(config, abc_mesh_data); - } - - if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { - read_custom_data(schema.getArbGeomParams(), config, selector); - } - - /* TODO: face sets */ -} - -DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag) +DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str) { ISampleSelector sample_sel(time); const ISubDSchema::Sample sample = m_schema.getValue(sample_sel); @@ -1281,6 +1298,21 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, settings.read_flag |= MOD_MESHSEQ_READ_ALL; } + else { + /* If the face count changed (e.g. by triangulation), only read points. + * This prevents crash from T49813. + * TODO(kevin): perhaps find a better way to do this? */ + if (face_counts->size() != dm->getNumPolys(dm) || + face_indices->size() != dm->getNumLoops(dm)) + { + settings.read_flag = MOD_MESHSEQ_READ_VERT; + + if (err_str) { + *err_str = "Topology has changed, perhaps by triangulating the" + " mesh. Only vertices will be read!"; + } + } + } /* Only read point data when streaming meshes, unless we need to create new ones. */ CDStreamConfig config = get_config(new_dm ? new_dm : dm); diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 66e6585a3d3..64a3109232c 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -102,19 +102,13 @@ public: void readObjectData(Main *bmain, float time); - DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str); private: void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, const Alembic::AbcGeom::ISampleSelector &sample_sel); }; -void read_mesh_sample(ImportSettings *settings, - const Alembic::AbcGeom::IPolyMeshSchema &schema, - const Alembic::AbcGeom::ISampleSelector &selector, - CDStreamConfig &config, - bool &do_normals); - /* ************************************************************************** */ class AbcSubDReader : public AbcObjectReader { @@ -128,14 +122,9 @@ public: bool valid() const; void readObjectData(Main *bmain, float time); - DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str); }; -void read_subd_sample(ImportSettings *settings, - const Alembic::AbcGeom::ISubDSchema &schema, - const Alembic::AbcGeom::ISampleSelector &selector, - CDStreamConfig &config); - /* ************************************************************************** */ void read_mverts(MVert *mverts, diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc index 314b2568bed..9dfccdb8c7f 100644 --- a/source/blender/alembic/intern/abc_object.cc +++ b/source/blender/alembic/intern/abc_object.cc @@ -170,13 +170,13 @@ static Imath::M44d blend_matrices(const Imath::M44d &m0, const Imath::M44d &m1, for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { - mat0[i][j] = m0[i][j]; + mat0[i][j] = static_cast<float>(m0[i][j]); } } for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { - mat1[i][j] = m1[i][j]; + mat1[i][j] = static_cast<float>(m1[i][j]); } } diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h index 7ff927b4d33..0f733e67d3f 100644 --- a/source/blender/alembic/intern/abc_object.h +++ b/source/blender/alembic/intern/abc_object.h @@ -76,7 +76,7 @@ private: /* ************************************************************************** */ -class CacheFile; +struct CacheFile; struct ImportSettings { bool do_convert_mat; @@ -165,10 +165,11 @@ public: virtual void readObjectData(Main *bmain, float time) = 0; - virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag) + virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str) { (void)time; (void)read_flag; + (void)err_str; return dm; } diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc index c16da621c77..4c78f3e83c7 100644 --- a/source/blender/alembic/intern/abc_points.cc +++ b/source/blender/alembic/intern/abc_points.cc @@ -156,7 +156,7 @@ void AbcPointsReader::readObjectData(Main *bmain, float time) Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str()); DerivedMesh *dm = CDDM_from_mesh(mesh); - DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0); + DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0, NULL); if (ndm != dm) { dm->release(dm); @@ -189,7 +189,8 @@ void read_points_sample(const IPointsSchema &schema, N3fArraySamplePtr vnormals; if (has_property(prop, "N")) { - const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", time); + const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(time); + const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime); if (normals_prop) { vnormals = normals_prop.getValue(selector); @@ -199,7 +200,7 @@ void read_points_sample(const IPointsSchema &schema, read_mverts(config.mvert, positions, vnormals); } -DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/) +DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/, const char **/*err_str*/) { ISampleSelector sample_sel(time); const IPointsSchema::Sample sample = m_schema.getValue(sample_sel); diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h index 54873eed346..cb68dbca4d5 100644 --- a/source/blender/alembic/intern/abc_points.h +++ b/source/blender/alembic/intern/abc_points.h @@ -28,7 +28,7 @@ #include "abc_object.h" #include "abc_customdata.h" -class ParticleSystem; +struct ParticleSystem; /* ************************************************************************** */ @@ -61,7 +61,7 @@ public: void readObjectData(Main *bmain, float time); - DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str); }; void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema, diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc index 979a72fcf4e..f8ce72d845d 100644 --- a/source/blender/alembic/intern/abc_util.cc +++ b/source/blender/alembic/intern/abc_util.cc @@ -215,7 +215,7 @@ void convert_matrix(const Imath::M44d &xform, Object *ob, { for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { - r_mat[i][j] = xform[i][j]; + r_mat[i][j] = static_cast<float>(xform[i][j]); } } diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h index 2f423a9f8c5..60a96855d14 100644 --- a/source/blender/alembic/intern/abc_util.h +++ b/source/blender/alembic/intern/abc_util.h @@ -39,7 +39,7 @@ struct CacheReader { using Alembic::Abc::chrono_t; class AbcObjectReader; -class ImportSettings; +struct ImportSettings; struct ID; struct Object; diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index e690a255505..d8d017119b1 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -625,8 +625,8 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa CFRA = SFRA; } else if (min_time < max_time) { - SFRA = min_time * FPS; - EFRA = max_time * FPS; + SFRA = static_cast<int>(min_time * FPS); + EFRA = static_cast<int>(max_time * FPS); CFRA = SFRA; } } @@ -816,7 +816,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader, return NULL; } - return abc_reader->read_derivedmesh(dm, time, read_flag); + return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); } else if (ISubD::matches(header)) { if (ob->type != OB_MESH) { @@ -824,7 +824,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader, return NULL; } - return abc_reader->read_derivedmesh(dm, time, read_flag); + return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); } else if (IPoints::matches(header)) { if (ob->type != OB_MESH) { @@ -832,7 +832,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader, return NULL; } - return abc_reader->read_derivedmesh(dm, time, read_flag); + return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); } else if (ICurves::matches(header)) { if (ob->type != OB_CURVE) { @@ -840,7 +840,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader, return NULL; } - return abc_reader->read_derivedmesh(dm, time, read_flag); + return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); } *err_str = "Unsupported object type: verify object path"; // or poke developer diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 00ea323f934..a67e903877a 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -73,7 +73,7 @@ struct AnimData *BKE_animdata_copy(struct AnimData *adt, const bool do_action); bool BKE_animdata_copy_id(struct ID *id_to, struct ID *id_from, const bool do_action); /* Copy AnimData Actions */ -void BKE_animdata_copy_id_action(struct ID *id); +void BKE_animdata_copy_id_action(struct ID *id, const bool set_newid); /* Merge copies of data from source AnimData block */ typedef enum eAnimData_MergeCopy_Modes { diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 855eb10976c..77ea7ecbefb 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -80,6 +80,7 @@ void id_us_plus(struct ID *id); void id_us_min(struct ID *id); void id_fake_user_set(struct ID *id); void id_fake_user_clear(struct ID *id); +void BKE_id_clear_newpoin(struct ID *id); void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_in_mainlist, const bool lib_local); bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ae18f5289d4..1f937d837b4 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -230,7 +230,9 @@ static MPoly *dm_dupPolyArray(DerivedMesh *dm) static int dm_getNumLoopTri(DerivedMesh *dm) { - return dm->looptris.num; + const int numlooptris = poly_to_tri_count(dm->getNumPolys(dm), dm->getNumLoops(dm)); + BLI_assert(ELEM(dm->looptris.num, 0, numlooptris)); + return numlooptris; } static CustomData *dm_getVertCData(DerivedMesh *dm) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index a5abc6beff8..21279392392 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -308,17 +308,19 @@ bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action) return true; } -void BKE_animdata_copy_id_action(ID *id) +void BKE_animdata_copy_id_action(ID *id, const bool set_newid) { AnimData *adt = BKE_animdata_from_id(id); if (adt) { if (adt->action) { id_us_min((ID *)adt->action); - adt->action = BKE_action_copy(G.main, adt->action); + adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(G.main, adt->action)) : + BKE_action_copy(G.main, adt->action); } if (adt->tmpact) { id_us_min((ID *)adt->tmpact); - adt->tmpact = BKE_action_copy(G.main, adt->tmpact); + adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(G.main, adt->tmpact)) : + BKE_action_copy(G.main, adt->tmpact); } } } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 8ef1fae1155..0d509ecea06 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -249,6 +249,9 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local) brush_new->id.us = 0; + /* setting newid is mandatory for complex make_lib_local logic... */ + ID_NEW_SET(brush, brush_new); + if (!lib_local) { BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE); } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 85ce399b770..9cb553aa27b 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -252,7 +252,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, const View3D *v3d, cons } else if (rv3d->persp == RV3D_ORTHO) { /* orthographic view */ - int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y); + float sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y); params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality params->clipsta = -params->clipend; @@ -337,6 +337,8 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win viewplane.ymin *= pixsize; viewplane.ymax *= pixsize; + /* Used for rendering (offset by near-clip with perspective views), passed to RE_SetPixelSize. + * For viewport drawing 'RegionView3D.pixsize'. */ params->viewdx = pixsize; params->viewdy = params->ycor * pixsize; params->viewplane = viewplane; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 50f8423bbff..7361645ba2c 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1428,7 +1428,6 @@ static void scene_sort_groups(Main *bmain, Scene *sce) /* test; are group objects all in this scene? */ for (ob = bmain->object.first; ob; ob = ob->id.next) { ob->id.tag &= ~LIB_TAG_DOIT; - ob->id.newid = NULL; /* newid abuse for GroupObject */ } for (base = sce->base.first; base; base = base->next) base->object->id.tag |= LIB_TAG_DOIT; @@ -1459,6 +1458,11 @@ static void scene_sort_groups(Main *bmain, Scene *sce) group->gobject = listb; } } + + /* newid abused for GroupObject, cleanup. */ + for (ob = bmain->object.first; ob; ob = ob->id.next) { + ob->id.newid = NULL; + } } static void dag_scene_tag_rebuild(Scene *sce) diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 05cf5f6d7bd..e7c0e69b1cb 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -621,10 +621,33 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm)) /* do nothing */ } -static void emDM_recalcLoopTri(DerivedMesh *UNUSED(dm)) +static void emDM_recalcLoopTri(DerivedMesh *dm) { - /* Nothing to do: emDM tessellation is known, - * allocate and fill in with emDM_getLoopTriArray */ + EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; + BMLoop *(*looptris)[3] = bmdm->em->looptris; + MLoopTri *mlooptri; + const int tottri = bmdm->em->tottri; + int i; + + DM_ensure_looptri_data(dm); + mlooptri = dm->looptris.array; + + BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); + BLI_assert(tottri == dm->looptris.num); + + BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP); + + for (i = 0; i < tottri; i++) { + BMLoop **ltri = looptris[i]; + MLoopTri *lt = &mlooptri[i]; + + ARRAY_SET_ITEMS( + lt->tri, + BM_elem_index_get(ltri[0]), + BM_elem_index_get(ltri[1]), + BM_elem_index_get(ltri[2])); + lt->poly = BM_elem_index_get(ltri[0]->f); + } } static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm) @@ -633,32 +656,9 @@ static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm) BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); } else { - EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; - BMLoop *(*looptris)[3] = bmdm->em->looptris; - MLoopTri *mlooptri; - const int tottri = bmdm->em->tottri; - int i; - - DM_ensure_looptri_data(dm); - mlooptri = dm->looptris.array; - - BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); - BLI_assert(tottri == dm->looptris.num); - - BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP); - - for (i = 0; i < tottri; i++) { - BMLoop **ltri = looptris[i]; - MLoopTri *lt = &mlooptri[i]; - - ARRAY_SET_ITEMS( - lt->tri, - BM_elem_index_get(ltri[0]), - BM_elem_index_get(ltri[1]), - BM_elem_index_get(ltri[2])); - lt->poly = BM_elem_index_get(ltri[0]->f); - } + dm->recalcLoopTri(dm); } + return dm->looptris.array; } diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 2242113b79b..cd2eac078cf 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -382,7 +382,8 @@ bGPDpalette *BKE_gpencil_palette_addnew(bGPdata *gpd, const char *name, bool set sizeof(palette->info)); /* make this one the active one */ - if (setactive) { + /* NOTE: Always make this active if there's nothing else yet (T50123) */ + if ((setactive) || (gpd->palettes.first == gpd->palettes.last)) { BKE_gpencil_palette_setactive(gpd, palette); } @@ -1263,7 +1264,11 @@ void BKE_gpencil_palettecolor_changename(bGPdata *gpd, char *oldname, const char bGPDlayer *gpl; bGPDframe *gpf; bGPDstroke *gps; - + + /* Sanity checks (gpd may not be set in the RNA pointers sometimes) */ + if (ELEM(NULL, gpd, oldname, newname)) + return; + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { for (gps = gpf->strokes.first; gps; gps = gps->next) { @@ -1282,7 +1287,11 @@ void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name) bGPDlayer *gpl; bGPDframe *gpf; bGPDstroke *gps, *gpsn; - + + /* Sanity checks (gpd may not be set in the RNA pointers sometimes) */ + if (ELEM(NULL, gpd, name)) + return; + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { for (gps = gpf->strokes.first; gps; gps = gpsn) { diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c9bad2160ff..a2d94ccc478 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -436,7 +436,6 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src) Image *BKE_image_copy(Main *bmain, Image *ima) { Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type); - ima->id.newid = &nima->id; BLI_strncpy(nima->name, ima->name, sizeof(ima->name)); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 3411eae22e1..31c10c843da 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -263,6 +263,14 @@ void id_fake_user_clear(ID *id) } } +void BKE_id_clear_newpoin(ID *id) +{ + if (id->newid) { + id->newid->tag &= ~LIB_TAG_NEW; + } + id->newid = NULL; +} + static int id_expand_local_callback( void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int UNUSED(cd_flag)) { @@ -326,6 +334,17 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c if (id_copy(bmain, id, &id_new, false)) { id_new->us = 0; + /* setting newid is mandatory for complex make_lib_local logic... */ + ID_NEW_SET(id, id_new); + Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id); + if (key && key_new) { + ID_NEW_SET(key, key_new); + } + bNodeTree *ntree = ntreeFromID(id), *ntree_new = ntreeFromID(id_new); + if (ntree && ntree_new) { + ID_NEW_SET(ntree, ntree_new); + } + if (!lib_local) { BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE); } @@ -337,6 +356,8 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c /** * Calls the appropriate make_local method for the block, unless test is set. * + * \note Always set ID->newid pointer in case it gets duplicated... + * * \param lib_local Special flag used when making a whole library's content local, it needs specific handling. * * \return true if the block can be made local. @@ -561,6 +582,7 @@ bool id_copy(Main *bmain, ID *id, ID **newid, bool test) return false; } +/** Does *not* set ID->newid pointer. */ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop) { ID *newid = NULL; @@ -571,11 +593,11 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop) if (RNA_property_editable(ptr, prop)) { if (id_copy(CTX_data_main(C), id, &newid, false) && newid) { /* copy animation actions too */ - BKE_animdata_copy_id_action(id); + BKE_animdata_copy_id_action(id, false); /* us is 1 by convention, but RNA_property_pointer_set * will also increment it, so set it to zero */ newid->us = 0; - + /* assign copy */ RNA_id_pointer_create(newid, &idptr); RNA_property_pointer_set(ptr, prop, idptr); @@ -1120,9 +1142,6 @@ void *BKE_libblock_copy(Main *bmain, ID *id) memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID)); } - - id->newid = idn; - idn->tag |= LIB_TAG_NEW; BKE_libblock_copy_data(idn, id, false); @@ -1147,8 +1166,6 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action) memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID)); } - id->newid = idn; - idn->tag |= LIB_TAG_NEW; idn->us = 1; BKE_libblock_copy_data(idn, id, do_action); @@ -1662,7 +1679,6 @@ void BKE_library_make_local( const bool do_skip = (id && !BKE_idcode_is_linkable(GS(id->name))); for (; id; id = id->next) { - id->newid = NULL; id->tag &= ~LIB_TAG_DOIT; if (id->lib == NULL) { @@ -1862,6 +1878,7 @@ void BKE_library_make_local( } } + BKE_main_id_clear_newpoins(bmain); BLI_memarena_free(linklist_mem); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4489ca907f6..c6666ec5ced 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1215,6 +1215,9 @@ void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, con ob_new->id.us = 0; ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL; + /* setting newid is mandatory for complex make_lib_local logic... */ + ID_NEW_SET(ob, ob_new); + if (!lib_local) { BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE); } diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index ebf9f017731..628222ed306 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -225,8 +225,8 @@ RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) /* preserve relationships between constraints and rigid bodies after duplication */ void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc) { - ID_NEW(rbc->ob1); - ID_NEW(rbc->ob2); + ID_NEW_REMAP(rbc->ob1); + ID_NEW_REMAP(rbc->ob2); } /* ************************************** */ diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index c7f406089d9..fa221348932 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -602,41 +602,41 @@ void set_sca_new_poins_ob(Object *ob) if (act->flag & ACT_NEW) { if (act->type==ACT_EDIT_OBJECT) { bEditObjectActuator *eoa= act->data; - ID_NEW(eoa->ob); + ID_NEW_REMAP(eoa->ob); } else if (act->type==ACT_SCENE) { bSceneActuator *sca= act->data; - ID_NEW(sca->camera); + ID_NEW_REMAP(sca->camera); } else if (act->type==ACT_CAMERA) { bCameraActuator *ca= act->data; - ID_NEW(ca->ob); + ID_NEW_REMAP(ca->ob); } else if (act->type==ACT_OBJECT) { bObjectActuator *oa= act->data; - ID_NEW(oa->reference); + ID_NEW_REMAP(oa->reference); } else if (act->type==ACT_MESSAGE) { bMessageActuator *ma= act->data; - ID_NEW(ma->toObject); + ID_NEW_REMAP(ma->toObject); } else if (act->type==ACT_PARENT) { bParentActuator *para = act->data; - ID_NEW(para->ob); + ID_NEW_REMAP(para->ob); } else if (act->type==ACT_ARMATURE) { bArmatureActuator *aa = act->data; - ID_NEW(aa->target); - ID_NEW(aa->subtarget); + ID_NEW_REMAP(aa->target); + ID_NEW_REMAP(aa->subtarget); } else if (act->type==ACT_PROPERTY) { bPropertyActuator *pa= act->data; - ID_NEW(pa->ob); + ID_NEW_REMAP(pa->ob); } else if (act->type==ACT_STEERING) { bSteeringActuator *sta = act->data; - ID_NEW(sta->navmesh); - ID_NEW(sta->target); + ID_NEW_REMAP(sta->navmesh); + ID_NEW_REMAP(sta->target); } } act= act->next; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index a440168c24b..ae1217ddf69 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -186,8 +186,6 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) scen = BKE_libblock_copy(bmain, &sce->id); BLI_duplicatelist(&(scen->base), &(sce->base)); - BKE_main_id_clear_newpoins(bmain); - id_us_plus((ID *)scen->world); id_us_plus((ID *)scen->set); /* id_us_plus((ID *)scen->gm.dome.warptext); */ /* XXX Not refcounted? see readfile.c */ @@ -225,7 +223,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) } /* copy action and remove animation used by sequencer */ - BKE_animdata_copy_id_action(&scen->id); + BKE_animdata_copy_id_action(&scen->id, false); if (type != SCE_COPY_FULL) remove_sequencer_fcurves(scen); @@ -318,7 +316,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) /* camera */ if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) { - ID_NEW(scen->camera); + ID_NEW_REMAP(scen->camera); } /* before scene copy */ @@ -329,7 +327,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) if (scen->world) { id_us_plus((ID *)scen->world); scen->world = BKE_world_copy(bmain, scen->world); - BKE_animdata_copy_id_action((ID *)scen->world); + BKE_animdata_copy_id_action((ID *)scen->world, false); } if (sce->ed) { diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 65d751a8a72..1d2f5aee440 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -320,7 +320,8 @@ void BKE_sequencer_free_clipboard(void) /* Manage pointers in the clipboard. * note that these pointers should _never_ be access in the sequencer, * they are only for storage while in the clipboard - * notice 'newid' is used for temp pointer storage here, validate on access. + * notice 'newid' is used for temp pointer storage here, validate on access (this is safe usage, + * since those datablocks are fully out of Main lists). */ #define ID_PT (*id_pt) static void seqclipboard_ptr_free(ID **id_pt) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 6d57c5f09e8..c4665c40ec4 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -4474,46 +4474,46 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm)) /* Nothing to do: CCG handles creating its own tessfaces */ } -static void ccgDM_recalcLoopTri(DerivedMesh *UNUSED(dm)) +static void ccgDM_recalcLoopTri(DerivedMesh *dm) { - /* Nothing to do: CCG tessellation is known, - * allocate and fill in with ccgDM_getLoopTriArray */ + BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE); + MLoopTri *mlooptri; + const int tottri = dm->numPolyData * 2; + int i, poly_index; + + DM_ensure_looptri_data(dm); + mlooptri = dm->looptris.array; + + BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); + BLI_assert(tottri == dm->looptris.num); + + for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) { + MLoopTri *lt; + lt = &mlooptri[i]; + /* quad is (0, 3, 2, 1) */ + lt->tri[0] = (poly_index * 4) + 0; + lt->tri[1] = (poly_index * 4) + 2; + lt->tri[2] = (poly_index * 4) + 3; + lt->poly = poly_index; + + lt = &mlooptri[i + 1]; + lt->tri[0] = (poly_index * 4) + 0; + lt->tri[1] = (poly_index * 4) + 1; + lt->tri[2] = (poly_index * 4) + 2; + lt->poly = poly_index; + } + BLI_rw_mutex_unlock(&loops_cache_rwlock); } static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm) { - BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE); if (dm->looptris.array) { BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); } else { - MLoopTri *mlooptri; - const int tottri = dm->numPolyData * 2; - int i, poly_index; - - DM_ensure_looptri_data(dm); - mlooptri = dm->looptris.array; - - BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); - BLI_assert(tottri == dm->looptris.num); - - for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) { - MLoopTri *lt; - lt = &mlooptri[i]; - /* quad is (0, 3, 2, 1) */ - lt->tri[0] = (poly_index * 4) + 0; - lt->tri[1] = (poly_index * 4) + 2; - lt->tri[2] = (poly_index * 4) + 3; - lt->poly = poly_index; - - lt = &mlooptri[i + 1]; - lt->tri[0] = (poly_index * 4) + 0; - lt->tri[1] = (poly_index * 4) + 1; - lt->tri[2] = (poly_index * 4) + 2; - lt->poly = poly_index; - } + dm->recalcLoopTri(dm); } - BLI_rw_mutex_unlock(&loops_cache_rwlock); + return dm->looptris.array; } diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0790d65345d..38947e139ff 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -3919,7 +3919,7 @@ void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py unit_m4(mat1); - axis_angle_to_mat3_single(mat, 'Z', -twist); + axis_angle_to_mat4_single(mat, 'Z', -twist); dx = px - vx; dy = py - vy; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 98c8a260993..af73410728b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8102,6 +8102,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short id->lib = main->curlib; id->us = ID_FAKE_USERS(id); id->icon_id = 0; + id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */ /* this case cannot be direct_linked: it's just the ID part */ if (bhead->code == ID_ID) { diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 2c60de0f732..8bb6ebf6115 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -46,6 +46,7 @@ #include "DNA_screen_types.h" #include "DNA_object_force.h" #include "DNA_object_types.h" +#include "DNA_mask_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_particle_types.h" @@ -60,6 +61,7 @@ #include "BKE_colortools.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_scene.h" @@ -1490,4 +1492,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) br->fill_threshold /= sqrt_3; } } + + /* To be added to next subversion bump! */ + { + /* Mask primitive adding code was not initializing correctly id_type of its points' parent. */ + for (Mask *mask = main->mask.first; mask; mask = mask->id.next) { + for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) { + for (MaskSpline *mspline = mlayer->splines.first; mspline; mspline = mspline->next) { + int i = 0; + for (MaskSplinePoint *mspoint = mspline->points; i < mspline->tot_point; mspoint++, i++) { + if (mspoint->parent.id_type == 0) { + BKE_mask_parent_init(&mspoint->parent); + } + } + } + } + } + } } diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index ae43c0a69d2..17334ca326c 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -169,6 +169,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon float angle; mat4_to_loc_rot_size(loc, rot, size, mat); mat3_to_vec_roll(rot, NULL, &angle); + bone->roll = angle; } copy_v3_v3(bone->head, mat[3]); add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index 8576cbca239..ec5a42c23a5 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -1798,6 +1798,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even case UPARROWKEY: case DOWNARROWKEY: return OPERATOR_PASS_THROUGH; + + /* Camera/View Manipulations - Allowed */ + /* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */ + case PAD0: case PAD1: case PAD2: case PAD3: case PAD4: + case PAD5: case PAD6: case PAD7: case PAD8: case PAD9: + return OPERATOR_PASS_THROUGH; /* Unhandled event */ default: diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 8073b13ba10..76e85f20c36 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -915,7 +915,7 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints) /** * Add randomness to stroke * \param gps Stroke data - * \param brsuh Brush data + * \param brush Brush data */ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush) { diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index fd5351394c3..9fbce7dd203 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -181,7 +181,7 @@ enum { UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */ UI_BUT_UPDATE_DELAY = (1 << 28), /* don't run updates while dragging (needed in rare cases). */ UI_BUT_TEXTEDIT_UPDATE = (1 << 29), /* when widget is in textedit mode, update value on each char stroke */ - UI_BUT_SEARCH_UNLINK = (1 << 30), /* show unlink for search button */ + UI_BUT_VALUE_CLEAR = (1 << 30), /* show 'x' icon to clear/unlink value of text or search button */ }; #define UI_PANEL_WIDTH 340 diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 6bba35e821f..a913421d12c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1987,22 +1987,29 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but) /** \name Check to show extra icons * * Extra icons are shown on the right hand side of buttons. + * This could (should!) definitely become more generic, but for now this is good enough. * \{ */ +static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but) +{ + BLI_assert(but->type == UI_BTYPE_TEXT); + return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr && but->drawstr[0]); +} + static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but) { BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); return ((but->editstr == NULL) && (but->drawstr[0] != '\0') && - (but->flag & UI_BUT_SEARCH_UNLINK)); + (but->flag & UI_BUT_VALUE_CLEAR)); } -static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but) +static bool ui_but_icon_extra_is_visible_search_eyedropper(uiBut *but) { StructRNA *type; short idcode; - BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_SEARCH_UNLINK)); + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_VALUE_CLEAR)); if (but->rnaprop == NULL) { return false; @@ -2011,21 +2018,31 @@ static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but) type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop); idcode = RNA_type_to_ID_code(type); - return ((but->editstr == NULL) && (idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode))); } uiButExtraIconType ui_but_icon_extra_get(uiBut *but) { - if ((but->flag & UI_BUT_SEARCH_UNLINK) == 0) { - /* pass */ - } - else if (ui_but_icon_extra_is_visible_search_unlink(but)) { - return UI_BUT_ICONEXTRA_UNLINK; - } - else if (ui_but_icon_extra_is_visible_eyedropper(but)) { - return UI_BUT_ICONEXTRA_EYEDROPPER; + switch (but->type) { + case UI_BTYPE_TEXT: + if (ui_but_icon_extra_is_visible_text_clear(but)) { + return UI_BUT_ICONEXTRA_CLEAR; + } + break; + case UI_BTYPE_SEARCH_MENU: + if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) { + /* pass */ + } + else if (ui_but_icon_extra_is_visible_search_unlink(but)) { + return UI_BUT_ICONEXTRA_CLEAR; + } + else if (ui_but_icon_extra_is_visible_search_eyedropper(but)) { + return UI_BUT_ICONEXTRA_EYEDROPPER; + } + break; + default: + break; } return UI_BUT_ICONEXTRA_NONE; diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index d7f06b7db13..5f7a018e4c2 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -748,7 +748,7 @@ static int datadropper_poll(bContext *C) if ((CTX_wm_window(C) != NULL) && (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) && (but->type == UI_BTYPE_SEARCH_MENU) && - (but->flag & UI_BUT_SEARCH_UNLINK)) + (but->flag & UI_BUT_VALUE_CLEAR)) { if (prop && RNA_property_type(prop) == PROP_POINTER) { StructRNA *type = RNA_property_pointer_type(&ptr, prop); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index fc511d61e2b..33f1d5e93cb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2563,6 +2563,18 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *bu } } +static void ui_but_text_clear(bContext *C, uiBut *but, uiHandleButtonData *data) +{ + /* most likely NULL, but let's check, and give it temp zero string */ + if (!data->str) { + data->str = MEM_callocN(1, "temp str"); + } + data->str[0] = 0; + + ui_apply_but_TEX(C, but, data); + button_activate_state(C, but, BUTTON_STATE_EXIT); +} + /* ************* in-button text selection/editing ************* */ @@ -3842,6 +3854,21 @@ static int ui_do_but_KEYEVT( return WM_UI_HANDLER_CONTINUE; } +static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2]) +{ + int x = mouse_xy[0], y = mouse_xy[1]; + rcti icon_rect; + + BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE); + + ui_window_to_block(region, but->block, &x, &y); + + BLI_rcti_rctf_copy(&icon_rect, &but->rect); + icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect)); + + return BLI_rcti_isect_pt(&icon_rect, x, y); +} + static int ui_do_but_TEX( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) @@ -3855,7 +3882,14 @@ static int ui_do_but_TEX( /* pass */ } else { - button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR; + + if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) { + ui_but_text_clear(C, but, data); + } + else { + button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + } return WM_UI_HANDLER_BREAK; } } @@ -3876,47 +3910,29 @@ static int ui_do_but_SEARCH_UNLINK( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - uiButExtraIconType extra_icon_type; + const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but); + const bool has_icon_extra = (extra_icon_type != UI_BUT_ICONEXTRA_NONE); /* unlink icon is on right */ if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) && - ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE)) + (has_icon_extra == true) && + (ui_but_is_mouse_over_icon_extra(data->region, but, &event->x) == true)) { - ARegion *ar = data->region; - rcti rect; - int x = event->x, y = event->y; - - ui_window_to_block(ar, but->block, &x, &y); - - BLI_rcti_rctf_copy(&rect, &but->rect); - - rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect)); - /* handle click on unlink/eyedropper icon */ - if (BLI_rcti_isect_pt(&rect, x, y)) { - /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */ - if (event->val == KM_RELEASE) { - /* unlink */ - if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) { - /* most likely NULL, but let's check, and give it temp zero string */ - if (data->str == NULL) { - data->str = MEM_callocN(1, "temp str"); - } - data->str[0] = 0; - - ui_apply_but_TEX(C, but, data); - button_activate_state(C, but, BUTTON_STATE_EXIT); - } - /* eyedropper */ - else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) { - WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL); - } - else { - BLI_assert(0); - } + /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */ + if (event->val == KM_RELEASE) { + /* unlink */ + if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) { + ui_but_text_clear(C, but, data); + } + /* eyedropper */ + else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) { + WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL); + } + else { + BLI_assert(0); } - - return WM_UI_HANDLER_BREAK; } + return WM_UI_HANDLER_BREAK; } return ui_do_but_TEX(C, block, but, data, event); } @@ -7091,7 +7107,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * case UI_BTYPE_TEXT: case UI_BTYPE_SEARCH_MENU: if ((but->type == UI_BTYPE_SEARCH_MENU) && - (but->flag & UI_BUT_SEARCH_UNLINK)) + (but->flag & UI_BUT_VALUE_CLEAR)) { retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event); if (retval & WM_UI_HANDLER_BREAK) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index fcf827bdbe6..d8f9fdcbaae 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -127,7 +127,7 @@ enum { * (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */ typedef enum uiButExtraIconType { UI_BUT_ICONEXTRA_NONE = 1, - UI_BUT_ICONEXTRA_UNLINK, + UI_BUT_ICONEXTRA_CLEAR, UI_BUT_ICONEXTRA_EYEDROPPER, } uiButExtraIconType; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 875522e01c6..b128bf47b5f 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1659,7 +1659,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN but->rnasearchprop = searchprop; but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; if (RNA_property_is_unlink(prop)) { - but->flag |= UI_BUT_SEARCH_UNLINK; + but->flag |= UI_BUT_VALUE_CLEAR; } if (RNA_property_type(prop) == PROP_ENUM) { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index cdf34642a8d..466978272bc 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -851,7 +851,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) } else { /* only let users step into an 'unset' state for unlink buttons */ - data->active = (but->flag & UI_BUT_SEARCH_UNLINK) ? -1 : 0; + data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0; } } @@ -922,8 +922,8 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar) return true; } - else if (but->flag & UI_BUT_SEARCH_UNLINK) { - /* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */ + else if (but->flag & UI_BUT_VALUE_CLEAR) { + /* It is valid for _VALUE_CLEAR flavor to have no active element (it's a valid way to unlink). */ but->editstr[0] = '\0'; return true; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b8b46d0e4c9..550a7b52921 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -303,7 +303,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) break; case UI_ID_LOCAL: if (id) { - if (id_make_local(CTX_data_main(C), id, false, false)) { + Main *bmain = CTX_data_main(C); + if (id_make_local(bmain, id, false, false)) { + BKE_main_id_clear_newpoins(bmain); + /* reassign to get get proper updates/notifiers */ idptr = RNA_property_pointer_get(&template->ptr, template->prop); RNA_property_pointer_set(&template->ptr, template->prop, idptr); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 1d51c0588b6..8dfbbdd02eb 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -119,6 +119,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind else but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + PropertySubType subtype = RNA_property_subtype(prop); + if (!(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME) || (block->flag & UI_BLOCK_LIST_ITEM))) { + UI_but_flag_enable(but, UI_BUT_VALUE_CLEAR); + } if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) { UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE); } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c285d753b96..d43a94c5514 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1508,10 +1508,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b /* draws text and icons for buttons */ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect) { + const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but); const bool show_menu_icon = ui_but_draw_menu_icon(but); float alpha = (float)wcol->text[3] / 255.0f; char password_str[UI_MAX_DRAW_STR]; - uiButExtraIconType extra_icon_type; ui_but_text_password_hide(password_str, but, false); @@ -1577,15 +1577,13 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } - /* unlink icon for this button type */ - if ((but->type == UI_BTYPE_SEARCH_MENU) && - ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE)) - { + /* extra icons, e.g. 'x' icon to clear text or icon for eyedropper */ + if (extra_icon_type != UI_BUT_ICONEXTRA_NONE) { rcti temp = *rect; temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f); - if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) { + if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) { widget_draw_icon(but, ICON_X, alpha, &temp, false); } else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) { diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index e3e8f35e7d8..f01af22cec9 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -779,6 +779,7 @@ static int create_primitive_from_points(bContext *C, wmOperator *op, const float for (i = 0; i < num_points; i++) { MaskSplinePoint *new_point = &new_spline->points[i]; + BKE_mask_parent_init(&new_point->parent); copy_v2_v2(new_point->bezt.vec[1], points[i]); mul_v2_fl(new_point->bezt.vec[1], scale); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 6647102acad..02dd3ed2df5 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1350,7 +1350,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, for (dob = lb->first; dob; dob = dob->next) { Base *basen; - Object *ob = BKE_object_copy(bmain, dob->ob); + Object *ob = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, dob->ob)); /* font duplis can have a totcol without material, we get them from parent * should be implemented better... @@ -1394,6 +1394,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, } } + /* Remap new object to itself, and clear again newid pointer of orig object. */ + BKE_libblock_relink(&ob->id); + set_sca_new_poins_ob(ob); + BKE_id_clear_newpoin(&dob->ob->id); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } @@ -1484,8 +1489,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (parent_gh) BLI_ghash_free(parent_gh, NULL, NULL); - copy_object_set_idnew(C); - free_object_duplilist(lb); base->object->transflag &= ~OB_DUPLI; @@ -1960,8 +1963,12 @@ void OBJECT_OT_convert(wmOperatorType *ot) /* used below, assumes id.new is correct */ /* leaves selection of base/object unaltered */ +/* Does set ID->newid pointers. */ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag) { +#define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; } +#define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; } + Base *basen = NULL; Material ***matarar; Object *ob, *obn; @@ -1973,7 +1980,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base ; /* nothing? */ } else { - obn = BKE_object_copy(bmain, ob); + obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); basen = MEM_mallocN(sizeof(Base), "duplibase"); @@ -1995,20 +2002,21 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base /* duplicates using userflags */ if (dupflag & USER_DUP_ACT) { - BKE_animdata_copy_id_action(&obn->id); + BKE_animdata_copy_id_action(&obn->id, true); } if (dupflag & USER_DUP_MAT) { for (a = 0; a < obn->totcol; a++) { id = (ID *)obn->mat[a]; if (id) { - ID_NEW_US(obn->mat[a]) - else - obn->mat[a] = BKE_material_copy(bmain, obn->mat[a]); + ID_NEW_REMAP_US(obn->mat[a]) + else { + obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a])); + } id_us_min(id); if (dupflag & USER_DUP_ACT) { - BKE_animdata_copy_id_action(&obn->mat[a]->id); + BKE_animdata_copy_id_action(&obn->mat[a]->id, true); } } } @@ -2018,12 +2026,13 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base for (psys = obn->particlesystem.first; psys; psys = psys->next) { id = (ID *) psys->part; if (id) { - ID_NEW_US(psys->part) - else - psys->part = BKE_particlesettings_copy(bmain, psys->part); + ID_NEW_REMAP_US(psys->part) + else { + psys->part = ID_NEW_SET(psys->part, BKE_particlesettings_copy(bmain, psys->part)); + } if (dupflag & USER_DUP_ACT) { - BKE_animdata_copy_id_action(&psys->part->id); + BKE_animdata_copy_id_action(&psys->part->id, true); } id_us_min(id); @@ -2037,9 +2046,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base switch (obn->type) { case OB_MESH: if (dupflag & USER_DUP_MESH) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_mesh_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2047,9 +2056,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_CURVE: if (dupflag & USER_DUP_CURVE) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_curve_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2057,9 +2066,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_SURF: if (dupflag & USER_DUP_SURF) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_curve_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2067,9 +2076,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_FONT: if (dupflag & USER_DUP_FONT) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_curve_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2077,9 +2086,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_MBALL: if (dupflag & USER_DUP_MBALL) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_mball_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2087,9 +2096,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_LAMP: if (dupflag & USER_DUP_LAMP) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_lamp_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_lamp_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2100,9 +2109,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base if (obn->pose) BKE_pose_tag_recalc(bmain, obn->pose); if (dupflag & USER_DUP_ARM) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_armature_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data)); BKE_pose_rebuild(obn, obn->data); didit = 1; } @@ -2111,9 +2120,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_LATTICE: if (dupflag != 0) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_lattice_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2121,9 +2130,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_CAMERA: if (dupflag != 0) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_camera_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2131,9 +2140,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base break; case OB_SPEAKER: if (dupflag != 0) { - ID_NEW_US2(obn->data) + ID_NEW_REMAP_US2(obn->data) else { - obn->data = BKE_speaker_copy(bmain, obn->data); + obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data)); didit = 1; } id_us_min(id); @@ -2148,12 +2157,15 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base if (dupflag & USER_DUP_ACT) { bActuator *act; - BKE_animdata_copy_id_action((ID *)obn->data); + BKE_animdata_copy_id_action((ID *)obn->data, true); if (key) { - BKE_animdata_copy_id_action((ID *)key); + BKE_animdata_copy_id_action((ID *)key, true); } /* Update the duplicated action in the action actuators */ + /* XXX TODO this code is all wrong! actact->act is user-refcounted (see readfile.c), + * and what about other ID pointers of other BGE logic bricks, + * and since this is object-level, why is it only ran if obdata was duplicated??? -mont29 */ for (act = obn->actuators.first; act; act = act->next) { if (act->type == ACT_ACTION) { bActionActuator *actact = (bActionActuator *) act->data; @@ -2170,9 +2182,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base for (a = 0; a < obn->totcol; a++) { id = (ID *)(*matarar)[a]; if (id) { - ID_NEW_US((*matarar)[a]) - else - (*matarar)[a] = BKE_material_copy(bmain, (*matarar)[a]); + ID_NEW_REMAP_US((*matarar)[a]) + else { + (*matarar)[a] = ID_NEW_SET((*matarar)[a], BKE_material_copy(bmain, (*matarar)[a])); + } id_us_min(id); } } @@ -2181,6 +2194,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } } return basen; + +#undef ID_NEW_REMAP_US +#undef ID_NEW_REMAP_US2 } /* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */ @@ -2193,8 +2209,7 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag Base *basen; Object *ob; - BKE_main_id_clear_newpoins(bmain); - clear_sca_new_poins(); /* sensor/contr/act */ + clear_sca_new_poins(); /* BGE logic */ basen = object_add_duplicate_internal(bmain, scene, base, dupflag); if (basen == NULL) { @@ -2213,6 +2228,8 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag ED_render_id_flush_update(bmain, ob->data); } + BKE_main_id_clear_newpoins(bmain); + return basen; } @@ -2224,8 +2241,7 @@ static int duplicate_exec(bContext *C, wmOperator *op) const bool linked = RNA_boolean_get(op->ptr, "linked"); int dupflag = (linked) ? 0 : U.dupflag; - BKE_main_id_clear_newpoins(bmain); - clear_sca_new_poins(); /* sensor/contr/act */ + clear_sca_new_poins(); /* BGE logic */ CTX_DATA_BEGIN (C, Base *, base, selected_bases) { @@ -2251,6 +2267,8 @@ static int duplicate_exec(bContext *C, wmOperator *op) copy_object_set_idnew(C); + BKE_main_id_clear_newpoins(bmain); + DAG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); @@ -2309,8 +2327,7 @@ static int add_named_exec(bContext *C, wmOperator *op) base->flag = ob->flag; /* prepare dupli */ - BKE_main_id_clear_newpoins(bmain); - clear_sca_new_poins(); /* sensor/contr/act */ + clear_sca_new_poins(); /* BGE logic */ basen = object_add_duplicate_internal(bmain, scene, base, dupflag); @@ -2336,6 +2353,8 @@ static int add_named_exec(bContext *C, wmOperator *op) copy_object_set_idnew(C); + BKE_main_id_clear_newpoins(bmain); + DAG_relations_tag_update(bmain); MEM_freeN(base); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index f448e925dd9..d670f4b8425 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1731,6 +1731,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) /**************************** Make Single User ********************************/ +/* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups) { Base *base; @@ -1738,18 +1739,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in Group *group, *groupn; GroupObject *go; - clear_sca_new_poins(); /* sensor/contr/act */ - - /* newid may still have some trash from Outliner tree building, so clear that first to avoid errors, see T26002. - * We have to clear whole datablocks, not only Object one may be accessed here, see T49905. */ - ListBase *lbarray[MAX_LIBARRAY]; - int a = set_listbasepointers(bmain, lbarray); - while (a--) { - ListBase *lb = lbarray[a]; - for (ID *id = lb->first; id; id = id->next) { - id->newid = NULL; - } - } + clear_sca_new_poins(); /* BGE logic */ /* duplicate (must set newid) */ for (base = FIRSTBASE; base; base = base->next) { @@ -1758,8 +1748,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in if ((base->flag & flag) == flag) { if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) { /* base gets copy of object */ - obn = BKE_object_copy(bmain, ob); - base->object = obn; + base->object = obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); if (copy_groups) { if (ob->flag & OB_FROMGROUP) { @@ -1789,8 +1778,6 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in /* duplicate groups that consist entirely of duplicated objects */ for (group = bmain->group.first; group; group = group->id.next) { - group->id.newid = NULL; - if (copy_groups && group->gobject.first) { bool all_duplicated = true; @@ -1802,10 +1789,11 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in } if (all_duplicated) { - groupn = BKE_group_copy(bmain, group); + groupn = ID_NEW_SET(group, BKE_group_copy(bmain, group)); - for (go = groupn->gobject.first; go; go = go->next) + for (go = groupn->gobject.first; go; go = go->next) { go->ob = (Object *)go->ob->id.newid; + } } } } @@ -1813,8 +1801,8 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in /* group pointers in scene */ BKE_scene_groups_relink(scene); - ID_NEW(scene->camera); - if (v3d) ID_NEW(v3d->camera); + ID_NEW_REMAP(scene->camera); + if (v3d) ID_NEW_REMAP(v3d->camera); /* object and group pointers */ for (base = FIRSTBASE; base; base = base->next) { @@ -1837,6 +1825,8 @@ void ED_object_single_user(Main *bmain, Scene *scene, Object *ob) } single_object_users(bmain, scene, NULL, OB_DONE, copy_groups); + + BKE_main_id_clear_newpoins(bmain); } static void new_id_matar(Main *bmain, Material **matar, const int totcol) @@ -1853,9 +1843,8 @@ static void new_id_matar(Main *bmain, Material **matar, const int totcol) id_us_min(id); } else if (id->us > 1) { - matar[a] = BKE_material_copy(bmain, matar[a]); + matar[a] = ID_NEW_SET(id, BKE_material_copy(bmain, matar[a])); id_us_min(id); - id->newid = (ID *)matar[a]; } } } @@ -1883,45 +1872,46 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) switch (ob->type) { case OB_LAMP: - ob->data = la = BKE_lamp_copy(bmain, ob->data); + ob->data = la = ID_NEW_SET(ob->data, BKE_lamp_copy(bmain, ob->data)); for (a = 0; a < MAX_MTEX; a++) { if (la->mtex[a]) { - ID_NEW(la->mtex[a]->object); + ID_NEW_REMAP(la->mtex[a]->object); } } break; case OB_CAMERA: - ob->data = BKE_camera_copy(bmain, ob->data); + ob->data = ID_NEW_SET(ob->data, BKE_camera_copy(bmain, ob->data)); break; case OB_MESH: - ob->data = me = BKE_mesh_copy(bmain, ob->data); - if (me->key) - BKE_animdata_copy_id_action((ID *)me->key); + /* Needed to remap texcomesh below. */ + me = ob->data = ID_NEW_SET(ob->data, BKE_mesh_copy(bmain, ob->data)); + if (me->key) /* We do not need to set me->key->id.newid here... */ + BKE_animdata_copy_id_action((ID *)me->key, false); break; case OB_MBALL: - ob->data = BKE_mball_copy(bmain, ob->data); + ob->data = ID_NEW_SET(ob->data, BKE_mball_copy(bmain, ob->data)); break; case OB_CURVE: case OB_SURF: case OB_FONT: - ob->data = cu = BKE_curve_copy(bmain, ob->data); - ID_NEW(cu->bevobj); - ID_NEW(cu->taperobj); - if (cu->key) - BKE_animdata_copy_id_action((ID *)cu->key); + ob->data = cu = ID_NEW_SET(ob->data, BKE_curve_copy(bmain, ob->data)); + ID_NEW_REMAP(cu->bevobj); + ID_NEW_REMAP(cu->taperobj); + if (cu->key) /* We do not need to set cu->key->id.newid here... */ + BKE_animdata_copy_id_action((ID *)cu->key, false); break; case OB_LATTICE: - ob->data = lat = BKE_lattice_copy(bmain, ob->data); - if (lat->key) - BKE_animdata_copy_id_action((ID *)lat->key); + ob->data = lat = ID_NEW_SET(ob->data, BKE_lattice_copy(bmain, ob->data)); + if (lat->key) /* We do not need to set lat->key->id.newid here... */ + BKE_animdata_copy_id_action((ID *)lat->key, false); break; case OB_ARMATURE: DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - ob->data = BKE_armature_copy(bmain, ob->data); + ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data)); BKE_pose_rebuild(ob, ob->data); break; case OB_SPEAKER: - ob->data = BKE_speaker_copy(bmain, ob->data); + ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data)); break; default: if (G.debug & G_DEBUG) @@ -1934,17 +1924,16 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) * AnimData structure, which is not what we want. * (sergey) */ - BKE_animdata_copy_id_action((ID *)ob->data); + BKE_animdata_copy_id_action((ID *)ob->data, false); id_us_min(id); - id->newid = ob->data; } } } me = bmain->mesh.first; while (me) { - ID_NEW(me->texcomesh); + ID_NEW_REMAP(me->texcomesh); me = me->id.next; } } @@ -1958,7 +1947,7 @@ static void single_object_action_users(Scene *scene, const int flag) ob = base->object; if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - BKE_animdata_copy_id_action(&ob->id); + BKE_animdata_copy_id_action(&ob->id, false); } } } @@ -1977,11 +1966,11 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo for (a = 1; a <= ob->totcol; a++) { ma = give_current_material(ob, a); if (ma) { - /* do not test for LIB_TAG_NEW: this functions guaranteed delivers single_users! */ + /* do not test for LIB_TAG_NEW or use newid: this functions guaranteed delivers single_users! */ if (ma->id.us > 1) { man = BKE_material_copy(bmain, ma); - BKE_animdata_copy_id_action(&man->id); + BKE_animdata_copy_id_action(&man->id, false); man->id.us = 0; assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF); @@ -1992,7 +1981,7 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo if (tex->id.us > 1) { id_us_min(&tex->id); tex = BKE_texture_copy(bmain, tex); - BKE_animdata_copy_id_action(&tex->id); + BKE_animdata_copy_id_action(&tex->id, false); man->mtex[b]->tex = tex; } } @@ -2018,8 +2007,8 @@ static void do_single_tex_user(Main *bmain, Tex **from) id_us_min(&tex->id); } else if (tex->id.us > 1) { - texn = BKE_texture_copy(bmain, tex); - BKE_animdata_copy_id_action(&texn->id); + texn = ID_NEW_SET(tex, BKE_texture_copy(bmain, tex)); + BKE_animdata_copy_id_action(&texn->id, false); tex->id.newid = (ID *)texn; id_us_min(&tex->id); *from = texn; @@ -2096,7 +2085,7 @@ static void single_mat_users_expand(Main *bmain) if (ma->id.tag & LIB_TAG_NEW) for (a = 0; a < MAX_MTEX; a++) if (ma->mtex[a]) - ID_NEW(ma->mtex[a]->object); + ID_NEW_REMAP(ma->mtex[a]->object); } /* used for copying scenes */ @@ -2247,7 +2236,6 @@ static int make_local_exec(bContext *C, wmOperator *op) } tag_localizable_objects(C, mode); - BKE_main_id_clear_newpoins(bmain); CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { @@ -2264,7 +2252,7 @@ static int make_local_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { if (ob->id.lib == NULL) { - ID_NEW(ob->parent); + ID_NEW_REMAP(ob->parent); } } CTX_DATA_END; @@ -2335,6 +2323,7 @@ static int make_local_exec(bContext *C, wmOperator *op) CTX_DATA_END; } + BKE_main_id_clear_newpoins(bmain); WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; @@ -2381,8 +2370,6 @@ static int make_single_user_exec(bContext *C, wmOperator *op) const bool copy_groups = false; bool update_deps = false; - BKE_main_id_clear_newpoins(bmain); - if (RNA_boolean_get(op->ptr, "object")) { single_object_users(bmain, scene, v3d, flag, copy_groups); @@ -2406,11 +2393,6 @@ static int make_single_user_exec(bContext *C, wmOperator *op) single_object_action_users(scene, flag); } - /* TODO(sergey): This should not be needed, however some tool still could rely - * on the fact, that id->newid is kept NULL by default. - * Need to make sure all the guys are learing newid before they're - * using it, not after. - */ BKE_main_id_clear_newpoins(bmain); WM_event_add_notifier(C, NC_WINDOW, NULL); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 13200e92e7e..7739d241bd3 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -442,6 +442,9 @@ static void id_local_cb( if (id_make_local(bmain, tselem->id, false, false) == false) { id_clear_lib_data(bmain, tselem->id); } + else { + BKE_main_id_clear_newpoins(bmain); + } } } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 20f7ca4db16..ec46c5df9a0 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1645,11 +1645,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) outliner_free_tree(&soops->tree); outliner_storage_cleanup(soops); - /* clear ob id.new flags */ - for (Object *ob = mainvar->object.first; ob; ob = ob->id.next) { - ob->id.newid = NULL; - } - /* options */ if (soops->outlinevis == SO_LIBRARIES) { Library *lib; @@ -1835,6 +1830,8 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) outliner_sort(&soops->tree); } outliner_filter_tree(soops, &soops->tree); + + BKE_main_id_clear_newpoins(mainvar); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 000d1fe4810..f23e587e55d 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2658,7 +2658,6 @@ CustomDataMask ED_view3d_screen_datamask(const bScreen *screen) void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; - rctf cameraborder; /* setup window matrices */ if (winmat) @@ -2672,7 +2671,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view else view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */ - /* update utilitity matrices */ + /* update utility matrices */ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat); @@ -2681,6 +2680,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view /* store window coordinates scaling/offset */ if (rv3d->persp == RV3D_CAMOB && v3d->camera) { + rctf cameraborder; ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false); rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder); rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder); @@ -2692,8 +2692,17 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f; rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f; } - - /* calculate pixelsize factor once, is used for lamps and obcenters */ + + /** + * Calculate pixel-size factor once, is used for lamps and object centers. + * Used by #ED_view3d_pixel_size and typically not accessed directly. + * + * \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value, + * passed to #RE_SetPixelSize, in ortho mode this is compatible with this value, + * but in perspective mode its offset by the near-clip. + * + * 'RegionView3D.pixsize' is used for viewport drawing, not rendering. + */ { /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])' * because of float point precision problems at large values [#23908] */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index daf0aed59e7..d4cd2351f46 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -103,7 +103,7 @@ static void drawEdgeSlide(TransInfo *t); static void drawVertSlide(TransInfo *t); static void postInputRotation(TransInfo *t, float values[3]); -static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around); +static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], const short around); static void initSnapSpatial(TransInfo *t, float r_snap[3]); diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index ef3743d9c8a..33750478bb4 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -89,11 +89,14 @@ void imb_mmap_unlock(void) void imb_freemipmapImBuf(ImBuf *ibuf) { int a; - - for (a = 1; a < ibuf->miptot; a++) { - if (ibuf->mipmap[a - 1]) - IMB_freeImBuf(ibuf->mipmap[a - 1]); - ibuf->mipmap[a - 1] = NULL; + + /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels, + * leading to memory leaks... */ + for (a = 0; a < IMB_MIPMAP_LEVELS; a++) { + if (ibuf->mipmap[a] != NULL) { + IMB_freeImBuf(ibuf->mipmap[a]); + ibuf->mipmap[a] = NULL; + } } ibuf->miptot = 0; diff --git a/source/blender/imbuf/intern/oiio/CMakeLists.txt b/source/blender/imbuf/intern/oiio/CMakeLists.txt index c873fa3f32d..a4fb9c5aee1 100644 --- a/source/blender/imbuf/intern/oiio/CMakeLists.txt +++ b/source/blender/imbuf/intern/oiio/CMakeLists.txt @@ -49,6 +49,11 @@ if(WITH_OPENIMAGEIO) ${OPENIMAGEIO_INCLUDE_DIRS} ${BOOST_INCLUDE_DIR} ) + if(WITH_IMAGE_OPENEXR) + list(APPEND INC_SYS + ${OPENEXR_INCLUDE_DIRS} + ) + endif() add_definitions(-DWITH_OPENIMAGEIO) endif() diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index feeb2d5e4d7..59fd0c7832c 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -290,9 +290,9 @@ typedef enum ID_Type { #endif #define GS(a) (CHECK_TYPE_ANY(a, char *, const char *, char [66], const char[66]), (*((const short *)(a)))) -#define ID_NEW(a) if ( (a) && (a)->id.newid ) (a) = (void *)(a)->id.newid -#define ID_NEW_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; } -#define ID_NEW_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; } +#define ID_NEW_SET(_id, _idn) \ + (((ID *)(_id))->newid = (ID *)(_idn), ((ID *)(_id))->newid->tag |= LIB_TAG_NEW, (void *)((ID *)(_id))->newid) +#define ID_NEW_REMAP(a) if ((a) && (a)->id.newid) (a) = (void *)(a)->id.newid /* id->flag (persitent). */ enum { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 46b30f41f5b..3a7e2b6f7f8 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -811,7 +811,10 @@ typedef struct NodeShaderTexPointDensity { short color_source; short ob_color_source; char vertex_attribute_name[64]; /* vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */ + /* Used at runtime only by sampling RNA API. */ PointDensity pd; + int cached_resolution; + int pad2; } NodeShaderTexPointDensity; /* TEX_output */ diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 87fb45a4419..896d4979089 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -358,7 +358,9 @@ static struct ID *rna_ID_make_local(struct ID *self, Main *bmain, int clear_prox id_make_local(bmain, self, false, false); } - return self->newid ? self->newid : self; + ID *ret_id = self->newid ? self->newid : self; + BKE_id_clear_newpoin(self); + return ret_id; } diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 7ba89538b18..16aa60e1b91 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -585,11 +585,11 @@ static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src) static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int setactive) { - bGPDlayer *gl = BKE_gpencil_layer_addnew(gpd, name, setactive != 0); + bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, name, setactive != 0); WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - return gl; + return gpl; } static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, PointerRNA *layer_ptr) @@ -1354,7 +1354,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Add a new grease pencil layer"); parm = RNA_def_string(func, "name", "GPencilLayer", MAX_NAME, "Name", "Name of the layer"); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "set_active", 0, "Set Active", "Set the newly created layer to the active layer"); + RNA_def_boolean(func, "set_active", true, "Set Active", "Set the newly created layer to the active layer"); parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The newly created layer"); RNA_def_function_return(func, parm); @@ -1443,7 +1443,7 @@ static void rna_def_gpencil_palettecolor(BlenderRNA *brna) prop = RNA_def_property(srna, "ghost", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_ONIONSKIN); RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); - RNA_def_property_ui_text(prop, "Ghost", "Display the color in onion skinning"); + RNA_def_property_ui_text(prop, "Show in Ghosts", "Display strokes using this color when showing onion skins"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Draw Style */ @@ -1557,7 +1557,7 @@ static void rna_def_gpencil_palettes_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Add a new grease pencil palette"); parm = RNA_def_string(func, "name", "GPencilPalette", MAX_NAME, "Name", "Name of the palette"); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "set_active", 0, "Set Active", "Activate the newly created palette"); + RNA_def_boolean(func, "set_active", true, "Set Active", "Activate the newly created palette"); parm = RNA_def_pointer(func, "palette", "GPencilPalette", "", "The newly created palette"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 47e9d989dbf..34002f8d550 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3107,6 +3107,9 @@ void rna_ShaderNodePointDensity_density_cache(bNode *self, sizeof(pd->vertex_attribute_name)); } + /* Store resolution, so it can be changed in the UI. */ + shader_point_density->cached_resolution = shader_point_density->resolution; + /* Single-threaded sampling of the voxel domain. */ RE_point_density_cache(scene, pd, @@ -3121,15 +3124,15 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, { NodeShaderTexPointDensity *shader_point_density = self->storage; PointDensity *pd = &shader_point_density->pd; + const int resolution = shader_point_density->cached_resolution; if (scene == NULL) { *length = 0; return; } - *length = 4 * shader_point_density->resolution * - shader_point_density->resolution * - shader_point_density->resolution; + /* TODO(sergey): Will likely overflow, but how to pass size_t via RNA? */ + *length = 4 * resolution * resolution * resolution; if (*values == NULL) { *values = MEM_mallocN(sizeof(float) * (*length), "point density dynamic array"); @@ -3137,13 +3140,14 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, /* Single-threaded sampling of the voxel domain. */ RE_point_density_sample(scene, pd, - shader_point_density->resolution, + resolution, settings == 1, *values); /* We're done, time to clean up. */ BKE_texture_pointdensity_free_data(pd); memset(pd, 0, sizeof(*pd)); + shader_point_density->cached_resolution = 0.0f; } void rna_ShaderNodePointDensity_density_minmax(bNode *self, diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index ff1761eb6d7..1eb8644a9a6 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -817,13 +817,14 @@ static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, P PyErr_Format(PyExc_ValueError, "%s: index %d must be less than %d", error_prefix, plink->poly[j], coords_len); - - Py_DECREF(py_tricoords_fast); + /* decref below */ valid = false; break; } } + Py_DECREF(py_tricoords_fast); + if (py_tricoords_len >= 3) { tris_len += (py_tricoords_len - 2); } diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index aa0a213cf64..04a79f6498f 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -1185,7 +1185,7 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE) message(FATAL_ERROR "Windows 10 SDK directory not found") endif() endif() - + FILE(TO_CMAKE_PATH ${KITSPATH} KITSPATH) install( FILES ${KITSPATH}/api-ms-win-core-file-l1-2-0.dll |