diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-05-31 16:51:17 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-05-31 16:52:11 +0300 |
commit | f32a18994ad7f37eb568771f01bab9db53d38d54 (patch) | |
tree | dc014ea9a34c0d1fc414f1afa937daf1f55a5f97 | |
parent | 82276d6cf7d3e18a0e5654d472bdff2b716b0d54 (diff) | |
parent | a481908232ef20449e6ad6951769677e0b108ca8 (diff) |
Merge branch 'master' into blender2.8
62 files changed, 821 insertions, 546 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt index 2d415296dac..dd446613fd0 100644 --- a/intern/audaspace/CMakeLists.txt +++ b/intern/audaspace/CMakeLists.txt @@ -19,7 +19,7 @@ # # ***** END LGPL LICENSE BLOCK ***** -remove_extra_strict_flags() +remove_strict_flags() if(CMAKE_COMPILER_IS_GNUCC) remove_cc_flag("-Wunused-macros") diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 280773c8aa9..3dfb2b1913d 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include "render/mesh.h" #include "render/object.h" #include "render/scene.h" @@ -293,7 +292,7 @@ static void create_mesh_volume_attribute(BL::Object& b_ob, if(!b_domain) return; - + Attribute *attr = mesh->attributes.add(std); VoxelAttribute *volume_data = attr->data_voxel(); bool is_float, is_linear; @@ -982,7 +981,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, else used_shaders.push_back(scene->default_surface); } - + /* test if we need to sync */ int requested_geometry_flags = Mesh::GEOMETRY_NONE; if(render_layer.use_surfaces) { @@ -1017,12 +1016,12 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, /* ensure we only sync instanced meshes once */ if(mesh_synced.find(mesh) != mesh_synced.end()) return mesh; - + mesh_synced.insert(mesh); /* create derived mesh */ array<int> oldtriangle = mesh->triangles; - + /* compares curve_keys rather than strands in order to handle quick hair * adjustments in dynamic BVH - other methods could probably do this better*/ array<float3> oldcurve_keys = mesh->curve_keys; @@ -1111,7 +1110,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0) rebuild = true; } - + mesh->tag_update(scene, rebuild); return mesh; @@ -1140,7 +1139,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, if(scene->need_motion() == Scene::MOTION_BLUR) { if(!mesh->use_motion_blur) return; - + /* see if this mesh needs motion data at this time */ vector<float> object_times = object->motion_times(); bool found = false; @@ -1172,7 +1171,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, if(!numverts && !numkeys) return; - + /* skip objects without deforming modifiers. this is not totally reliable, * would need a more extensive check to see which objects are animated */ BL::Mesh b_mesh(PointerRNA_NULL); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index abdbb6be0fd..ebbf325f95b 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -299,7 +299,7 @@ static inline uint get_layer(const BL::Array<int, 20>& array) for(uint i = 0; i < 20; i++) if(array[i]) layer |= (1 << i); - + return layer; } @@ -434,7 +434,7 @@ static inline string get_string(PointerRNA& ptr, const char *name) string str(cstr); if(cstr != cstrbuf) MEM_freeN(cstr); - + return str; } @@ -451,7 +451,7 @@ static inline string blender_absolute_path(BL::BlendData& b_data, { if(path.size() >= 2 && path[0] == '/' && path[1] == '/') { string dirname; - + if(b_id.library()) { BL::ID b_library_id(b_id.library()); dirname = blender_absolute_path(b_data, @@ -544,7 +544,7 @@ static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object& b_ob) return b_smd.domain_settings(); } } - + return BL::SmokeDomainSettings(PointerRNA_NULL); } @@ -816,4 +816,3 @@ protected: CCL_NAMESPACE_END #endif /* __BLENDER_UTIL_H__ */ - diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 188c3960a5f..27a96720c1e 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -191,7 +191,7 @@ class PrincipledBSSRDFClosure : public CBSSRDFClosure { public: void setup(ShaderData *sd, int path_flag, float3 weight) { - alloc(sd, path_flag, weight * albedo, CLOSURE_BSSRDF_PRINCIPLED_ID); + alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_ID); } }; diff --git a/intern/cycles/kernel/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_bsdf.osl index 57f40789d49..9d85d56ba78 100644 --- a/intern/cycles/kernel/shaders/node_principled_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_principled_bsdf.osl @@ -57,8 +57,8 @@ shader node_principled_bsdf( if (diffuse_weight > 1e-5) { if (Subsurface > 1e-5) { - color Albedo = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface); - BSDF = bssrdf_principled(Normal, Subsurface * SubsurfaceRadius, 0.0, Albedo, Roughness); + color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface); + BSDF = mixed_ss_base_color * bssrdf_principled(Normal, Subsurface * SubsurfaceRadius, 0.0, SubsurfaceColor, Roughness); } else { BSDF = BaseColor * principled_diffuse(Normal, Roughness); } diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index f04f765686e..f3bbd7a7dac 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -141,8 +141,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float3 weight = sd->svm_closure_weight * mix_weight; #ifdef __SUBSURFACE__ - float3 albedo = subsurface_color * subsurface + base_color * (1.0f - subsurface); - float3 subsurf_weight = weight * albedo * diffuse_weight; + float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface); + float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight; float subsurf_sample_weight = fabsf(average(subsurf_weight)); /* disable in case of diffuse ancestor, can't see it well then and @@ -154,7 +154,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * /* need to set the base color in this case such that the * rays get the correctly mixed color after transmitting * the object */ - base_color = albedo; + base_color = mixed_ss_base_color; } /* diffuse */ @@ -186,7 +186,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bssrdf->sample_weight = subsurf_sample_weight; bssrdf->radius = radius.x; bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.x; + bssrdf->albedo = subsurface_color.x; bssrdf->sharpness = sharpness; bssrdf->N = N; bssrdf->roughness = roughness; @@ -200,7 +200,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bssrdf->sample_weight = subsurf_sample_weight; bssrdf->radius = radius.y; bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.y; + bssrdf->albedo = subsurface_color.y; bssrdf->sharpness = sharpness; bssrdf->N = N; bssrdf->roughness = roughness; @@ -214,7 +214,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bssrdf->sample_weight = subsurf_sample_weight; bssrdf->radius = radius.z; bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.z; + bssrdf->albedo = subsurface_color.z; bssrdf->sharpness = sharpness; bssrdf->N = N; bssrdf->roughness = roughness; diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 5fb1a365ee9..9f8bb8c42fa 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -111,11 +111,6 @@ public: && tile_size == params.tile_size && start_resolution == params.start_resolution && threads == params.threads - && use_denoising == params.use_denoising - && denoising_radius == params.denoising_radius - && denoising_strength == params.denoising_strength - && denoising_feature_strength == params.denoising_feature_strength - && denoising_relative_pca == params.denoising_relative_pca && display_buffer_linear == params.display_buffer_linear && cancel_timeout == params.cancel_timeout && reset_timeout == params.reset_timeout diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index ca7118de7b0..9f03b5e9537 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -890,16 +890,7 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw) // send motion. Mark as 'sent' so motion will always get dispatched. eventSent = true; -#if defined(_MSC_VER) - // using Microsoft compiler & header files - // they invented the RawInput API, so this version is (probably) correct. BYTE const *data = raw.data.hid.bRawData; - // struct RAWHID { - // DWORD dwSizeHid; - // DWORD dwCount; - // BYTE bRawData[1]; - // }; -#endif BYTE packetType = data[0]; switch (packetType) { diff --git a/intern/libmv/ChangeLog b/intern/libmv/ChangeLog index 45be9c25afa..81096dd90c9 100644 --- a/intern/libmv/ChangeLog +++ b/intern/libmv/ChangeLog @@ -1,3 +1,156 @@ +commit efd7a93317e0278b99e66785f667823e451daef1 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue May 9 10:16:42 2017 +0200 + + Fix strict compiler warnings, unused variables + +commit 8efd47e13dfdd3f7209bc96f26d0b13127dd6376 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Dec 14 10:44:57 2016 +0100 + + Fix T50243: libmv_panography_test is broken + + There was fully wrong logic in comparison: was actually accessing memory + past the array boundary. Run test manually and the figure seems correct + to me now. + + Spotted by @LazyDodo, thanks! + +commit 6dfb9cd1bd14669d84be789000ce234747fb00ff +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Jul 14 11:49:38 2016 +0200 + + Fix some strict compiler warnings + + One of them was a real bug! + +commit f61adaecf7b29ebe6677be0e1c825f0a8d475e4b +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 11:22:34 2017 +0200 + + Enable explicit schur complement for BA step + + This is something we do in Blender and only reason it was not + enabled for standalone Libmv is because we did not have fresh + enough version of Ceres bundled. + +commit fc5d3a1d4880c6658aff693c1c1e8c10c96ce1a7 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Nov 2 15:32:11 2016 +0100 + + Update tests to make tests pass after recent Ceres update + + Just a precision issue, difference is around 1e-7. Should be fine to + simply update expected value. + +commit e1ac9f6124110c1a90d8e417bea47acfcbdcca42 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:54:48 2017 +0200 + + Update Ceres to latest release 1.12.0 + +commit ac1571352b4962f110929b963f8616d7310ceea5 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Fri Apr 7 17:10:44 2017 +0200 + + Fix crash of keyframe selection on 32bit linux + +commit 5f8df3da965686df39a6ae5c9f17482075017bf4 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Jan 19 14:00:53 2016 +0500 + + Solve some strict warnings in tests + +commit 8ea3a5d752a9ce3337ab7643897472a4d33747f1 +Author: Brecht Van Lommel <brechtvanlommel@gmail.com> +Date: Sat Feb 18 23:52:31 2017 +0100 + + Fix a few compiler warnings with macOS / clang. + +commit ffbe81461770e70736e80b8cab8e6eb1f8b27160 +Author: Mike Erwin <significant.bit@gmail.com> +Date: Wed May 31 10:43:08 2017 +0200 + + Fix comparison of identicals + + Some of these check that dimensions match before running code that + assumes they do match. + + Found with PVS-Studio T48917. + +commit 206c01999cde16c1c6c43a8e13ffa86020821d98 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:39:16 2017 +0200 + + Add basic track masking API in place + + This brings back ability to mask non-interesting parts of + specific track (the feature got lost with new auto-track API). + + Added it back by extending frame accessor class. This isn't really + a frame thing, but we don't have other type of accessor here. + + Surely, we can use old-style API here and pass mask via region + tracker options for this particular case, but then it becomes much + less obvious how real auto-tracker will access this mask with old + style API. + + So seems we do need an accessor for such data, just matter of + finding better place than frame accessor. + +commit faa069cb826892780356477cc10602390fecf06b +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:36:26 2017 +0200 + + Tests: Tweak epsilon to avoid what looks a false-positive failure + +commit 7c84e45c1d330871477ba3516f57178e5b9d101f +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed May 31 10:15:43 2017 +0200 + + CMake: Fix mistake in closing branch + +commit cb769a0d319a8c95948153d78a4c3378a0142ece +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Jul 21 12:52:33 2016 +0200 + + Set of fixes for MSVC215 + + - Move GLOG/GFLAGS defines to a more global scope, + this way ANY of our own libraries will use proper + declspec. + + - Compile png/zlib/openexif on Windows as well since + those are required for a correct linking. + +commit bb95c8654fd2cea72d66ed04cd825cc3712ea804 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Jul 20 18:14:46 2016 +0200 + + Disable unexisting Ceres option + + Explicit Schur complement requires having + newer Ceres than we currently have bundled. + +commit a2e12c959ef32cc9382244d1581992c2f7aa9c09 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Jul 20 18:04:57 2016 +0200 + + Various fixes for MSVC + + - Update Eigen to 3.2.7 since this brings crucial + fixes for MSVC 2015. + + - Switch to STATIC build by default. + + There are issues building current sources as dynamic + libraries with MSVC2015 and additionally building + dynamic Ceres is not recommended anyway, so let's + not do this for the time being. + + If anyone finds a way to make this all working -- + it'llsurely be a welcome addition. + commit 7a676106720fb126a27ff010abdd8bb65d7e0d9a Author: Sergey Sharybin <sergey.vfx@gmail.com> Date: Mon Jan 4 18:30:12 2016 +0500 @@ -365,239 +518,3 @@ Date: Thu May 8 15:50:26 2014 +0200 Reviewed By: sergey Differential Revision: https://developer.blender.org/D516 - -commit 4405dff60ea08d454b64da1a7c0595d9328cf8a3 -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 8 15:38:14 2014 +0200 - - Add public SetMarkers to AutoTrack - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D515 - -commit c90837f6db276a3b1f610eaad509155f6a43b24f -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 8 15:17:48 2014 +0200 - - Make autotrack skeleton compile - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D514 - -commit be01baa2e82e36f63e548f073157e68d2ff870c0 -Author: Keir Mierle <mierle@gmail.com> -Date: Wed May 7 18:48:55 2014 +0200 - - Add preliminary TrackMarkerToFrame in autotrack - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D509 - -commit 0cab028d591b3d08672ca86eb6c6e4ac1aacf1d0 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 7 17:59:11 2014 +0200 - - Remove assert from ArrayND Resize - - That assert broke initialization of arrays which doesn't - own the data since constructor uses Resize to set shape - and strides. - - Strides are still to be fixed, but that's for later. - -commit 64f9c118029a9351e9023e96527c120e1d724d5b -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 7 17:42:21 2014 +0200 - - Fix ArrayND freeing the data it doesn't own - - Can't really guarantee it works fully correct now, - but at least this check is needed anyway and compilation - works just fine. - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D508 - -commit 0618f1c8e88dfc738cdde55784da80b889905e7c -Author: Keir Mierle <mierle@gmail.com> -Date: Wed May 7 12:03:32 2014 +0200 - - Minor changes - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D505 - -commit 5c34335e1bb90c4ed701ee830c718ed4e20dbffa -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 7 11:12:23 2014 +0200 - - Fix compilation error in frame accessor - - - int64 is not a standard type, we've got int64_t defined in - std int. We also have an msvc port of this header, so should - not be an issue. - - - Fixed inconsistency in usage of CacheKey and Key, used Key. - - - Some functions weren't marked as virtual. - - Additional change: added self to authors. - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D504 - -commit 06bc207614e262cd688e2c3ed820ade7c77bdb66 -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 22:30:59 2014 +0200 - - Start new Tracks implementation - - This adds the new Tracks implementation, as well as a - trivial test to show it compiles. - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D502 - -commit 25ce061e6da69881460ba7718bb0d660a2380a02 -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 19:10:51 2014 +0200 - - Add Reconstruction class for new API - - This starts the new Reconstruction class (with support for e.g. planes). This - also starts the new namespace "mv" which will eventually have all the symbols - we wish to export. - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D501 - -commit 0a6af3e29016048978aea607673340500e050339 -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 17:52:53 2014 +0200 - - Add a new Tracks implementation - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D500 - -commit 887b68d29c2b198f4939f9ab5153881aa2c1806e -Author: Keir Mierle <mierle@gmail.com> -Date: Tue May 6 17:01:39 2014 +0200 - - Initial commit of unfinished AutoTrack API - - This starts the creating the new AutoTrack API. The new API will - make it possible for libmv to do full autotracking, including - predictive tracking and also support multiple motion models (3D - planes etc). - - The first goal (not in this patch) is to convert Blender to use - the new API without adding any new functionality. - - Note: This does not add any of the API to the build system! - It likely does not compile. - - Reviewers: sergey - - Reviewed By: sergey - - Differential Revision: https://developer.blender.org/D499 - -commit 08cc227d431d257d27f300fbb8e6991e663302da -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Tue May 6 13:09:22 2014 +0200 - - Fix homography test failure - - It was caused by assuming that reconstructed homography matrix - should look exactly the same as the matrix used to generate a - test case. - - It's not actually valid assumption because different-looking - matrices could correspond to the same exact transform. - - In this change we make it so actual "re-projected" vectors - are being checked, not the values in matrix. This makes it - more predictable verification. - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D488 - -commit 0b7d83dc9627447dc7df64d7e3a468aefe9ddc13 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed Apr 23 19:14:55 2014 +0600 - - Fix compilation on OSX after previous commit - - EXPECT_EQ wasn't defined in the scope. - -commit d14049e00dabf8fdf49056779f0a3718fbb39e8f -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed Apr 23 15:08:16 2014 +0600 - - Move aligned malloc implementation into own file - - It was rather stupid having it in brute region tracker, - now it is in own file in base library (which was also - added in this commit, before this it consist of header - files only). - - Reviewers: keir - - Reviewed By: keir - - Differential Revision: https://developer.blender.org/D479 - -commit 0ddf3851bfcb8de43660b119a25a77a25674200d -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Mon Apr 21 14:14:03 2014 +0600 - - Optimization of PearsonProductMomentCorrelation - - Pass the arrays by reference rather than by value, - should give some percent of speedup. - - Also don't pass the dimensions to the function but - get them from the images themselves. - - Hopefully this will give some %% of tracker speedup. - -commit f68fdbe5896a6c5bd8b500caeec61b876c5e44c6 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Mon Apr 21 14:10:43 2014 +0600 - - Fix wrong assert in ResizeImage() - - The assert didn't make any sense because ComputeBoundingBox() - is intended to return bounding box in the following way: - (xmin, xmax, ymin, ymax). diff --git a/intern/libmv/bundle.sh b/intern/libmv/bundle.sh index 27e012f665f..d155d050782 100755 --- a/intern/libmv/bundle.sh +++ b/intern/libmv/bundle.sh @@ -120,6 +120,7 @@ if(WITH_LIBMV) add_definitions(\${GFLAGS_DEFINES}) add_definitions(\${GLOG_DEFINES}) add_definitions(\${CERES_DEFINES}) + add_definitions(-DLIBMV_GFLAGS_NAMESPACE=\${GFLAGS_NAMESPACE}) list(APPEND INC \${GFLAGS_INCLUDE_DIRS} diff --git a/intern/libmv/intern/frame_accessor.cc b/intern/libmv/intern/frame_accessor.cc index e7fc0ab4883..a741eb88fc7 100644 --- a/intern/libmv/intern/frame_accessor.cc +++ b/intern/libmv/intern/frame_accessor.cc @@ -134,6 +134,11 @@ struct LibmvFrameAccessor : public FrameAccessor { &width, &height); + if (cache_key == NULL) { + // No mask for the given track. + return NULL; + } + // TODO(sergey): Dumb code for until we can set data directly. FloatImage temp_image(float_buffer, height, diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index 316415555ab..285e2ebe477 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -93,7 +93,7 @@ class SpellChecker: "deadzone", "deconstruct", "defocus", - "denoise", + "denoise", "denoising", "deselect", "deselecting", "deselection", "despill", "despilling", "dirtree", @@ -439,6 +439,7 @@ class SpellChecker: "editmode", "fcurve", "fcurves", "fedge", "fedges", + "filmic", "fluidsim", "frameserver", "freestyle", diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 5df02c82e36..6737b8e1089 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -338,19 +338,19 @@ class SEQUENCER_MT_add(Menu): if len(bpy.data.scenes) > 10: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("sequencer.scene_strip_add", text="Scene...") + layout.operator("sequencer.scene_strip_add", text="Scene") else: layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene...") if len(bpy.data.movieclips) > 10: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("sequencer.movieclip_strip_add", text="Clips...") + layout.operator("sequencer.movieclip_strip_add", text="Clips") else: layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip...") if len(bpy.data.masks) > 10: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("sequencer.mask_strip_add", text="Masks...") + layout.operator("sequencer.mask_strip_add", text="Masks") else: layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask...") @@ -362,7 +362,7 @@ class SEQUENCER_MT_add(Menu): class SEQUENCER_MT_add_effect(Menu): - bl_label = "Effect Strip..." + bl_label = "Effect Strip" def draw(self, context): layout = self.layout diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h index 6228ae60c56..70250310213 100644 --- a/source/blender/alembic/ABC_alembic.h +++ b/source/blender/alembic/ABC_alembic.h @@ -47,8 +47,8 @@ struct AlembicExportParams { double frame_start; double frame_end; - double frame_step_xform; - double frame_step_shape; + unsigned int frame_samples_xform; + unsigned int frame_samples_shape; double shutter_open; double shutter_close; diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index d974509d0ae..59a4cb082df 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -72,8 +72,8 @@ ExportSettings::ExportSettings() , renderable_only(false) , frame_start(1) , frame_end(1) - , frame_step_xform(1) - , frame_step_shape(1) + , frame_samples_xform(1) + , frame_samples_shape(1) , shutter_open(0.0) , shutter_close(1.0) , global_scale(1.0f) @@ -189,60 +189,56 @@ AbcExporter::~AbcExporter() delete m_writer; } -void AbcExporter::getShutterSamples(double step, bool time_relative, +void AbcExporter::getShutterSamples(unsigned int nr_of_samples, + bool time_relative, std::vector<double> &samples) { + Scene *scene = m_scene; /* for use in the FPS macro */ samples.clear(); - const double time_factor = time_relative ? m_scene->r.frs_sec : 1.0; - const double shutter_open = m_settings.shutter_open; - const double shutter_close = m_settings.shutter_close; + unsigned int frame_offset = time_relative ? m_settings.frame_start : 0; + double time_factor = time_relative ? FPS : 1.0; + double shutter_open = m_settings.shutter_open; + double shutter_close = m_settings.shutter_close; + double time_inc = (shutter_close - shutter_open) / nr_of_samples; - /* sample all frame */ - if (shutter_open == 0.0 && shutter_close == 1.0) { - 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 = static_cast<int>(std::max((1.0 / step) - 1.0, 1.0)); - const double time_inc = (shutter_close - shutter_open) / nsamples; + /* sample between shutter open & close */ + for (int sample=0; sample < nr_of_samples; ++sample) { + double sample_time = shutter_open + time_inc * sample; + double time = (frame_offset + sample_time) / time_factor; - for (double t = shutter_open; t <= shutter_close; t += time_inc) { - samples.push_back((t + m_settings.frame_start) / time_factor); - } + samples.push_back(time); } } Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step) { - TimeSamplingPtr time_sampling; std::vector<double> samples; if (m_settings.frame_start == m_settings.frame_end) { - time_sampling.reset(new Alembic::Abc::TimeSampling()); - return time_sampling; + return TimeSamplingPtr(new Alembic::Abc::TimeSampling()); } getShutterSamples(step, true, samples); - Alembic::Abc::TimeSamplingType ts(static_cast<uint32_t>(samples.size()), 1.0 / m_scene->r.frs_sec); - time_sampling.reset(new Alembic::Abc::TimeSampling(ts, samples)); + Alembic::Abc::TimeSamplingType ts( + static_cast<uint32_t>(samples.size()), + 1.0 / m_scene->r.frs_sec); - return time_sampling; + return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples)); } -void AbcExporter::getFrameSet(double step, std::set<double> &frames) +void AbcExporter::getFrameSet(unsigned int nr_of_samples, + std::set<double> &frames) { frames.clear(); std::vector<double> shutter_samples; - getShutterSamples(step, false, shutter_samples); + getShutterSamples(nr_of_samples, false, shutter_samples); 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) { + for (size_t j = 0; j < nr_of_samples; ++j) { frames.insert(frame + shutter_samples[j]); } } @@ -274,20 +270,20 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) /* Create time samplings for transforms and shapes. */ - TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_step_xform); + TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_samples_xform); m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time); TimeSamplingPtr shape_time; - if ((m_settings.frame_step_shape == m_settings.frame_step_xform) || + if ((m_settings.frame_samples_shape == m_settings.frame_samples_xform) || (m_settings.frame_start == m_settings.frame_end)) { shape_time = trans_time; m_shape_sampling_index = m_trans_sampling_index; } else { - shape_time = createTimeSampling(m_settings.frame_step_shape); + shape_time = createTimeSampling(m_settings.frame_samples_shape); m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time); } @@ -299,13 +295,12 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) /* Make a list of frames to export. */ std::set<double> xform_frames; - getFrameSet(m_settings.frame_step_xform, xform_frames); + getFrameSet(m_settings.frame_samples_xform, xform_frames); std::set<double> shape_frames; - getFrameSet(m_settings.frame_step_shape, shape_frames); + getFrameSet(m_settings.frame_samples_shape, shape_frames); /* Merge all frames needed. */ - std::set<double> frames(xform_frames); frames.insert(shape_frames.begin(), shape_frames.end()); @@ -328,7 +323,7 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) const double frame = *begin; /* 'frame' is offset by start frame, so need to cancel the offset. */ - setCurrentFrame(bmain, frame - m_settings.frame_start); + setCurrentFrame(bmain, frame); if (shape_frames.count(frame) != 0) { for (int i = 0, e = m_shapes.size(); i != e; ++i) { diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h index 3831acaafab..15158a9ef51 100644 --- a/source/blender/alembic/intern/abc_exporter.h +++ b/source/blender/alembic/intern/abc_exporter.h @@ -53,8 +53,8 @@ struct ExportSettings { bool renderable_only; double frame_start, frame_end; - double frame_step_xform; - double frame_step_shape; + double frame_samples_xform; + double frame_samples_shape; double shutter_open; double shutter_close; float global_scale; @@ -106,13 +106,15 @@ public: void operator()(Main *bmain, float &progress, bool &was_canceled); -private: - void getShutterSamples(double step, bool time_relative, std::vector<double> &samples); +protected: + void getShutterSamples(unsigned int nr_of_samples, + bool time_relative, + std::vector<double> &samples); + void getFrameSet(unsigned int nr_of_samples, std::set<double> &frames); +private: Alembic::Abc::TimeSamplingPtr createTimeSampling(double step); - void getFrameSet(double step, std::set<double> &frames); - void createTransformWritersHierarchy(EvaluationContext *eval_ctx); AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent); void exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, Object *parent, Object *dupliObParent); diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc index e2369e80618..5392387663f 100644 --- a/source/blender/alembic/intern/abc_transform.cc +++ b/source/blender/alembic/intern/abc_transform.cc @@ -108,6 +108,7 @@ void AbcTransformWriter::do_write() scale_m4_fl(scale_mat, m_settings.global_scale); scale_mat[3][3] = m_settings.global_scale; /* also scale translation */ mul_m4_m4m4(yup_mat, yup_mat, scale_mat); + yup_mat[3][3] /= m_settings.global_scale; /* normalise the homogeneous component */ } m_matrix = convert_matrix(yup_mat); diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index cfff13ec77e..3cad132b7be 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -341,8 +341,8 @@ bool ABC_export( job->settings.frame_start = params->frame_start; job->settings.frame_end = params->frame_end; - job->settings.frame_step_xform = params->frame_step_xform; - job->settings.frame_step_shape = params->frame_step_shape; + job->settings.frame_samples_xform = params->frame_samples_xform; + job->settings.frame_samples_shape = params->frame_samples_shape; job->settings.shutter_open = params->shutter_open; job->settings.shutter_close = params->shutter_close; @@ -976,7 +976,9 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader, return NULL; } - ISampleSelector sample_sel(time); + /* kFloorIndex is used to be compatible with non-interpolating + * properties; they use the floor. */ + ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex); return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str); } diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 9a60eb29957..e353d032ee4 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -144,6 +144,8 @@ void BKE_texture_get_value( const struct Scene *scene, struct Tex *texture, float *tex_co, struct TexResult *texres, bool use_color_management); +void BKE_texture_fetch_images_for_pool(struct Tex *texture, struct ImagePool *pool); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 93a26082ee3..874637896cd 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2125,6 +2125,8 @@ static void mesh_calc_modifiers( DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); append_mask |= CD_MASK_PREVIEW_MLOOPCOL; } + + dm->deformedOnly = false; } isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); @@ -2465,6 +2467,8 @@ static void editbmesh_calc_modifiers( deformedVerts = NULL; } } + + dm->deformedOnly = false; } /* In case of active preview modifier, make sure preview mask remains for following modifiers. */ diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 2a34a2e9418..73e9f5d0774 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -695,4 +695,8 @@ void BKE_pose_eval_proxy_copy(struct EvaluationContext *UNUSED(eval_ctx), Object printf("Proxy copy error, lib Object: %s proxy Object: %s\n", ob->id.name + 2, ob->proxy_from->id.name + 2); } + /* Rest of operations are NO-OP in depsgraph, so can clear + * flag now. + */ + ob->recalc &= ~OB_RECALC_ALL; } diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 537ff2b3c69..fb5ef403218 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1897,8 +1897,8 @@ static DerivedMesh *dynamicPaint_Modifier_apply( /* apply weights into a vertex group, if doesnt exists add a new layer */ if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) { - dvert = CustomData_add_layer_named(&result->vertData, CD_MDEFORMVERT, CD_CALLOC, - NULL, sData->total_points, surface->output_name); + dvert = CustomData_add_layer(&result->vertData, CD_MDEFORMVERT, CD_CALLOC, + NULL, sData->total_points); } if (defgrp_index != -1 && dvert) { int i; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 026e8aea74f..9b28d9732e5 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -62,6 +62,7 @@ #include "BLI_blenlib.h" #include "BLI_math_vector.h" +#include "BLI_mempool.h" #include "BLI_threads.h" #include "BLI_timecode.h" /* for stamp timecode format */ #include "BLI_utildefines.h" @@ -4132,33 +4133,32 @@ typedef struct ImagePoolEntry { typedef struct ImagePool { ListBase image_buffers; + BLI_mempool *memory_pool; } ImagePool; ImagePool *BKE_image_pool_new(void) { ImagePool *pool = MEM_callocN(sizeof(ImagePool), "Image Pool"); + pool->memory_pool = BLI_mempool_create(sizeof(ImagePoolEntry), 0, 128, BLI_MEMPOOL_NOP); return pool; } void BKE_image_pool_free(ImagePool *pool) { - ImagePoolEntry *entry, *next_entry; - - /* use single lock to dereference all the image buffers */ + /* Use single lock to dereference all the image buffers. */ BLI_spin_lock(&image_spin); - - for (entry = pool->image_buffers.first; entry; entry = next_entry) { - next_entry = entry->next; - - if (entry->ibuf) + for (ImagePoolEntry *entry = pool->image_buffers.first; + entry != NULL; + entry = entry->next) + { + if (entry->ibuf) { IMB_freeImBuf(entry->ibuf); - - MEM_freeN(entry); + } } - BLI_spin_unlock(&image_spin); + BLI_mempool_destroy(pool->memory_pool); MEM_freeN(pool); } @@ -4210,7 +4210,7 @@ ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool ibuf = image_acquire_ibuf(ima, iuser, NULL); - entry = MEM_callocN(sizeof(ImagePoolEntry), "Image Pool Entry"); + entry = BLI_mempool_alloc(pool->memory_pool); entry->image = ima; entry->frame = frame; entry->index = index; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 76d1b77b3a7..2df601ee4f5 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -4192,9 +4192,10 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha if (free_imbuf) { if (ibuf_change) { - if (seq->type == SEQ_TYPE_MOVIE) + if (seq->type == SEQ_TYPE_MOVIE) { BKE_sequence_free_anim(seq); - if (seq->type == SEQ_TYPE_SPEED) { + } + else if (seq->type == SEQ_TYPE_SPEED) { BKE_sequence_effect_speed_rebuild_map(scene, seq, true); } } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index ba04dd9b8f4..b62a72c7d9c 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1519,3 +1519,33 @@ void BKE_texture_get_value( { BKE_texture_get_value_ex(scene, texture, tex_co, texres, NULL, use_color_management); } + +static void texture_nodes_fetch_images_for_pool(bNodeTree *ntree, struct ImagePool *pool) +{ + for (bNode *node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_TEX_IMAGE && node->id != NULL) { + Image *image = (Image *)node->id; + BKE_image_pool_acquire_ibuf(image, NULL, pool); + } + else if (node->type == NODE_GROUP && node->id != NULL) { + /* TODO(sergey): Do we need to control recursion here? */ + bNodeTree *nested_tree = (bNodeTree *)node->id; + texture_nodes_fetch_images_for_pool(nested_tree, pool); + } + } +} + +/* Make sure all images used by texture are loaded into pool. */ +void BKE_texture_fetch_images_for_pool(Tex *texture, struct ImagePool *pool) +{ + if (texture->nodetree != NULL) { + texture_nodes_fetch_images_for_pool(texture->nodetree, pool); + } + else { + if (texture->type == TEX_IMAGE) { + if (texture->ima != NULL) { + BKE_image_pool_acquire_ibuf(texture->ima, NULL, pool); + } + } + } +} diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index 068c188e336..8bf5c3da90d 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -168,6 +168,8 @@ unsigned int BLI_ghashutil_inthash_p_murmur(const void *ptr); unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr); bool BLI_ghashutil_intcmp(const void *a, const void *b); +size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b); + unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]); #define BLI_ghashutil_inthash_v4(key) ( \ @@ -295,6 +297,25 @@ double BLI_ghash_calc_quality(GHash *gh); double BLI_gset_calc_quality(GSet *gs); #endif /* GHASH_INTERNAL_API */ +#define GHASH_FOREACH_BEGIN(type, var, what) \ + do { \ + GHashIterator gh_iter##var; \ + GHASH_ITER(gh_iter##var, what) { \ + type var = (type)(BLI_ghashIterator_getValue(&gh_iter##var)); \ + +#define GHASH_FOREACH_END() \ + } \ + } while(0) + +#define GSET_FOREACH_BEGIN(type, var, what) \ + do { \ + GSetIterator gh_iter##var; \ + GSET_ITER(gh_iter##var, what) { \ + type var = (type)(BLI_gsetIterator_getKey(&gh_iter##var)); + +#define GSET_FOREACH_END() \ + } \ + } while(0) #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 5f57f46066f..c1e28d5ebc3 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -126,6 +126,11 @@ if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \ (lb_iter != lb_init)); \ } +#define LINKLIST_FOREACH(type, var, list) \ + for (type var = (type)((list)->first); \ + var != NULL; \ + var = (type)(((Link*)(var))->next)) + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index c3c587275e1..721327d26a8 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -106,6 +106,13 @@ void *BLI_task_pool_userdata(TaskPool *pool); /* optional mutex to use from run function */ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool); +/* Delayed push, use that to reduce thread overhead by accumulating + * all new tasks into local queue first and pushing it to scheduler + * from within a single mutex lock. + */ +void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id); +void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id); + /* Parallel for routines */ typedef void (*TaskParallelRangeFunc)(void *userdata, const int iter); typedef void (*TaskParallelRangeFuncEx)(void *userdata, void *userdata_chunk, const int iter, const int thread_id); diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 944ee18e6b2..d1fe3557801 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -1225,6 +1225,11 @@ bool BLI_ghashutil_intcmp(const void *a, const void *b) return (a != b); } +size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b) +{ + return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2)); +} + /** * This function implements the widely used "djb" hash apparently posted * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index eb4e6e91aee..a1eae8f1955 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -52,7 +52,14 @@ * * This allows thread to fetch next task without locking the whole queue. */ -#define LOCALQUEUE_SIZE 1 +#define LOCAL_QUEUE_SIZE 1 + +/* Number of tasks which are allowed to be scheduled in a delayed manner. + * + * This allows to use less locks per graph node children schedule. More details + * could be found at TaskThreadLocalStorage::do_delayed_push. + */ +#define DELAYED_QUEUE_SIZE 4096 #ifndef NDEBUG # define ASSERT_THREAD_ID(scheduler, thread_id) \ @@ -129,9 +136,28 @@ typedef struct TaskMemPoolStats { #endif typedef struct TaskThreadLocalStorage { + /* Memory pool for faster task allocation. + * The idea is to re-use memory of finished/discarded tasks by this thread. + */ TaskMemPool task_mempool; + + /* Local queue keeps thread alive by keeping small amount of tasks ready + * to be picked up without causing global thread locks for synchronization. + */ int num_local_queue; - Task *local_queue[LOCALQUEUE_SIZE]; + Task *local_queue[LOCAL_QUEUE_SIZE]; + + /* Thread can be marked for delayed tasks push. This is helpful when it's + * know that lots of subsequent task pushed will happen from the same thread + * without "interrupting" for task execution. + * + * We try to accumulate as much tasks as possible in a local queue without + * any locks first, and then we push all of them into a scheduler's queue + * from within a single mutex lock. + */ + bool do_delayed_push; + int num_delayed_queue; + Task *delayed_queue[DELAYED_QUEUE_SIZE]; } TaskThreadLocalStorage; struct TaskPool { @@ -378,6 +404,7 @@ static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls, const int thread_id) { + BLI_assert(!tls->do_delayed_push); while (tls->num_local_queue > 0) { /* We pop task from queue before handling it so handler of the task can * push next job to the local queue. @@ -391,6 +418,7 @@ BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls, local_task->run(local_pool, local_task->taskdata, thread_id); task_free(local_pool, local_task, thread_id); } + BLI_assert(!tls->do_delayed_push); } static void *task_scheduler_thread_run(void *thread_p) @@ -408,7 +436,9 @@ static void *task_scheduler_thread_run(void *thread_p) TaskPool *pool = task->pool; /* run task */ + BLI_assert(!tls->do_delayed_push); task->run(pool, task->taskdata, thread_id); + BLI_assert(!tls->do_delayed_push); /* delete task */ task_free(pool, task, thread_id); @@ -547,6 +577,27 @@ static void task_scheduler_push(TaskScheduler *scheduler, Task *task, TaskPriori BLI_mutex_unlock(&scheduler->queue_mutex); } +static void task_scheduler_push_all(TaskScheduler *scheduler, + TaskPool *pool, + Task **tasks, + int num_tasks) +{ + if (num_tasks == 0) { + return; + } + + task_pool_num_increase(pool, num_tasks); + + BLI_mutex_lock(&scheduler->queue_mutex); + + for (int i = 0; i < num_tasks; i++) { + BLI_addhead(&scheduler->queue, tasks[i]); + } + + BLI_condition_notify_all(&scheduler->queue_cond); + BLI_mutex_unlock(&scheduler->queue_mutex); +} + static void task_scheduler_clear(TaskScheduler *scheduler, TaskPool *pool) { Task *task, *nexttask; @@ -714,38 +765,59 @@ void BLI_task_pool_free(TaskPool *pool) BLI_end_threaded_malloc(); } +BLI_INLINE bool task_can_use_local_queues(TaskPool *pool, int thread_id) +{ + return (thread_id != -1 && (thread_id != pool->thread_id || pool->do_work)); +} + static void task_pool_push( TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority, int thread_id) { + /* Allocate task and fill it's properties. */ Task *task = task_alloc(pool, thread_id); - task->run = run; task->taskdata = taskdata; task->free_taskdata = free_taskdata; task->freedata = freedata; task->pool = pool; - + /* For suspended pools we put everything yo a global queue first + * and exit as soon as possible. + * + * This tasks will be moved to actual execution when pool is + * activated by work_and_wait(). + */ if (pool->is_suspended) { BLI_addhead(&pool->suspended_queue, task); atomic_fetch_and_add_z(&pool->num_suspended, 1); return; } - - if (thread_id != -1 && - (thread_id != pool->thread_id || pool->do_work)) - { + /* Populate to any local queue first, this is cheapest push ever. */ + if (task_can_use_local_queues(pool, thread_id)) { ASSERT_THREAD_ID(pool->scheduler, thread_id); - TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id); - if (tls->num_local_queue < LOCALQUEUE_SIZE) { + /* Try to push to a local execution queue. + * These tasks will be picked up next. + */ + if (tls->num_local_queue < LOCAL_QUEUE_SIZE) { tls->local_queue[tls->num_local_queue] = task; tls->num_local_queue++; return; } + /* If we are in the delayed tasks push mode, we push tasks to a + * temporary local queue first without any locks, and then move them + * to global execution queue with a single lock. + */ + if (tls->do_delayed_push && tls->num_delayed_queue < DELAYED_QUEUE_SIZE) { + tls->delayed_queue[tls->num_delayed_queue] = task; + tls->num_delayed_queue++; + return; + } } - + /* Do push to a global execution ppol, slowest possible method, + * causes quite reasonable amount of threading overhead. + */ task_scheduler_push(pool->scheduler, task, priority); } @@ -816,7 +888,9 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* if found task, do it, otherwise wait until other tasks are done */ if (found_task) { /* run task */ + BLI_assert(!tls->do_delayed_push); work_task->run(pool, work_task->taskdata, pool->thread_id); + BLI_assert(!tls->do_delayed_push); /* delete task */ task_free(pool, task, pool->thread_id); @@ -871,6 +945,30 @@ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool) return &pool->user_mutex; } +void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id) +{ + if (task_can_use_local_queues(pool, thread_id)) { + ASSERT_THREAD_ID(pool->scheduler, thread_id); + TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id); + tls->do_delayed_push = true; + } +} + +void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id) +{ + if (task_can_use_local_queues(pool, thread_id)) { + ASSERT_THREAD_ID(pool->scheduler, thread_id); + TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id); + BLI_assert(tls->do_delayed_push); + task_scheduler_push_all(pool->scheduler, + pool, + tls->delayed_queue, + tls->num_delayed_queue); + tls->do_delayed_push = false; + tls->num_delayed_queue = 0; + } +} + /* Parallel range routines */ /** diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 5f4ed3db261..74841dc2756 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -205,6 +205,15 @@ static int bev_debug_flags = 0; #define DEBUG_OLD_PROJ_TO_PERP_PLANE (bev_debug_flags & 2) #define DEBUG_OLD_FLAT_MID (bev_debug_flags & 4) +/* Are d1 and d2 parallel or nearly so? */ +static bool nearly_parallel(const float d1[3], const float d2[3]) +{ + float ang; + + ang = angle_v3v3(d1, d2); + return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - M_PI) < BEVEL_EPSILON_ANG); +} + /* Make a new BoundVert of the given kind, insert it at the end of the circular linked * list with entry point bv->boundstart, and return it. */ static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) @@ -1059,7 +1068,7 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) { EdgeHalf *e; Profile *pro; - float co1[3], co2[3], co3[3], d1[3], d2[3], l; + float co1[3], co2[3], co3[3], d1[3], d2[3]; bool do_linear_interp; copy_v3_v3(co1, bndv->nv.co); @@ -1097,8 +1106,8 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) normalize_v3(d1); normalize_v3(d2); cross_v3_v3v3(pro->plane_no, d1, d2); - l = normalize_v3(pro->plane_no); - if (l <= BEVEL_EPSILON_BIG) { + normalize_v3(pro->plane_no); + if (nearly_parallel(d1, d2)) { /* co1 - midco -co2 are collinear. * Should be case that beveled edge is coplanar with two boundary verts. * We want to move the profile to that common plane, if possible. @@ -1130,17 +1139,24 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) sub_v3_v3v3(d4, e->next->e->v1->co, e->next->e->v2->co); normalize_v3(d3); normalize_v3(d4); - add_v3_v3v3(co3, co1, d3); - add_v3_v3v3(co4, co2, d4); - isect_kind = isect_line_line_v3(co1, co3, co2, co4, meetco, isect2); - if (isect_kind != 0) { - copy_v3_v3(pro->midco, meetco); - } - else { + if (nearly_parallel(d3, d4)) { /* offset lines are collinear - want linear interpolation */ mid_v3_v3v3(pro->midco, co1, co2); do_linear_interp = true; } + else { + add_v3_v3v3(co3, co1, d3); + add_v3_v3v3(co4, co2, d4); + isect_kind = isect_line_line_v3(co1, co3, co2, co4, meetco, isect2); + if (isect_kind != 0) { + copy_v3_v3(pro->midco, meetco); + } + else { + /* offset lines don't intersect - want linear interpolation */ + mid_v3_v3v3(pro->midco, co1, co2); + do_linear_interp = true; + } + } } } copy_v3_v3(pro->cob, co2); @@ -1149,8 +1165,8 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) sub_v3_v3v3(d2, pro->midco, co2); normalize_v3(d2); cross_v3_v3v3(pro->plane_no, d1, d2); - l = normalize_v3(pro->plane_no); - if (l <= BEVEL_EPSILON_BIG) { + normalize_v3(pro->plane_no); + if (nearly_parallel(d1, d2)) { /* whole profile is collinear with edge: just interpolate */ do_linear_interp = true; } diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index a266f30fe11..d5dcb84aaf5 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -90,7 +90,6 @@ set(SRC intern/depsgraph_types.h util/deg_util_function.h - util/deg_util_hash.h ) if(WITH_CXX11) diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index f8e384bf51c..dba589ed24f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -30,9 +30,6 @@ #include "intern/builder/deg_builder.h" -// TODO(sergey): Use own wrapper over STD. -#include <stack> - #include "DNA_anim_types.h" #include "DNA_object_types.h" #include "DNA_ID.h" @@ -40,6 +37,10 @@ #include "BLI_utildefines.h" #include "BLI_ghash.h" +extern "C" { +#include "BLI_stack.h" +} + #include "intern/depsgraph.h" #include "intern/depsgraph_types.h" #include "intern/nodes/deg_node.h" diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc index 9b37aaa12ff..1420b5fc8a5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc @@ -32,10 +32,10 @@ // TOO(sergey): Use some wrappers over those? #include <cstdio> #include <cstdlib> -#include <stack> extern "C" { #include "BLI_utildefines.h" +#include "BLI_stack.h" } #include "util/deg_util_foreach.h" @@ -48,12 +48,6 @@ extern "C" { namespace DEG { -struct StackEntry { - OperationDepsNode *node; - StackEntry *from; - DepsRelation *via_relation; -}; - void deg_graph_detect_cycles(Depsgraph *graph) { enum { @@ -65,7 +59,15 @@ void deg_graph_detect_cycles(Depsgraph *graph) NODE_IN_STACK = 2, }; - std::stack<StackEntry> traversal_stack; + struct StackEntry { + OperationDepsNode *node; + StackEntry *from; + DepsRelation *via_relation; + }; + + BLI_Stack *traversal_stack = BLI_stack_new(sizeof(StackEntry), + "DEG detect cycles stack"); + foreach (OperationDepsNode *node, graph->operations) { bool has_inlinks = false; foreach (DepsRelation *rel, node->inlinks) { @@ -78,7 +80,7 @@ void deg_graph_detect_cycles(Depsgraph *graph) entry.node = node; entry.from = NULL; entry.via_relation = NULL; - traversal_stack.push(entry); + BLI_stack_push(traversal_stack, &entry); node->tag = NODE_IN_STACK; } else { @@ -87,9 +89,9 @@ void deg_graph_detect_cycles(Depsgraph *graph) node->done = 0; } - while (!traversal_stack.empty()) { - StackEntry& entry = traversal_stack.top(); - OperationDepsNode *node = entry.node; + while (!BLI_stack_is_empty(traversal_stack)) { + StackEntry *entry = (StackEntry *)BLI_stack_peek(traversal_stack); + OperationDepsNode *node = entry->node; bool all_child_traversed = true; for (int i = node->done; i < node->outlinks.size(); ++i) { DepsRelation *rel = node->outlinks[i]; @@ -102,7 +104,7 @@ void deg_graph_detect_cycles(Depsgraph *graph) node->full_identifier().c_str(), rel->name); - StackEntry *current = &entry; + StackEntry *current = entry; while (current->node != to) { BLI_assert(current != NULL); printf(" '%s' depends on '%s' through '%s'\n", @@ -117,9 +119,9 @@ void deg_graph_detect_cycles(Depsgraph *graph) else if (to->tag == NODE_NOT_VISITED) { StackEntry new_entry; new_entry.node = to; - new_entry.from = &entry; + new_entry.from = entry; new_entry.via_relation = rel; - traversal_stack.push(new_entry); + BLI_stack_push(traversal_stack, &new_entry); to->tag = NODE_IN_STACK; all_child_traversed = false; node->done = i; @@ -129,9 +131,11 @@ void deg_graph_detect_cycles(Depsgraph *graph) } if (all_child_traversed) { node->tag = NODE_VISITED; - traversal_stack.pop(); + BLI_stack_discard(traversal_stack); } } + + BLI_stack_free(traversal_stack); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 00995ef2f31..e4b5fd6ffec 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -412,7 +412,6 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob) BuilderWalkUserData data; data.builder = this; data.scene = scene; - modifiers_foreachObjectLink(ob, modifier_walk, &data); BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 5a85a227453..70c430b5419 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -113,6 +113,41 @@ extern "C" { namespace DEG { +namespace { + +struct BuilderWalkUserData { + DepsgraphRelationBuilder *builder; + Main *bmain; + Scene *scene; +}; + +static void modifier_walk(void *user_data, + struct Object * /*ob*/, + struct Object **obpoin, + int /*cb_flag*/) +{ + BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; + if (*obpoin) { + data->builder->build_object(data->bmain, data->scene, *obpoin); + } +} + +void constraint_walk(bConstraint * /*con*/, + ID **idpoin, + bool /*is_reference*/, + void *user_data) +{ + BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; + if (*idpoin) { + ID *id = *idpoin; + if (GS(id->name) == ID_OB) { + data->builder->build_object(data->bmain, data->scene, (Object *)id); + } + } +} + +} /* namespace */ + /* ***************** */ /* Relations Builder */ @@ -407,6 +442,21 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o "[ObLocal -> ObParent]"); } + if (ob->modifiers.first != NULL) { + BuilderWalkUserData data; + data.builder = this; + data.bmain = bmain; + data.scene = scene; + modifiers_foreachObjectLink(ob, modifier_walk, &data); + } + if (ob->constraints.first != NULL) { + BuilderWalkUserData data; + data.builder = this; + data.bmain = bmain; + data.scene = scene; + BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data); + } + /* object constraints */ if (ob->constraints.first != NULL) { OperationKey constraint_key(&ob->id, diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 978e329136a..c3d64dc05bd 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -43,6 +43,7 @@ extern "C" { #include "DNA_windowmanager_types.h" #include "BLI_task.h" +#include "BLI_listbase.h" #include "BKE_idcode.h" #include "BKE_library.h" diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 8bed13d0499..a2bc38a7b5e 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -123,7 +123,9 @@ static void deg_task_run_func(TaskPool *pool, #endif } + BLI_task_pool_delayed_push_begin(pool, thread_id); schedule_children(pool, state->graph, node, thread_id); + BLI_task_pool_delayed_push_end(pool, thread_id); } typedef struct CalculatePengindData { diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index e10f86f6e95..afcf6994253 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -164,14 +164,33 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) * Plus it ensures visibility changes and relations and * layers visibility update has proper flags to work with. */ - if (comp_node->type == DEPSNODE_TYPE_ANIMATION) { - object->recalc |= OB_RECALC_TIME; - } - else if (comp_node->type == DEPSNODE_TYPE_TRANSFORM) { - object->recalc |= OB_RECALC_OB; - } - else { - object->recalc |= OB_RECALC_DATA; + switch (comp_node->type) { + case DEPSNODE_TYPE_UNDEFINED: + case DEPSNODE_TYPE_OPERATION: + case DEPSNODE_TYPE_ROOT: + case DEPSNODE_TYPE_TIMESOURCE: + case DEPSNODE_TYPE_ID_REF: + case DEPSNODE_TYPE_SUBGRAPH: + case DEPSNODE_TYPE_PARAMETERS: + case DEPSNODE_TYPE_SEQUENCER: + case DEPSNODE_TYPE_LAYER_COLLECTIONS: + /* Ignore, does not translate to object component. */ + break; + case DEPSNODE_TYPE_ANIMATION: + object->recalc |= OB_RECALC_TIME; + break; + case DEPSNODE_TYPE_TRANSFORM: + object->recalc |= OB_RECALC_OB; + break; + case DEPSNODE_TYPE_GEOMETRY: + case DEPSNODE_TYPE_EVAL_POSE: + case DEPSNODE_TYPE_BONE: + case DEPSNODE_TYPE_EVAL_PARTICLES: + case DEPSNODE_TYPE_SHADING: + case DEPSNODE_TYPE_CACHE: + case DEPSNODE_TYPE_PROXY: + object->recalc |= OB_RECALC_DATA; + break; } } } diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index b480cad2298..855b55fd23a 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -49,7 +49,6 @@ extern "C" { #include "intern/nodes/deg_node_operation.h" #include "intern/depsgraph_intern.h" #include "util/deg_util_foreach.h" -#include "util/deg_util_hash.h" namespace DEG { @@ -158,8 +157,8 @@ static unsigned int id_deps_node_hash_key(const void *key_v) { const IDDepsNode::ComponentIDKey *key = reinterpret_cast<const IDDepsNode::ComponentIDKey *>(key_v); - return hash_combine(BLI_ghashutil_uinthash(key->type), - BLI_ghashutil_strhash_p(key->name)); + return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->type), + BLI_ghashutil_strhash_p(key->name)); } static bool id_deps_node_hash_key_cmp(const void *a, const void *b) diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 4a741c80086..cf6224a3d82 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -35,6 +35,7 @@ extern "C" { #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "DNA_object_types.h" @@ -44,7 +45,6 @@ extern "C" { #include "intern/nodes/deg_node_operation.h" #include "intern/depsgraph_intern.h" #include "util/deg_util_foreach.h" -#include "util/deg_util_hash.h" namespace DEG { @@ -95,8 +95,8 @@ static unsigned int comp_node_hash_key(const void *key_v) { const ComponentDepsNode::OperationIDKey *key = reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(key_v); - return hash_combine(BLI_ghashutil_uinthash(key->opcode), - BLI_ghashutil_strhash_p(key->name)); + return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->opcode), + BLI_ghashutil_strhash_p(key->name)); } static bool comp_node_hash_key_cmp(const void *a, const void *b) diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc index 9eed4dfe8d8..cbf397bc7a9 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc @@ -32,13 +32,11 @@ #include "MEM_guardedalloc.h" -extern "C" { #include "BLI_utildefines.h" -} /* extern "C" */ +#include "BLI_ghash.h" #include "intern/depsgraph.h" #include "intern/depsgraph_intern.h" -#include "util/deg_util_hash.h" namespace DEG { diff --git a/source/blender/depsgraph/util/deg_util_foreach.h b/source/blender/depsgraph/util/deg_util_foreach.h index 8c234eae7de..e00aa5dbb5e 100644 --- a/source/blender/depsgraph/util/deg_util_foreach.h +++ b/source/blender/depsgraph/util/deg_util_foreach.h @@ -38,28 +38,3 @@ #else # error "Depsgraph requires either Boost or C++11 for range-based loops." #endif - -#define GHASH_FOREACH_BEGIN(type, var, what) \ - do { \ - GHashIterator gh_iter##var; \ - GHASH_ITER(gh_iter##var, what) { \ - type var = reinterpret_cast<type>(BLI_ghashIterator_getValue(&gh_iter##var)); \ - -#define GHASH_FOREACH_END() \ - } \ - } while(0) - -#define GSET_FOREACH_BEGIN(type, var, what) \ - do { \ - GSetIterator gh_iter##var; \ - GSET_ITER(gh_iter##var, what) { \ - type var = reinterpret_cast<type>(BLI_gsetIterator_getKey(&gh_iter##var)); \ - -#define GSET_FOREACH_END() \ - } \ - } while(0) - -#define LINKLIST_FOREACH(type, var, list) \ - for (type var = (type)((list)->first); \ - var != NULL; \ - var = (type)(((Link*)(var))->next)) diff --git a/source/blender/depsgraph/util/deg_util_hash.h b/source/blender/depsgraph/util/deg_util_hash.h deleted file mode 100644 index e490be1a7a1..00000000000 --- a/source/blender/depsgraph/util/deg_util_hash.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2014 Blender Foundation. - * All rights reserved. - * - * Original Author: Brecht van Lommel - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/depsgraph/util/deg_util_hash.h - * \ingroup depsgraph - */ - -#pragma once - -#include "BLI_utildefines.h" - -#include "BLI_ghash.h" - -/* XXX this might require 2 different variants for sizeof(size_t) (32 vs 64 bit) */ -BLI_INLINE size_t hash_combine(size_t hash_a, size_t hash_b) -{ - return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2)); -} diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 546f5e4208a..b4cfc1a8d87 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -748,10 +748,10 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op) void GPENCIL_OT_blank_frame_add(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Blank Frame"; + ot->name = "Insert Blank Frame"; ot->idname = "GPENCIL_OT_blank_frame_add"; - ot->description = "Add a new frame with nothing in it on the current frame. " - "If there is already a frame, all existing frames are shifted one frame later"; + ot->description = "Inserts a blank frame on the current frame " + "(all subsequently existing frames, if any, are shifted right by one frame)"; /* callbacks */ ot->exec = gp_blank_frame_add_exec; diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index 62c36552048..ba8792d12ff 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -102,12 +102,12 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op) char filename[FILE_MAX]; RNA_string_get(op->ptr, "filepath", filename); - const struct AlembicExportParams params = { + struct AlembicExportParams params = { .frame_start = RNA_int_get(op->ptr, "start"), .frame_end = RNA_int_get(op->ptr, "end"), - .frame_step_xform = 1.0 / (double)RNA_int_get(op->ptr, "xsamples"), - .frame_step_shape = 1.0 / (double)RNA_int_get(op->ptr, "gsamples"), + .frame_samples_xform = RNA_int_get(op->ptr, "xsamples"), + .frame_samples_shape = RNA_int_get(op->ptr, "gsamples"), .shutter_open = RNA_float_get(op->ptr, "sh_open"), .shutter_close = RNA_float_get(op->ptr, "sh_close"), @@ -133,8 +133,17 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op) .global_scale = RNA_float_get(op->ptr, "global_scale"), }; + /* Take some defaults from the scene, if not specified explicitly. */ + Scene *scene = CTX_data_scene(C); + if (params.frame_start == INT_MIN) { + params.frame_start = SFRA; + } + if (params.frame_end == INT_MIN) { + params.frame_end = EFRA; + } + const bool as_background_job = RNA_boolean_get(op->ptr, "as_background_job"); - bool ok = ABC_export(CTX_data_scene(C), C, filename, ¶ms, as_background_job); + bool ok = ABC_export(scene, C, filename, ¶ms, as_background_job); return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -295,11 +304,17 @@ void WM_OT_alembic_export(wmOperatorType *ot) FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - RNA_def_int(ot->srna, "start", 1, INT_MIN, INT_MAX, - "Start Frame", "Start Frame", INT_MIN, INT_MAX); - - RNA_def_int(ot->srna, "end", 1, INT_MIN, INT_MAX, - "End Frame", "End Frame", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "start", INT_MIN, INT_MIN, INT_MAX, + "Start Frame", + "Start frame of the export, use the default value to " + "take the start frame of the current scene", + INT_MIN, INT_MAX); + + RNA_def_int(ot->srna, "end", INT_MIN, INT_MIN, INT_MAX, + "End Frame", + "End frame of the export, use the default value to " + "take the end frame of the current scene", + INT_MIN, INT_MAX); RNA_def_int(ot->srna, "xsamples", 1, 1, 128, "Transform Samples", "Number of times per frame transformations are sampled", 1, 128); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 5b204b385de..a4aff5b10f3 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -51,6 +51,7 @@ #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_node.h" #include "BKE_report.h" #include "BKE_modifier.h" @@ -414,22 +415,18 @@ static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports) } } else { - if (ob->mat[i]) { - BKE_reportf(reports, RPT_ERROR, - "No active image found in material \"%s\" (%d) for object \"%s\"", - ob->mat[i]->id.name + 2, i, ob->id.name + 2); - } - else if (((Mesh *) ob->data)->mat[i]) { - BKE_reportf(reports, RPT_ERROR, + Material *mat = give_current_material(ob, i); + if (mat != NULL) { + BKE_reportf(reports, RPT_INFO, "No active image found in material \"%s\" (%d) for object \"%s\"", - ((Mesh *) ob->data)->mat[i]->id.name + 2, i, ob->id.name + 2); + mat->id.name + 2, i, ob->id.name + 2); } else { - BKE_reportf(reports, RPT_ERROR, - "No active image found in material (%d) for object \"%s\"", + BKE_reportf(reports, RPT_INFO, + "No active image found in material slot (%d) for object \"%s\"", i, ob->id.name + 2); } - return false; + continue; } image->id.tag |= LIB_TAG_DOIT; @@ -569,7 +566,11 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images) Image *image; ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL); - if ((image->id.tag & LIB_TAG_DOIT)) { + /* Some materials have no image, we just ignore those cases. */ + if (image == NULL) { + bake_images->lookup[i] = -1; + } + else if (image->id.tag & LIB_TAG_DOIT) { for (j = 0; j < i; j++) { if (bake_images->data[j].image == image) { bake_images->lookup[i] = j; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 065d1b4926c..f19b5619066 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -85,6 +85,7 @@ #include "BKE_mball.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_node.h" #include "BKE_object.h" #include "BKE_report.h" #include "BKE_sca.h" @@ -2006,6 +2007,18 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo single_tex_users_expand(bmain); } + /* Relink nodetrees' pointers that have been duplicated. */ + FOREACH_NODETREE(bmain, ntree, id) + { + /* This is a bit convoluted, we want to root ntree of copied IDs and only those, + * so we first check that old ID has been copied and that ntree is root tree of old ID, + * then get root tree of new ID and remap its pointers to new ID... */ + if (id->newid && (&ntree->id != id)) { + ntree = ntreeFromID(id->newid); + BKE_libblock_relink_to_newid(&ntree->id); + } + } FOREACH_NODETREE_END + /* Relink datablock pointer properties */ { IDP_RelinkProperty(scene->id.properties); diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index 9c73af12e3f..f497a06cb12 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -345,7 +345,7 @@ static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op)) ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); - if (ibuf == NULL) { + if ((ibuf == NULL) || (ibuf->x == 0) || (ibuf->y == 0)) { BKE_image_release_ibuf(ima, ibuf, lock); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index bf004db2c84..3f1f6a9d12d 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -429,6 +429,13 @@ static void object_delete_cb( tselem->id = NULL; #endif } + else { + /* No base, means object is no more instantiated in any scene. + * Should not happen ideally, but does happens, see T51625. + * Rather than twisting in all kind of ways to address all possible cases leading to that situation, simpler + * to allow deleting such object as a mere generic data-block. */ + WM_operator_name_call(C, "OUTLINER_OT_id_delete", WM_OP_INVOKE_REGION_WIN, NULL); + } } static void id_local_cb( diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index f87a0b5e7af..35b54bfd097 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3329,6 +3329,9 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) if (seq_act->sound) BKE_sound_add_scene_sound_defaults(scene, seq_act); if (seq_other->sound) BKE_sound_add_scene_sound_defaults(scene, seq_other); + BKE_sequence_invalidate_cache(scene, seq_act); + BKE_sequence_invalidate_cache(scene, seq_other); + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index 6fb1bccf491..600642f5e44 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -177,19 +177,18 @@ unsigned int getRowLength(int width, LogImageElement logElement) return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4; else if (logElement.packing == 1 || logElement.packing == 2) return ((width * logElement.depth - 1) / 3 + 1) * 4; - + break; case 12: if (logElement.packing == 0) return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4; else if (logElement.packing == 1 || logElement.packing == 2) return width * logElement.depth * 2; - + break; case 16: return width * logElement.depth * 2; - default: - return 0; } + return 0; } @@ -572,20 +571,20 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle return logImageElementGetData10Packed(logImage, logElement, data); else if (logElement.packing == 1 || logElement.packing == 2) return logImageElementGetData10(logImage, logElement, data); + break; case 12: if (logElement.packing == 0) return logImageElementGetData12Packed(logImage, logElement, data); else if (logElement.packing == 1 || logElement.packing == 2) return logImageElementGetData12(logImage, logElement, data); + break; case 16: return logImageElementGetData16(logImage, logElement, data); - - default: - /* format not supported */ - return 1; } + /* format not supported */ + return 1; } static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logElement, float *data) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 9d68c05dda0..de436172bfd 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -3746,7 +3746,7 @@ static const char *cpp_classes = "" "template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n" "class CollectionIterator {\n" "public:\n" -" CollectionIterator() : t(iter.ptr), init(false) { iter.valid = false; }\n" +" CollectionIterator() : iter(), t(iter.ptr), init(false) { iter.valid = false; }\n" " ~CollectionIterator(void) { if (init) Tend(&iter); };\n" "\n" " operator bool(void)\n" diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 49983b0bc2b..42c0344f46e 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -71,8 +71,8 @@ BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1, 1}; if (description && (description)[0]) { \ int i = strlen(description); \ if (i > 3 && (description)[i - 1] == '.' && (description)[i - 3] != '.') { \ - fprintf(stderr, "%s: '%s' '%s' description ends with a '.' !\n", \ - __func__, id1 ? id1 : "", id2 ? id2 : ""); \ + fprintf(stderr, "%s: '%s' description from '%s' '%s' ends with a '.' !\n", \ + __func__, description, id1 ? id1 : "", id2 ? id2 : ""); \ } \ } (void)0 diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index 091950a8e66..8c3984e4b29 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -185,12 +185,16 @@ static void rna_DomainFluidSettings_memory_estimate_get(PointerRNA *ptr, char *v #endif } -static int rna_DomainFluidSettings_memory_estimate_length(PointerRNA *UNUSED(ptr)) +static int rna_DomainFluidSettings_memory_estimate_length(PointerRNA *ptr) { #ifndef WITH_MOD_FLUID + UNUSED_VARS(ptr); return 0; #else - return 31; + char value[32]; + + rna_DomainFluidSettings_memory_estimate_get(ptr, value); + return strlen(value); #endif } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 8de706008ad..7bae2d64474 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -520,8 +520,9 @@ static void rna_Object_dup_group_set(PointerRNA *ptr, PointerRNA value) * thus causing a cycle/infinite-recursion leading to crashes on load [#25298] */ if (BKE_group_object_exists(grp, ob) == 0) { + id_us_min(&ob->dup_group->id); ob->dup_group = grp; - id_lib_extern((ID *)grp); + id_us_plus(&ob->dup_group->id); } else { BKE_report(NULL, RPT_ERROR, diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index c19da203844..f9f4e1dcdb4 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -226,8 +226,8 @@ static void rna_Scene_alembic_export( .frame_start = frame_start, .frame_end = frame_end, - .frame_step_xform = 1.0 / (double)xform_samples, - .frame_step_shape = 1.0 / (double)geom_samples, + .frame_samples_xform = xform_samples, + .frame_samples_shape = geom_samples, .shutter_open = shutter_open, .shutter_close = shutter_close, diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 3e6d8441363..84b62721999 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1095,7 +1095,7 @@ static void rna_def_strip_element(BlenderRNA *brna) prop = RNA_def_property(srna, "filename", PROP_STRING, PROP_FILENAME); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Filename", ""); + RNA_def_property_ui_text(prop, "Filename", "Name of the source file"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceElement_update"); prop = RNA_def_property(srna, "orig_width", PROP_INT, PROP_NONE); @@ -1120,25 +1120,25 @@ static void rna_def_strip_crop(BlenderRNA *brna) prop = RNA_def_property(srna, "max_y", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "top"); - RNA_def_property_ui_text(prop, "Top", ""); + RNA_def_property_ui_text(prop, "Top", "Number of pixels to crop from the top"); RNA_def_property_ui_range(prop, 0, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update"); prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "bottom"); - RNA_def_property_ui_text(prop, "Bottom", ""); + RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the buttom"); RNA_def_property_ui_range(prop, 0, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update"); prop = RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "left"); - RNA_def_property_ui_text(prop, "Left", ""); + RNA_def_property_ui_text(prop, "Left", "Number of pixels to crop from the left side"); RNA_def_property_ui_range(prop, 0, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update"); prop = RNA_def_property(srna, "max_x", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "right"); - RNA_def_property_ui_text(prop, "Right", ""); + RNA_def_property_ui_text(prop, "Right", "Number of pixels to crop from the right side"); RNA_def_property_ui_range(prop, 0, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update"); @@ -1156,13 +1156,13 @@ static void rna_def_strip_transform(BlenderRNA *brna) prop = RNA_def_property(srna, "offset_x", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "xofs"); - RNA_def_property_ui_text(prop, "Offset X", ""); + RNA_def_property_ui_text(prop, "Offset X", "Amount to move the input on the X axis within its boundaries"); RNA_def_property_ui_range(prop, -4096, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); prop = RNA_def_property(srna, "offset_y", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "yofs"); - RNA_def_property_ui_text(prop, "Offset Y", ""); + RNA_def_property_ui_text(prop, "Offset Y", "Amount to move the input on the Y axis within its boundaries"); RNA_def_property_ui_range(prop, -4096, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); @@ -1246,7 +1246,7 @@ static void rna_def_strip_proxy(BlenderRNA *brna) prop = RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "tc"); RNA_def_property_enum_items(prop, seq_tc_items); - RNA_def_property_ui_text(prop, "Timecode", ""); + RNA_def_property_ui_text(prop, "Timecode", "Method for reading the inputs timecode"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_tcindex_update"); prop = RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE); @@ -1289,17 +1289,17 @@ static void rna_def_color_balance(BlenderRNA *brna) prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN); - RNA_def_property_ui_text(prop, "Inverse Gain", ""); + RNA_def_property_ui_text(prop, "Inverse Gain", "Invert the gain color`"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); prop = RNA_def_property(srna, "invert_gamma", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAMMA); - RNA_def_property_ui_text(prop, "Inverse Gamma", ""); + RNA_def_property_ui_text(prop, "Inverse Gamma", "Invert the gamma color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); prop = RNA_def_property(srna, "invert_lift", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_LIFT); - RNA_def_property_ui_text(prop, "Inverse Lift", ""); + RNA_def_property_ui_text(prop, "Inverse Lift", "Invert the lift color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); /* not yet used */ @@ -1453,13 +1453,13 @@ static void rna_def_sequence(BlenderRNA *brna) prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MUTE); RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, true); - RNA_def_property_ui_text(prop, "Mute", ""); + RNA_def_property_ui_text(prop, "Mute", "Disable strip so that it cannot be viewed in the output"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_mute_update"); prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_LOCK); RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true); - RNA_def_property_ui_text(prop, "Lock", "Lock strip so that it can't be transformed"); + RNA_def_property_ui_text(prop, "Lock", "Lock strip so that it cannot be transformed"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); /* strip positioning */ @@ -1481,7 +1481,7 @@ static void rna_def_sequence(BlenderRNA *brna) prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "start"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Start Frame", ""); + RNA_def_property_ui_text(prop, "Start Frame", "X position where the strip begins"); RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_start_frame_set", NULL); /* overlap tests and calc_seq_disp */ RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); @@ -1552,12 +1552,12 @@ static void rna_def_sequence(BlenderRNA *brna) prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "blend_mode"); RNA_def_property_enum_items(prop, blend_mode_items); - RNA_def_property_ui_text(prop, "Blend Mode", ""); + RNA_def_property_ui_text(prop, "Blend Mode", "Method for controlling how the strip combines with other strips"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "blend_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Blend Opacity", ""); + RNA_def_property_ui_text(prop, "Blend Opacity", "Percentage of how much the strip's colors affect other strips"); /* stupid 0-100 -> 0-1 */ RNA_def_property_float_funcs(prop, "rna_Sequence_opacity_get", "rna_Sequence_opacity_set", NULL); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); @@ -1566,7 +1566,7 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_float_sdna(prop, NULL, "effect_fader"); - RNA_def_property_ui_text(prop, "Effect fader position", ""); + RNA_def_property_ui_text(prop, "Effect fader position", "Custom fade value"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "use_default_fade", PROP_BOOLEAN, PROP_NONE); @@ -1714,7 +1714,7 @@ static void rna_def_filter_video(StructRNA *srna) RNA_def_property_range(prop, 0.0f, 20.0f); RNA_def_property_ui_range(prop, 0.0f, 2.0f, 3, 3); RNA_def_property_float_default(prop, 1.0f); - RNA_def_property_ui_text(prop, "Saturation", ""); + RNA_def_property_ui_text(prop, "Saturation", "Adjust the intensity of the input's color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "strobe", PROP_FLOAT, PROP_NONE); @@ -2205,13 +2205,13 @@ static void rna_def_transform(StructRNA *srna) prop = RNA_def_property(srna, "scale_start_x", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "ScalexIni"); - RNA_def_property_ui_text(prop, "Scale X", ""); + RNA_def_property_ui_text(prop, "Scale X", "Amount to scale the input in the X axis"); RNA_def_property_ui_range(prop, 0, 10, 3, 6); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "scale_start_y", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "ScaleyIni"); - RNA_def_property_ui_text(prop, "Scale Y", ""); + RNA_def_property_ui_text(prop, "Scale Y", "Amount to scale the input in the Y axis"); RNA_def_property_ui_range(prop, 0, 10, 3, 6); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); @@ -2222,33 +2222,33 @@ static void rna_def_transform(StructRNA *srna) prop = RNA_def_property(srna, "translate_start_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xIni"); - RNA_def_property_ui_text(prop, "Translate X", ""); + RNA_def_property_ui_text(prop, "Translate X", "Amount to move the input on the X axis"); RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "translate_start_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yIni"); - RNA_def_property_ui_text(prop, "Translate Y", ""); + RNA_def_property_ui_text(prop, "Translate Y", "Amount to move the input on the Y axis"); RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "rotation_start", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rotIni"); RNA_def_property_range(prop, -360.0f, 360.0f); - RNA_def_property_ui_text(prop, "Rotation", ""); + RNA_def_property_ui_text(prop, "Rotation", "Degrees to rotate the input"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "translation_unit", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "percent"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */ RNA_def_property_enum_items(prop, translation_unit_items); - RNA_def_property_ui_text(prop, "Translation Unit", ""); + RNA_def_property_ui_text(prop, "Translation Unit", "Unit of measure to translate the input"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, interpolation_items); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */ - RNA_def_property_ui_text(prop, "Interpolation", ""); + RNA_def_property_ui_text(prop, "Interpolation", "Method to determine how missing pixels are created"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); } @@ -2260,7 +2260,7 @@ static void rna_def_solid_color(StructRNA *srna) prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "col"); - RNA_def_property_ui_text(prop, "Color", ""); + RNA_def_property_ui_text(prop, "Color", "Effect Strip color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); } @@ -2333,12 +2333,12 @@ static void rna_def_text(StructRNA *srna) prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "color"); - RNA_def_property_ui_text(prop, "Color", ""); + RNA_def_property_ui_text(prop, "Color", "Text color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shadow_color"); - RNA_def_property_ui_text(prop, "Shadow Color", ""); + RNA_def_property_ui_text(prop, "Shadow Color", "Shadow color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ); @@ -2358,13 +2358,13 @@ static void rna_def_text(StructRNA *srna) prop = RNA_def_property(srna, "align_x", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "align"); RNA_def_property_enum_items(prop, text_align_x_items); - RNA_def_property_ui_text(prop, "Align X", ""); + RNA_def_property_ui_text(prop, "Align X", "Align the text along the X axis"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "align_y", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "align_y"); RNA_def_property_enum_items(prop, text_align_y_items); - RNA_def_property_ui_text(prop, "Align Y", ""); + RNA_def_property_ui_text(prop, "Align Y", "Align the image along the Y axis"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "text", PROP_STRING, PROP_NONE); @@ -2512,7 +2512,7 @@ static void rna_def_colorbalance_modifier(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "color_multiply"); RNA_def_property_range(prop, 0.0f, 20.0f); RNA_def_property_float_default(prop, 1.0f); - RNA_def_property_ui_text(prop, "Multiply Colors", ""); + RNA_def_property_ui_text(prop, "Multiply Colors", "Multiply the intensity of each pixel"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update"); } @@ -2576,13 +2576,13 @@ static void rna_def_brightcontrast_modifier(BlenderRNA *brna) prop = RNA_def_property(srna, "bright", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "bright"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); - RNA_def_property_ui_text(prop, "Bright", ""); + RNA_def_property_ui_text(prop, "Bright", "Adjust the luminosity of the colors"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update"); prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "contrast"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); - RNA_def_property_ui_text(prop, "Contrast", ""); + RNA_def_property_ui_text(prop, "Contrast", "Adjust the difference in luminosity between pixels"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update"); } @@ -2599,13 +2599,12 @@ static void rna_def_tonemap_modifier(BlenderRNA *brna) srna = RNA_def_struct(brna, "SequencerTonemapModifierData", "SequenceModifier"); RNA_def_struct_sdna(srna, "SequencerTonemapModifierData"); - RNA_def_struct_ui_text(srna, "SequencerTonemapModifierData", - "Tone mapping modifier"); + RNA_def_struct_ui_text(srna, "SequencerTonemapModifierData", "Tone mapping modifier"); prop = RNA_def_property(srna, "tonemap_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, type_items); - RNA_def_property_ui_text(prop, "Tonemap Type", ""); + RNA_def_property_ui_text(prop, "Tonemap Type", "Tone mapping algorithm"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update"); prop = RNA_def_property(srna, "key", PROP_FLOAT, PROP_FACTOR); diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index f2f2a8a5a49..c422aa05b12 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -358,6 +358,7 @@ static void displaceModifier_do( data.vert_clnors = vert_clnors; if (dmd->texture != NULL) { data.pool = BKE_image_pool_new(); + BKE_texture_fetch_images_for_pool(dmd->texture, data.pool); } BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, numVerts > 512); diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index 73424a4e846..588c327ab91 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -684,6 +684,10 @@ void RE_bake_pixels_populate( int mat_nr = mp->mat_nr; int image_id = bake_images->lookup[mat_nr]; + if (image_id < 0) { + continue; + } + bd.bk_image = &bake_images->data[image_id]; bd.primitive_id = ++p_id; diff --git a/tests/gtests/alembic/CMakeLists.txt b/tests/gtests/alembic/CMakeLists.txt index c1480910d42..fadf549e212 100644 --- a/tests/gtests/alembic/CMakeLists.txt +++ b/tests/gtests/alembic/CMakeLists.txt @@ -26,6 +26,7 @@ set(INC .. ../../../source/blender/blenlib ../../../source/blender/alembic + ../../../source/blender/makesdna ${ALEMBIC_INCLUDE_DIRS} ${BOOST_INCLUDE_DIR} ${HDF5_INCLUDE_DIRS} @@ -44,8 +45,8 @@ else() endif() # For motivation on doubling BLENDER_SORTED_LIBS, see ../bmesh/CMakeLists.txt -BLENDER_SRC_GTEST(abc_matrix "abc_matrix_test.cc;${_buildinfo_src}" "${BLENDER_SORTED_LIBS};${BLENDER_SORTED_LIBS}") +BLENDER_SRC_GTEST(alembic "abc_matrix_test.cc;abc_export_test.cc;${_buildinfo_src}" "${BLENDER_SORTED_LIBS};${BLENDER_SORTED_LIBS}") unset(_buildinfo_src) -setup_liblinks(abc_matrix_test) +setup_liblinks(alembic_test) diff --git a/tests/gtests/alembic/abc_export_test.cc b/tests/gtests/alembic/abc_export_test.cc new file mode 100644 index 00000000000..63c1d179e51 --- /dev/null +++ b/tests/gtests/alembic/abc_export_test.cc @@ -0,0 +1,120 @@ +#include "testing/testing.h" + +// Keep first since utildefines defines AT which conflicts with fucking STL +#include "intern/abc_util.h" +#include "intern/abc_exporter.h" + +extern "C" { +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "DNA_scene_types.h" +} + +class TestableAbcExporter : public AbcExporter { +public: + TestableAbcExporter(Scene *scene, const char *filename, ExportSettings &settings) + : AbcExporter(scene, filename, settings) + {} + + void getShutterSamples(unsigned int nr_of_samples, + bool time_relative, + std::vector<double> &samples) + { + AbcExporter::getShutterSamples(nr_of_samples, time_relative, samples); + } + + void getFrameSet(unsigned int nr_of_samples, + std::set<double> &frames) { + AbcExporter::getFrameSet(nr_of_samples, frames); + } + +}; + + +TEST(abc_export, TimeSamplesFullShutter) { + ExportSettings settings; + settings.frame_start = 31.0; + settings.frame_end = 223.0; + settings.shutter_open = 0.0; + settings.shutter_close = 1.0; + + /* Fake a 25 FPS scene with a nonzero base (because that's sometimes forgotten) */ + Scene scene; + scene.r.frs_sec = 50; + scene.r.frs_sec_base = 2; + + TestableAbcExporter exporter(&scene, "somefile.abc", settings); + std::vector<double> samples; + + /* test 5 samples per frame */ + exporter.getShutterSamples(5, true, samples); + EXPECT_EQ(5, samples.size()); + EXPECT_NEAR(1.240, samples[0], 1e-5f); + EXPECT_NEAR(1.248, samples[1], 1e-5f); + EXPECT_NEAR(1.256, samples[2], 1e-5f); + EXPECT_NEAR(1.264, samples[3], 1e-5f); + EXPECT_NEAR(1.272, samples[4], 1e-5f); + + /* test same, but using frame number offset instead of time */ + exporter.getShutterSamples(5, false, samples); + EXPECT_EQ(5, samples.size()); + EXPECT_NEAR(0.0, samples[0], 1e-5f); + EXPECT_NEAR(0.2, samples[1], 1e-5f); + EXPECT_NEAR(0.4, samples[2], 1e-5f); + EXPECT_NEAR(0.6, samples[3], 1e-5f); + EXPECT_NEAR(0.8, samples[4], 1e-5f); + + /* use the same setup to test getFrameSet() */ + std::set<double> frames; + exporter.getFrameSet(5, frames); + EXPECT_EQ(965, frames.size()); + EXPECT_EQ(1, frames.count(31.0)); + EXPECT_EQ(1, frames.count(31.2)); + EXPECT_EQ(1, frames.count(31.4)); + EXPECT_EQ(1, frames.count(31.6)); + EXPECT_EQ(1, frames.count(31.8)); +} + + +TEST(abc_export, TimeSamples180degShutter) { + ExportSettings settings; + settings.frame_start = 31.0; + settings.frame_end = 223.0; + settings.shutter_open = -0.25; + settings.shutter_close = 0.25; + + /* Fake a 25 FPS scene with a nonzero base (because that's sometimes forgotten) */ + Scene scene; + scene.r.frs_sec = 50; + scene.r.frs_sec_base = 2; + + TestableAbcExporter exporter(&scene, "somefile.abc", settings); + std::vector<double> samples; + + /* test 5 samples per frame */ + exporter.getShutterSamples(5, true, samples); + EXPECT_EQ(5, samples.size()); + EXPECT_NEAR(1.230, samples[0], 1e-5f); + EXPECT_NEAR(1.234, samples[1], 1e-5f); + EXPECT_NEAR(1.238, samples[2], 1e-5f); + EXPECT_NEAR(1.242, samples[3], 1e-5f); + EXPECT_NEAR(1.246, samples[4], 1e-5f); + + /* test same, but using frame number offset instead of time */ + exporter.getShutterSamples(5, false, samples); + EXPECT_EQ(5, samples.size()); + EXPECT_NEAR(-0.25, samples[0], 1e-5f); + EXPECT_NEAR(-0.15, samples[1], 1e-5f); + EXPECT_NEAR(-0.05, samples[2], 1e-5f); + EXPECT_NEAR( 0.05, samples[3], 1e-5f); + EXPECT_NEAR( 0.15, samples[4], 1e-5f); + + /* Use the same setup to test getFrameSet(). + * Here only a few numbers are tested, due to rounding issues. */ + std::set<double> frames; + exporter.getFrameSet(5, frames); + EXPECT_EQ(965, frames.size()); + EXPECT_EQ(1, frames.count(30.75)); + EXPECT_EQ(1, frames.count(30.95)); + EXPECT_EQ(1, frames.count(31.15)); +} |