Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-05-31 16:51:17 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-05-31 16:52:11 +0300
commitf32a18994ad7f37eb568771f01bab9db53d38d54 (patch)
treedc014ea9a34c0d1fc414f1afa937daf1f55a5f97
parent82276d6cf7d3e18a0e5654d472bdff2b716b0d54 (diff)
parenta481908232ef20449e6ad6951769677e0b108ca8 (diff)
Merge branch 'master' into blender2.8
-rw-r--r--intern/audaspace/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/blender_mesh.cpp15
-rw-r--r--intern/cycles/blender/blender_util.h9
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp2
-rw-r--r--intern/cycles/kernel/shaders/node_principled_bsdf.osl4
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h12
-rw-r--r--intern/cycles/render/session.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp9
-rw-r--r--intern/libmv/ChangeLog389
-rwxr-xr-xintern/libmv/bundle.sh1
-rw-r--r--intern/libmv/intern/frame_accessor.cc5
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py3
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py8
-rw-r--r--source/blender/alembic/ABC_alembic.h4
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc65
-rw-r--r--source/blender/alembic/intern/abc_exporter.h14
-rw-r--r--source/blender/alembic/intern/abc_transform.cc1
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc8
-rw-r--r--source/blender/blenkernel/BKE_texture.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/armature_update.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/image.c24
-rw-r--r--source/blender/blenkernel/intern/sequencer.c5
-rw-r--r--source/blender/blenkernel/intern/texture.c30
-rw-r--r--source/blender/blenlib/BLI_ghash.h21
-rw-r--r--source/blender/blenlib/BLI_listbase.h5
-rw-r--r--source/blender/blenlib/BLI_task.h7
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c5
-rw-r--r--source/blender/blenlib/intern/task.c120
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c40
-rw-r--r--source/blender/depsgraph/CMakeLists.txt1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc36
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc50
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc1
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc35
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc5
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.cc6
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_operation.cc4
-rw-r--r--source/blender/depsgraph/util/deg_util_foreach.h25
-rw-r--r--source/blender/depsgraph/util/deg_util_hash.h41
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c6
-rw-r--r--source/blender/editors/io/io_alembic.c33
-rw-r--r--source/blender/editors/object/object_bake_api.c25
-rw-r--r--source/blender/editors/object/object_relations.c13
-rw-r--r--source/blender/editors/space_node/node_view.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c3
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c15
-rw-r--r--source/blender/makesrna/intern/makesrna.c2
-rw-r--r--source/blender/makesrna/intern/rna_define.c4
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c8
-rw-r--r--source/blender/makesrna/intern/rna_object.c3
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c71
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c1
-rw-r--r--source/blender/render/intern/source/bake_api.c4
-rw-r--r--tests/gtests/alembic/CMakeLists.txt5
-rw-r--r--tests/gtests/alembic/abc_export_test.cc120
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, &params, as_background_job);
+ bool ok = ABC_export(scene, C, filename, &params, 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));
+}