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:
-rw-r--r--doc/doxygen/Doxyfile2
-rw-r--r--intern/libmv/intern/reconstruction.cc23
m---------release/datafiles/locale0
-rw-r--r--release/freedesktop/org.blender.Blender.appdata.xml14
-rw-r--r--release/freedesktop/snap/README.txt38
-rwxr-xr-xrelease/freedesktop/snap/bundle.py21
-rw-r--r--release/freedesktop/snap/snapcraft.yaml.in48
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py2
-rw-r--r--release/scripts/modules/bl_keymap_utils/platform_helpers.py1
-rw-r--r--release/scripts/modules/bl_ui_utils/bug_report_url.py21
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py1
-rw-r--r--release/scripts/modules/bpy_extras/node_shader_utils.py16
-rw-r--r--release/scripts/modules/bpy_types.py4
-rw-r--r--release/scripts/modules/rna_prop_ui.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_material_gpencil.py6
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py8
-rw-r--r--release/scripts/startup/bl_ui/space_image.py4
-rw-r--r--release/scripts/startup/bl_ui/space_node.py21
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py26
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py7
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py3
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py2
-rw-r--r--source/blender/alembic/intern/abc_customdata.cc5
-rw-r--r--source/blender/alembic/intern/abc_customdata.h7
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc203
-rw-r--r--source/blender/alembic/intern/abc_mesh.h2
-rw-r--r--source/blender/alembic/intern/abc_object.cc3
-rw-r--r--source/blender/blenfont/BLF_api.h1
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c2
-rw-r--r--source/blender/blenfont/intern/blf_thumbs.c3
-rw-r--r--source/blender/blenkernel/BKE_armature.h3
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_blendfile.h6
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h4
-rw-r--r--source/blender/blenkernel/BKE_tracking.h6
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h19
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_legacy.c24
-rw-r--r--source/blender/blenkernel/intern/armature.c36
-rw-r--r--source/blender/blenkernel/intern/blender.c1
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c2
-rw-r--r--source/blender/blenkernel/intern/blendfile.c14
-rw-r--r--source/blender/blenkernel/intern/collection.c8
-rw-r--r--source/blender/blenkernel/intern/collision.c8
-rw-r--r--source/blender/blenkernel/intern/colortools.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c116
-rw-r--r--source/blender/blenkernel/intern/lattice.c4
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c4
-rw-r--r--source/blender/blenkernel/intern/mesh.c9
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c8
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c2
-rw-r--r--source/blender/blenkernel/intern/movieclip.c24
-rw-r--r--source/blender/blenkernel/intern/multires.c4
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.c4
-rw-r--r--source/blender/blenkernel/intern/object.c10
-rw-r--r--source/blender/blenkernel/intern/ocean.c4
-rw-r--r--source/blender/blenkernel/intern/particle.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c16
-rw-r--r--source/blender/blenkernel/intern/pbvh.c10
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c12
-rw-r--r--source/blender/blenkernel/intern/smoke.c16
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c28
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c10
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c23
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c4
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c4
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c23
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c17
-rw-r--r--source/blender/blenkernel/intern/undo_system.c205
-rw-r--r--source/blender/blenlib/BLI_math_geom.h7
-rw-r--r--source/blender/blenlib/BLI_task.h30
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c10
-rw-r--r--source/blender/blenlib/intern/math_geom.c40
-rw-r--r--source/blender/blenlib/intern/math_statistics.c4
-rw-r--r--source/blender/blenlib/intern/storage.c123
-rw-r--r--source/blender/blenlib/intern/task.c61
-rw-r--r--source/blender/blenloader/intern/readfile.c15
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c16
-rw-r--r--source/blender/blentranslation/CMakeLists.txt1
-rw-r--r--source/blender/blentranslation/intern/blt_lang.c3
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c19
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c3
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c9
-rw-r--r--source/blender/collada/Materials.cpp2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc3
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc1
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc68
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc4
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc23
-rw-r--r--source/blender/draw/CMakeLists.txt5
-rw-r--r--source/blender/draw/DRW_engine.h39
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c6
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c6
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl6
-rw-r--r--source/blender/draw/engines/select/select_engine.c641
-rw-r--r--source/blender/draw/engines/select/select_engine.h29
-rw-r--r--source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl26
-rw-r--r--source/blender/draw/engines/select/shaders/selection_id_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl)3
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c2
-rw-r--r--source/blender/draw/intern/draw_manager.c403
-rw-r--r--source/blender/draw/modes/object_mode.c10
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c7
-rw-r--r--source/blender/editors/animation/anim_draw.c43
-rw-r--r--source/blender/editors/curve/editcurve_paint.c4
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c2
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c77
-rw-r--r--source/blender/editors/gpencil/gpencil_add_monkey.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_add_stroke.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c42
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c15
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c53
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c18
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h6
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c12
-rw-r--r--source/blender/editors/gpencil/gpencil_merge.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c97
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c36
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c36
-rw-r--r--source/blender/editors/include/ED_gpencil.h6
-rw-r--r--source/blender/editors/include/ED_view3d.h20
-rw-r--r--source/blender/editors/include/UI_interface.h3
-rw-r--r--source/blender/editors/interface/interface_draw.c5
-rw-r--r--source/blender/editors/interface/interface_handlers.c2
-rw-r--r--source/blender/editors/interface/interface_region_hud.c59
-rw-r--r--source/blender/editors/interface/interface_region_popover.c24
-rw-r--r--source/blender/editors/lattice/editlattice_undo.c14
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt1
-rw-r--r--source/blender/editors/mesh/editmesh_select.c31
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c5
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c9
-rw-r--r--source/blender/editors/object/object_data_transfer.c2
-rw-r--r--source/blender/editors/object/object_hook.c10
-rw-r--r--source/blender/editors/object/object_intern.h5
-rw-r--r--source/blender/editors/object/object_modifier.c33
-rw-r--r--source/blender/editors/object/object_relations.c1
-rw-r--r--source/blender/editors/object/object_transform.c4
-rw-r--r--source/blender/editors/physics/particle_edit.c20
-rw-r--r--source/blender/editors/physics/particle_object.c8
-rw-r--r--source/blender/editors/render/render_preview.c5
-rw-r--r--source/blender/editors/screen/screen_edit.c2
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt1
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c7
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c48
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_undo.c68
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c28
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c104
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c4
-rw-r--r--source/blender/editors/space_action/action_select.c7
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c220
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c55
-rw-r--r--source/blender/editors/space_clip/clip_intern.h57
-rw-r--r--source/blender/editors/space_clip/clip_ops.c2
-rw-r--r--source/blender/editors/space_clip/clip_utils.c178
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops_solve.c11
-rw-r--r--source/blender/editors/space_file/filelist.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c238
-rw-r--r--source/blender/editors/transform/transform.c84
-rw-r--r--source/blender/editors/transform/transform_constraints.c21
-rw-r--r--source/blender/editors/transform/transform_conversions.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c33
-rw-r--r--source/blender/gpu/CMakeLists.txt3
-rw-r--r--source/blender/gpu/GPU_shader.h5
-rw-r--r--source/blender/gpu/intern/gpu_shader.c19
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl26
-rw-r--r--source/blender/imbuf/IMB_thumbs.h17
-rw-r--r--source/blender/imbuf/intern/thumbs_font.c34
-rw-r--r--source/blender/makesdna/DNA_ID.h9
-rw-r--r--source/blender/makesdna/DNA_collection_types.h12
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h2
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_meta.c2
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c5
-rw-r--r--source/blender/makesrna/intern/rna_object.c2
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c6
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c4
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c8
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c8
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c8
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c4
-rw-r--r--source/blender/python/intern/bpy.c52
-rw-r--r--source/blender/python/intern/bpy_traceback.c2
-rw-r--r--source/blender/render/intern/source/pointdensity.c4
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c3
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c35
-rw-r--r--source/blender/windowmanager/intern/wm_files.c16
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c5
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c7
-rw-r--r--source/creator/CMakeLists.txt6
213 files changed, 2924 insertions, 2257 deletions
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index de2026a6ca0..366d0b1b507 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = "V2.79"
+PROJECT_NUMBER = "V2.81"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/intern/libmv/intern/reconstruction.cc b/intern/libmv/intern/reconstruction.cc
index e271d663c4a..64f00b19df0 100644
--- a/intern/libmv/intern/reconstruction.cc
+++ b/intern/libmv/intern/reconstruction.cc
@@ -264,15 +264,15 @@ libmv_Reconstruction *libmv_solveReconstruction(
update_callback.invoke(0, "Selecting keyframes");
- selectTwoKeyframesBasedOnGRICAndVariance(tracks,
+ if (selectTwoKeyframesBasedOnGRICAndVariance(tracks,
normalized_tracks,
*camera_intrinsics,
keyframe1,
- keyframe2);
-
- /* so keyframes in the interface would be updated */
- libmv_reconstruction_options->keyframe1 = keyframe1;
- libmv_reconstruction_options->keyframe2 = keyframe2;
+ keyframe2)) {
+ /* so keyframes in the interface would be updated */
+ libmv_reconstruction_options->keyframe1 = keyframe1;
+ libmv_reconstruction_options->keyframe2 = keyframe2;
+ }
}
/* Actual reconstruction. */
@@ -283,7 +283,7 @@ libmv_Reconstruction *libmv_solveReconstruction(
LG << "number of markers for init: " << keyframe_markers.size();
- if (keyframe_markers.size() < 8) {
+ if (keyframe_markers.size() < 16) {
LG << "No enough markers to initialize from";
libmv_reconstruction->is_valid = false;
return libmv_reconstruction;
@@ -291,13 +291,18 @@ libmv_Reconstruction *libmv_solveReconstruction(
update_callback.invoke(0, "Initial reconstruction");
- EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
+ if (!EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction)) {
+ LG << "Failed to initialize reconstruction";
+ libmv_reconstruction->is_valid = false;
+ return libmv_reconstruction;
+ }
+
EuclideanBundle(normalized_tracks, &reconstruction);
EuclideanCompleteReconstruction(normalized_tracks,
&reconstruction,
&update_callback);
- /* Refinement/ */
+ /* Refinement. */
if (libmv_reconstruction_options->refine_intrinsics) {
libmv_solveRefineIntrinsics(
tracks,
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject 6625026f62f492dd677f5f29c68b9d70c96fb34
+Subproject 63f65770e67f38db29f76ac910dd87bd9841b91
diff --git a/release/freedesktop/org.blender.Blender.appdata.xml b/release/freedesktop/org.blender.Blender.appdata.xml
index 635d08b937d..1287c9eea5d 100644
--- a/release/freedesktop/org.blender.Blender.appdata.xml
+++ b/release/freedesktop/org.blender.Blender.appdata.xml
@@ -10,15 +10,15 @@
<p>
Blender is the free and open source 3D creation suite. It supports
the entirety of the 3D pipeline — modeling, rigging, animation,
- simulation, rendering, compositing and motion tracking, even video
- editing and game creation.
+ simulation, rendering, compositing, motion tracking, and video
+ editing.
</p>
<p>
- Advanced users can employ Blender’s API for Python scripting to
- customize the application and write specialized tools. Blender is
- well suited to individuals and small studios who benefit from its
- unified pipeline and responsive development process.
+ Blender is a public project, made by hundreds of people from around the
+ world; by studios and individual artists, professionals and hobbyists,
+ scientists, students, VFX experts, animators, game artists, modders, and
+ the list goes on.
</p>
</description>
<url type="homepage">https://www.blender.org</url>
@@ -40,7 +40,7 @@
</screenshot>
</screenshots>
<releases>
- <release version="2.80" date="2019-07-18">
+ <release version="2.80" date="2019-07-30">
<description>
<p>New features:</p>
<ul>
diff --git a/release/freedesktop/snap/README.txt b/release/freedesktop/snap/README.txt
new file mode 100644
index 00000000000..2e8822f32dc
--- /dev/null
+++ b/release/freedesktop/snap/README.txt
@@ -0,0 +1,38 @@
+
+Snap Package Instructions
+=========================
+
+This folder contains the scripts for creating and uploading the snap on:
+https://snapcraft.io/blender
+
+
+Setup
+-----
+
+This has only been tested to work on Ubuntu.
+
+# Install required packages
+sudo apt install snapd snapcraft
+
+
+Steps
+-----
+
+# Build the snap file
+python3 bundle.py --version 2.XX --url https://download.blender.org/release/Blender2.XX/blender-2.XX-x86_64.tar.bz2
+
+# Install snap to test
+# --dangerous is needed since the snap has not been signed yet
+# --classic is required for installing Blender in general
+sudo snap install --dangerous --classic blender_2.XX_amd64.snap
+
+# Upload
+snapcraft push --release=stable blender_2.XX_amd64.snap
+
+
+Release Values
+--------------
+
+stable: final release
+candidate: release candidates
+
diff --git a/release/freedesktop/snap/bundle.py b/release/freedesktop/snap/bundle.py
new file mode 100755
index 00000000000..c3ecc5af561
--- /dev/null
+++ b/release/freedesktop/snap/bundle.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import pathlib
+import subprocess
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--version", required=True)
+parser.add_argument("--url", required=True)
+parser.add_argument("--grade", default="stable", choices=["stable", "devel"])
+args = parser.parse_args()
+
+yaml_text = pathlib.Path("snapcraft.yaml.in").read_text()
+yaml_text = yaml_text.replace("@VERSION@", args.version)
+yaml_text = yaml_text.replace("@URL@", args.url)
+yaml_text = yaml_text.replace("@GRADE@", args.grade)
+pathlib.Path("snapcraft.yaml").write_text(yaml_text)
+
+subprocess.call(["snapcraft", "clean"])
+subprocess.call(["snapcraft", "snap"])
diff --git a/release/freedesktop/snap/snapcraft.yaml.in b/release/freedesktop/snap/snapcraft.yaml.in
new file mode 100644
index 00000000000..a79d9ccc0a2
--- /dev/null
+++ b/release/freedesktop/snap/snapcraft.yaml.in
@@ -0,0 +1,48 @@
+name: blender
+summary: Blender is the free and open source 3D creation suite.
+description: |
+ Blender is the free and open source 3D creation suite. It supports the
+ entirety of the 3D pipeline—modeling, rigging, animation, simulation,
+ rendering, compositing and motion tracking, and video editing.
+
+ Blender is a public project, made by hundreds of people from around the
+ world; by studios and individual artists, professionals and hobbyists,
+ scientists, students, VFX experts, animators, game artists, modders, and
+ the list goes on.
+
+ The standard snap channels are used in the following way:
+
+ stable - Latest stable release.
+ candidate - Test builds for the upcoming stable release.
+
+icon: ../icons/scalable/apps/blender.svg
+
+passthrough:
+ license: GPL-3.0
+
+confinement: classic
+
+apps:
+ blender:
+ command: ./blender
+ desktop: ./blender.desktop
+
+version: '@VERSION@'
+grade: @GRADE@
+
+parts:
+ blender:
+ plugin: dump
+ source: @URL@
+ build-attributes: [keep-execstack, no-patchelf]
+ override-build: |
+ snapcraftctl build
+ sed -i 's|Icon=blender|Icon=${SNAP}/blender.svg|' ${SNAPCRAFT_PART_INSTALL}/blender.desktop
+ stage-packages:
+ - libxcb1
+ - libxext6
+ - libx11-6
+ - libxi6
+ - libxfixes3
+ - libxrender1
+ - libxxf86vm1
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 979298511916b25ec97bb22feb1c06cc9fbc86d
+Subproject 37a8bdc661649cb6197e73b5eb96481cd5fb0c5
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject b4fce25e94ec139554e821f58bbada3384b13af
+Subproject d9ed9d4d064c74c86e2767cd4be32d602a0ee31
diff --git a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
index fe7068afc5a..e98251ecc77 100644
--- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
+++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
@@ -432,7 +432,7 @@ def generate(context, space_type):
)
kmi.properties.name = tap_reset_tool
- if use_release_confirm:
+ if use_release_confirm and (kmi_toolbar_type is not None):
kmi = keymap.keymap_items.new(
"ui.button_execute",
type=kmi_toolbar_type,
diff --git a/release/scripts/modules/bl_keymap_utils/platform_helpers.py b/release/scripts/modules/bl_keymap_utils/platform_helpers.py
index 9aacb08e109..e6506f11b71 100644
--- a/release/scripts/modules/bl_keymap_utils/platform_helpers.py
+++ b/release/scripts/modules/bl_keymap_utils/platform_helpers.py
@@ -44,6 +44,7 @@ def keyconfig_data_oskey_from_ctrl_for_macos(keyconfig_data_src):
'M',
'SPACE',
'W',
+ 'ACCENT_GRAVE',
}) and (
item_event.get("ctrl") and
(not item_event.get("alt")) and
diff --git a/release/scripts/modules/bl_ui_utils/bug_report_url.py b/release/scripts/modules/bl_ui_utils/bug_report_url.py
index 510ea5d7e57..be94b45c8ac 100644
--- a/release/scripts/modules/bl_ui_utils/bug_report_url.py
+++ b/release/scripts/modules/bl_ui_utils/bug_report_url.py
@@ -18,7 +18,8 @@
# <pep8-80 compliant>
-def url_prefill_from_blender():
+
+def url_prefill_from_blender(addon_info=None):
import bpy
import bgl
import struct
@@ -44,7 +45,7 @@ def url_prefill_from_blender():
)
fh.write(
"\n"
- "\n**Blender Version**\n"
+ "**Blender Version**\n"
)
fh.write(
"Broken: version: {!s}, branch: {!s}, commit date: {!s} {!s}, hash: `rB{!s}`\n".format(
@@ -57,7 +58,18 @@ def url_prefill_from_blender():
)
fh.write(
"Worked: (optional)\n"
- "\n"
+ )
+ if addon_info:
+ fh.write(
+ "\n"
+ "**Addon Information**\n"
+ )
+ fh.write((
+ "Name: {name} {version}\n"
+ "Author: {author}\n").format(**addon_info)
+ )
+
+ fh.write(
"\n"
"**Short description of error**\n"
"[Please fill out a short description of the error here]\n"
@@ -70,7 +82,8 @@ def url_prefill_from_blender():
fh.seek(0)
+ form_number = 2 if addon_info else 1
return (
- "https://developer.blender.org/maniphest/task/edit/form/1?description=" +
+ "https://developer.blender.org/maniphest/task/edit/form/%i?description=" % form_number +
urllib.parse.quote(fh.read())
)
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index e6424de0742..b39099158c6 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -65,6 +65,7 @@ from _bpy import (
script_paths as _bpy_script_paths,
unregister_class,
user_resource as _user_resource,
+ system_resource,
)
import bpy as _bpy
diff --git a/release/scripts/modules/bpy_extras/node_shader_utils.py b/release/scripts/modules/bpy_extras/node_shader_utils.py
index 01ccd51aada..0eac9794930 100644
--- a/release/scripts/modules/bpy_extras/node_shader_utils.py
+++ b/release/scripts/modules/bpy_extras/node_shader_utils.py
@@ -42,6 +42,13 @@ def rgb_to_rgba(rgb):
def rgba_to_rgb(rgba):
return Color((rgba[0], rgba[1], rgba[2]))
+# All clamping value shall follow Blender's defined min/max (check relevant node definition .c file).
+def values_clamp(val, minv, maxv):
+ if hasattr(val, "__iter__"):
+ return tuple(max(minv, min(maxv, v)) for v in val)
+ else:
+ return max(minv, min(maxv, val))
+
class ShaderWrapper():
"""
@@ -267,6 +274,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def base_color_set(self, color):
+ color = values_clamp(color, 0.0, 1.0)
color = rgb_to_rgba(color)
self.material.diffuse_color = color
if self.use_nodes and self.node_principled_bsdf is not None:
@@ -297,6 +305,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def specular_set(self, value):
+ value = values_clamp(value, 0.0, 1.0)
self.material.specular_intensity = value
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Specular"].default_value = value
@@ -311,6 +320,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def specular_tint_set(self, value):
+ value = values_clamp(value, 0.0, 1.0)
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Specular Tint"].default_value = value
@@ -341,6 +351,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def roughness_set(self, value):
+ value = values_clamp(value, 0.0, 1.0)
self.material.roughness = value
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Roughness"].default_value = value
@@ -371,6 +382,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def metallic_set(self, value):
+ value = values_clamp(value, 0.0, 1.0)
self.material.metallic = value
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Metallic"].default_value = value
@@ -401,6 +413,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def ior_set(self, value):
+ value = values_clamp(value, 0.0, 1000.0)
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["IOR"].default_value = value
@@ -427,6 +440,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def transmission_set(self, value):
+ value = values_clamp(value, 0.0, 1.0)
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Transmission"].default_value = value
@@ -453,6 +467,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def alpha_set(self, value):
+ value = values_clamp(value, 0.0, 1.0)
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Alpha"].default_value = value
@@ -483,6 +498,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def normalmap_strength_set(self, value):
+ value = values_clamp(value, 0.0, 10.0)
if self.use_nodes and self.node_normalmap is not None:
self.node_normalmap.inputs["Strength"].default_value = value
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index ec016d364c6..eca79795269 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -151,10 +151,12 @@ class WindowManager(bpy_types.ID):
self, draw_func, *,
ui_units_x=0,
keymap=None,
+ from_active_button=False,
):
import bpy
popup = self.popover_begin__internal(
ui_units_x=ui_units_x,
+ from_active_button=from_active_button,
)
try:
@@ -655,7 +657,7 @@ class Gizmo(StructRNA):
return (batch, shader)
- # Dummy class to keep the reference in `bpy_types_dict` and avoid
+# Dummy class to keep the reference in `bpy_types_dict` and avoid
# erros like: "TypeError: expected GizmoGroup subclass of class ..."
class GizmoGroup(StructRNA):
__slots__ = ()
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 50becba0e3f..9d1ba035b3e 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -280,7 +280,7 @@ class PropertyPanel:
"""
bl_label = "Custom Properties"
bl_options = {'DEFAULT_CLOSED'}
- bl_order = 1000 # Order panel after all others
+ bl_order = 1000 # Order panel after all others
@classmethod
def poll(cls, context):
diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py
index 29a89c7b4a3..8db0f8182ab 100644
--- a/release/scripts/startup/bl_ui/properties_material_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py
@@ -120,6 +120,7 @@ class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel):
ma = context.material
if ma is not None and ma.grease_pencil is not None:
gpcolor = ma.grease_pencil
+ self.layout.enabled = not gpcolor.lock
self.layout.prop(gpcolor, "show_stroke", text="")
def draw(self, context):
@@ -131,7 +132,7 @@ class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel):
gpcolor = ma.grease_pencil
col = layout.column()
- col.active = not gpcolor.lock
+ col.enabled = not gpcolor.lock
col.prop(gpcolor, "mode")
@@ -169,6 +170,7 @@ class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
def draw_header(self, context):
ma = context.material
gpcolor = ma.grease_pencil
+ self.layout.enabled = not gpcolor.lock
self.layout.prop(gpcolor, "show_fill", text="")
def draw(self, context):
@@ -180,7 +182,7 @@ class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
# color settings
col = layout.column()
- col.active = not gpcolor.lock
+ col.enabled = not gpcolor.lock
col.prop(gpcolor, "fill_style", text="Style")
if gpcolor.fill_style == 'GRADIENT':
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 8a812c005f6..084ba4b36d8 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -1152,6 +1152,7 @@ class CLIP_PT_tools_mask_transforms(MASK_PT_transforms, Panel):
bl_region_type = 'TOOLS'
bl_category = "Mask"
+
class CLIP_PT_tools_mask_tools(MASK_PT_tools, Panel):
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'TOOLS'
@@ -1203,7 +1204,7 @@ class CLIP_PT_tools_scenesetup(Panel):
# Grease Pencil properties
-class CLIP_PT_grease_pencil(AnnotationDataPanel, CLIP_PT_clip_view_panel, Panel):
+class CLIP_PT_annotation(AnnotationDataPanel, CLIP_PT_clip_view_panel, Panel):
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'UI'
bl_category = "Annotation"
@@ -1426,6 +1427,7 @@ class CLIP_MT_select_grouped(Menu):
layout.operator_enum("clip.select_grouped", "group")
+
class CLIP_MT_mask_handle_type_menu(Menu):
bl_label = "Set Handle Type"
@@ -1434,6 +1436,7 @@ class CLIP_MT_mask_handle_type_menu(Menu):
layout.operator_enum("mask.handle_type_set", "type")
+
class CLIP_MT_tracking_context_menu(Menu):
bl_label = "Context Menu"
@@ -1512,6 +1515,7 @@ class CLIP_MT_tracking_context_menu(Menu):
layout.operator("mask.delete")
+
class CLIP_PT_camera_presets(PresetPanel, Panel):
"""Predefined tracking camera intrinsics"""
bl_label = "Camera Presets"
@@ -1758,7 +1762,7 @@ classes = (
CLIP_PT_tools_mask_transforms,
CLIP_PT_tools_mask_tools,
CLIP_PT_tools_scenesetup,
- CLIP_PT_grease_pencil,
+ CLIP_PT_annotation,
CLIP_PT_tools_grease_pencil_draw,
CLIP_MT_view,
CLIP_MT_clip,
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 8f6e9d71790..bd003063e16 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -1684,7 +1684,7 @@ class IMAGE_PT_uv_cursor(Panel):
# Grease Pencil properties
-class IMAGE_PT_grease_pencil(AnnotationDataPanel, Panel):
+class IMAGE_PT_annotation(AnnotationDataPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
bl_category = "View"
@@ -1750,7 +1750,7 @@ classes = (
IMAGE_PT_sample_line,
IMAGE_PT_scope_sample,
IMAGE_PT_uv_cursor,
- IMAGE_PT_grease_pencil,
+ IMAGE_PT_annotation,
)
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index c65893ae280..939102bc11b 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -25,7 +25,6 @@ from bpy.app.translations import contexts as i18n_contexts
from bl_ui.utils import PresetPanel
from bl_ui.properties_grease_pencil_common import (
AnnotationDataPanel,
- GreasePencilToolsPanel,
)
from bl_ui.space_toolsystem_common import (
ToolActivePanelHelper,
@@ -173,9 +172,9 @@ class NODE_HT_header(Header):
# Backdrop
if is_compositor:
- row=layout.row(align=True)
+ row = layout.row(align=True)
row.prop(snode, "show_backdrop", toggle=True)
- sub=row.row(align=True)
+ sub = row.row(align=True)
sub.active = snode.show_backdrop
sub.prop(snode, "backdrop_channels", icon_only=True, text="", expand=True)
@@ -656,7 +655,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
# Grease Pencil properties
-class NODE_PT_grease_pencil(AnnotationDataPanel, Panel):
+class NODE_PT_annotation(AnnotationDataPanel, Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_category = "View"
@@ -670,17 +669,6 @@ class NODE_PT_grease_pencil(AnnotationDataPanel, Panel):
return snode is not None and snode.node_tree is not None
-class NODE_PT_grease_pencil_tools(GreasePencilToolsPanel, Panel):
- bl_space_type = 'NODE_EDITOR'
- bl_region_type = 'UI'
- bl_category = "View"
- bl_options = {'DEFAULT_CLOSED'}
-
- # NOTE: this is just a wrapper around the generic GP tools panel
- # It contains access to some essential tools usually found only in
- # toolbar, but which may not necessarily be open
-
-
def node_draw_tree_view(_layout, _context):
pass
@@ -717,8 +705,7 @@ classes = (
NODE_PT_active_tool,
NODE_PT_backdrop,
NODE_PT_quality,
- NODE_PT_grease_pencil,
- NODE_PT_grease_pencil_tools,
+ NODE_PT_annotation,
NODE_UL_interface_sockets,
node_panel(EEVEE_MATERIAL_PT_settings),
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index ff0220c2e2c..d5ef24d7ff3 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -29,7 +29,6 @@ from bpy.app.translations import (
)
from bl_ui.properties_grease_pencil_common import (
AnnotationDataPanel,
- GreasePencilToolsPanel,
)
from rna_prop_ui import PropertyPanel
@@ -1348,7 +1347,6 @@ class SEQUENCER_PT_time(SequencerButtonsPanel, Panel):
frame_offset_start = strip.frame_offset_start
frame_offset_end = strip.frame_offset_end
-
length_list = (
str(frame_start),
str(frame_final_end),
@@ -1993,23 +1991,22 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
col.prop(mod, "gamma")
-class SEQUENCER_PT_grease_pencil(AnnotationDataPanel, SequencerButtonsPanel_Output, Panel):
+class SEQUENCER_PT_annotation(AnnotationDataPanel, SequencerButtonsPanel_Output, Panel):
bl_space_type = 'SEQUENCE_EDITOR'
bl_region_type = 'UI'
bl_category = "View"
- # NOTE: this is just a wrapper around the generic GP Panel
- # But, it should only show up when there are images in the preview region
-
+ @staticmethod
+ def has_preview(context):
+ st = context.space_data
+ return st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
-class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
- bl_category = "View"
+ @classmethod
+ def poll(cls, context):
+ return cls.has_preview(context)
- # NOTE: this is just a wrapper around the generic GP tools panel
- # It contains access to some essential tools usually found only in
- # toolbar, which doesn't exist here...
+ # NOTE: this is just a wrapper around the generic GP Panel
+ # But, it should only show up when there are images in the preview region
class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel):
@@ -2079,8 +2076,7 @@ classes = (
SEQUENCER_PT_view_safe_areas,
SEQUENCER_PT_view_safe_areas_center_cut,
- SEQUENCER_PT_grease_pencil,
- SEQUENCER_PT_grease_pencil_tools,
+ SEQUENCER_PT_annotation,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index e7e95c26b55..222185e18d5 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -195,11 +195,8 @@ class ToolSelectPanelHelper:
assert(type(icon_name) is str)
icon_value = _icon_cache.get(icon_name)
if icon_value is None:
- dirname = bpy.utils.resource_path('LOCAL')
- if not os.path.exists(dirname):
- # TODO(campbell): use a better way of finding datafiles.
- dirname = bpy.utils.resource_path('SYSTEM')
- filename = os.path.join(dirname, "datafiles", "icons", icon_name + ".dat")
+ dirname = bpy.utils.system_resource('DATAFILES', "icons")
+ filename = os.path.join(dirname, icon_name + ".dat")
try:
icon_value = bpy.app.icons.new_triangles_from_file(filename)
except Exception as ex:
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 02d9f797581..6a18766fae2 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -1700,6 +1700,7 @@ class USERPREF_PT_addons(Panel):
def draw(self, context):
import os
import addon_utils
+ from bl_ui_utils.bug_report_url import url_prefill_from_blender
layout = self.layout
@@ -1879,7 +1880,7 @@ class USERPREF_PT_addons(Panel):
"wm.url_open", text="Report a Bug", icon='URL',
).url = info.get(
"tracker_url",
- "https://developer.blender.org/maniphest/task/edit/form/2",
+ url_prefill_from_blender(info),
)
if user_addon:
sub.operator(
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index a94635c86f3..40e4f97a395 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2746,7 +2746,7 @@ class VIEW3D_MT_hook(Menu):
layout.operator("object.hook_add_selob").use_bone = False
layout.operator("object.hook_add_selob", text="Hook to Selected Object Bone").use_bone = True
- if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
+ if any([mod.type == 'HOOK' for mod in context.active_object.modifiers]):
layout.separator()
layout.operator_menu_enum("object.hook_assign", "modifier")
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc
index 20ca659d32f..63887d36381 100644
--- a/source/blender/alembic/intern/abc_customdata.cc
+++ b/source/blender/alembic/intern/abc_customdata.cc
@@ -353,7 +353,7 @@ static void read_custom_data_mcols(const std::string &iobject_full_name,
/* Read the vertex colors */
void *cd_data = config.add_customdata_cb(
- config.user_data, prop_header.getName().c_str(), CD_MLOOPCOL);
+ config.mesh, prop_header.getName().c_str(), CD_MLOOPCOL);
MCol *cfaces = static_cast<MCol *>(cd_data);
MPoly *mpolys = config.mpoly;
MLoop *mloops = config.mloop;
@@ -437,8 +437,7 @@ static void read_custom_data_uvs(const ICompoundProperty &prop,
return;
}
- void *cd_data = config.add_customdata_cb(
- config.user_data, prop_header.getName().c_str(), CD_MLOOPUV);
+ void *cd_data = config.add_customdata_cb(config.mesh, prop_header.getName().c_str(), CD_MLOOPUV);
read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
}
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index c36029d5116..0ffafa8848e 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -28,6 +28,7 @@
#include <Alembic/AbcGeom/All.h>
struct CustomData;
+struct Mesh;
struct MLoop;
struct MLoopUV;
struct MPoly;
@@ -60,8 +61,8 @@ struct CDStreamConfig {
/* TODO(kevin): might need a better way to handle adding and/or updating
* custom datas such that it updates the custom data holder and its pointers
* properly. */
- void *user_data;
- void *(*add_customdata_cb)(void *user_data, const char *name, int data_type);
+ Mesh *mesh;
+ void *(*add_customdata_cb)(Mesh *mesh, const char *name, int data_type);
float weight;
float time;
@@ -75,7 +76,7 @@ struct CDStreamConfig {
totpoly(0),
totvert(0),
pack_uvs(false),
- user_data(NULL),
+ mesh(NULL),
add_customdata_cb(NULL),
weight(0.0f),
time(0.0f),
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index b0129a358ec..9e6f2dd6b52 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -46,6 +46,8 @@ extern "C" {
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "MEM_guardedalloc.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -122,7 +124,7 @@ static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
static void get_topology(struct Mesh *mesh,
std::vector<int32_t> &poly_verts,
std::vector<int32_t> &loop_counts,
- bool &smooth_normal)
+ bool &r_export_loop_normals)
{
const int num_poly = mesh->totpoly;
const int num_loops = mesh->totloop;
@@ -139,7 +141,7 @@ static void get_topology(struct Mesh *mesh,
MPoly &poly = mpoly[i];
loop_counts.push_back(poly.totloop);
- smooth_normal |= ((poly.flag & ME_SMOOTH) != 0);
+ r_export_loop_normals |= (poly.flag & ME_SMOOTH) != 0;
MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
@@ -203,17 +205,14 @@ static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals
normals.clear();
normals.resize(mesh->totloop);
- unsigned loop_index = 0;
-
/* NOTE: data needs to be written in the reverse order. */
+ int abc_index = 0;
if (lnors) {
for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
- ml = mloop + mp->loopstart + (mp->totloop - 1);
-
- for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
- const int index = ml->v;
- copy_yup_from_zup(normals[loop_index].getValue(), lnors[index]);
+ for (int j = mp->totloop - 1; j >= 0; --j, ++abc_index) {
+ int blender_index = mp->loopstart + j;
+ copy_yup_from_zup(normals[abc_index].getValue(), lnors[blender_index]);
}
}
}
@@ -227,15 +226,15 @@ static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals
if ((mp->flag & ME_SMOOTH) == 0) {
BKE_mesh_calc_poly_normal(mp, ml - (mp->totloop - 1), verts, no);
- for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
- copy_yup_from_zup(normals[loop_index].getValue(), no);
+ for (int j = 0; j < mp->totloop; --ml, ++j, ++abc_index) {
+ copy_yup_from_zup(normals[abc_index].getValue(), no);
}
}
else {
/* Smooth shaded, use individual vert normals. */
- for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+ for (int j = 0; j < mp->totloop; --ml, ++j, ++abc_index) {
normal_short_to_float_v3(no, verts[ml->v].no);
- copy_yup_from_zup(normals[loop_index].getValue(), no);
+ copy_yup_from_zup(normals[abc_index].getValue(), no);
}
}
}
@@ -411,10 +410,10 @@ void AbcGenericMeshWriter::writeMesh(struct Mesh *mesh)
std::vector<int32_t> poly_verts, loop_counts;
std::vector<Imath::V3f> velocities;
- bool smooth_normal = false;
+ bool export_loop_normals = (mesh->flag & ME_AUTOSMOOTH) != 0;
get_vertices(mesh, points);
- get_topology(mesh, poly_verts, loop_counts, smooth_normal);
+ get_topology(mesh, poly_verts, loop_counts, export_loop_normals);
if (m_first_frame && m_settings.export_face_sets) {
writeFaceSets(mesh, m_mesh_schema);
@@ -442,7 +441,7 @@ void AbcGenericMeshWriter::writeMesh(struct Mesh *mesh)
}
if (m_settings.export_normals) {
- if (smooth_normal) {
+ if (export_loop_normals) {
get_loop_normals(mesh, normals);
}
else {
@@ -451,7 +450,7 @@ void AbcGenericMeshWriter::writeMesh(struct Mesh *mesh)
ON3fGeomParam::Sample normals_sample;
if (!normals.empty()) {
- normals_sample.setScope((smooth_normal) ? kFacevaryingScope : kVertexScope);
+ normals_sample.setScope(export_loop_normals ? kFacevaryingScope : kVertexScope);
normals_sample.setVals(V3fArraySample(normals));
}
@@ -477,10 +476,10 @@ void AbcGenericMeshWriter::writeSubD(struct Mesh *mesh)
std::vector<int32_t> poly_verts, loop_counts;
std::vector<int32_t> crease_indices, crease_lengths;
- bool smooth_normal = false;
+ bool export_loop_normals = false;
get_vertices(mesh, points);
- get_topology(mesh, poly_verts, loop_counts, smooth_normal);
+ get_topology(mesh, poly_verts, loop_counts, export_loop_normals);
get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
if (m_first_frame && m_settings.export_face_sets) {
@@ -758,7 +757,8 @@ struct AbcMeshData {
P3fArraySamplePtr ceil_positions;
N3fArraySamplePtr vertex_normals;
- N3fArraySamplePtr face_normals;
+ N3fArraySamplePtr loop_normals;
+ bool poly_flag_smooth;
V2fArraySamplePtr uvs;
UInt32ArraySamplePtr uvs_indices;
@@ -832,7 +832,6 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
const size_t uvs_size = uvs == nullptr ? 0 : uvs->size();
const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
- const N3fArraySamplePtr &normals = mesh_data.face_normals;
const bool do_uvs = (mloopuvs && uvs && uvs_indices) &&
(uvs_indices->size() == face_indices->size());
@@ -847,9 +846,12 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
poly.loopstart = loop_index;
poly.totloop = face_size;
- if (normals != NULL) {
+ if (mesh_data.poly_flag_smooth) {
poly.flag |= ME_SMOOTH;
}
+ else {
+ poly.flag &= ~ME_SMOOTH;
+ }
/* NOTE: Alembic data is stored in the reverse order. */
rev_loop_index = loop_index + (face_size - 1);
@@ -873,6 +875,40 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
}
}
}
+
+ BKE_mesh_calc_edges(config.mesh, false, false);
+}
+
+static void process_normals(CDStreamConfig &config, const AbcMeshData &mesh_data)
+{
+ Mesh *mesh = config.mesh;
+
+ if (!mesh_data.loop_normals) {
+ BKE_mesh_calc_normals(config.mesh);
+ config.mesh->flag &= ~ME_AUTOSMOOTH;
+ return;
+ }
+
+ config.mesh->flag |= ME_AUTOSMOOTH;
+
+ const Alembic::AbcGeom::N3fArraySample &loop_normals = *mesh_data.loop_normals;
+ long int loop_count = loop_normals.size();
+
+ float(*lnors)[3] = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(loop_count, sizeof(float[3]), "ABC::FaceNormals"));
+
+ MPoly *mpoly = mesh->mpoly;
+ int abc_index = 0;
+ for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) {
+ /* As usual, ABC orders the loops in reverse. */
+ for (int j = mpoly->totloop - 1; j >= 0; --j, ++abc_index) {
+ int blender_index = mpoly->loopstart + j;
+ copy_zup_from_yup(lnors[blender_index], loop_normals[abc_index].getValue());
+ }
+ }
+ BKE_mesh_set_custom_normals(config.mesh, lnors);
+
+ MEM_freeN(lnors);
}
ABC_INLINE void read_uvs_params(CDStreamConfig &config,
@@ -900,15 +936,11 @@ ABC_INLINE void read_uvs_params(CDStreamConfig &config,
name = uv.getName();
}
- void *cd_ptr = config.add_customdata_cb(config.user_data, name.c_str(), CD_MLOOPUV);
+ void *cd_ptr = config.add_customdata_cb(config.mesh, name.c_str(), CD_MLOOPUV);
config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
}
}
-/* TODO(kevin): normals from Alembic files are not read in anymore, this is due
- * to the fact that there are many issues that are not so easy to solve, mainly
- * regarding the way normals are handled in Blender (MPoly.flag vs loop normals).
- */
ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
const IN3fGeomParam &normals,
const ISampleSelector &selector)
@@ -919,42 +951,26 @@ ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
IN3fGeomParam::Sample normsamp = normals.getExpandedValue(selector);
- if (normals.getScope() == kFacevaryingScope) {
- abc_data.face_normals = normsamp.getVals();
- }
- else if ((normals.getScope() == kVertexScope) || (normals.getScope() == kVaryingScope)) {
- abc_data.vertex_normals = N3fArraySamplePtr();
- }
-}
-
-static bool check_smooth_poly_flag(Mesh *mesh)
-{
- MPoly *mpolys = mesh->mpoly;
-
- for (int i = 0, e = mesh->totpoly; i < e; ++i) {
- MPoly &poly = mpolys[i];
-
- if ((poly.flag & ME_SMOOTH) != 0) {
- return true;
- }
- }
-
- return false;
-}
-
-static void set_smooth_poly_flag(Mesh *mesh)
-{
- MPoly *mpolys = mesh->mpoly;
-
- for (int i = 0, e = mesh->totpoly; i < e; ++i) {
- MPoly &poly = mpolys[i];
- poly.flag |= ME_SMOOTH;
+ Alembic::AbcGeom::GeometryScope scope = normals.getScope();
+ switch (scope) {
+ case Alembic::AbcGeom::kFacevaryingScope:
+ abc_data.loop_normals = normsamp.getVals();
+ break;
+ case Alembic::AbcGeom::kVertexScope:
+ case Alembic::AbcGeom::kVaryingScope:
+ /* Vertex normals from ABC aren't handled for now. */
+ abc_data.poly_flag_smooth = true;
+ abc_data.vertex_normals = N3fArraySamplePtr();
+ break;
+ case Alembic::AbcGeom::kConstantScope:
+ case Alembic::AbcGeom::kUniformScope:
+ case Alembic::AbcGeom::kUnknownScope:
+ break;
}
}
-static void *add_customdata_cb(void *user_data, const char *name, int data_type)
+static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type)
{
- Mesh *mesh = static_cast<Mesh *>(user_data);
CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
void *cd_ptr;
CustomData *loopdata;
@@ -994,8 +1010,7 @@ static void read_mesh_sample(const std::string &iobject_full_name,
ImportSettings *settings,
const IPolyMeshSchema &schema,
const ISampleSelector &selector,
- CDStreamConfig &config,
- bool &do_normals)
+ CDStreamConfig &config)
{
const IPolyMeshSchema::Sample sample = schema.getValue(selector);
@@ -1003,11 +1018,10 @@ static void read_mesh_sample(const std::string &iobject_full_name,
abc_mesh_data.face_counts = sample.getFaceCounts();
abc_mesh_data.face_indices = sample.getFaceIndices();
abc_mesh_data.positions = sample.getPositions();
+ abc_mesh_data.poly_flag_smooth = false;
read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
- do_normals = (abc_mesh_data.face_normals != NULL);
-
get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
if (config.weight != 0.0f) {
@@ -1026,6 +1040,7 @@ static void read_mesh_sample(const std::string &iobject_full_name,
if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
read_mpolys(config, abc_mesh_data);
+ process_normals(config, abc_mesh_data);
}
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
@@ -1039,7 +1054,7 @@ CDStreamConfig get_config(Mesh *mesh)
BLI_assert(mesh->mvert || mesh->totvert == 0);
- config.user_data = mesh;
+ config.mesh = mesh;
config.mvert = mesh->mvert;
config.mloop = mesh->mloop;
config.mpoly = mesh->mpoly;
@@ -1079,13 +1094,16 @@ void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
if (read_mesh != mesh) {
BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
+
+ /* XXX fixme after 2.80; mesh->flag isn't copied by BKE_mesh_nomain_to_mesh() */
+ mesh->flag |= (read_mesh->flag & ME_AUTOSMOOTH);
}
if (m_settings->validate_meshes) {
BKE_mesh_validate(mesh, false, false);
}
- readFaceSetsSample(bmain, mesh, 0, sample_sel);
+ readFaceSetsSample(bmain, mesh, sample_sel);
if (has_animations(m_schema, m_settings)) {
addCacheModifier();
@@ -1151,6 +1169,8 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
existing_mesh, positions->size(), 0, 0, face_indices->size(), face_counts->size());
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
+ /* XXX fixme after 2.80; mesh->flag isn't copied by BKE_mesh_new_nomain_from_template() */
+ new_mesh->flag |= (existing_mesh->flag & ME_AUTOSMOOTH);
}
else {
/* If the face count changed (e.g. by triangulation), only read points.
@@ -1171,39 +1191,25 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
config.time = sample_sel.getRequestedTime();
- bool do_normals = false;
- read_mesh_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config, do_normals);
+ read_mesh_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config);
if (new_mesh) {
- /* Check if we had ME_SMOOTH flag set to restore it. */
- if (!do_normals && check_smooth_poly_flag(existing_mesh)) {
- set_smooth_poly_flag(new_mesh);
- }
-
- BKE_mesh_calc_normals(new_mesh);
- BKE_mesh_calc_edges(new_mesh, false, false);
-
/* Here we assume that the number of materials doesn't change, i.e. that
* the material slots that were created when the object was loaded from
* Alembic are still valid now. */
size_t num_polys = new_mesh->totpoly;
if (num_polys > 0) {
std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, 0, new_mesh->mpoly, num_polys, mat_map);
+ assign_facesets_to_mpoly(sample_sel, new_mesh->mpoly, num_polys, mat_map);
}
return new_mesh;
}
- if (do_normals) {
- BKE_mesh_calc_normals(existing_mesh);
- }
-
return existing_mesh;
}
void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
- size_t poly_start,
MPoly *mpoly,
int totpoly,
std::map<std::string, int> &r_mat_map)
@@ -1239,7 +1245,7 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
const size_t num_group_faces = group_faces->size();
for (size_t l = 0; l < num_group_faces; l++) {
- size_t pos = (*group_faces)[l] + poly_start;
+ size_t pos = (*group_faces)[l];
if (pos >= totpoly) {
std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
@@ -1252,13 +1258,10 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
}
}
-void AbcMeshReader::readFaceSetsSample(Main *bmain,
- Mesh *mesh,
- size_t poly_start,
- const ISampleSelector &sample_sel)
+void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const ISampleSelector &sample_sel)
{
std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, poly_start, mesh->mpoly, mesh->totpoly, mat_map);
+ assign_facesets_to_mpoly(sample_sel, mesh->mpoly, mesh->totpoly, mat_map);
utils::assign_materials(bmain, m_object, mat_map);
}
@@ -1289,7 +1292,7 @@ static void read_subd_sample(const std::string &iobject_full_name,
abc_mesh_data.face_counts = sample.getFaceCounts();
abc_mesh_data.face_indices = sample.getFaceIndices();
abc_mesh_data.vertex_normals = N3fArraySamplePtr();
- abc_mesh_data.face_normals = N3fArraySamplePtr();
+ abc_mesh_data.loop_normals = N3fArraySamplePtr();
abc_mesh_data.positions = sample.getPositions();
get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
@@ -1309,7 +1312,14 @@ static void read_subd_sample(const std::string &iobject_full_name,
}
if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
+ /* Alembic's 'SubD' scheme is used to store subdivision surfaces, i.e. the pre-subdivision
+ * mesh. Currently we don't add a subdivison modifier when we load such data. This code is
+ * assuming that the subdivided surface should be smooth, and sets a flag that will eventually
+ * mark all polygons as such. */
+ abc_mesh_data.poly_flag_smooth = true;
+
read_mpolys(config, abc_mesh_data);
+ process_normals(config, abc_mesh_data);
}
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
@@ -1397,9 +1407,6 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
}
- BKE_mesh_calc_normals(mesh);
- BKE_mesh_calc_edges(mesh, false, false);
-
if (m_settings->validate_meshes) {
BKE_mesh_validate(mesh, false, false);
}
@@ -1466,17 +1473,5 @@ Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
config.time = sample_sel.getRequestedTime();
read_subd_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config);
- if (new_mesh) {
- /* Check if we had ME_SMOOTH flag set to restore it. */
- if (check_smooth_poly_flag(existing_mesh)) {
- set_smooth_poly_flag(new_mesh);
- }
-
- BKE_mesh_calc_normals(new_mesh);
- BKE_mesh_calc_edges(new_mesh, false, false);
-
- return new_mesh;
- }
-
- return existing_mesh;
+ return config.mesh;
}
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 6cbaeea6536..859ab121eb6 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -114,11 +114,9 @@ class AbcMeshReader : public AbcObjectReader {
private:
void readFaceSetsSample(Main *bmain,
Mesh *mesh,
- size_t poly_start,
const Alembic::AbcGeom::ISampleSelector &sample_sel);
void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel,
- size_t poly_start,
MPoly *mpoly,
int totpoly,
std::map<std::string, int> &r_mat_map);
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 54450ce1cb2..7b0d94a2305 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -343,8 +343,7 @@ void AbcObjectReader::read_matrix(float r_mat[4][4],
/* Only apply scaling to root objects, parenting will propagate it. */
float scale_mat[4][4];
scale_m4_fl(scale_mat, scale);
- scale_mat[3][3] = scale; /* scale translations too */
- mul_m4_m4m4(r_mat, r_mat, scale_mat);
+ mul_m4_m4m4(r_mat, scale_mat, r_mat);
}
is_constant = schema.isConstant();
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 448bb0d621a..bf0aa96df84 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -223,6 +223,7 @@ void BLF_dir_free(char **dirs, int count) ATTR_NONNULL();
/* blf_thumbs.c */
void BLF_thumb_preview(const char *filename,
const char **draw_str,
+ const char **i18n_draw_str,
const unsigned char draw_str_lines,
const float font_color[4],
const int font_size,
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 049af7678d5..66be94aaa06 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -96,7 +96,7 @@ KerningCacheBLF *blf_kerning_cache_new(FontBLF *font)
.x = 0,
.y = 0,
};
- if (g_prev && FT_Get_Kerning(font->face, g_prev->idx, g->idx, kc->mode, &delta) == 0) {
+ if (g && g_prev && FT_Get_Kerning(font->face, g_prev->idx, g->idx, kc->mode, &delta) == 0) {
kc->table[i][j] = (int)delta.x >> 6;
}
else {
diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c
index 802f97fc5f5..d6710b91539 100644
--- a/source/blender/blenfont/intern/blf_thumbs.c
+++ b/source/blender/blenfont/intern/blf_thumbs.c
@@ -50,6 +50,7 @@
*/
void BLF_thumb_preview(const char *filename,
const char **draw_str,
+ const char **i18n_draw_str,
const unsigned char draw_str_lines,
const float font_color[4],
const int font_size,
@@ -90,7 +91,7 @@ void BLF_thumb_preview(const char *filename,
blf_draw_buffer__start(font);
for (i = 0; i < draw_str_lines; i++) {
- const char *draw_str_i18n = BLT_translate_do(BLT_I18NCONTEXT_DEFAULT, draw_str[i]);
+ const char *draw_str_i18n = i18n_draw_str[i] != NULL ? i18n_draw_str[i] : draw_str[i];
const size_t draw_str_i18n_len = strlen(draw_str_i18n);
int draw_str_i18n_nbr = 0;
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 73e62f6a7b3..99c6bb405b5 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -75,6 +75,9 @@ void BKE_armature_copy_data(struct Main *bmain,
const int flag);
struct bArmature *BKE_armature_copy(struct Main *bmain, const struct bArmature *arm);
+void BKE_armature_copy_bone_transforms(struct bArmature *armature_dst,
+ const struct bArmature *armature_src);
+
/* Bounding box. */
struct BoundBox *BKE_armature_boundbox_get(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index a400e4411cf..062e185eb23 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -26,8 +26,8 @@
*
* \note Use #STRINGIFY() rather than defining with quotes.
*/
-#define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 75
+#define BLENDER_VERSION 281
+#define BLENDER_SUBVERSION 0
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
@@ -36,7 +36,7 @@
/** Can be left blank, otherwise a,b,c... etc with no quotes. */
#define BLENDER_VERSION_CHAR
/** alpha/beta/rc/release, docs use this. */
-#define BLENDER_VERSION_CYCLE beta
+#define BLENDER_VERSION_CYCLE alpha
/** Defined in from blender.c */
extern char versionstr[];
diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h
index 76c05b0411a..7fc27321fc7 100644
--- a/source/blender/blenkernel/BKE_blendfile.h
+++ b/source/blender/blenkernel/BKE_blendfile.h
@@ -32,12 +32,6 @@ struct ReportList;
struct UserDef;
struct bContext;
-enum {
- BKE_BLENDFILE_READ_FAIL = 0, /* no load */
- BKE_BLENDFILE_READ_OK = 1, /* OK */
- BKE_BLENDFILE_READ_OK_USERPREFS = 2, /* OK, and with new user settings */
-};
-
int BKE_blendfile_read(struct bContext *C,
const char *filepath,
const struct BlendFileReadParams *params,
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 54fbda1fa31..d6b4fa72281 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -123,6 +123,8 @@ struct Mesh *BKE_mesh_new_nomain_from_template(const struct Mesh *me_src,
int loops_len,
int polys_len);
+void BKE_mesh_eval_delete(struct Mesh *me_eval);
+
/* Performs copy for use during evaluation,
* optional referencing original arrays to reduce memory. */
struct Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 9425f396bc5..14d7784f93e 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -118,7 +118,9 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip,
/* Dependency graph evaluation. */
-void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, struct MovieClip *clip);
+void BKE_movieclip_eval_update(struct Depsgraph *depsgraph,
+ struct Main *bmain,
+ struct MovieClip *clip);
void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, struct MovieClip *clip);
/* caching flags */
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 6b6eb24d5fa..bf417403d43 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -355,6 +355,12 @@ void BKE_tracking_reconstruction_solve(struct MovieReconstructContext *context,
bool BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context,
struct MovieTracking *tracking);
+void BKE_tracking_reconstruction_report_error_message(struct MovieReconstructContext *context,
+ const char *error_message);
+
+const char *BKE_tracking_reconstruction_error_message_get(
+ const struct MovieReconstructContext *context);
+
void BKE_tracking_reconstruction_scale(struct MovieTracking *tracking, float scale[3]);
/* **** Feature detection **** */
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index 50c29c456d1..6d8e04336ac 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -48,6 +48,7 @@ UNDO_REF_ID_TYPE(Mesh);
UNDO_REF_ID_TYPE(Object);
UNDO_REF_ID_TYPE(Scene);
UNDO_REF_ID_TYPE(Text);
+UNDO_REF_ID_TYPE(Image);
typedef struct UndoStack {
ListBase steps;
@@ -194,24 +195,6 @@ void BKE_undosys_foreach_ID_ref(UndoStack *ustack,
void *user_data);
#endif
-/* Use when the undo step stores many arbitrary pointers. */
-struct UndoIDPtrMap;
-struct UndoIDPtrMap *BKE_undosys_ID_map_create(void);
-void BKE_undosys_ID_map_destroy(struct UndoIDPtrMap *map);
-void BKE_undosys_ID_map_add(struct UndoIDPtrMap *map, ID *id);
-struct ID *BKE_undosys_ID_map_lookup(const struct UndoIDPtrMap *map, const struct ID *id_src);
-
-void BKE_undosys_ID_map_add_with_prev(struct UndoIDPtrMap *map,
- struct ID *id,
- struct ID **id_prev);
-struct ID *BKE_undosys_ID_map_lookup_with_prev(const struct UndoIDPtrMap *map,
- struct ID *id_src,
- struct ID *id_prev_match[2]);
-
-void BKE_undosys_ID_map_foreach_ID_ref(struct UndoIDPtrMap *map,
- UndoTypeForEachIDRefFn foreach_ID_ref_fn,
- void *user_data);
-
void BKE_undosys_print(UndoStack *ustack);
#endif /* __BKE_UNDO_SYSTEM_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
index 720c828664a..d8b30c9d4ef 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
@@ -135,7 +135,7 @@ typedef struct CCGSubSurfCalcSubdivData {
} CCGSubSurfCalcSubdivData;
static void ccgSubSurf__calcVertNormals_faces_accumulate_cb(
- void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGSubSurfCalcSubdivData *data = userdata;
@@ -234,7 +234,7 @@ static void ccgSubSurf__calcVertNormals_faces_accumulate_cb(
}
static void ccgSubSurf__calcVertNormals_faces_finalize_cb(
- void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGSubSurfCalcSubdivData *data = userdata;
@@ -273,7 +273,7 @@ static void ccgSubSurf__calcVertNormals_faces_finalize_cb(
}
static void ccgSubSurf__calcVertNormals_edges_accumulate_cb(
- void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGSubSurfCalcSubdivData *data = userdata;
@@ -347,7 +347,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
};
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
BLI_task_parallel_range(
@@ -379,7 +379,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
}
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
BLI_task_parallel_range(
@@ -387,7 +387,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
}
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
BLI_task_parallel_range(
@@ -425,7 +425,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
}
static void ccgSubSurf__calcSubdivLevel_interior_faces_edges_midpoints_cb(
- void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGSubSurfCalcSubdivData *data = userdata;
@@ -513,7 +513,7 @@ static void ccgSubSurf__calcSubdivLevel_interior_faces_edges_midpoints_cb(
}
static void ccgSubSurf__calcSubdivLevel_interior_faces_edges_centerpoints_shift_cb(
- void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGSubSurfCalcSubdivData *data = userdata;
@@ -619,7 +619,7 @@ static void ccgSubSurf__calcSubdivLevel_interior_faces_edges_centerpoints_shift_
}
static void ccgSubSurf__calcSubdivLevel_verts_copydata_cb(
- void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGSubSurfCalcSubdivData *data = userdata;
@@ -691,7 +691,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
};
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
BLI_task_parallel_range(0,
@@ -991,7 +991,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
}
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
BLI_task_parallel_range(0,
@@ -1012,7 +1012,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
}
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
BLI_task_parallel_range(
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index c36acd1eae1..742e3634bf1 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -239,6 +239,35 @@ bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
return arm_copy;
}
+static void copy_bone_transform(Bone *bone_dst, const Bone *bone_src)
+{
+ bone_dst->roll = bone_src->roll;
+
+ copy_v3_v3(bone_dst->head, bone_src->head);
+ copy_v3_v3(bone_dst->tail, bone_src->tail);
+
+ copy_m3_m3(bone_dst->bone_mat, bone_src->bone_mat);
+
+ copy_v3_v3(bone_dst->arm_head, bone_src->arm_head);
+ copy_v3_v3(bone_dst->arm_tail, bone_src->arm_tail);
+
+ copy_m4_m4(bone_dst->arm_mat, bone_src->arm_mat);
+
+ bone_dst->arm_roll = bone_src->arm_roll;
+}
+
+void BKE_armature_copy_bone_transforms(bArmature *armature_dst, const bArmature *armature_src)
+{
+ Bone *bone_dst = armature_dst->bonebase.first;
+ const Bone *bone_src = armature_src->bonebase.first;
+ while (bone_dst != NULL) {
+ BLI_assert(bone_src != NULL);
+ copy_bone_transform(bone_dst, bone_src);
+ bone_dst = bone_dst->next;
+ bone_src = bone_src->next;
+ }
+}
+
static Bone *get_named_bone_bonechildren(ListBase *lb, const char *name)
{
Bone *curBone, *rbone;
@@ -1350,7 +1379,7 @@ typedef struct ArmatureUserdata {
static void armature_vert_task(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const ArmatureUserdata *data = userdata;
float(*const vertexCos)[3] = data->vertexCos;
@@ -1648,7 +1677,7 @@ void armature_deform_verts(Object *armOb,
mul_m4_m4m4(data.postmat, obinv, armOb->obmat);
invert_m4_m4(data.premat, data.postmat);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 32;
BLI_task_parallel_range(0, numVerts, &data, armature_vert_task, &settings);
@@ -2374,6 +2403,9 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchanw.mpath = pchan->mpath;
pchan->mpath = NULL;
+ /* Reset runtime data, we don't want to share that with the proxy. */
+ BKE_pose_channel_runtime_reset(&pchanw.runtime);
+
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 9fd3c24092c..805c098d238 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -306,6 +306,7 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
LIST_SWAP(themes);
LIST_SWAP(addons);
LIST_SWAP(user_keymaps);
+ LIST_SWAP(user_keyconfig_prefs);
DATA_SWAP(font_path_ui);
DATA_SWAP(font_path_ui_mono);
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index 6c077ac75ba..7c12747283c 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -73,7 +73,7 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu, bContext *C)
G.fileflags |= G_FILE_NO_UI;
if (UNDO_DISK) {
- success = (BKE_blendfile_read(C, mfu->filename, NULL, 0) != BKE_BLENDFILE_READ_FAIL);
+ success = BKE_blendfile_read(C, mfu->filename, NULL, 0);
}
else {
success = BKE_blendfile_read_from_memfile(
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index afbd2627a2a..e31494ecb4e 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -405,35 +405,31 @@ int BKE_blendfile_read(bContext *C,
ReportList *reports)
{
BlendFileData *bfd;
- int retval = BKE_BLENDFILE_READ_OK;
+ bool success = false;
- /* don't print user-pref loading */
- if (strstr(filepath, BLENDER_STARTUP_FILE) == NULL) {
+ /* Don't print startup file loading. */
+ if (params->is_startup == false) {
printf("Read blend: %s\n", filepath);
}
bfd = BLO_read_from_file(filepath, params->skip_flags, reports);
if (bfd) {
- if (bfd->user) {
- retval = BKE_BLENDFILE_READ_OK_USERPREFS;
- }
-
if (0 == handle_subversion_warning(bfd->main, reports)) {
BKE_main_free(bfd->main);
MEM_freeN(bfd);
bfd = NULL;
- retval = BKE_BLENDFILE_READ_FAIL;
}
else {
setup_app_blend_file_data(C, bfd, filepath, params, reports);
BLO_blendfiledata_free(bfd);
+ success = true;
}
}
else {
BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath);
}
- return (bfd ? retval : BKE_BLENDFILE_READ_FAIL);
+ return success;
}
bool BKE_blendfile_read_from_memory(bContext *C,
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 965f6e4bc51..25f2797915a 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1100,7 +1100,7 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
static void collection_parents_rebuild_recursive(Collection *collection)
{
BKE_collection_parent_relations_rebuild(collection);
- collection->id.tag &= ~LIB_TAG_DOIT;
+ collection->tag &= ~COLLECTION_TAG_RELATION_REBUILD;
for (CollectionChild *child = collection->children.first; child != NULL; child = child->next) {
collection_parents_rebuild_recursive(child->collection);
@@ -1109,8 +1109,6 @@ static void collection_parents_rebuild_recursive(Collection *collection)
/**
* Rebuild parent relationships from child ones, for all collections in given \a bmain.
- *
- * \note Uses LIB_TAG_DOIT internally...
*/
void BKE_main_collections_parent_relations_rebuild(Main *bmain)
{
@@ -1119,7 +1117,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
collection = collection->id.next) {
BLI_freelistN(&collection->parents);
- collection->id.tag |= LIB_TAG_DOIT;
+ collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
}
/* Scene's master collections will be 'root' parent of most of our collections, so start with
@@ -1132,7 +1130,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
* lib_link_collection_data() seems to assume that, so do the same here. */
for (Collection *collection = bmain->collections.first; collection != NULL;
collection = collection->id.next) {
- if (collection->id.tag & LIB_TAG_DOIT) {
+ if (collection->tag & COLLECTION_TAG_RELATION_REBUILD) {
/* Note: we do not have easy access to 'which collections is root' info in that case, which
* means test for cycles in collection relationships may fail here. I don't think that is an
* issue in practice here, but worth keeping in mind... */
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index ff6258ac339..69afda9997a 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -851,7 +851,7 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
static void cloth_collision(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
ColDetectData *data = (ColDetectData *)userdata;
@@ -908,7 +908,7 @@ static void cloth_collision(void *__restrict userdata,
static void cloth_selfcollision(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SelfColDetectData *data = (SelfColDetectData *)userdata;
@@ -1154,7 +1154,7 @@ static bool cloth_bvh_objcollisions_nearcheck(ClothModifierData *clmd,
.collided = false,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = true;
BLI_task_parallel_range(0, numresult, &data, cloth_collision, &settings);
@@ -1174,7 +1174,7 @@ static bool cloth_bvh_selfcollisions_nearcheck(ClothModifierData *clmd,
.collided = false,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = true;
BLI_task_parallel_range(0, numresult, &data, cloth_selfcollision, &settings);
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 863d6351738..aa5f74c6297 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1385,7 +1385,7 @@ typedef struct ScopesUpdateDataChunk {
static void scopes_update_cb(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
const ScopesUpdateData *data = userdata;
@@ -1634,7 +1634,7 @@ void scopes_update(Scopes *scopes,
ScopesUpdateDataChunk data_chunk = {{0}};
INIT_MINMAX(data_chunk.min, data_chunk.max);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (ibuf->y > 256);
settings.userdata_chunk = &data_chunk;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 7e916feac24..936fe3b3bea 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -645,7 +645,7 @@ static void freeGrid(PaintSurfaceData *data)
static void grid_bound_insert_cb_ex(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
PaintBakeData *bData = userdata;
@@ -667,7 +667,7 @@ static void grid_bound_insert_finalize(void *__restrict userdata, void *__restri
static void grid_cell_points_cb_ex(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
PaintBakeData *bData = userdata;
VolumeGrid *grid = bData->grid;
@@ -702,7 +702,7 @@ static void grid_cell_points_finalize(void *__restrict userdata, void *__restric
static void grid_cell_bounds_cb(void *__restrict userdata,
const int x,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
PaintBakeData *bData = userdata;
VolumeGrid *grid = bData->grid;
@@ -749,7 +749,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
/* Important to init correctly our ref grid_bound... */
boundInsert(&grid->grid_bounds, bData->realCoord[bData->s_pos[0]].v);
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
settings.userdata_chunk = &grid->grid_bounds;
@@ -810,7 +810,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
if (!error) {
/* calculate number of points within each cell */
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
settings.userdata_chunk = grid->s_num;
@@ -834,7 +834,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
/* calculate cell bounds */
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (grid_cells > 1000);
BLI_task_parallel_range(0, grid->dim[0], bData, grid_cell_bounds_cb, &settings);
@@ -1508,7 +1508,7 @@ typedef struct DynamicPaintSetInitColorData {
} DynamicPaintSetInitColorData;
static void dynamic_paint_set_init_color_tex_to_vcol_cb(
- void *__restrict userdata, const int i, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintSetInitColorData *data = userdata;
@@ -1543,7 +1543,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(
}
static void dynamic_paint_set_init_color_tex_to_imseq_cb(
- void *__restrict userdata, const int i, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintSetInitColorData *data = userdata;
@@ -1582,7 +1582,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb(
}
static void dynamic_paint_set_init_color_vcol_to_imseq_cb(
- void *__restrict userdata, const int i, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintSetInitColorData *data = userdata;
@@ -1667,7 +1667,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
.pool = pool,
.scene_color_manage = scene_color_manage,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (tottri > 1000);
BLI_task_parallel_range(
@@ -1681,7 +1681,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
.mloopuv = mloopuv,
.scene_color_manage = scene_color_manage,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -1718,7 +1718,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
.mlooptri = mlooptri,
.mloopcol = col,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -1820,7 +1820,7 @@ typedef struct DynamicPaintModifierApplyData {
static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintModifierApplyData *data = userdata;
@@ -1854,7 +1854,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
.surface = surface,
.mvert = mvert,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 10000);
BLI_task_parallel_range(
@@ -1863,7 +1863,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
}
static void dynamic_paint_apply_surface_vpaint_blend_cb(
- void *__restrict userdata, const int i, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintModifierApplyData *data = userdata;
@@ -1877,7 +1877,7 @@ static void dynamic_paint_apply_surface_vpaint_blend_cb(
static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
const int p_index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintModifierApplyData *data = userdata;
@@ -1913,7 +1913,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintModifierApplyData *data = userdata;
@@ -1966,7 +1966,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
.fcolor = fcolor,
};
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(0,
@@ -2001,7 +2001,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
data.mloopcol_wet = mloopcol_wet;
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (totpoly > 1000);
BLI_task_parallel_range(
@@ -2053,7 +2053,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
.surface = surface,
.mvert = mvert,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -2236,7 +2236,7 @@ typedef struct DynamicPaintCreateUVSurfaceData {
} DynamicPaintCreateUVSurfaceData;
static void dynamic_paint_create_uv_surface_direct_cb(
- void *__restrict userdata, const int ty, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintCreateUVSurfaceData *data = userdata;
@@ -2330,7 +2330,7 @@ static void dynamic_paint_create_uv_surface_direct_cb(
}
static void dynamic_paint_create_uv_surface_neighbor_cb(
- void *__restrict userdata, const int ty, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintCreateUVSurfaceData *data = userdata;
@@ -2948,7 +2948,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
.faceBB = faceBB,
};
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (h > 64 || tottri > 1000);
BLI_task_parallel_range(0, h, &data, dynamic_paint_create_uv_surface_direct_cb, &settings);
@@ -2965,7 +2965,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
*/
data.active_points = &active_points;
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (h > 64);
BLI_task_parallel_range(0, h, &data, dynamic_paint_create_uv_surface_neighbor_cb, &settings);
@@ -3216,7 +3216,7 @@ typedef struct DynamicPaintOutputSurfaceImageData {
} DynamicPaintOutputSurfaceImageData;
static void dynamic_paint_output_surface_image_paint_cb(
- void *__restrict userdata, const int index, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintOutputSurfaceImageData *data = userdata;
@@ -3238,7 +3238,7 @@ static void dynamic_paint_output_surface_image_paint_cb(
}
static void dynamic_paint_output_surface_image_displace_cb(
- void *__restrict userdata, const int index, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintOutputSurfaceImageData *data = userdata;
@@ -3264,7 +3264,7 @@ static void dynamic_paint_output_surface_image_displace_cb(
}
static void dynamic_paint_output_surface_image_wave_cb(
- void *__restrict userdata, const int index, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintOutputSurfaceImageData *data = userdata;
@@ -3288,7 +3288,7 @@ static void dynamic_paint_output_surface_image_wave_cb(
}
static void dynamic_paint_output_surface_image_wetmap_cb(
- void *__restrict userdata, const int index, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintOutputSurfaceImageData *data = userdata;
@@ -3346,7 +3346,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
case MOD_DPAINT_SURFACE_T_PAINT:
switch (output_layer) {
case 0: {
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 10000);
BLI_task_parallel_range(0,
@@ -3357,7 +3357,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
break;
}
case 1: {
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 10000);
BLI_task_parallel_range(0,
@@ -3375,7 +3375,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
case MOD_DPAINT_SURFACE_T_DISPLACE:
switch (output_layer) {
case 0: {
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 10000);
BLI_task_parallel_range(0,
@@ -3395,7 +3395,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
case MOD_DPAINT_SURFACE_T_WAVE:
switch (output_layer) {
case 0: {
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 10000);
BLI_task_parallel_range(0,
@@ -3758,7 +3758,7 @@ typedef struct DynamicPaintBrushVelocityData {
static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintBrushVelocityData *data = userdata;
@@ -3857,7 +3857,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
.prev_obmat = prev_obmat,
.timescale = timescale,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (numOfVerts_c > 10000);
BLI_task_parallel_range(
@@ -3942,7 +3942,7 @@ typedef struct DynamicPaintPaintData {
* Paint a brush object mesh to the surface
*/
static void dynamic_paint_paint_mesh_cell_point_cb_ex(
- void *__restrict userdata, const int id, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int id, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintPaintData *data = userdata;
@@ -4365,7 +4365,7 @@ static int dynamicPaint_paintMesh(Depsgraph *depsgraph,
.brushVelocity = brushVelocity,
.treeData = &treeData,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (grid->s_num[c_index] > 250);
BLI_task_parallel_range(0,
@@ -4393,7 +4393,7 @@ static int dynamicPaint_paintMesh(Depsgraph *depsgraph,
* Paint a particle system to the surface
*/
static void dynamic_paint_paint_particle_cell_point_cb_ex(
- void *__restrict userdata, const int id, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int id, const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintPaintData *data = userdata;
@@ -4666,7 +4666,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
.c_index = c_index,
.treeData = tree,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (grid->s_num[c_index] > 250);
BLI_task_parallel_range(0,
@@ -4685,7 +4685,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
/* paint a single point of defined proximity radius to the surface */
static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintPaintData *data = userdata;
@@ -4808,7 +4808,7 @@ static int dynamicPaint_paintSinglePoint(Depsgraph *depsgraph,
.brushVelocity = &brushVel,
.pointCoord = pointCoord,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -4825,7 +4825,7 @@ static int dynamicPaint_paintSinglePoint(Depsgraph *depsgraph,
static void dynamic_paint_prepare_adjacency_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
PaintSurfaceData *sData = userdata;
PaintBakeData *bData = sData->bData;
@@ -4870,7 +4870,7 @@ static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, cons
return;
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -5085,7 +5085,7 @@ typedef struct DynamicPaintEffectData {
*/
static void dynamic_paint_prepare_effect_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintEffectData *data = userdata;
@@ -5167,7 +5167,7 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph,
.force = *force,
.effectors = effectors,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -5207,7 +5207,7 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph,
*/
static void dynamic_paint_effect_spread_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintEffectData *data = userdata;
@@ -5266,7 +5266,7 @@ static void dynamic_paint_effect_spread_cb(void *__restrict userdata,
static void dynamic_paint_effect_shrink_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintEffectData *data = userdata;
@@ -5327,7 +5327,7 @@ static void dynamic_paint_effect_shrink_cb(void *__restrict userdata,
static void dynamic_paint_effect_drip_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintEffectData *data = userdata;
@@ -5481,7 +5481,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
.prevPoint = prevPoint,
.eff_scale = eff_scale,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -5503,7 +5503,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
.prevPoint = prevPoint,
.eff_scale = eff_scale,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -5530,7 +5530,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
.force = force,
.point_locks = point_locks,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -5542,7 +5542,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
static void dynamic_paint_border_cb(void *__restrict userdata,
const int b_index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintEffectData *data = userdata;
@@ -5613,7 +5613,7 @@ static void dynamicPaint_doBorderStep(DynamicPaintSurface *surface)
.surface = surface,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->adj_data->total_border > 1000);
BLI_task_parallel_range(
@@ -5622,7 +5622,7 @@ static void dynamicPaint_doBorderStep(DynamicPaintSurface *surface)
static void dynamic_paint_wave_step_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintEffectData *data = userdata;
@@ -5777,7 +5777,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
.damp_factor = damp_factor,
.reset_wave = (ss == steps - 1),
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(0, sData->total_points, &data, dynamic_paint_wave_step_cb, &settings);
@@ -5802,7 +5802,7 @@ typedef struct DynamicPaintDissolveDryData {
static void dynamic_paint_surface_pre_step_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintDissolveDryData *data = userdata;
@@ -5938,7 +5938,7 @@ typedef struct DynamicPaintGenerateBakeData {
static void dynamic_paint_generate_bake_data_cb(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const DynamicPaintGenerateBakeData *data = userdata;
@@ -6170,7 +6170,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
.do_velocity_data = do_velocity_data,
.new_bdata = new_bdata,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
@@ -6217,7 +6217,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph,
.surface = surface,
.timescale = timescale,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (sData->total_points > 1000);
BLI_task_parallel_range(
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index b8178bec52f..83b354ffb4a 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -889,7 +889,7 @@ typedef struct LatticeDeformUserdata {
static void lattice_deform_vert_task(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const LatticeDeformUserdata *data = userdata;
@@ -948,7 +948,7 @@ void lattice_deform_verts(Object *laOb,
.defgrp_index = defgrp_index,
.fac = fac};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 32;
BLI_task_parallel_range(0, numVerts, &data, lattice_deform_vert_task, &settings);
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 2ab5b69a022..e03903c05e4 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -1462,7 +1462,7 @@ typedef struct MaskRasterizeBufferData {
static void maskrasterize_buffer_cb(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MaskRasterizeBufferData *data = userdata;
@@ -1503,7 +1503,7 @@ void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
.width = width,
.buffer = buffer,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((size_t)height * width > 10000);
BLI_task_parallel_range(0, (int)height, &data, maskrasterize_buffer_cb, &settings);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f5e93dcf9b7..9e01bfe62d6 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -697,6 +697,15 @@ Mesh *BKE_mesh_new_nomain_from_template(const Mesh *me_src,
me_src, verts_len, edges_len, tessface_len, loops_len, polys_len, CD_MASK_EVERYTHING);
}
+void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
+{
+ /* Evaluated mesh may point to edit mesh, but never owns it. */
+ mesh_eval->edit_mesh = NULL;
+ BKE_mesh_free(mesh_eval);
+ BKE_libblock_free_data(&mesh_eval->id, false);
+ MEM_freeN(mesh_eval);
+}
+
Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
{
int flags = LIB_ID_COPY_LOCALIZE;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 17b22a6d095..e28d50cbde4 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -220,7 +220,7 @@ typedef struct MeshCalcNormalsData {
static void mesh_calc_normals_poly_cb(void *__restrict userdata,
const int pidx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MeshCalcNormalsData *data = userdata;
const MPoly *mp = &data->mpolys[pidx];
@@ -230,7 +230,7 @@ static void mesh_calc_normals_poly_cb(void *__restrict userdata,
static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata,
const int pidx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MeshCalcNormalsData *data = userdata;
const MPoly *mp = &data->mpolys[pidx];
@@ -294,7 +294,7 @@ static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata,
static void mesh_calc_normals_poly_finalize_cb(void *__restrict userdata,
const int vidx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MeshCalcNormalsData *data = userdata;
@@ -321,7 +321,7 @@ void BKE_mesh_calc_normals_poly(MVert *mverts,
{
float(*pnors)[3] = r_polynors;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index dac12233539..c8e75532075 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -1200,7 +1200,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
int i = p->loopstart;
int stop = i + p->totloop;
- if (stop > me->totloop || stop < i) {
+ if (stop > me->totloop || stop < i || p->loopstart < 0) {
invalid = true;
}
else {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 6bc83f8dd09..f67bc419210 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -53,6 +53,7 @@
#include "BKE_animsys.h"
#include "BKE_colortools.h"
+#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_movieclip.h"
@@ -1772,9 +1773,17 @@ static void movieclip_selection_synchronize(MovieClip *clip_dst, const MovieClip
}
}
-void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, MovieClip *clip)
+static void movieclip_eval_update_reload(struct Depsgraph *depsgraph, Main *bmain, MovieClip *clip)
+{
+ BKE_movieclip_reload(bmain, clip);
+ if (DEG_is_active(depsgraph)) {
+ MovieClip *clip_orig = (MovieClip *)DEG_get_original_id(&clip->id);
+ BKE_movieclip_reload(bmain, clip_orig);
+ }
+}
+
+static void movieclip_eval_update_generic(struct Depsgraph *depsgraph, MovieClip *clip)
{
- DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
BKE_tracking_dopesheet_tag_update(&clip->tracking);
if (DEG_is_active(depsgraph)) {
MovieClip *clip_orig = (MovieClip *)DEG_get_original_id(&clip->id);
@@ -1782,6 +1791,17 @@ void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, MovieClip *clip)
}
}
+void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, Main *bmain, MovieClip *clip)
+{
+ DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
+ if (clip->id.recalc & ID_RECALC_SOURCE) {
+ movieclip_eval_update_reload(depsgraph, bmain, clip);
+ }
+ else {
+ movieclip_eval_update_generic(depsgraph, clip);
+ }
+}
+
void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip *clip)
{
DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 29337ca9985..bbae1f4d3bc 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -1078,7 +1078,7 @@ typedef struct MultiresThreadedData {
static void multires_disp_run_cb(void *__restrict userdata,
const int pidx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MultiresThreadedData *tdata = userdata;
@@ -1230,7 +1230,7 @@ static void multiresModifier_disp_run(
}
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index 749cedb5388..d939267ac5a 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -955,7 +955,7 @@ typedef struct ReshapeFromCCGTaskData {
static void reshape_from_ccg_task(void *__restrict userdata,
const int coarse_poly_index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
ReshapeFromCCGTaskData *data = userdata;
const CCGKey *key = data->key;
@@ -1045,7 +1045,7 @@ bool multiresModifier_reshapeFromCCG(const int tot_level, Mesh *coarse_mesh, Sub
MultiresPropagateData propagate_data;
multires_reshape_propagate_prepare(&propagate_data, coarse_mesh, key.level, top_level);
/* Threaded grids iteration. */
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
BLI_task_parallel_range(
0, coarse_mesh->totpoly, &data, reshape_from_ccg_task, &parallel_range_settings);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d7256cc9604..69ba7ccab8e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -442,19 +442,13 @@ void BKE_object_free_derived_caches(Object *ob)
if (ob->runtime.mesh_eval != NULL) {
if (ob->runtime.is_mesh_eval_owned) {
Mesh *mesh_eval = ob->runtime.mesh_eval;
- /* Evaluated mesh points to edit mesh, but does not own it. */
- mesh_eval->edit_mesh = NULL;
- BKE_mesh_free(mesh_eval);
- BKE_libblock_free_data(&mesh_eval->id, false);
- MEM_freeN(mesh_eval);
+ BKE_mesh_eval_delete(mesh_eval);
}
ob->runtime.mesh_eval = NULL;
}
if (ob->runtime.mesh_deform_eval != NULL) {
Mesh *mesh_deform_eval = ob->runtime.mesh_deform_eval;
- BKE_mesh_free(mesh_deform_eval);
- BKE_libblock_free_data(&mesh_deform_eval->id, false);
- MEM_freeN(mesh_deform_eval);
+ BKE_mesh_eval_delete(mesh_deform_eval);
ob->runtime.mesh_deform_eval = NULL;
}
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index b5df7d5fe9b..39fb668c873 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -510,7 +510,7 @@ typedef struct OceanSimulateData {
static void ocean_compute_htilda(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
OceanSimulateData *osd = userdata;
const Ocean *o = osd->o;
@@ -779,7 +779,7 @@ void BKE_ocean_simulate(struct Ocean *o, float t, float scale, float chop_amount
* but remains reasonably simple and should be OK most of the time. */
/* compute a new htilda */
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (o->_M > 16);
BLI_task_parallel_range(0, o->_M, &osd, ocean_compute_htilda, &settings);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 079a348745c..b80f64e3472 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3112,7 +3112,7 @@ typedef struct CacheEditrPathsIterData {
static void psys_cache_edit_paths_iter(void *__restrict iter_data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
CacheEditrPathsIterData *iter_data = (CacheEditrPathsIterData *)iter_data_v;
PTCacheEdit *edit = iter_data->edit;
@@ -3334,7 +3334,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph,
iter_data.nosel_col[2] = (float)edit->nosel_col[2] / 255.0f;
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(0, edit->totpoint, &iter_data, psys_cache_edit_paths_iter, &settings);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 27722aab2d9..e12537784f3 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3685,7 +3685,7 @@ typedef struct DynamicStepSolverTaskData {
static void dynamics_step_sph_ddr_task_cb_ex(void *__restrict userdata,
const int p,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
DynamicStepSolverTaskData *data = userdata;
ParticleSimulationData *sim = data->sim;
@@ -3720,7 +3720,7 @@ static void dynamics_step_sph_ddr_task_cb_ex(void *__restrict userdata,
}
static void dynamics_step_sph_classical_basic_integrate_task_cb_ex(
- void *__restrict userdata, const int p, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int p, const TaskParallelTLS *__restrict UNUSED(tls))
{
DynamicStepSolverTaskData *data = userdata;
ParticleSimulationData *sim = data->sim;
@@ -3736,7 +3736,7 @@ static void dynamics_step_sph_classical_basic_integrate_task_cb_ex(
}
static void dynamics_step_sph_classical_calc_density_task_cb_ex(
- void *__restrict userdata, const int p, const ParallelRangeTLS *__restrict tls)
+ void *__restrict userdata, const int p, const TaskParallelTLS *__restrict tls)
{
DynamicStepSolverTaskData *data = userdata;
ParticleSimulationData *sim = data->sim;
@@ -3754,7 +3754,7 @@ static void dynamics_step_sph_classical_calc_density_task_cb_ex(
}
static void dynamics_step_sph_classical_integrate_task_cb_ex(
- void *__restrict userdata, const int p, const ParallelRangeTLS *__restrict tls)
+ void *__restrict userdata, const int p, const TaskParallelTLS *__restrict tls)
{
DynamicStepSolverTaskData *data = userdata;
ParticleSimulationData *sim = data->sim;
@@ -3963,7 +3963,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
/* Apply SPH forces using double-density relaxation algorithm
* (Clavat et. al.) */
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (psys->totpart > 100);
settings.userdata_chunk = &sphdata;
@@ -3980,7 +3980,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
* this algorithm is separated into distinct loops. */
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (psys->totpart > 100);
BLI_task_parallel_range(0,
@@ -3994,7 +3994,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
/* Note that we could avoid copying sphdata for each thread here (it's only read here),
* but doubt this would gain us anything except confusion... */
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (psys->totpart > 100);
settings.userdata_chunk = &sphdata;
@@ -4008,7 +4008,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
/* do global forces & effectors */
{
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (psys->totpart > 100);
settings.userdata_chunk = &sphdata;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index ffc4ec65d4d..860e2bdaa93 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -995,7 +995,7 @@ typedef struct PBVHUpdateData {
static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
PBVHUpdateData *data = userdata;
@@ -1045,7 +1045,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
static void pbvh_update_normals_store_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
PBVHUpdateData *data = userdata;
PBVH *bvh = data->bvh;
@@ -1094,7 +1094,7 @@ static void pbvh_faces_update_normals(PBVH *bvh, PBVHNode **nodes, int totnode)
.vnors = vnors,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (totnode > PBVH_THREADED_LIMIT);
@@ -1107,7 +1107,7 @@ static void pbvh_faces_update_normals(PBVH *bvh, PBVHNode **nodes, int totnode)
static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
PBVHUpdateData *data = userdata;
PBVH *bvh = data->bvh;
@@ -1138,7 +1138,7 @@ void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
.flag = flag,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (totnode > PBVH_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, pbvh_update_BB_redraw_task_cb, &settings);
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 6a72b46a8f2..9b9fd33f52d 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -344,7 +344,7 @@ void BKE_shrinkwrap_compute_boundary_data(struct Mesh *mesh)
*/
static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
ShrinkwrapCalcCBData *data = userdata;
@@ -416,7 +416,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
.calc = calc,
.tree = calc->tree,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
settings.userdata_chunk = &nearest;
@@ -510,7 +510,7 @@ bool BKE_shrinkwrap_project_normal(char options,
static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
ShrinkwrapCalcCBData *data = userdata;
@@ -703,7 +703,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
.proj_axis = proj_axis,
.local2aux = &local2aux,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
settings.userdata_chunk = &hit;
@@ -1115,7 +1115,7 @@ void BKE_shrinkwrap_find_nearest_surface(struct ShrinkwrapTreeData *tree,
*/
static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
ShrinkwrapCalcCBData *data = userdata;
@@ -1363,7 +1363,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
.calc = calc,
.tree = calc->tree,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
settings.userdata_chunk = &nearest;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index bb8fd18ea58..1dcbf7615f7 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -819,7 +819,7 @@ typedef struct ObstaclesFromDMData {
static void obstacles_from_mesh_task_cb(void *__restrict userdata,
const int z,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
ObstaclesFromDMData *data = userdata;
SmokeDomainSettings *sds = data->sds;
@@ -974,7 +974,7 @@ static void obstacles_from_mesh(Object *coll_ob,
.velocityZ = velocityZ,
.num_obstacles = num_obstacles,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(
@@ -1328,7 +1328,7 @@ typedef struct EmitFromParticlesData {
static void emit_from_particles_task_cb(void *__restrict userdata,
const int z,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
EmitFromParticlesData *data = userdata;
SmokeFlowSettings *sfs = data->sfs;
@@ -1567,7 +1567,7 @@ static void emit_from_particles(Object *flow_ob,
.hr_smooth = hr_smooth,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(min[2], max[2], &data, emit_from_particles_task_cb, &settings);
@@ -1770,7 +1770,7 @@ typedef struct EmitFromDMData {
static void emit_from_mesh_task_cb(void *__restrict userdata,
const int z,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
EmitFromDMData *data = userdata;
EmissionMap *em = data->em;
@@ -1975,7 +1975,7 @@ static void emit_from_mesh(
.res = res,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(min[2], max[2], &data, emit_from_mesh_task_cb, &settings);
@@ -2893,7 +2893,7 @@ typedef struct UpdateEffectorsData {
static void update_effectors_task_cb(void *__restrict userdata,
const int x,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
UpdateEffectorsData *data = userdata;
SmokeDomainSettings *sds = data->sds;
@@ -2967,7 +2967,7 @@ static void update_effectors(
data.velocity_z = smoke_get_velocity_z(sds->fluid);
data.obstacle = smoke_get_obstacle(sds->fluid);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(0, sds->res[0], &data, update_effectors_task_cb, &settings);
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index fac1e1dbe75..472fbd9ad18 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -267,7 +267,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
static void subdiv_ccg_eval_grids_task(void *__restrict userdata_v,
const int face_index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
CCGEvalGridsData *data = userdata_v;
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
@@ -295,7 +295,7 @@ static bool subdiv_ccg_evaluate_grids(SubdivCCG *subdiv_ccg,
data.mask_evaluator = mask_evaluator;
data.material_flags_evaluator = material_flags_evaluator;
/* Threaded grids evaluation. */
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
BLI_task_parallel_range(
0, num_faces, &data, subdiv_ccg_eval_grids_task, &parallel_range_settings);
@@ -747,7 +747,7 @@ static void subdiv_ccg_average_inner_face_normals(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_recalc_inner_normal_task(void *__restrict userdata_v,
const int grid_index,
- const ParallelRangeTLS *__restrict tls_v)
+ const TaskParallelTLS *__restrict tls_v)
{
RecalcInnerNormalsData *data = userdata_v;
RecalcInnerNormalsTLSData *tls = tls_v->userdata_chunk;
@@ -772,7 +772,7 @@ static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG *subdiv_ccg)
.key = &key,
};
RecalcInnerNormalsTLSData tls_data = {NULL};
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
@@ -802,7 +802,7 @@ typedef struct RecalcModifiedInnerNormalsData {
static void subdiv_ccg_recalc_modified_inner_normal_task(void *__restrict userdata_v,
const int face_index,
- const ParallelRangeTLS *__restrict tls_v)
+ const TaskParallelTLS *__restrict tls_v)
{
RecalcModifiedInnerNormalsData *data = userdata_v;
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
@@ -838,7 +838,7 @@ static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
.effected_ccg_faces = (SubdivCCGFace **)effected_faces,
};
RecalcInnerNormalsTLSData tls_data = {NULL};
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
@@ -991,7 +991,7 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_average_inner_grids_task(void *__restrict userdata_v,
const int face_index,
- const ParallelRangeTLS *__restrict UNUSED(tls_v))
+ const TaskParallelTLS *__restrict UNUSED(tls_v))
{
AverageInnerGridsData *data = userdata_v;
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
@@ -1050,7 +1050,7 @@ static void subdiv_ccg_average_grids_boundary(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_average_grids_boundaries_task(void *__restrict userdata_v,
const int adjacent_edge_index,
- const ParallelRangeTLS *__restrict tls_v)
+ const TaskParallelTLS *__restrict tls_v)
{
AverageGridsBoundariesData *data = userdata_v;
AverageGridsBoundariesTLSData *tls = tls_v->userdata_chunk;
@@ -1097,7 +1097,7 @@ static void subdiv_ccg_average_grids_corners(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_average_grids_corners_task(void *__restrict userdata_v,
const int adjacent_vertex_index,
- const ParallelRangeTLS *__restrict UNUSED(tls_v))
+ const TaskParallelTLS *__restrict UNUSED(tls_v))
{
AverageGridsCornerData *data = userdata_v;
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
@@ -1108,7 +1108,7 @@ static void subdiv_ccg_average_grids_corners_task(void *__restrict userdata_v,
static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key)
{
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
AverageGridsBoundariesData boundaries_data = {
.subdiv_ccg = subdiv_ccg,
@@ -1127,7 +1127,7 @@ static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key
static void subdiv_ccg_average_all_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
{
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
AverageGridsCornerData corner_data = {
.subdiv_ccg = subdiv_ccg,
@@ -1150,7 +1150,7 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
/* Average inner boundaries of grids (within one face), across faces
* from different face-corners. */
@@ -1175,7 +1175,7 @@ typedef struct StitchFacesInnerGridsData {
static void subdiv_ccg_stitch_face_inner_grids_task(
void *__restrict userdata_v,
const int face_index,
- const ParallelRangeTLS *__restrict UNUSED(tls_v))
+ const TaskParallelTLS *__restrict UNUSED(tls_v))
{
StitchFacesInnerGridsData *data = userdata_v;
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
@@ -1197,7 +1197,7 @@ void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
.key = &key,
.effected_ccg_faces = effected_faces,
};
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
BLI_task_parallel_range(0,
num_effected_faces,
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index 98afbef6c0a..c3f9bc3400c 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -1681,7 +1681,7 @@ static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int p
static void subdiv_foreach_loose_vertices_task(void *__restrict userdata,
const int coarse_vertex_index,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SubdivForeachTaskContext *ctx = userdata;
if (BLI_BITMAP_TEST_BOOL(ctx->coarse_vertices_used_map, coarse_vertex_index)) {
@@ -1695,7 +1695,7 @@ static void subdiv_foreach_loose_vertices_task(void *__restrict userdata,
static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdata,
const int coarse_edge_index,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SubdivForeachTaskContext *ctx = userdata;
if (BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge_index)) {
@@ -1767,7 +1767,7 @@ static void subdiv_foreach_single_thread_tasks(SubdivForeachTaskContext *ctx)
static void subdiv_foreach_task(void *__restrict userdata,
const int poly_index,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SubdivForeachTaskContext *ctx = userdata;
/* Traverse hi-poly vertex coordinates and normals. */
@@ -1786,7 +1786,7 @@ static void subdiv_foreach_task(void *__restrict userdata,
static void subdiv_foreach_boundary_edges_task(void *__restrict userdata,
const int edge_index,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SubdivForeachTaskContext *ctx = userdata;
subdiv_foreach_boundary_edges(ctx, tls->userdata_chunk, edge_index);
@@ -1821,7 +1821,7 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv,
/* Run all the code which is not supposed to be run from threads. */
subdiv_foreach_single_thread_tasks(&ctx);
/* Threaded traversal of the rest of topology. */
- ParallelRangeSettings parallel_range_settings;
+ TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = context->user_data_tls;
parallel_range_settings.userdata_chunk_size = context->user_data_tls_size;
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 75e05f8ffab..1ff9140681f 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -1086,20 +1086,27 @@ static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext *
const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
+ const bool is_simple = ctx->subdiv->settings.is_simple;
/* Find neighbors of the current loose edge. */
const MEdge *neighbors[2];
find_edge_neighbors(ctx, coarse_edge, neighbors);
- /* Get points for b-spline interpolation. */
- float points[4][3];
- points_for_loose_edges_interpolation_get(ctx, coarse_edge, neighbors, points);
- /* Perform interpolation. */
- float weights[4];
- key_curve_position_weights(u, weights, KEY_BSPLINE);
/* Interpolate custom data. */
subdiv_mesh_vertex_of_loose_edge_interpolate(ctx, coarse_edge, u, subdiv_vertex_index);
- /* Initialize */
+ /* Interpolate coordinate. */
MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
- interp_v3_v3v3v3v3(subdiv_vertex->co, points[0], points[1], points[2], points[3], weights);
+ if (is_simple) {
+ const MVert *coarse_mvert = coarse_mesh->mvert;
+ const MVert *vert_1 = &coarse_mvert[coarse_edge->v1];
+ const MVert *vert_2 = &coarse_mvert[coarse_edge->v2];
+ interp_v3_v3v3(subdiv_vertex->co, vert_1->co, vert_2->co, u);
+ }
+ else {
+ float points[4][3];
+ points_for_loose_edges_interpolation_get(ctx, coarse_edge, neighbors, points);
+ float weights[4];
+ key_curve_position_weights(u, weights, KEY_BSPLINE);
+ interp_v3_v3v3v3v3(subdiv_vertex->co, points[0], points[1], points[2], points[3], weights);
+ }
/* Reset flags and such. */
subdiv_vertex->flag = 0;
/* TODO(sergey): This matches old behavior, but we can as well interpolate
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 4171c1aac4f..09a073e3ca6 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1459,7 +1459,7 @@ typedef struct CopyFinalLoopArrayData {
static void copyFinalLoopArray_task_cb(void *__restrict userdata,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
CopyFinalLoopArrayData *data = userdata;
CCGDerivedMesh *ccgdm = data->ccgdm;
@@ -1536,7 +1536,7 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
*/
data.mloop_index = data.grid_size >= 5 ? 1 : 8;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1;
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
index 8a474725b0c..84855cf4b82 100644
--- a/source/blender/blenkernel/intern/tracking_auto.c
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -377,7 +377,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
static void autotrack_context_step_cb(void *__restrict userdata,
const int track,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
AutoTrackContext *context = userdata;
const int frame_delta = context->backwards ? -1 : 1;
@@ -446,7 +446,7 @@ bool BKE_autotrack_context_step(AutoTrackContext *context)
const int frame_delta = context->backwards ? -1 : 1;
context->step_ok = false;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (context->num_tracks > 1);
BLI_task_parallel_range(0, context->num_tracks, context, autotrack_context_step_cb, &settings);
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index cfa41cb7d92..7e7a839b645 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -65,6 +65,9 @@ typedef struct MovieReconstructContext {
TracksMap *tracks_map;
int sfra, efra;
+
+ /* Details about reconstruction error, reported by Libmv. */
+ char error_message[1024];
} MovieReconstructContext;
typedef struct ReconstructProgressData {
@@ -426,9 +429,26 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
context->keyframe2 = keyframe2;
context->refine_flags = reconstruct_refine_intrinsics_get_flags(tracking, object);
+ context->error_message[0] = '\0';
+
return context;
}
+void BKE_tracking_reconstruction_report_error_message(MovieReconstructContext *context,
+ const char *error_message)
+{
+ if (context->error_message[0]) {
+ /* Only keep initial error message, the rest are inducted ones. */
+ return;
+ }
+ BLI_strncpy(context->error_message, error_message, sizeof(context->error_message));
+}
+
+const char *BKE_tracking_reconstruction_error_message_get(const MovieReconstructContext *context)
+{
+ return context->error_message;
+}
+
/* Free memory used by a reconstruction process. */
void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
{
@@ -534,7 +554,8 @@ bool BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieT
MovieTrackingObject *object;
if (!libmv_reconstructionIsValid(context->reconstruction)) {
- printf("Failed solve the motion: most likely there are no good keyframes\n");
+ BKE_tracking_reconstruction_report_error_message(
+ context, "Failed to solve the motion: most likely there are no good keyframes");
return false;
}
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index b852e8a12cd..03229c654fb 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -611,16 +611,19 @@ static bool average_track_contributions(StabContext *ctx,
float rotation, scale, quality;
quality = rotation_contribution(
stabilization_base, marker, aspect, r_pivot, &rotation, &scale);
- weight *= quality;
- weight_sum += weight;
- *r_angle += rotation * weight;
+ const float quality_weight = weight * quality;
+ weight_sum += quality_weight;
+ *r_angle += rotation * quality_weight;
if (stab->flag & TRACKING_STABILIZE_SCALE) {
- *r_scale_step += logf(scale) * weight;
+ *r_scale_step += logf(scale) * quality_weight;
}
else {
*r_scale_step = 0;
}
- ok |= (weight_sum > EPSILON_WEIGHT);
+ /* NOTE: Use original marker weight and not the scaled one with the proximity here to allow
+ * simple stabilization setups when there is a single track in a close proximity of the
+ * center. */
+ ok |= (weight > EPSILON_WEIGHT);
}
}
}
@@ -1338,7 +1341,7 @@ typedef struct TrackingStabilizeFrameInterpolationData {
} TrackingStabilizeFrameInterpolationData;
static void tracking_stabilize_frame_interpolation_cb(
- void *__restrict userdata, const int j, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
{
TrackingStabilizeFrameInterpolationData *data = userdata;
ImBuf *ibuf = data->ibuf;
@@ -1443,7 +1446,7 @@ ImBuf *BKE_tracking_stabilize_frame(
.interpolation = interpolation,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (tmpibuf->y > 128);
BLI_task_parallel_range(
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index d312dc0190b..07cf5205cab 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -311,13 +311,20 @@ static void undosys_stack_clear_all_last(UndoStack *ustack, UndoStep *us)
}
}
-static void undosys_stack_clear_all_first(UndoStack *ustack, UndoStep *us)
+static void undosys_stack_clear_all_first(UndoStack *ustack, UndoStep *us, UndoStep *us_exclude)
{
+ if (us && us == us_exclude) {
+ us = us->prev;
+ }
+
if (us) {
bool is_not_empty = true;
UndoStep *us_iter;
do {
us_iter = ustack->steps.first;
+ if (us_iter == us_exclude) {
+ us_iter = us_iter->next;
+ }
BLI_assert(us_iter != ustack->step_active);
undosys_step_free_and_unlink(ustack, us_iter);
undosys_stack_validate(ustack, is_not_empty);
@@ -395,9 +402,7 @@ void BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size
CLOG_INFO(&LOG, 1, "steps=%d, memory_limit=%zu", steps, memory_limit);
UndoStep *us;
-#ifdef WITH_GLOBAL_UNDO_KEEP_ONE
UndoStep *us_exclude = NULL;
-#endif
/* keep at least two (original + other) */
size_t data_size_all = 0;
size_t us_count = 0;
@@ -427,23 +432,14 @@ void BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size
/* Hack, we need to keep at least one BKE_UNDOSYS_TYPE_MEMFILE. */
if (us->type != BKE_UNDOSYS_TYPE_MEMFILE) {
us_exclude = us->prev;
- while (us_exclude && us->type != BKE_UNDOSYS_TYPE_MEMFILE) {
+ while (us_exclude && us_exclude->type != BKE_UNDOSYS_TYPE_MEMFILE) {
us_exclude = us_exclude->prev;
}
- if (us_exclude) {
- BLI_remlink(&ustack->steps, us_exclude);
- }
}
#endif
/* Free from first to last, free functions may update de-duplication info
* (see #MemFileUndoStep). */
- undosys_stack_clear_all_first(ustack, us->prev);
-
-#ifdef WITH_GLOBAL_UNDO_KEEP_ONE
- if (us_exclude) {
- BLI_addhead(&ustack->steps, us_exclude);
- }
-#endif
+ undosys_stack_clear_all_first(ustack, us->prev, us_exclude);
}
}
@@ -564,12 +560,15 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
}
if (use_memfile_step) {
- const char *name_internal = "MemFile Internal (post)";
+ /* Make this the user visible undo state, so redo always applies
+ * on top of the mem-file undo instead of skipping it. see: T67256. */
+ UndoStep *us_prev = ustack->step_active;
+ const char *name_internal = us_prev->name;
const bool ok = undosys_stack_push_main(ustack, name_internal, G_MAIN);
if (ok) {
UndoStep *us = ustack->steps.last;
BLI_assert(STREQ(us->name, name_internal));
- us->skip = true;
+ us_prev->skip = true;
#ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER
ustack->step_active_memfile = us;
#endif
@@ -849,10 +848,6 @@ void BKE_undosys_type_free_all(void)
* Unfortunately we need this for a handful of places.
*/
-/* Disable for now since it accesses freed memory.
- * The pointer can only be a key, we can't read it's contents. */
-#define USE_LIB_SKIP
-
static void UNUSED_FUNCTION(BKE_undosys_foreach_ID_ref(UndoStack *ustack,
UndoTypeForEachIDRefFn foreach_ID_ref_fn,
void *user_data))
@@ -865,176 +860,6 @@ static void UNUSED_FUNCTION(BKE_undosys_foreach_ID_ref(UndoStack *ustack,
}
}
-typedef struct UndoIDPtrMapItem {
- /** Never changes (matches undo data). Use as sort key for binary search. */
- const void *ptr;
- /** Write the new pointers here. */
- uint index;
-} UndoIDPtrMapItem;
-
-typedef struct UndoIDPtrMap {
- UndoRefID *refs;
- /**
- * Pointer map, update 'dst' members before use.
- * This is always sorted (adds some overhead when adding, in practice it's acceptable since).
- */
- UndoIDPtrMapItem *pmap;
-
- /** Length for both 'refs' & 'pmap' */
- uint len;
- uint len_alloc;
-} UndoIDPtrMap;
-
-#ifdef DEBUG
-# define PMAP_DEFAULT_ALLOC 1
-#else
-# define PMAP_DEFAULT_ALLOC 32
-#endif
-
-void BKE_undosys_ID_map_foreach_ID_ref(UndoIDPtrMap *map,
- UndoTypeForEachIDRefFn foreach_ID_ref_fn,
- void *user_data)
-{
- for (uint i = 0; i < map->len; i++) {
- foreach_ID_ref_fn(user_data, &map->refs[i]);
- }
-}
-
-/**
- * Return true when found, otherwise index is set to the index we should insert.
- */
-static bool undosys_ID_map_lookup_index(const UndoIDPtrMap *map, const void *key, uint *r_index)
-{
- const UndoIDPtrMapItem *pmap = map->pmap;
- const uint len = map->len;
- if (len == 0) {
- if (r_index) {
- *r_index = 0;
- }
- return false;
- }
- int min = 0, max = len - 1;
- while (min <= max) {
- const uint mid = (min + max) / 2;
- if (pmap[mid].ptr < key) {
- min = mid + 1;
- }
- else if (pmap[mid].ptr == key) {
- if (r_index) {
- *r_index = mid;
- }
- return true;
- }
- else if (pmap[mid].ptr > key) {
- max = mid - 1;
- }
- }
- if (r_index) {
- *r_index = min;
- }
- return false;
-}
-
-/**
- * A set of ID's use for efficient decoding, so we can map pointers back to the newly loaded data
- * without performing full look ups each time.
- *
- * This can be used as an old_pointer -> new_pointer lookup.
- */
-UndoIDPtrMap *BKE_undosys_ID_map_create(void)
-{
- UndoIDPtrMap *map = MEM_mallocN(sizeof(*map), __func__);
- map->len_alloc = PMAP_DEFAULT_ALLOC;
- map->refs = MEM_mallocN(sizeof(*map->refs) * map->len_alloc, __func__);
- map->pmap = MEM_mallocN(sizeof(*map->pmap) * map->len_alloc, __func__);
- map->len = 0;
- return map;
-}
-void BKE_undosys_ID_map_destroy(UndoIDPtrMap *idpmap)
-{
- MEM_SAFE_FREE(idpmap->refs);
- MEM_SAFE_FREE(idpmap->pmap);
- MEM_freeN(idpmap);
-}
-
-void BKE_undosys_ID_map_add(UndoIDPtrMap *map, ID *id)
-{
- uint index;
-#ifdef USE_LIB_SKIP
- if (id->lib != NULL) {
- return;
- }
-#endif
-
- if (undosys_ID_map_lookup_index(map, id, &index)) {
- return; /* exists. */
- }
-
- const uint len_src = map->len;
- const uint len_dst = map->len + 1;
- if (len_dst > map->len_alloc) {
- map->len_alloc *= 2;
- BLI_assert(map->len_alloc >= len_dst);
- map->pmap = MEM_reallocN(map->pmap, sizeof(*map->pmap) * map->len_alloc);
- map->refs = MEM_reallocN(map->refs, sizeof(*map->refs) * map->len_alloc);
- }
-
-#if 0 /* Will be done automatically in callback. */
- BLI_strncpy(map->refs[len_src].name, id->name, sizeof(id->name));
-#else
- map->refs[len_src].name[0] = '\0';
-#endif
- map->refs[len_src].ptr = id;
-
- if (len_src != 0 && index != len_src) {
- memmove(&map->pmap[index + 1], &map->pmap[index], sizeof(*map->pmap) * (len_src - index));
- }
- map->pmap[index].ptr = id;
- map->pmap[index].index = len_src;
-
- map->len = len_dst;
-}
-
-ID *BKE_undosys_ID_map_lookup(const UndoIDPtrMap *map, const ID *id_src)
-{
- /* We should only ever lookup indices which exist! */
- uint index;
- if (!undosys_ID_map_lookup_index(map, id_src, &index)) {
- BLI_assert(0);
- }
- index = map->pmap[index].index;
- ID *id_dst = map->refs[index].ptr;
- BLI_assert(id_dst != NULL);
- BLI_assert(STREQ(id_dst->name, map->refs[index].name));
- return id_dst;
-}
-
-void BKE_undosys_ID_map_add_with_prev(UndoIDPtrMap *map, ID *id, ID **id_prev)
-{
- if (id == *id_prev) {
- return;
- }
- *id_prev = id;
- BKE_undosys_ID_map_add(map, id);
-}
-
-ID *BKE_undosys_ID_map_lookup_with_prev(const UndoIDPtrMap *map, ID *id_src, ID *id_prev_match[2])
-{
- if (id_src == id_prev_match[0]) {
- return id_prev_match[1];
- }
- else {
-#ifdef USE_LIB_SKIP
- ID *id_dst = BKE_undosys_ID_map_lookup(map, id_src);
-#else
- ID *id_dst = (id_src->lib == NULL) ? BKE_undosys_ID_map_lookup(map, id_src) : id_src;
-#endif
- id_prev_match[0] = id_src;
- id_prev_match[1] = id_dst;
- return id_dst;
- }
-}
-
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 18689cca55a..c1618061b38 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -302,6 +302,13 @@ bool isect_line_line_strict_v3(const float v1[3],
float vi[3],
float *r_lambda);
+bool isect_ray_ray_v3(const float ray_origin_a[3],
+ const float ray_direction_a[3],
+ const float ray_origin_b[3],
+ const float ray_direction_b[3],
+ float *r_lambda_a,
+ float *r_lambda_b);
+
bool isect_ray_plane_v3(const float ray_origin[3],
const float ray_direction[3],
const float plane[4],
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
index d11ba15a7e0..568d6c9a84a 100644
--- a/source/blender/blenlib/BLI_task.h
+++ b/source/blender/blenlib/BLI_task.h
@@ -142,22 +142,23 @@ typedef enum eTaskSchedulingMode {
} eTaskSchedulingMode;
/* Per-thread specific data passed to the callback. */
-typedef struct ParallelRangeTLS {
+typedef struct TaskParallelTLS {
/* Identifier of the thread who this data belongs to. */
int thread_id;
/* Copy of user-specifier chunk, which is copied from original chunk to all
* worker threads. This is similar to OpenMP's firstprivate.
*/
void *userdata_chunk;
-} ParallelRangeTLS;
+} TaskParallelTLS;
+
+typedef void (*TaskParallelFinalizeFunc)(void *__restrict userdata,
+ void *__restrict userdata_chunk);
typedef void (*TaskParallelRangeFunc)(void *__restrict userdata,
const int iter,
- const ParallelRangeTLS *__restrict tls);
-typedef void (*TaskParallelRangeFuncFinalize)(void *__restrict userdata,
- void *__restrict userdata_chunk);
+ const TaskParallelTLS *__restrict tls);
-typedef struct ParallelRangeSettings {
+typedef struct TaskParallelSettings {
/* Whether caller allows to do threading of the particular range.
* Usually set by some equation, which forces threading off when threading
* overhead becomes higher than speed benefit.
@@ -175,7 +176,7 @@ typedef struct ParallelRangeSettings {
/* Function called from calling thread once whole range have been
* processed.
*/
- TaskParallelRangeFuncFinalize func_finalize;
+ TaskParallelFinalizeFunc func_finalize;
/* Minimum allowed number of range iterators to be handled by a single
* thread. This allows to achieve following:
* - Reduce amount of threading overhead.
@@ -187,15 +188,15 @@ typedef struct ParallelRangeSettings {
* having a global use_threading switch based on just range size.
*/
int min_iter_per_thread;
-} ParallelRangeSettings;
+} TaskParallelSettings;
-BLI_INLINE void BLI_parallel_range_settings_defaults(ParallelRangeSettings *settings);
+BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings);
void BLI_task_parallel_range(const int start,
const int stop,
void *userdata,
TaskParallelRangeFunc func,
- const ParallelRangeSettings *settings);
+ const TaskParallelSettings *settings);
typedef void (*TaskParallelListbaseFunc)(void *userdata, struct Link *iter, int index);
void BLI_task_parallel_listbase(struct ListBase *listbase,
@@ -211,16 +212,13 @@ void BLI_task_parallel_mempool(struct BLI_mempool *mempool,
const bool use_threading);
/* TODO(sergey): Think of a better place for this. */
-BLI_INLINE void BLI_parallel_range_settings_defaults(ParallelRangeSettings *settings)
+BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
{
memset(settings, 0, sizeof(*settings));
settings->use_threading = true;
settings->scheduling_mode = TASK_SCHEDULING_STATIC;
- /* NOTE: Current value mimics old behavior, but it's not ideal by any
- * means. Would be cool to find a common value which will work good enough
- * for both static and dynamic scheduling.
- */
- settings->min_iter_per_thread = 1;
+ /* Use default heuristic to define actual chunk size. */
+ settings->min_iter_per_thread = 0;
}
#ifdef __cplusplus
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index f43f55a352b..f1811ff6e4f 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -700,7 +700,7 @@ typedef struct BVHDivNodesData {
static void non_recursive_bvh_div_nodes_task_cb(void *__restrict userdata,
const int j,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
BVHDivNodesData *data = userdata;
@@ -841,14 +841,14 @@ static void non_recursive_bvh_div_nodes(const BVHTree *tree,
cb_data.depth = depth;
if (true) {
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD);
BLI_task_parallel_range(i, i_stop, &cb_data, non_recursive_bvh_div_nodes_task_cb, &settings);
}
else {
/* Less hassle for debugging. */
- ParallelRangeTLS tls = {0};
+ TaskParallelTLS tls = {0};
for (int i_task = i; i_task < i_stop; i_task++) {
non_recursive_bvh_div_nodes_task_cb(&cb_data, i_task, &tls);
}
@@ -1195,7 +1195,7 @@ int BLI_bvhtree_overlap_thread_num(const BVHTree *tree)
static void bvhtree_overlap_task_cb(void *__restrict userdata,
const int j,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
BVHOverlapData_Thread *data = &((BVHOverlapData_Thread *)userdata)[j];
BVHOverlapData_Shared *data_shared = data->shared;
@@ -1262,7 +1262,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(
data[j].thread = j;
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (tree1->totleaf > KDOPBVH_THREAD_LEAF_THRESHOLD);
BLI_task_parallel_range(0, thread_num, data, bvhtree_overlap_task_cb, &settings);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 367494537e3..c130c46a0fb 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -2798,6 +2798,46 @@ bool isect_line_line_strict_v3(const float v1[3],
}
}
+/**
+ * Check if two rays are not parallel and returns a factor that indicates
+ * the distance from \a ray_origin_b to the closest point on ray-a to ray-b.
+ *
+ * \note Neither directions need to be normalized.
+ */
+bool isect_ray_ray_v3(const float ray_origin_a[3],
+ const float ray_direction_a[3],
+ const float ray_origin_b[3],
+ const float ray_direction_b[3],
+ float *r_lambda_a,
+ float *r_lambda_b)
+{
+ BLI_assert(r_lambda_a || r_lambda_b);
+ float n[3];
+ cross_v3_v3v3(n, ray_direction_b, ray_direction_a);
+ const float nlen = len_squared_v3(n);
+
+ if (UNLIKELY(nlen == 0.0f)) {
+ /* The lines are parallel. */
+ return false;
+ }
+
+ float t[3], c[3], cray[3];
+ sub_v3_v3v3(t, ray_origin_b, ray_origin_a);
+ sub_v3_v3v3(c, n, t);
+
+ if (r_lambda_a != NULL) {
+ cross_v3_v3v3(cray, c, ray_direction_b);
+ *r_lambda_a = dot_v3v3(cray, n) / nlen;
+ }
+
+ if (r_lambda_b != NULL) {
+ cross_v3_v3v3(cray, c, ray_direction_a);
+ *r_lambda_b = dot_v3v3(cray, n) / nlen;
+ }
+
+ return true;
+}
+
bool isect_aabb_aabb_v3(const float min1[3],
const float max1[3],
const float min2[3],
diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c
index 7c461120520..d4fcb32ce37 100644
--- a/source/blender/blenlib/intern/math_statistics.c
+++ b/source/blender/blenlib/intern/math_statistics.c
@@ -42,7 +42,7 @@ typedef struct CovarianceData {
static void covariance_m_vn_ex_task_cb(void *__restrict userdata,
const int a,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
CovarianceData *data = userdata;
const float *cos_vn = data->cos_vn;
@@ -122,7 +122,7 @@ void BLI_covariance_m_vn_ex(const int n,
.nbr_cos_vn = nbr_cos_vn,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((nbr_cos_vn * n * n) >= 10000);
BLI_task_parallel_range(0, n * n, &data, covariance_m_vn_ex_task_cb, &settings);
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 39af73ac175..4ba198ac0b8 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -297,56 +297,72 @@ bool BLI_is_file(const char *path)
return (mode && !S_ISDIR(mode));
}
-void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
+/**
+ * Use for both text and binary file reading.
+ */
+static void *file_read_data_as_mem_impl(FILE *fp,
+ bool read_size_exact,
+ size_t pad_bytes,
+ size_t *r_size)
{
- FILE *fp = BLI_fopen(filepath, "r");
- void *mem = NULL;
+ struct stat st;
+ if (fstat(fileno(fp), &st) == -1) {
+ return NULL;
+ }
+ if (S_ISDIR(st.st_mode)) {
+ return NULL;
+ }
+ if (fseek(fp, 0L, SEEK_END) == -1) {
+ return NULL;
+ }
+ /* Don't use the 'st_size' because it may be the symlink. */
+ const long int filelen = ftell(fp);
+ if (filelen == -1) {
+ return NULL;
+ }
+ if (fseek(fp, 0L, SEEK_SET) == -1) {
+ return NULL;
+ }
- if (fp) {
- struct stat st;
- if (fstat(fileno(fp), &st) == -1) {
- goto finally;
- }
- if (S_ISDIR(st.st_mode)) {
- goto finally;
- }
- if (fseek(fp, 0L, SEEK_END) == -1) {
- goto finally;
- }
- /* Don't use the 'st_size' because it may be the symlink. */
- const long int filelen = ftell(fp);
- if (filelen == -1) {
- goto finally;
- }
- if (fseek(fp, 0L, SEEK_SET) == -1) {
- goto finally;
- }
+ void *mem = MEM_mallocN(filelen + pad_bytes, __func__);
+ if (mem == NULL) {
+ return NULL;
+ }
- mem = MEM_mallocN(filelen + pad_bytes, __func__);
- if (mem == NULL) {
- goto finally;
- }
+ const long int filelen_read = fread(mem, 1, filelen, fp);
+ if ((filelen_read < 0) || ferror(fp)) {
+ MEM_freeN(mem);
+ return NULL;
+ }
- const long int filelen_read = fread(mem, 1, filelen, fp);
- if ((filelen_read < 0) || ferror(fp)) {
+ if (read_size_exact) {
+ if (filelen_read != filelen) {
MEM_freeN(mem);
- mem = NULL;
- goto finally;
+ return NULL;
}
-
+ }
+ else {
if (filelen_read < filelen) {
mem = MEM_reallocN(mem, filelen_read + pad_bytes);
if (mem == NULL) {
- goto finally;
+ return NULL;
}
}
+ }
- *r_size = filelen_read;
+ *r_size = filelen_read;
+
+ return mem;
+}
- finally:
+void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
+{
+ FILE *fp = BLI_fopen(filepath, "r");
+ void *mem = NULL;
+ if (fp) {
+ mem = file_read_data_as_mem_impl(fp, true, pad_bytes, r_size);
fclose(fp);
}
-
return mem;
}
@@ -354,45 +370,10 @@ void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t
{
FILE *fp = BLI_fopen(filepath, "rb");
void *mem = NULL;
-
if (fp) {
- struct stat st;
- if (fstat(fileno(fp), &st) == -1) {
- goto finally;
- }
- if (S_ISDIR(st.st_mode)) {
- goto finally;
- }
- if (fseek(fp, 0L, SEEK_END) == -1) {
- goto finally;
- }
- /* Don't use the 'st_size' because it may be the symlink. */
- const long int filelen = ftell(fp);
- if (filelen == -1) {
- goto finally;
- }
- if (fseek(fp, 0L, SEEK_SET) == -1) {
- goto finally;
- }
-
- mem = MEM_mallocN(filelen + pad_bytes, __func__);
- if (mem == NULL) {
- goto finally;
- }
-
- const long int filelen_read = fread(mem, 1, filelen, fp);
- if ((filelen_read != filelen) || ferror(fp)) {
- MEM_freeN(mem);
- mem = NULL;
- goto finally;
- }
-
- *r_size = filelen_read;
-
- finally:
+ mem = file_read_data_as_mem_impl(fp, false, pad_bytes, r_size);
fclose(fp);
}
-
return mem;
}
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 85d39f2f98e..bea38a232cc 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -1054,6 +1054,49 @@ typedef struct ParallelRangeState {
int chunk_size;
} ParallelRangeState;
+BLI_INLINE void task_parallel_range_calc_chunk_size(const TaskParallelSettings *settings,
+ const int num_tasks,
+ ParallelRangeState *state)
+{
+ const int tot_items = state->stop - state->start;
+ int chunk_size = 0;
+
+ if (settings->min_iter_per_thread > 0) {
+ /* Already set by user, no need to do anything here. */
+ chunk_size = settings->min_iter_per_thread;
+ }
+ else {
+ /* Basic heuristic to avoid threading on low amount of items. We could make that limit
+ * configurable in settings too... */
+ if (tot_items > 0 && tot_items < 256) {
+ chunk_size = tot_items;
+ }
+ /* NOTE: The idea here is to compensate for rather measurable threading
+ * overhead caused by fetching tasks. With too many CPU threads we are starting
+ * to spend too much time in those overheads. */
+ else if (num_tasks > 32) {
+ chunk_size = 128;
+ }
+ else if (num_tasks > 16) {
+ chunk_size = 64;
+ }
+ else {
+ chunk_size = 32;
+ }
+ }
+
+ BLI_assert(chunk_size > 0);
+
+ switch (settings->scheduling_mode) {
+ case TASK_SCHEDULING_STATIC:
+ state->chunk_size = max_ii(chunk_size, tot_items / (num_tasks));
+ break;
+ case TASK_SCHEDULING_DYNAMIC:
+ state->chunk_size = chunk_size;
+ break;
+ }
+}
+
BLI_INLINE bool parallel_range_next_iter_get(ParallelRangeState *__restrict state,
int *__restrict iter,
int *__restrict count)
@@ -1069,7 +1112,7 @@ BLI_INLINE bool parallel_range_next_iter_get(ParallelRangeState *__restrict stat
static void parallel_range_func(TaskPool *__restrict pool, void *userdata_chunk, int thread_id)
{
ParallelRangeState *__restrict state = BLI_task_pool_userdata(pool);
- ParallelRangeTLS tls = {
+ TaskParallelTLS tls = {
.thread_id = thread_id,
.userdata_chunk = userdata_chunk,
};
@@ -1085,7 +1128,7 @@ static void parallel_range_single_thread(const int start,
int const stop,
void *userdata,
TaskParallelRangeFunc func,
- const ParallelRangeSettings *settings)
+ const TaskParallelSettings *settings)
{
void *userdata_chunk = settings->userdata_chunk;
const size_t userdata_chunk_size = settings->userdata_chunk_size;
@@ -1095,7 +1138,7 @@ static void parallel_range_single_thread(const int start,
userdata_chunk_local = MALLOCA(userdata_chunk_size);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
}
- ParallelRangeTLS tls = {
+ TaskParallelTLS tls = {
.thread_id = 0,
.userdata_chunk = userdata_chunk_local,
};
@@ -1118,7 +1161,7 @@ void BLI_task_parallel_range(const int start,
const int stop,
void *userdata,
TaskParallelRangeFunc func,
- const ParallelRangeSettings *settings)
+ const TaskParallelSettings *settings)
{
TaskScheduler *task_scheduler;
TaskPool *task_pool;
@@ -1162,16 +1205,8 @@ void BLI_task_parallel_range(const int start,
state.userdata = userdata;
state.func = func;
state.iter = start;
- switch (settings->scheduling_mode) {
- case TASK_SCHEDULING_STATIC:
- state.chunk_size = max_ii(settings->min_iter_per_thread, (stop - start) / (num_tasks));
- break;
- case TASK_SCHEDULING_DYNAMIC:
- /* TODO(sergey): Make it configurable from min_iter_per_thread. */
- state.chunk_size = 32;
- break;
- }
+ task_parallel_range_calc_chunk_size(settings, num_tasks, &state);
num_tasks = min_ii(num_tasks, max_ii(1, (stop - start) / state.chunk_size));
if (num_tasks == 1) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 19e9c5142dd..6fe5c4516b5 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6220,6 +6220,7 @@ static void direct_link_collection(FileData *fd, Collection *collection)
collection->preview = direct_link_preview_image(fd, collection->preview);
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
+ collection->tag = 0;
BLI_listbase_clear(&collection->object_cache);
BLI_listbase_clear(&collection->parents);
@@ -7038,6 +7039,7 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
/* init stroke buffer */
gpd->runtime.sbuffer = NULL;
+ gpd->runtime.sbuffer_used = 0;
gpd->runtime.sbuffer_size = 0;
gpd->runtime.tot_cp_points = 0;
@@ -9138,7 +9140,18 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta
id->icon_id = 0;
id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
id->orig_id = NULL;
- id->recalc = 0;
+
+ /* NOTE: It is important to not clear the recalc flags for undo/redo.
+ * Preserving recalc flags on redo/undo is the only way to make dependency graph detect
+ * that animation is to be evaluated on undo/redo. If this is not enforced by the recalc
+ * flags dependency graph does not do animation update to avoid loss of unkeyed changes.,
+ * which conflicts with undo/redo of changes to animation data itself.
+ *
+ * But for regular file load we clear the flag, since the flags might have been changed sinde
+ * the version the file has been saved with. */
+ if (!fd->memfile) {
+ id->recalc = 0;
+ }
/* this case cannot be direct_linked: it's just the ID part */
if (bhead->code == ID_LINK_PLACEHOLDER) {
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 57c674ae1b1..1cbafc7a707 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -36,6 +36,8 @@
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_workspace_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "BKE_appdir.h"
#include "BKE_brush.h"
@@ -358,6 +360,20 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
CURVE_PRESET_BELL,
CURVEMAP_SLOPE_POSITIVE);
}
+
+ /* Correct default startup UV's. */
+ Mesh *me = BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2);
+ if (me && (me->totloop == 24) && (me->mloopuv != NULL)) {
+ const float uv_values[24][2] = {
+ {0.625, 0.50}, {0.875, 0.50}, {0.875, 0.75}, {0.625, 0.75}, {0.375, 0.75}, {0.625, 0.75},
+ {0.625, 1.00}, {0.375, 1.00}, {0.375, 0.00}, {0.625, 0.00}, {0.625, 0.25}, {0.375, 0.25},
+ {0.125, 0.50}, {0.375, 0.50}, {0.375, 0.75}, {0.125, 0.75}, {0.375, 0.50}, {0.625, 0.50},
+ {0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50},
+ };
+ for (int i = 0; i < ARRAY_SIZE(uv_values); i++) {
+ copy_v2_v2(me->mloopuv[i].uv, uv_values[i]);
+ }
+ }
}
/**
diff --git a/source/blender/blentranslation/CMakeLists.txt b/source/blender/blentranslation/CMakeLists.txt
index 34952911dce..70e68ca06d7 100644
--- a/source/blender/blentranslation/CMakeLists.txt
+++ b/source/blender/blentranslation/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
.
../blenkernel
../blenlib
+ ../imbuf
../makesdna
../makesrna
../../../intern/guardedalloc
diff --git a/source/blender/blentranslation/intern/blt_lang.c b/source/blender/blentranslation/intern/blt_lang.c
index 75a4681deb2..82386a17776 100644
--- a/source/blender/blentranslation/intern/blt_lang.c
+++ b/source/blender/blentranslation/intern/blt_lang.c
@@ -42,6 +42,8 @@
#include "BKE_appdir.h"
+#include "IMB_thumbs.h"
+
#include "DNA_userdef_types.h"
#include "MEM_guardedalloc.h"
@@ -288,6 +290,7 @@ void BLT_lang_set(const char *str)
(void)str;
#endif
blt_lang_check_ime_supported();
+ IMB_thumb_clear_translations();
}
/* Get the current locale (short code, e.g. es_ES). */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index c58521297dd..5aa67ad8c78 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -461,7 +461,7 @@ typedef struct BMLoopInterpMultiresData {
static void loop_interp_multires_cb(void *__restrict userdata,
const int ix,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
BMLoopInterpMultiresData *data = userdata;
@@ -561,7 +561,7 @@ void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
.res = res,
.d = 1.0f / (float)(res - 1),
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (res > 5);
BLI_task_parallel_range(0, res, &data, loop_interp_multires_cb, &settings);
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 14b73693b03..64768474765 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -495,13 +495,16 @@ bool BM_face_split_edgenet(BMesh *bm,
return false;
}
+ /* These arrays used to be stack memory, however they can be
+ * large for singe faces with complex edgenets, see: T65980. */
+
/* over-alloc (probably 2-4 is only used in most cases), for the biggest-fan */
- edge_order = BLI_array_alloca(edge_order, edge_order_len);
+ edge_order = MEM_mallocN(sizeof(*edge_order) * edge_order_len, __func__);
/* use later */
- face_verts = BLI_array_alloca(face_verts, edge_net_len + f->len);
+ face_verts = MEM_mallocN(sizeof(*face_verts) * (edge_net_len + f->len), __func__);
- vert_queue = BLI_array_alloca(vert_queue, edge_net_len + f->len);
+ vert_queue = MEM_mallocN(sizeof(vert_queue) * (edge_net_len + f->len), __func__);
STACK_INIT(vert_queue, f->len + edge_net_len);
BLI_assert(BM_ELEM_API_FLAG_TEST(f, FACE_NET) == 0);
@@ -687,6 +690,10 @@ bool BM_face_split_edgenet(BMesh *bm,
}
}
+ MEM_freeN(edge_order);
+ MEM_freeN(face_verts);
+ MEM_freeN(vert_queue);
+
return true;
}
@@ -1247,7 +1254,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm,
*/
const uint edge_arr_len = (uint)edge_net_init_len + (uint)f->len;
- BMEdge **edge_arr = BLI_array_alloca(edge_arr, edge_arr_len);
+ BMEdge **edge_arr = BLI_memarena_alloc(mem_arena, sizeof(*edge_arr) * edge_arr_len);
bool ok = false;
uint edge_net_new_len = (uint)edge_net_init_len;
@@ -1342,7 +1349,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm,
BM_elem_flag_disable(e_iter, EDGE_NOT_IN_STACK);
unique_edges_in_group++;
- BLI_linklist_prepend_alloca(&edge_links, e_iter);
+ BLI_linklist_prepend_arena(&edge_links, e_iter, mem_arena);
BMVert *v_other = BM_edge_other_vert(e_iter, v_iter);
if (BM_elem_flag_test(v_other, VERT_NOT_IN_STACK)) {
@@ -1353,7 +1360,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm,
} while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_iter)) != v_iter->e);
}
- struct EdgeGroupIsland *g = alloca(sizeof(*g));
+ struct EdgeGroupIsland *g = BLI_memarena_alloc(mem_arena, sizeof(*g));
g->vert_len = unique_verts_in_group;
g->edge_len = unique_edges_in_group;
edge_in_group_tot += unique_edges_in_group;
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index cf3d6b8bf56..2eedefe7980 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -807,6 +807,7 @@ void BM_mesh_calc_uvs_grid(BMesh *bm,
const float dx = 1.0f / (float)(x_segments - 1);
const float dy = 1.0f / (float)(y_segments - 1);
+ const float dx_wrap = 1.0 - (dx / 2.0f);
float x = 0.0f;
float y = dy;
@@ -844,7 +845,7 @@ void BM_mesh_calc_uvs_grid(BMesh *bm,
}
x += dx;
- if (x >= 1.0f) {
+ if (x >= dx_wrap) {
x = 0.0f;
y += dy;
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 90df3cd225e..c317d064086 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -3837,7 +3837,7 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
/* Is this a good candidate for using tri_corner_adj_vmesh? */
static int tri_corner_test(BevelParams *bp, BevVert *bv)
{
- float ang, totang, angdiff;
+ float ang, absang, totang, angdiff;
EdgeHalf *e;
int i;
int in_plane_e = 0;
@@ -3852,10 +3852,11 @@ static int tri_corner_test(BevelParams *bp, BevVert *bv)
for (i = 0; i < bv->edgecount; i++) {
e = &bv->edges[i];
ang = BM_edge_calc_face_angle_signed_ex(e->e, 0.0f);
- if (ang <= M_PI_4) {
+ absang = fabsf(ang);
+ if (absang <= M_PI_4) {
in_plane_e++;
}
- else if (ang >= 3.0f * (float)M_PI_4) {
+ else if (absang >= 3.0f * (float)M_PI_4) {
return -1;
}
totang += ang;
@@ -3863,7 +3864,7 @@ static int tri_corner_test(BevelParams *bp, BevVert *bv)
if (in_plane_e != bv->edgecount - 3) {
return -1;
}
- angdiff = fabsf(totang - 3.0f * (float)M_PI_2);
+ angdiff = fabsf(fabsf(totang) - 3.0f * (float)M_PI_2);
if ((bp->pro_super_r == PRO_SQUARE_R && angdiff > (float)M_PI / 16.0f) ||
(angdiff > (float)M_PI_4)) {
return -1;
diff --git a/source/blender/collada/Materials.cpp b/source/blender/collada/Materials.cpp
index e1d5b2e9d5c..3b2c68ef95e 100644
--- a/source/blender/collada/Materials.cpp
+++ b/source/blender/collada/Materials.cpp
@@ -196,7 +196,7 @@ void MaterialNode::set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode,
}
float alpha = transparent_alpha * transparency_alpha;
- if (mode == COLLADASW::EffectProfile::RGB_ZERO) {
+ if (mode == COLLADAFW::EffectCommon::RGB_ZERO) {
alpha = 1 - alpha;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 36c6d246097..4cbdd169980 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -204,7 +204,7 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
/* Re-tag IDs for update if it was tagged before the relations
* update tag. */
for (IDNode *id_node : graph->id_nodes) {
- ID *id = id_node->id_orig;
+ ID *id_orig = id_node->id_orig;
id_node->finalize_build(graph);
int flag = 0;
/* Tag rebuild if special evaluation flags changed. */
@@ -219,10 +219,13 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
flag |= ID_RECALC_COPY_ON_WRITE;
/* This means ID is being added to the dependency graph first
* time, which is similar to "ob-visible-change" */
- if (GS(id->name) == ID_OB) {
+ if (GS(id_orig->name) == ID_OB) {
flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
}
}
+ /* Restore recalc flags from original ID, which could possibly contain recalc flags set by
+ * an operator and then were carried on by the undo system. */
+ flag |= id_orig->recalc;
if (flag != 0) {
graph_id_tag_update(bmain, graph, id_node->id_orig, flag, DEG_UPDATE_SOURCE_RELATIONS);
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index fa6d7bc6028..b06d6e73de0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1557,7 +1557,7 @@ void DepsgraphNodeBuilder::build_movieclip(MovieClip *clip)
add_operation_node(clip_id,
NodeType::PARAMETERS,
OperationCode::MOVIECLIP_EVAL,
- function_bind(BKE_movieclip_eval_update, _1, clip_cow));
+ function_bind(BKE_movieclip_eval_update, _1, bmain_, clip_cow));
add_operation_node(clip_id,
NodeType::BATCH_CACHE,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 5bb3ebf40c4..be494104522 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -279,7 +279,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
}
else if (RNA_struct_is_a(ptr->type, &RNA_Mesh) || RNA_struct_is_a(ptr->type, &RNA_Modifier) ||
RNA_struct_is_a(ptr->type, &RNA_GpencilModifier) ||
- RNA_struct_is_a(ptr->type, &RNA_Spline) || RNA_struct_is_a(ptr->type, &RNA_TextBox)) {
+ RNA_struct_is_a(ptr->type, &RNA_Spline) || RNA_struct_is_a(ptr->type, &RNA_TextBox) ||
+ RNA_struct_is_a(ptr->type, &RNA_GPencilLayer)) {
/* When modifier is used as FROM operation this is likely referencing to
* the property (for example, modifier's influence).
* But when it's used as TO operation, this is geometry component. */
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index d8a9b41206b..6d3aed65a14 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -68,6 +68,7 @@ template<typename T> static void remove_from_vector(vector<T> *vector, const T &
Depsgraph::Depsgraph(Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
: time_source(NULL),
need_update(true),
+ need_update_time(false),
scene(scene),
view_layer(view_layer),
mode(mode),
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index f194a44346b..507d2d9ec08 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -160,6 +160,10 @@ struct Depsgraph {
/* Nodes which have been tagged as "directly modified". */
GSet *entry_tags;
+ /* Special entry tag for time source. Allows to tag invisible dependency graphs for update when
+ * scene frame changes, so then when dependency graph becomes visible it is on a proper state. */
+ bool need_update_time;
+
/* Convenience Data ................... */
/* XXX: should be collected after building (if actually needed?) */
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index 6f3262174b4..f519fe76724 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -61,6 +61,7 @@ void DEG_evaluate_on_refresh(Depsgraph *graph)
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
}
DEG::deg_evaluate_on_refresh(deg_graph);
+ deg_graph->need_update_time = false;
}
/* Frame-change happened for root scene that graph belongs to. */
@@ -79,6 +80,7 @@ void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime)
}
/* Perform recalculation updates. */
DEG::deg_evaluate_on_refresh(deg_graph);
+ deg_graph->need_update_time = false;
}
bool DEG_needs_eval(Depsgraph *graph)
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 583191490d2..59f0c8c1933 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -229,6 +229,12 @@ void depsgraph_tag_to_component_opcode(const ID *id,
case ID_RECALC_PARAMETERS:
*component_type = NodeType::PARAMETERS;
break;
+ case ID_RECALC_SOURCE:
+ *component_type = NodeType::PARAMETERS;
+ break;
+ case ID_RECALC_TIME:
+ BLI_assert(!"Should be handled outside of this function");
+ break;
case ID_RECALC_ALL:
case ID_RECALC_PSYS_ALL:
BLI_assert(!"Should not happen");
@@ -360,6 +366,12 @@ static void graph_id_tag_update_single_flag(Main *bmain,
}
return;
}
+ else if (tag == ID_RECALC_TIME) {
+ if (graph != NULL) {
+ graph->need_update_time = true;
+ }
+ return;
+ }
/* Get description of what is to be tagged. */
NodeType component_type;
OperationCode operation_code;
@@ -438,6 +450,24 @@ const char *update_source_as_string(eUpdateSource source)
return "UNKNOWN";
}
+int deg_recalc_flags_for_legacy_zero()
+{
+ return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE);
+}
+
+int deg_recalc_flags_effective(Depsgraph *graph, int flags)
+{
+ if (graph != NULL) {
+ if (!graph->is_active) {
+ return 0;
+ }
+ }
+ if (flags == 0) {
+ return deg_recalc_flags_for_legacy_zero();
+ }
+ return flags;
+}
+
/* Special tag function which tags all components which needs to be tagged
* for update flag=0.
*
@@ -453,7 +483,7 @@ void deg_graph_node_tag_zero(Main *bmain,
}
ID *id = id_node->id_orig;
/* TODO(sergey): Which recalc flags to set here? */
- id_node->id_cow->recalc |= ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION);
+ id_node->id_cow->recalc |= deg_recalc_flags_for_legacy_zero();
GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) {
if (comp_node->type == NodeType::ANIMATION) {
continue;
@@ -598,6 +628,16 @@ void graph_id_tag_update(
if (id_node != NULL) {
id_node->id_cow->recalc |= flag;
}
+ /* When ID is tagged for update based on an user edits store the recalc flags in the original ID.
+ * This way IDs in the undo steps will have this flag preserved, making it possible to restore
+ * all needed tags when new dependency graph is created on redo.
+ * This is the only way to ensure modifications to animation data (such as keyframes i.e.)
+ * properly triggers animation update for the newely constructed dependency graph on redo (while
+ * usually newly created dependency graph skips animation update to avoid loss of unkeyed
+ * changes). */
+ if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
+ id->recalc |= deg_recalc_flags_effective(graph, flag);
+ }
int current_flag = flag;
while (current_flag != 0) {
IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_i(&current_flag));
@@ -664,6 +704,10 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "AUDIO";
case ID_RECALC_PARAMETERS:
return "PARAMETERS";
+ case ID_RECALC_TIME:
+ return "TIME";
+ case ID_RECALC_SOURCE:
+ return "SOURCE";
case ID_RECALC_ALL:
return "ALL";
}
@@ -768,9 +812,19 @@ void DEG_ids_check_recalc(
DEG::deg_editors_scene_update(&update_ctx, updated);
}
+static void deg_graph_clear_id_recalc_flags(ID *id)
+{
+ id->recalc &= ~ID_RECALC_ALL;
+ bNodeTree *ntree = ntreeFromID(id);
+ /* Clear embedded node trees too. */
+ if (ntree) {
+ ntree->id.recalc &= ~ID_RECALC_ALL;
+ }
+}
+
static void deg_graph_clear_id_node_func(void *__restrict data_v,
const int i,
- const ParallelRangeTLS *__restrict /*tls*/)
+ const TaskParallelTLS *__restrict /*tls*/)
{
/* TODO: we clear original ID recalc flags here, but this may not work
* correctly when there are multiple depsgraph with others still using
@@ -779,12 +833,10 @@ static void deg_graph_clear_id_node_func(void *__restrict data_v,
DEG::IDNode *id_node = deg_graph->id_nodes[i];
id_node->is_user_modified = false;
- id_node->id_cow->recalc &= ~ID_RECALC_ALL;
- /* Clear embedded node trees too. */
- bNodeTree *ntree_cow = ntreeFromID(id_node->id_cow);
- if (ntree_cow) {
- ntree_cow->id.recalc &= ~ID_RECALC_ALL;
+ deg_graph_clear_id_recalc_flags(id_node->id_cow);
+ if (deg_graph->is_active) {
+ deg_graph_clear_id_recalc_flags(id_node->id_orig);
}
}
@@ -798,7 +850,7 @@ void DEG_ids_clear_recalc(Main *UNUSED(bmain), Depsgraph *depsgraph)
}
/* Go over all ID nodes nodes, clearing tags. */
const int num_id_nodes = deg_graph->id_nodes.size();
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
BLI_task_parallel_range(0, num_id_nodes, deg_graph, deg_graph_clear_id_node_func, &settings);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 950deee2b07..b2415c9e89d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -108,7 +108,7 @@ static bool check_operation_node_visible(OperationNode *op_node)
static void calculate_pending_func(void *__restrict data_v,
const int i,
- const ParallelRangeTLS *__restrict /*tls*/)
+ const TaskParallelTLS *__restrict /*tls*/)
{
CalculatePendingData *data = (CalculatePendingData *)data_v;
Depsgraph *graph = data->graph;
@@ -148,7 +148,7 @@ static void calculate_pending_parents(Depsgraph *graph)
const int num_operations = graph->operations.size();
CalculatePendingData data;
data.graph = graph;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
BLI_task_parallel_range(0, num_operations, &data, calculate_pending_func, &settings);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 83fcf4c6ea1..8079a3df879 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -39,6 +39,7 @@
extern "C" {
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DRW_engine.h"
} /* extern "C" */
@@ -53,6 +54,7 @@ extern "C" {
#include "intern/node/deg_node_factory.h"
#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_operation.h"
+#include "intern/node/deg_node_time.h"
#include "intern/eval/deg_eval_copy_on_write.h"
@@ -86,7 +88,7 @@ namespace {
void flush_init_operation_node_func(void *__restrict data_v,
const int i,
- const ParallelRangeTLS *__restrict /*tls*/)
+ const TaskParallelTLS *__restrict /*tls*/)
{
Depsgraph *graph = (Depsgraph *)data_v;
OperationNode *node = graph->operations[i];
@@ -95,7 +97,7 @@ void flush_init_operation_node_func(void *__restrict data_v,
void flush_init_id_node_func(void *__restrict data_v,
const int i,
- const ParallelRangeTLS *__restrict /*tls*/)
+ const TaskParallelTLS *__restrict /*tls*/)
{
Depsgraph *graph = (Depsgraph *)data_v;
IDNode *id_node = graph->id_nodes[i];
@@ -109,14 +111,14 @@ BLI_INLINE void flush_prepare(Depsgraph *graph)
{
{
const int num_operations = graph->operations.size();
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
BLI_task_parallel_range(0, num_operations, graph, flush_init_operation_node_func, &settings);
}
{
const int num_id_nodes = graph->id_nodes.size();
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
BLI_task_parallel_range(0, num_id_nodes, graph, flush_init_id_node_func, &settings);
@@ -348,9 +350,16 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
BLI_assert(bmain != NULL);
BLI_assert(graph != NULL);
/* Nothing to update, early out. */
- if (BLI_gset_len(graph->entry_tags) == 0) {
+ if (BLI_gset_len(graph->entry_tags) == 0 && !graph->need_update_time) {
return;
}
+ if (graph->need_update_time) {
+ const Scene *scene_orig = graph->scene;
+ const float ctime = scene_orig->r.cfra + scene_orig->r.subframe;
+ DEG::TimeSourceNode *time_source = graph->find_time_source();
+ graph->ctime = ctime;
+ time_source->tag_update(graph, DEG::DEG_UPDATE_SOURCE_TIME);
+ }
/* Reset all flags, get ready for the flush. */
flush_prepare(graph);
/* Starting from the tagged "entry" nodes, flush outwards. */
@@ -387,7 +396,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
static void graph_clear_operation_func(void *__restrict data_v,
const int i,
- const ParallelRangeTLS *__restrict /*tls*/)
+ const TaskParallelTLS *__restrict /*tls*/)
{
Depsgraph *graph = (Depsgraph *)data_v;
OperationNode *node = graph->operations[i];
@@ -402,7 +411,7 @@ void deg_graph_clear_tags(Depsgraph *graph)
/* Go over all operation nodes, clearing tags. */
{
const int num_operations = graph->operations.size();
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
BLI_task_parallel_range(0, num_operations, graph, graph_clear_operation_func, &settings);
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 8631a9f556b..664484d9a57 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -126,6 +126,7 @@ set(SRC
engines/gpencil/gpencil_engine.h
engines/gpencil/gpencil_render.c
engines/gpencil/gpencil_shader_fx.c
+ engines/select/select_engine.c
DRW_engine.h
intern/DRW_render.h
@@ -150,6 +151,7 @@ set(SRC
engines/external/external_engine.h
engines/workbench/workbench_engine.h
engines/workbench/workbench_private.h
+ engines/select/select_engine.h
)
set(LIB
@@ -363,6 +365,9 @@ data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl SRC)
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC)
+data_to_c_simple(engines/select/shaders/selection_id_3D_vert.glsl SRC)
+data_to_c_simple(engines/select/shaders/selection_id_frag.glsl SRC)
+
list(APPEND INC
)
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index b4a7d3b84fc..a51c3a04239 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -26,6 +26,7 @@
#include "BLI_sys_types.h" /* for bool */
struct ARegion;
+struct Base;
struct DRWInstanceDataList;
struct DRWPass;
struct Depsgraph;
@@ -128,7 +129,8 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
struct ARegion *ar,
struct View3D *v3d,
- struct GPUViewport *viewport);
+ struct GPUViewport *viewport,
+ bool use_opengl_context);
void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
struct ARegion *ar,
struct View3D *v3d,
@@ -136,19 +138,12 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
void DRW_draw_depth_object(struct ARegion *ar,
struct GPUViewport *viewport,
struct Object *object);
-void DRW_draw_select_id_object(struct Scene *scene,
- struct RegionView3D *rv3d,
- struct Object *ob,
- short select_mode,
- bool draw_facedot,
- uint initial_offset,
- uint *r_vert_offset,
- uint *r_edge_offset,
- uint *r_face_offset);
-
-void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
-void DRW_framebuffer_select_id_release(struct ARegion *ar);
-void DRW_framebuffer_select_id_read(const struct rcti *rect, uint *r_buf);
+void DRW_draw_select_id(struct Depsgraph *depsgraph,
+ struct ARegion *ar,
+ struct View3D *v3d,
+ struct Base **bases,
+ const uint bases_len,
+ short select_mode);
/* grease pencil render */
bool DRW_render_check_grease_pencil(struct Depsgraph *depsgraph);
@@ -186,4 +181,20 @@ void DRW_deferred_shader_remove(struct GPUMaterial *mat);
struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id);
void DRW_drawdata_free(struct ID *id);
+/* select_engine.c */
+void DRW_select_context_create(struct Depsgraph *depsgraph,
+ struct Base **bases,
+ const uint bases_len,
+ short select_mode);
+bool DRW_select_elem_get(const uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type);
+uint DRW_select_context_offset_for_object_elem(const uint base_index, char elem_type);
+uint DRW_select_context_elem_len(void);
+void DRW_framebuffer_select_id_read(const struct rcti *rect, uint *r_buf);
+void DRW_draw_select_id_object(struct Depsgraph *depsgraph,
+ struct ViewLayer *view_layer,
+ struct ARegion *ar,
+ struct View3D *v3d,
+ struct Object *ob,
+ short select_mode);
+
#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 3977fd160fc..c82a112b343 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -266,7 +266,8 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
(irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
int mip_len = (int)(floorf(log2f(cube_res)) - MIN_CUBE_LOD_LEVEL);
if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
- (cube_len == light_cache->cube_tx.tex_size[2]) && (mip_len == light_cache->mips_len)) {
+ (cube_len == light_cache->cube_tx.tex_size[2]) && (cube_len == light_cache->cube_len) &&
+ (mip_len == light_cache->mips_len)) {
return true;
}
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 18950f00823..d5f8d062593 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -375,7 +375,7 @@ GPUBatch *gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
Object *ob = draw_ctx->obact;
tGPspoint *points = gpd->runtime.sbuffer;
- int totpoints = gpd->runtime.sbuffer_size;
+ int totpoints = gpd->runtime.sbuffer_used;
/* if cyclic needs more vertex */
int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0;
int totvertex = totpoints + cyclic_add + 2;
@@ -477,7 +477,7 @@ GPUBatch *gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
Object *ob = draw_ctx->obact;
tGPspoint *points = gpd->runtime.sbuffer;
- int totpoints = gpd->runtime.sbuffer_size;
+ int totpoints = gpd->runtime.sbuffer_used;
static GPUVertFormat format = {0};
static uint pos_id, color_id, thickness_id, uvdata_id, prev_pos_id;
@@ -621,7 +621,7 @@ GPUBatch *gpencil_get_buffer_fill_geom(bGPdata *gpd)
}
const tGPspoint *points = gpd->runtime.sbuffer;
- int totpoints = gpd->runtime.sbuffer_size;
+ int totpoints = gpd->runtime.sbuffer_used;
if (totpoints < 3) {
return NULL;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 181d2efbabb..9b755217946 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -1493,7 +1493,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke buffer is currently stored in gp-data)
*/
- if (gpd->runtime.sbuffer_size > 0) {
+ if (gpd->runtime.sbuffer_used > 0) {
if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* It should also be noted that sbuffer contains temporary point types
* i.e. tGPspoints NOT bGPDspoints
@@ -1506,7 +1506,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
stl->storage->alignment_mode = (gp_style) ? gp_style->alignment_mode : GP_STYLE_FOLLOW_PATH;
/* if only one point, don't need to draw buffer because the user has no time to see it */
- if (gpd->runtime.sbuffer_size > 1) {
+ if (gpd->runtime.sbuffer_used > 1) {
if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
stl->g_data->shgrps_drawing_stroke = gpencil_shgroup_stroke_create(
vedata,
@@ -1562,7 +1562,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
DRW_shgroup_call(
stl->g_data->shgrps_drawing_stroke, stl->g_data->batch_buffer_stroke, NULL);
- if ((gpd->runtime.sbuffer_size >= 3) &&
+ if ((gpd->runtime.sbuffer_used >= 3) &&
(gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 5d7ec490fb6..16162645f3d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -430,7 +430,7 @@ void GPENCIL_cache_init(void *vedata)
/* need the original to avoid cow overhead while drawing */
bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id);
if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
- (gpd_orig->runtime.sbuffer_size > 0) &&
+ (gpd_orig->runtime.sbuffer_used > 0) &&
((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0) && !DRW_state_is_depth() &&
(stl->storage->background_ready == true)) {
stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index 306444303e2..0f4043ce278 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -463,12 +463,11 @@ static void gpencil_fx_shadow(ShaderFxData *fx,
DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
}
- const int nowave = -1;
if (fxd->flag & FX_SHADOW_USE_WAVE) {
DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
}
else {
- DRW_shgroup_uniform_int(fx_shgrp, "orientation", &nowave, 1);
+ DRW_shgroup_uniform_int_copy(fx_shgrp, "orientation", -1);
}
DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
index b226d4f93bc..01d4fe40195 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
@@ -42,7 +42,11 @@ void main()
vec2 tc = uv - center;
float dist = length(tc);
- float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) :
+ float locpixsize = abs((loc.z * defaultpixsize));
+ if (locpixsize == 0) {
+ locpixsize = 1;
+ }
+ float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / locpixsize) :
(radius / defaultpixsize);
pxradius = max(pxradius, 1);
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
new file mode 100644
index 00000000000..260fe8793e6
--- /dev/null
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -0,0 +1,641 @@
+/*
+ * 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.
+ *
+ * Copyright 2019, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ *
+ * Engine for drawing a selection map where the pixels indicate the selection indices.
+ */
+
+#include "BLI_rect.h"
+
+#include "BKE_editmesh.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_screen_types.h"
+
+#include "ED_view3d.h"
+
+#include "GPU_shader.h"
+#include "GPU_select.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "UI_resources.h"
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "draw_cache_impl.h"
+
+#include "select_engine.h"
+/* Shaders */
+
+#define SELECT_ENGINE "SELECT_ENGINE"
+
+/* *********** LISTS *********** */
+
+/* GPUViewport.storage
+ * Is freed everytime the viewport engine changes */
+typedef struct SELECTID_StorageList {
+ struct SELECTID_PrivateData *g_data;
+} SELECTID_StorageList;
+
+typedef struct SELECTID_PassList {
+ struct DRWPass *select_id_face_pass;
+ struct DRWPass *select_id_edge_pass;
+ struct DRWPass *select_id_vert_pass;
+} SELECTID_PassList;
+
+typedef struct SELECTID_Data {
+ void *engine_type;
+ DRWViewportEmptyList *fbl;
+ DRWViewportEmptyList *txl;
+ SELECTID_PassList *psl;
+ SELECTID_StorageList *stl;
+} SELECTID_Data;
+
+typedef struct SELECTID_Shaders {
+ /* Depth Pre Pass */
+ struct GPUShader *select_id_flat;
+ struct GPUShader *select_id_uniform;
+} SELECTID_Shaders;
+
+/* *********** STATIC *********** */
+
+static struct {
+ SELECTID_Shaders sh_data[GPU_SHADER_CFG_LEN];
+
+ struct GPUFrameBuffer *framebuffer_select_id;
+ struct GPUTexture *texture_u32;
+
+ struct {
+ struct BaseOffset *base_array_index_offsets;
+ uint bases_len;
+ uint last_base_drawn;
+ /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */
+ uint last_index_drawn;
+
+ struct Depsgraph *depsgraph;
+ short select_mode;
+ } context;
+} e_data = {{{NULL}}}; /* Engine data */
+
+typedef struct SELECTID_PrivateData {
+ DRWShadingGroup *shgrp_face_unif;
+ DRWShadingGroup *shgrp_face_flat;
+ DRWShadingGroup *shgrp_edge;
+ DRWShadingGroup *shgrp_vert;
+
+ DRWView *view_faces;
+ DRWView *view_edges;
+ DRWView *view_verts;
+} SELECTID_PrivateData; /* Transient data */
+
+struct BaseOffset {
+ /* For convenience only. */
+ union {
+ uint offset;
+ uint face_start;
+ };
+ union {
+ uint face;
+ uint edge_start;
+ };
+ union {
+ uint edge;
+ uint vert_start;
+ };
+ uint vert;
+};
+
+/* Shaders */
+extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_selection_id_3D_vert_glsl[];
+extern char datatoc_selection_id_frag_glsl[];
+
+/* -------------------------------------------------------------------- */
+/** \name Selection Utilities
+ * \{ */
+
+static void draw_select_framebuffer_select_id_setup(void)
+{
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ int size[2];
+ size[0] = GPU_texture_width(dtxl->depth);
+ size[1] = GPU_texture_height(dtxl->depth);
+
+ if (e_data.framebuffer_select_id == NULL) {
+ e_data.framebuffer_select_id = GPU_framebuffer_create();
+ }
+
+ if ((e_data.texture_u32 != NULL) && ((GPU_texture_width(e_data.texture_u32) != size[0]) ||
+ (GPU_texture_height(e_data.texture_u32) != size[1]))) {
+
+ GPU_texture_free(e_data.texture_u32);
+ e_data.texture_u32 = NULL;
+ }
+
+ if (e_data.texture_u32 == NULL) {
+ e_data.texture_u32 = GPU_texture_create_2d(size[0], size[1], GPU_R32UI, NULL, NULL);
+
+ GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, dtxl->depth, 0, 0);
+ GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, e_data.texture_u32, 0, 0);
+ GPU_framebuffer_check_valid(e_data.framebuffer_select_id, NULL);
+ }
+}
+
+static void draw_select_id_object(void *vedata,
+ Object *ob,
+ short select_mode,
+ bool draw_facedot,
+ uint initial_offset,
+ uint *r_vert_offset,
+ uint *r_edge_offset,
+ uint *r_face_offset)
+{
+ SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
+
+ BLI_assert(initial_offset > 0);
+
+ switch (ob->type) {
+ case OB_MESH:
+ if (ob->mode & OB_MODE_EDIT) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_mesh;
+ const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
+
+ DRW_mesh_batch_cache_validate(me);
+
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
+
+ struct GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
+ geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ if (select_mode & SCE_SELECT_EDGE) {
+ geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
+ }
+ if (select_mode & SCE_SELECT_VERTEX) {
+ geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ }
+ if (use_faceselect && draw_facedot) {
+ geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
+ }
+
+ DRWShadingGroup *face_shgrp;
+ if (use_faceselect) {
+ face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat);
+ DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset);
+
+ if (draw_facedot) {
+ DRW_shgroup_call(face_shgrp, geom_facedots, ob);
+ }
+ *r_face_offset = initial_offset + em->bm->totface;
+ }
+ else {
+ face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_unif);
+ DRW_shgroup_uniform_int_copy(face_shgrp, "id", 0);
+
+ *r_face_offset = initial_offset;
+ }
+ DRW_shgroup_call(face_shgrp, geom_faces, ob);
+
+ /* Unlike faces, only draw edges if edge select mode. */
+ if (select_mode & SCE_SELECT_EDGE) {
+ DRWShadingGroup *edge_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_edge);
+ DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset);
+ DRW_shgroup_call(edge_shgrp, geom_edges, ob);
+ *r_edge_offset = *r_face_offset + em->bm->totedge;
+ }
+ else {
+ /* Note that `r_vert_offset` is calculated from `r_edge_offset`.
+ * Otherwise the first vertex is never selected, see: T53512. */
+ *r_edge_offset = *r_face_offset;
+ }
+
+ /* Unlike faces, only verts if vert select mode. */
+ if (select_mode & SCE_SELECT_VERTEX) {
+ DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert);
+ DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)r_edge_offset);
+ DRW_shgroup_call(vert_shgrp, geom_verts, ob);
+ *r_vert_offset = *r_edge_offset + em->bm->totvert;
+ }
+ else {
+ *r_vert_offset = *r_edge_offset;
+ }
+ }
+ else {
+ Mesh *me_orig = DEG_get_original_object(ob)->data;
+ Mesh *me_eval = ob->data;
+
+ struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval);
+ if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) &&
+ /* Currently vertex select supports weight paint and vertex paint. */
+ ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
+
+ struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval);
+
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ DRWShadingGroup *face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_unif);
+ DRW_shgroup_uniform_int_copy(face_shgrp, "id", 0);
+ DRW_shgroup_call(face_shgrp, geom_faces, ob);
+
+ DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert);
+ DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", 1);
+ DRW_shgroup_call(vert_shgrp, geom_verts, ob);
+
+ *r_face_offset = *r_edge_offset = initial_offset;
+ *r_vert_offset = me_eval->totvert + 1;
+ }
+ else {
+ DRWShadingGroup *face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat);
+ DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset);
+ DRW_shgroup_call(face_shgrp, geom_faces, ob);
+
+ *r_face_offset = initial_offset + me_eval->totpoly;
+ *r_edge_offset = *r_vert_offset = *r_face_offset;
+ }
+ }
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ }
+}
+
+static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt)
+{
+ if (select_mode & SCE_SELECT_FACE) {
+ if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) {
+ return true;
+ }
+ if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) {
+ return true;
+ }
+ if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
+ /* Since we can't deduce face selection when edges aren't visible - show dots. */
+ return true;
+ }
+ }
+ return false;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Engine Functions
+ * \{ */
+
+static void select_engine_init(void *vedata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg;
+
+ SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
+ SELECTID_Shaders *sh_data = &e_data.sh_data[sh_cfg];
+
+ /* Prepass */
+ if (!sh_data->select_id_flat) {
+ const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
+ sh_data->select_id_flat = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_selection_id_3D_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_selection_id_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, NULL},
+ });
+ }
+ if (!sh_data->select_id_uniform) {
+ const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
+ sh_data->select_id_uniform = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_selection_id_3D_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_selection_id_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, "#define UNIFORM_ID\n", NULL},
+ });
+ }
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+
+ {
+ /* Create view with depth offset */
+ stl->g_data->view_faces = (DRWView *)DRW_view_default_get();
+ stl->g_data->view_edges = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.0f);
+ stl->g_data->view_verts = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.1f);
+ }
+}
+
+static void select_cache_init(void *vedata)
+{
+ SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl;
+ SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SELECTID_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ {
+ psl->select_id_face_pass = DRW_pass_create("Face Pass", DRW_STATE_DEFAULT);
+ stl->g_data->shgrp_face_unif = DRW_shgroup_create(sh_data->select_id_uniform,
+ psl->select_id_face_pass);
+
+ stl->g_data->shgrp_face_flat = DRW_shgroup_create(sh_data->select_id_flat,
+ psl->select_id_face_pass);
+
+ psl->select_id_edge_pass = DRW_pass_create(
+ "Edge Pass", DRW_STATE_DEFAULT | DRW_STATE_FIRST_VERTEX_CONVENTION);
+
+ stl->g_data->shgrp_edge = DRW_shgroup_create(sh_data->select_id_flat,
+ psl->select_id_edge_pass);
+
+ psl->select_id_vert_pass = DRW_pass_create("Vert Pass", DRW_STATE_DEFAULT);
+ stl->g_data->shgrp_vert = DRW_shgroup_create(sh_data->select_id_flat,
+ psl->select_id_vert_pass);
+
+ DRW_shgroup_uniform_float_copy(stl->g_data->shgrp_vert, "sizeVertex", G_draw.block.sizeVertex);
+
+ if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
+ DRW_shgroup_state_enable(stl->g_data->shgrp_face_unif, DRW_STATE_CLIP_PLANES);
+ DRW_shgroup_state_enable(stl->g_data->shgrp_face_flat, DRW_STATE_CLIP_PLANES);
+ DRW_shgroup_state_enable(stl->g_data->shgrp_edge, DRW_STATE_CLIP_PLANES);
+ DRW_shgroup_state_enable(stl->g_data->shgrp_vert, DRW_STATE_CLIP_PLANES);
+ }
+ }
+
+ e_data.context.last_base_drawn = 0;
+ e_data.context.last_index_drawn = 1;
+}
+
+static void select_cache_populate(void *vedata, Object *ob)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ short select_mode = e_data.context.select_mode;
+
+ if (select_mode == -1) {
+ ToolSettings *ts = draw_ctx->scene->toolsettings;
+ select_mode = ts->selectmode;
+ }
+
+ bool draw_facedot = check_ob_drawface_dot(select_mode, draw_ctx->v3d, ob->dt);
+
+ struct BaseOffset *base_ofs =
+ &e_data.context.base_array_index_offsets[e_data.context.last_base_drawn++];
+
+ uint offset = e_data.context.last_index_drawn;
+
+ draw_select_id_object(vedata,
+ ob,
+ select_mode,
+ draw_facedot,
+ offset,
+ &base_ofs->vert,
+ &base_ofs->edge,
+ &base_ofs->face);
+
+ base_ofs->offset = offset;
+ e_data.context.last_index_drawn = base_ofs->vert;
+}
+
+static void select_draw_scene(void *vedata)
+{
+ SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
+ SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl;
+
+ /* Setup framebuffer */
+ draw_select_framebuffer_select_id_setup();
+ GPU_framebuffer_bind(e_data.framebuffer_select_id);
+
+ /* dithering and AA break color coding, so disable */
+ glDisable(GL_DITHER);
+
+ GPU_framebuffer_clear_color_depth(e_data.framebuffer_select_id, (const float[4]){0.0f}, 1.0f);
+
+ DRW_view_set_active(stl->g_data->view_faces);
+ DRW_draw_pass(psl->select_id_face_pass);
+
+ DRW_view_set_active(stl->g_data->view_edges);
+ DRW_draw_pass(psl->select_id_edge_pass);
+
+ DRW_view_set_active(stl->g_data->view_verts);
+ DRW_draw_pass(psl->select_id_vert_pass);
+}
+
+static void select_engine_free(void)
+{
+ for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
+ SELECTID_Shaders *sh_data = &e_data.sh_data[sh_data_index];
+ DRW_SHADER_FREE_SAFE(sh_data->select_id_flat);
+ DRW_SHADER_FREE_SAFE(sh_data->select_id_uniform);
+ }
+
+ DRW_TEXTURE_FREE_SAFE(e_data.texture_u32);
+ GPU_FRAMEBUFFER_FREE_SAFE(e_data.framebuffer_select_id);
+ MEM_SAFE_FREE(e_data.context.base_array_index_offsets);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exposed `DRW_engine.h` functions
+ * \{ */
+
+bool DRW_select_elem_get(const uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type)
+{
+ char elem_type = 0;
+ uint elem_id;
+ uint base_index = 0;
+
+ for (; base_index < e_data.context.bases_len; base_index++) {
+ struct BaseOffset *base_ofs = &e_data.context.base_array_index_offsets[base_index];
+
+ if (base_ofs->face > sel_id) {
+ elem_id = sel_id - base_ofs->face_start;
+ elem_type = SCE_SELECT_FACE;
+ break;
+ }
+ if (base_ofs->edge > sel_id) {
+ elem_id = sel_id - base_ofs->edge_start;
+ elem_type = SCE_SELECT_EDGE;
+ break;
+ }
+ if (base_ofs->vert > sel_id) {
+ elem_id = sel_id - base_ofs->vert_start;
+ elem_type = SCE_SELECT_VERTEX;
+ break;
+ }
+ }
+
+ if (base_index == e_data.context.bases_len) {
+ return false;
+ }
+
+ *r_elem = elem_id;
+
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+
+ if (r_elem_type) {
+ *r_elem_type = elem_type;
+ }
+
+ return true;
+}
+
+uint DRW_select_context_offset_for_object_elem(const uint base_index, char elem_type)
+{
+ struct BaseOffset *base_ofs = &e_data.context.base_array_index_offsets[base_index];
+
+ if (elem_type == SCE_SELECT_VERTEX) {
+ return base_ofs->vert_start - 1;
+ }
+ if (elem_type == SCE_SELECT_EDGE) {
+ return base_ofs->edge_start - 1;
+ }
+ if (elem_type == SCE_SELECT_FACE) {
+ return base_ofs->face_start - 1;
+ }
+ BLI_assert(0);
+ return 0;
+}
+
+uint DRW_select_context_elem_len(void)
+{
+ return e_data.context.last_index_drawn;
+}
+
+/* Read a block of pixels from the select frame buffer. */
+void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf)
+{
+ /* clamp rect by texture */
+ rcti r = {
+ .xmin = 0,
+ .xmax = GPU_texture_width(e_data.texture_u32),
+ .ymin = 0,
+ .ymax = GPU_texture_height(e_data.texture_u32),
+ };
+
+ rcti rect_clamp = *rect;
+ if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) {
+ DRW_opengl_context_enable();
+ GPU_framebuffer_bind(e_data.framebuffer_select_id);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glReadPixels(rect_clamp.xmin,
+ rect_clamp.ymin,
+ BLI_rcti_size_x(&rect_clamp),
+ BLI_rcti_size_y(&rect_clamp),
+ GL_RED_INTEGER,
+ GL_UNSIGNED_INT,
+ r_buf);
+
+ GPU_framebuffer_restore();
+ DRW_opengl_context_disable();
+
+ if (!BLI_rcti_compare(rect, &rect_clamp)) {
+ GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf);
+ }
+ }
+ else {
+ size_t buf_size = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect) * sizeof(*r_buf);
+
+ memset(r_buf, 0, buf_size);
+ }
+}
+
+void DRW_select_context_create(Depsgraph *depsgraph,
+ Base **UNUSED(bases),
+ const uint bases_len,
+ short select_mode)
+{
+ e_data.context.depsgraph = depsgraph;
+ e_data.context.select_mode = select_mode;
+ e_data.context.bases_len = bases_len;
+
+ MEM_SAFE_FREE(e_data.context.base_array_index_offsets);
+ e_data.context.base_array_index_offsets = MEM_mallocN(
+ sizeof(*e_data.context.base_array_index_offsets) * bases_len, __func__);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Legacy
+ * \{ */
+
+void DRW_draw_select_id_object(Depsgraph *depsgraph,
+ ViewLayer *view_layer,
+ ARegion *ar,
+ View3D *v3d,
+ Object *ob,
+ short select_mode)
+{
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ DRW_draw_select_id(depsgraph, ar, v3d, &base, 1, select_mode);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Engine Type
+ * \{ */
+
+static const DrawEngineDataSize select_data_size = DRW_VIEWPORT_DATA_SIZE(SELECTID_Data);
+
+DrawEngineType draw_engine_select_type = {
+ NULL,
+ NULL,
+ N_("Select ID"),
+ &select_data_size,
+ &select_engine_init,
+ &select_engine_free,
+ &select_cache_init,
+ &select_cache_populate,
+ NULL,
+ NULL,
+ &select_draw_scene,
+ NULL,
+ NULL,
+ NULL,
+};
+
+/* Note: currently unused, we may want to register so we can see this when debugging the view. */
+
+RenderEngineType DRW_engine_viewport_select_type = {
+ NULL,
+ NULL,
+ SELECT_ENGINE,
+ N_("Select ID"),
+ RE_INTERNAL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &draw_engine_select_type,
+ {NULL, NULL, NULL},
+};
+
+/** \} */
+
+#undef SELECT_ENGINE
diff --git a/source/blender/draw/engines/select/select_engine.h b/source/blender/draw/engines/select/select_engine.h
new file mode 100644
index 00000000000..5b900ccaf27
--- /dev/null
+++ b/source/blender/draw/engines/select/select_engine.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ * Copyright 2019, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#ifndef __SELECT_ENGINE_H__
+#define __SELECT_ENGINE_H__
+
+extern DrawEngineType draw_engine_select_type;
+extern RenderEngineType DRW_engine_viewport_select_type;
+
+#endif /* __SELECT_ID_ENGINE_H__ */
diff --git a/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl b/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl
new file mode 100644
index 00000000000..9b0107cffdb
--- /dev/null
+++ b/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl
@@ -0,0 +1,26 @@
+
+uniform float sizeVertex;
+
+in vec3 pos;
+
+#ifndef UNIFORM_ID
+uniform int offset;
+in uint color;
+
+flat out uint id;
+#endif
+
+void main()
+{
+#ifndef UNIFORM_ID
+ id = floatBitsToUint(intBitsToFloat(offset)) + color;
+#endif
+
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+ gl_PointSize = sizeVertex;
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(world_pos);
+#endif
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl b/source/blender/draw/engines/select/shaders/selection_id_frag.glsl
index 1f22b9cb0b4..ea86ddc7301 100644
--- a/source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl
+++ b/source/blender/draw/engines/select/shaders/selection_id_frag.glsl
@@ -1,6 +1,7 @@
#ifdef UNIFORM_ID
-uniform uint id;
+uniform int id;
+# define id floatBitsToUint(intBitsToFloat(id))
#else
flat in uint id;
#endif
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 306031809d1..2376787a273 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -4830,7 +4830,7 @@ static void uvedit_fill_buffer_data(MeshRenderData *rdata,
/* Tag hidden faces */
BM_elem_flag_set(efa, BM_ELEM_TAG, uvedit_face_visible_nolocal_ex(rdata->toolsettings, efa));
- if (vbo_area && BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ if (vbo_area) {
edit_uv_preprocess_stretch_area(
efa, cd_loop_uv_offset, fidx++, &totarea, &totuvarea, faces_areas);
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 1abe68b622d..f8640f17419 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -89,6 +89,7 @@
#include "engines/workbench/workbench_engine.h"
#include "engines/external/external_engine.h"
#include "engines/gpencil/gpencil_engine.h"
+#include "engines/select/select_engine.h"
#include "GPU_context.h"
@@ -2136,16 +2137,13 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
static struct DRWSelectBuffer {
struct GPUFrameBuffer *framebuffer_depth_only;
- struct GPUFrameBuffer *framebuffer_select_id;
struct GPUTexture *texture_depth;
- struct GPUTexture *texture_u32;
} g_select_buffer = {NULL};
static void draw_select_framebuffer_depth_only_setup(const int size[2])
{
if (g_select_buffer.framebuffer_depth_only == NULL) {
g_select_buffer.framebuffer_depth_only = GPU_framebuffer_create();
- g_select_buffer.framebuffer_select_id = GPU_framebuffer_create();
}
if ((g_select_buffer.texture_depth != NULL) &&
@@ -2162,32 +2160,7 @@ static void draw_select_framebuffer_depth_only_setup(const int size[2])
GPU_framebuffer_texture_attach(
g_select_buffer.framebuffer_depth_only, g_select_buffer.texture_depth, 0, 0);
- GPU_framebuffer_texture_attach(
- g_select_buffer.framebuffer_select_id, g_select_buffer.texture_depth, 0, 0);
-
GPU_framebuffer_check_valid(g_select_buffer.framebuffer_depth_only, NULL);
- GPU_framebuffer_check_valid(g_select_buffer.framebuffer_select_id, NULL);
- }
-}
-
-static void draw_select_framebuffer_select_id_setup(const int size[2])
-{
- draw_select_framebuffer_depth_only_setup(size);
-
- if ((g_select_buffer.texture_u32 != NULL) &&
- ((GPU_texture_width(g_select_buffer.texture_u32) != size[0]) ||
- (GPU_texture_height(g_select_buffer.texture_u32) != size[1]))) {
- GPU_texture_free(g_select_buffer.texture_u32);
- g_select_buffer.texture_u32 = NULL;
- }
-
- if (g_select_buffer.texture_u32 == NULL) {
- g_select_buffer.texture_u32 = GPU_texture_create_2d(size[0], size[1], GPU_R32UI, NULL, NULL);
-
- GPU_framebuffer_texture_attach(
- g_select_buffer.framebuffer_select_id, g_select_buffer.texture_u32, 0, 0);
-
- GPU_framebuffer_check_valid(g_select_buffer.framebuffer_select_id, NULL);
}
}
@@ -2479,14 +2452,17 @@ static void drw_draw_depth_loop_imp(void)
void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
ARegion *ar,
View3D *v3d,
- GPUViewport *viewport)
+ GPUViewport *viewport,
+ bool use_opengl_context)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
- DRW_opengl_context_enable();
+ if (use_opengl_context) {
+ DRW_opengl_context_enable();
+ }
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -2525,7 +2501,9 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
#endif
/* Changin context */
- DRW_opengl_context_disable();
+ if (use_opengl_context) {
+ DRW_opengl_context_disable();
+ }
}
/**
@@ -2575,6 +2553,78 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
DRW_opengl_context_disable();
}
+void DRW_draw_select_id(Depsgraph *depsgraph,
+ ARegion *ar,
+ View3D *v3d,
+ Base **bases,
+ const uint bases_len,
+ short select_mode)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+
+ DRW_select_context_create(depsgraph, bases, bases_len, select_mode);
+
+ DRW_opengl_context_enable();
+
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
+ DST.buffer_finish_called = true;
+
+ /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
+ DST.draw_ctx = (DRWContextState){
+ .ar = ar,
+ .rv3d = ar->regiondata,
+ .v3d = v3d,
+ .scene = scene,
+ .view_layer = view_layer,
+ .obact = OBACT(view_layer),
+ .depsgraph = depsgraph,
+ };
+
+ use_drw_engine(&draw_engine_select_type);
+ drw_context_state_init();
+
+ /* Setup viewport */
+ DST.viewport = WM_draw_region_get_viewport(ar, 0);
+ drw_viewport_var_init();
+
+ /* Update ubos */
+ DRW_globals_update();
+
+ /* Init engines */
+ drw_engines_init();
+
+ {
+ drw_engines_cache_init();
+
+ /* Keep `base_index` in sync with `e_data.context.last_base_drawn`.
+ * So don't skip objects. */
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Object *obj_eval = DEG_get_evaluated_object(depsgraph, bases[base_index]->object);
+ drw_engines_cache_populate(obj_eval);
+ }
+
+ drw_engines_cache_finish();
+ }
+
+ /* Start Drawing */
+ DRW_state_reset();
+ drw_engines_draw_scene();
+ DRW_state_reset();
+
+ drw_engines_disable();
+
+#ifdef DEBUG
+ /* Avoid accidental reuse. */
+ drw_state_ensure_not_reused(&DST);
+#endif
+
+ /* Changin context */
+ GPU_framebuffer_restore();
+ DRW_opengl_context_disable();
+}
+
/** See #DRW_shgroup_world_clip_planes_from_rv3d. */
static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
{
@@ -2646,294 +2696,6 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
DRW_opengl_context_disable();
}
-static void draw_mesh_verts(GPUBatch *batch, uint offset, const float world_clip_planes[6][4])
-{
- GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-}
-
-static void draw_mesh_edges(GPUBatch *batch, uint offset, const float world_clip_planes[6][4])
-{
- GPU_line_width(1.0f);
- glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
-
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-
- glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
-}
-
-/* two options, facecolors or black */
-static void draw_mesh_face(GPUBatch *batch,
- uint offset,
- const bool use_select,
- const float world_clip_planes[6][4])
-{
- if (use_select) {
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
- }
- else {
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "id", 0);
- if (world_clip_planes != NULL) {
- draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
- }
-}
-
-static void draw_mesh_face_dot(GPUBatch *batch, uint offset, const float world_clip_planes[6][4])
-{
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-}
-
-void DRW_draw_select_id_object(Scene *scene,
- RegionView3D *rv3d,
- Object *ob,
- short select_mode,
- bool draw_facedot,
- uint initial_offset,
- uint *r_vert_offset,
- uint *r_edge_offset,
- uint *r_face_offset)
-{
- ToolSettings *ts = scene->toolsettings;
- if (select_mode == -1) {
- select_mode = ts->selectmode;
- }
-
- /* Init the scene of the draw context. When using face dot selection on
- * when the subsurf modifier is active on the cage, the scene needs to be
- * valid. It is read from the context in the
- * `DRW_mesh_batch_cache_create_requested` and used in the `isDisabled`
- * method of the SubSurfModifier. */
- DRWContextState *draw_ctx = &DST.draw_ctx;
- draw_ctx->scene = scene;
-
- GPU_matrix_mul(ob->obmat);
-
- const float(*world_clip_planes)[4] = NULL;
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_local(rv3d, ob->obmat);
- world_clip_planes = rv3d->clip_local;
- }
-
- BLI_assert(initial_offset > 0);
-
- switch (ob->type) {
- case OB_MESH:
- if (ob->mode & OB_MODE_EDIT) {
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
- const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
-
- DRW_mesh_batch_cache_validate(me);
-
- BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
-
- GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
- geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- if (select_mode & SCE_SELECT_EDGE) {
- geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
- }
- if (select_mode & SCE_SELECT_VERTEX) {
- geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
- }
- if (use_faceselect && draw_facedot) {
- geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
- }
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
-
- draw_mesh_face(geom_faces, initial_offset, use_faceselect, world_clip_planes);
-
- if (use_faceselect && draw_facedot) {
- draw_mesh_face_dot(geom_facedots, initial_offset, world_clip_planes);
- }
-
- if (select_mode & SCE_SELECT_FACE) {
- *r_face_offset = initial_offset + em->bm->totface;
- }
- else {
- *r_face_offset = initial_offset;
- }
-
- ED_view3d_polygon_offset(rv3d, 1.0);
-
- /* Unlike faces, only draw edges if edge select mode. */
- if (select_mode & SCE_SELECT_EDGE) {
- draw_mesh_edges(geom_edges, *r_face_offset, world_clip_planes);
- *r_edge_offset = *r_face_offset + em->bm->totedge;
- }
- else {
- /* Note that `r_vert_offset` is calculated from `r_edge_offset`.
- * Otherwise the first vertex is never selected, see: T53512. */
- *r_edge_offset = *r_face_offset;
- }
-
- ED_view3d_polygon_offset(rv3d, 1.1);
-
- /* Unlike faces, only verts if vert select mode. */
- if (select_mode & SCE_SELECT_VERTEX) {
- draw_mesh_verts(geom_verts, *r_edge_offset, world_clip_planes);
- *r_vert_offset = *r_edge_offset + em->bm->totvert;
- }
- else {
- *r_vert_offset = *r_edge_offset;
- }
-
- ED_view3d_polygon_offset(rv3d, 0.0);
- }
- else {
- Mesh *me_orig = DEG_get_original_object(ob)->data;
- Mesh *me_eval = ob->data;
-
- DRW_mesh_batch_cache_validate(me_eval);
- GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval);
- if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) &&
- /* Currently vertex select supports weight paint and vertex paint. */
- ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
-
- GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval);
- DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, true);
-
- /* Only draw faces to mask out verts, we don't want their selection ID's. */
- draw_mesh_face(geom_faces, 0, false, world_clip_planes);
- draw_mesh_verts(geom_verts, 1, world_clip_planes);
-
- *r_face_offset = *r_edge_offset = initial_offset;
- *r_vert_offset = me_eval->totvert + 1;
- }
- else {
- const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
- DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, use_hide);
-
- draw_mesh_face(geom_faces, initial_offset, true, world_clip_planes);
-
- *r_face_offset = initial_offset + me_eval->totpoly;
- *r_edge_offset = *r_vert_offset = *r_face_offset;
- }
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- }
-
- GPU_matrix_set(rv3d->viewmat);
-}
-
-/* Set an opengl context to be used with shaders that draw on U32 colors. */
-void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
-{
- RegionView3D *rv3d = ar->regiondata;
-
- DRW_opengl_context_enable();
-
- /* Setup framebuffer */
- int viewport_size[2] = {ar->winx, ar->winy};
- draw_select_framebuffer_select_id_setup(viewport_size);
- GPU_framebuffer_bind(g_select_buffer.framebuffer_select_id);
-
- /* dithering and AA break color coding, so disable */
- glDisable(GL_DITHER);
-
- GPU_depth_test(true);
- GPU_program_point_size(false);
-
- if (clear) {
- GPU_framebuffer_clear_color_depth(
- g_select_buffer.framebuffer_select_id, (const float[4]){0.0f}, 1.0f);
- }
-
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
-}
-
-/* Ends the context for selection and restoring the previous one. */
-void DRW_framebuffer_select_id_release(ARegion *ar)
-{
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_disable();
- }
-
- GPU_depth_test(false);
-
- GPU_framebuffer_restore();
-
- DRW_opengl_context_disable();
-}
-
-/* Read a block of pixels from the select frame buffer. */
-void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf)
-{
- /* clamp rect by texture */
- rcti r = {
- .xmin = 0,
- .xmax = GPU_texture_width(g_select_buffer.texture_u32),
- .ymin = 0,
- .ymax = GPU_texture_height(g_select_buffer.texture_u32),
- };
-
- rcti rect_clamp = *rect;
- if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) {
- DRW_opengl_context_enable();
- GPU_framebuffer_bind(g_select_buffer.framebuffer_select_id);
- glReadBuffer(GL_COLOR_ATTACHMENT0);
- glReadPixels(rect_clamp.xmin,
- rect_clamp.ymin,
- BLI_rcti_size_x(&rect_clamp),
- BLI_rcti_size_y(&rect_clamp),
- GL_RED_INTEGER,
- GL_UNSIGNED_INT,
- r_buf);
-
- GPU_framebuffer_restore();
- DRW_opengl_context_disable();
-
- if (!BLI_rcti_compare(rect, &rect_clamp)) {
- GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf);
- }
- }
- else {
- size_t buf_size = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect) * sizeof(*r_buf);
-
- memset(r_buf, 0, buf_size);
- }
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -3089,6 +2851,7 @@ void DRW_engines_register(void)
DRW_engine_register(&draw_engine_pose_type);
DRW_engine_register(&draw_engine_sculpt_type);
DRW_engine_register(&draw_engine_gpencil_type);
+ DRW_engine_register(&draw_engine_select_type);
/* setup callbacks */
{
@@ -3123,9 +2886,7 @@ void DRW_engines_free(void)
DRW_opengl_context_enable();
- DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_u32);
DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth);
- GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_select_id);
GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only);
DRW_hair_free();
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 9fc11e4f36f..8d4083f1723 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -1242,7 +1242,7 @@ static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data,
unit_m4(win_m4_scale);
unit_m4(win_m4_translate);
unit_m4(scale_m4);
- axis_angle_to_mat4_single(rot_m4, 'Z', bgpic->rotation);
+ axis_angle_to_mat4_single(rot_m4, 'Z', -bgpic->rotation);
unit_m4(translate_m4);
const float *size = DRW_viewport_size_get();
@@ -1256,7 +1256,7 @@ static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data,
if (!DRW_state_is_image_render()) {
rctf render_border;
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &render_border, true);
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &render_border, false);
camera_width = render_border.xmax - render_border.xmin;
camera_height = render_border.ymax - render_border.ymin;
camera_aspect = camera_width / camera_height;
@@ -1311,9 +1311,9 @@ static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data,
scale_m4[0][0] = scale_x;
scale_m4[1][1] = scale_y;
- // translate
- translate_m4[3][0] = bgpic->offset[0];
- translate_m4[3][1] = bgpic->offset[1];
+ /* Translate, using coordinates that aren't squashed by the aspect. */
+ translate_m4[3][0] = bgpic->offset[0] * 2.0f * max_ff(1.0f, 1.0f / camera_aspect);
+ translate_m4[3][1] = bgpic->offset[1] * 2.0f * max_ff(1.0f, camera_aspect);
mul_m4_series(bg_data->transform_mat,
win_m4_translate,
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index b93d52a1b2d..7e913014a87 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -1705,7 +1705,7 @@ static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
/* ******************** Delete Channel Operator *********************** */
-static void update_dependencies_on_delete(bAnimListElem *ale)
+static void tag_update_animation_element(bAnimListElem *ale)
{
ID *id = ale->id;
AnimData *adt = BKE_animdata_from_id(id);
@@ -1801,7 +1801,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* try to free F-Curve */
ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
- update_dependencies_on_delete(ale);
+ tag_update_animation_element(ale);
break;
}
case ANIMTYPE_NLACURVE: {
@@ -1823,7 +1823,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* unlink and free the F-Curve */
BLI_remlink(&strip->fcurves, fcu);
free_fcurve(fcu);
- update_dependencies_on_delete(ale);
+ tag_update_animation_element(ale);
break;
}
case ANIMTYPE_GPLAYER: {
@@ -1967,6 +1967,7 @@ static void setflag_anim_channels(bAnimContext *ac,
/* set the setting in the appropriate way */
ANIM_channel_setting_set(ac, ale, setting, mode);
+ tag_update_animation_element(ale);
/* if flush status... */
if (flush) {
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 61bf7f95340..7ab50afe3a1 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -422,23 +422,16 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
}
else {
const BezTriple *prev_bezt = bezt - 1;
- if (prev_bezt->ipo == BEZT_IPO_CONST) {
- /* Constant interpolation: previous CV value is used up
- * to the current keyframe.
- */
- max_coord = max_ff(max_coord, bezt->vec[1][1]);
- min_coord = min_ff(min_coord, bezt->vec[1][1]);
- }
- else if (prev_bezt->ipo == BEZT_IPO_LIN) {
- /* Linear interpolation: min/max using both previous and
- * and current CV.
+ if (!ELEM(prev_bezt->ipo, BEZT_IPO_BEZ, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) {
+ /* The points on the curve will lie inside the start and end points.
+ * Calculate min/max using both previous and current CV.
*/
max_coord = max_ff(max_coord, bezt->vec[1][1]);
min_coord = min_ff(min_coord, bezt->vec[1][1]);
max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
}
- else if (prev_bezt->ipo == BEZT_IPO_BEZ) {
+ else {
const int resol = fcu->driver ?
32 :
min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])),
@@ -448,30 +441,12 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
}
else {
- float data[120];
- float v1[2], v2[2], v3[2], v4[2];
-
- v1[0] = prev_bezt->vec[1][0];
- v1[1] = prev_bezt->vec[1][1];
- v2[0] = prev_bezt->vec[2][0];
- v2[1] = prev_bezt->vec[2][1];
-
- v3[0] = bezt->vec[0][0];
- v3[1] = bezt->vec[0][1];
- v4[0] = bezt->vec[1][0];
- v4[1] = bezt->vec[1][1];
-
- correct_bezpart(v1, v2, v3, v4);
-
- BKE_curve_forward_diff_bezier(
- v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
- BKE_curve_forward_diff_bezier(
- v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
-
+ float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol;
for (int j = 0; j <= resol; ++j) {
- const float *fp = &data[j * 3];
- max_coord = max_ff(max_coord, fp[1]);
- min_coord = min_ff(min_coord, fp[1]);
+ float eval_time = prev_bezt->vec[1][0] + step_size * j;
+ float eval_value = evaluate_fcurve_only_curve(fcu, eval_time);
+ max_coord = max_ff(max_coord, eval_value);
+ min_coord = min_ff(min_coord, eval_value);
}
}
}
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 6811e32cc2a..9debea7bf88 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -89,8 +89,6 @@ struct StrokeElem {
};
struct CurveDrawData {
- Depsgraph *depsgraph;
-
short init_event_type;
short curve_type;
@@ -578,8 +576,6 @@ static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke)
struct CurveDrawData *cdd = MEM_callocN(sizeof(*cdd), __func__);
- cdd->depsgraph = CTX_data_depsgraph(C);
-
if (is_invoke) {
ED_view3d_viewcontext_init(C, &cdd->vc);
if (ELEM(NULL, cdd->vc.ar, cdd->vc.rv3d, cdd->vc.v3d, cdd->vc.win, cdd->vc.scene)) {
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index e8f97290173..dce6ed29c05 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -924,7 +924,7 @@ static void annotation_draw_data_layers(
* i.e. tGPspoints NOT bGPDspoints
*/
annotation_draw_stroke_buffer(gpd->runtime.sbuffer,
- gpd->runtime.sbuffer_size,
+ gpd->runtime.sbuffer_used,
lthick,
dflag,
gpd->runtime.sbuffer_sflag,
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 5962d95c5af..5793b407bdc 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -281,7 +281,7 @@ static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2
int dy = (int)fabsf(mval[1] - pmval[1]);
/* if buffer is empty, just let this go through (i.e. so that dots will work) */
- if (p->gpd->runtime.sbuffer_size == 0) {
+ if (p->gpd->runtime.sbuffer_used == 0) {
return true;
/* check if mouse moved at least certain distance on both axes (best case)
@@ -382,7 +382,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
{
bGPdata *gpd = p->gpd;
- short num_points = gpd->runtime.sbuffer_size;
+ short num_points = gpd->runtime.sbuffer_used;
/* Do nothing if not enough points to smooth out */
if ((num_points < 3) || (idx < 3) || (inf == 0.0f)) {
@@ -437,7 +437,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
/* check painting mode */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only - i.e. only store start and end point in buffer */
- if (gpd->runtime.sbuffer_size == 0) {
+ if (gpd->runtime.sbuffer_used == 0) {
/* first point in buffer (start point) */
pt = (tGPspoint *)(gpd->runtime.sbuffer);
@@ -449,7 +449,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt->time = (float)(curtime - p->inittime);
/* increment buffer size */
- gpd->runtime.sbuffer_size++;
+ gpd->runtime.sbuffer_used++;
}
else {
/* just reset the endpoint to the latest value
@@ -465,20 +465,19 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt->time = (float)(curtime - p->inittime);
/* now the buffer has 2 points (and shouldn't be allowed to get any larger) */
- gpd->runtime.sbuffer_size = 2;
+ gpd->runtime.sbuffer_used = 2;
}
/* can keep carrying on this way :) */
return GP_STROKEADD_NORMAL;
}
else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */
- /* check if still room in buffer */
- if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX) {
- return GP_STROKEADD_OVERFLOW;
- }
+ /* check if still room in buffer or add more */
+ gpd->runtime.sbuffer = ED_gpencil_sbuffer_ensure(
+ gpd->runtime.sbuffer, &gpd->runtime.sbuffer_size, &gpd->runtime.sbuffer_used, false);
/* get pointer to destination point */
- pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size);
+ pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_used);
/* store settings */
copy_v2_v2(&pt->x, mval);
@@ -490,19 +489,13 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt->time = (float)(curtime - p->inittime);
/* increment counters */
- gpd->runtime.sbuffer_size++;
+ gpd->runtime.sbuffer_used++;
/* smooth while drawing previous points with a reduction factor for previous */
for (int s = 0; s < 3; s++) {
- gp_smooth_buffer(p, 0.5f * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_size - s);
+ gp_smooth_buffer(p, 0.5f * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_used - s);
}
- /* check if another operation can still occur */
- if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX) {
- return GP_STROKEADD_FULL;
- }
- else {
- return GP_STROKEADD_NORMAL;
- }
+ return GP_STROKEADD_NORMAL;
}
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
/* get pointer to destination point */
@@ -524,7 +517,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
bGPDspoint *pts;
/* first time point is adding to temporary buffer -- need to allocate new point in stroke */
- if (gpd->runtime.sbuffer_size == 0) {
+ if (gpd->runtime.sbuffer_used == 0) {
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
gps->totpoints++;
}
@@ -557,8 +550,8 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
}
/* increment counters */
- if (gpd->runtime.sbuffer_size == 0) {
- gpd->runtime.sbuffer_size++;
+ if (gpd->runtime.sbuffer_used == 0) {
+ gpd->runtime.sbuffer_used++;
}
return GP_STROKEADD_NORMAL;
@@ -576,7 +569,7 @@ static void gp_stroke_simplify(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
tGPspoint *old_points = (tGPspoint *)gpd->runtime.sbuffer;
- short num_points = gpd->runtime.sbuffer_size;
+ short num_points = gpd->runtime.sbuffer_used;
short flag = gpd->runtime.sbuffer_sflag;
short i, j;
@@ -668,17 +661,17 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
* - drawing straight-lines only requires the endpoints
*/
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
- totelem = (gpd->runtime.sbuffer_size >= 2) ? 2 : gpd->runtime.sbuffer_size;
+ totelem = (gpd->runtime.sbuffer_used >= 2) ? 2 : gpd->runtime.sbuffer_used;
}
else {
- totelem = gpd->runtime.sbuffer_size;
+ totelem = gpd->runtime.sbuffer_used;
}
/* exit with error if no valid points from this stroke */
if (totelem == 0) {
if (G.debug & G_DEBUG) {
printf("Error: No valid points in stroke buffer to convert (tot=%d)\n",
- gpd->runtime.sbuffer_size);
+ gpd->runtime.sbuffer_used);
}
return;
}
@@ -736,7 +729,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (totelem == 2) {
/* last point if applicable */
- ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_size - 1);
+ ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_used - 1);
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
@@ -769,9 +762,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int interp_depth = 0;
int found_depth = 0;
- depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points");
+ depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_used, "depth_points");
- for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) {
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used; i++, ptc++, pt++) {
round_v2i_v2fl(mval_i, &ptc->x);
if ((ED_view3d_autodist_depth(p->ar, mval_i, depth_margin, depth_arr + i) == 0) &&
@@ -788,7 +781,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (found_depth == false) {
/* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
- for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) {
+ for (i = gpd->runtime.sbuffer_used - 1; i >= 0; i--) {
depth_arr[i] = 0.9999f;
}
}
@@ -798,14 +791,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int first_valid = 0;
int last_valid = 0;
- for (i = 0; i < gpd->runtime.sbuffer_size; i++) {
+ for (i = 0; i < gpd->runtime.sbuffer_used; i++) {
if (depth_arr[i] != FLT_MAX) {
break;
}
}
first_valid = i;
- for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) {
+ for (i = gpd->runtime.sbuffer_used - 1; i >= 0; i--) {
if (depth_arr[i] != FLT_MAX) {
break;
}
@@ -821,7 +814,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
if (interp_depth) {
- interp_sparse_array(depth_arr, gpd->runtime.sbuffer_size, FLT_MAX);
+ interp_sparse_array(depth_arr, gpd->runtime.sbuffer_used, FLT_MAX);
}
}
}
@@ -829,7 +822,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
pt = gps->points;
/* convert all points (normal behavior) */
- for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && ptc;
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used && ptc;
i++, ptc++, pt++) {
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
@@ -1049,19 +1042,8 @@ static void gp_session_validatebuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
- /* clear memory of buffer (or allocate it if starting a new session) */
- if (gpd->runtime.sbuffer) {
- /* printf("\t\tGP - reset sbuffer\n"); */
- memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
- }
- else {
- /* printf("\t\tGP - allocate sbuffer\n"); */
- gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX,
- "gp_session_strokebuffer");
- }
-
- /* reset indices */
- gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.sbuffer = ED_gpencil_sbuffer_ensure(
+ gpd->runtime.sbuffer, &gpd->runtime.sbuffer_size, &gpd->runtime.sbuffer_used, true);
/* reset flags */
gpd->runtime.sbuffer_sflag = 0;
@@ -1295,6 +1277,7 @@ static void gp_session_cleanup(tGPsdata *p)
}
/* clear flags */
+ gpd->runtime.sbuffer_used = 0;
gpd->runtime.sbuffer_size = 0;
gpd->runtime.sbuffer_sflag = 0;
p->inittime = 0.0;
diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c
index 4d62d169bf8..c4528518009 100644
--- a/source/blender/editors/gpencil/gpencil_add_monkey.c
+++ b/source/blender/editors/gpencil/gpencil_add_monkey.c
@@ -829,8 +829,7 @@ static const ColorTemplate gp_monkey_pct_pupils = {
void ED_gpencil_create_monkey(bContext *C, Object *ob, float mat[4][4])
{
Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
bGPdata *gpd = (bGPdata *)ob->data;
bGPDstroke *gps;
@@ -852,8 +851,8 @@ void ED_gpencil_create_monkey(bContext *C, Object *ob, float mat[4][4])
/* frames */
/* NOTE: No need to check for existing, as this will take care of it for us */
- bGPDframe *frameFills = BKE_gpencil_frame_addnew(Fills, cfra_eval);
- bGPDframe *frameLines = BKE_gpencil_frame_addnew(Lines, cfra_eval);
+ bGPDframe *frameFills = BKE_gpencil_frame_addnew(Fills, CFRA);
+ bGPDframe *frameLines = BKE_gpencil_frame_addnew(Lines, CFRA);
/* generate strokes */
gps = BKE_gpencil_add_stroke(frameFills, color_Skin, 270, 75);
diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c
index f6ff5ed4f13..80e239c9ae5 100644
--- a/source/blender/editors/gpencil/gpencil_add_stroke.c
+++ b/source/blender/editors/gpencil/gpencil_add_stroke.c
@@ -215,8 +215,7 @@ static const ColorTemplate gp_stroke_material_grey = {
void ED_gpencil_create_stroke(bContext *C, Object *ob, float mat[4][4])
{
Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
bGPdata *gpd = (bGPdata *)ob->data;
bGPDstroke *gps;
@@ -236,8 +235,8 @@ void ED_gpencil_create_stroke(bContext *C, Object *ob, float mat[4][4])
bGPDlayer *lines = BKE_gpencil_layer_addnew(gpd, "Lines", true);
/* frames */
- bGPDframe *frame_color = BKE_gpencil_frame_addnew(colors, cfra_eval);
- bGPDframe *frame_lines = BKE_gpencil_frame_addnew(lines, cfra_eval);
+ bGPDframe *frame_color = BKE_gpencil_frame_addnew(colors, CFRA);
+ bGPDframe *frame_lines = BKE_gpencil_frame_addnew(lines, CFRA);
UNUSED_VARS(frame_color);
/* generate stroke */
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 7d866aedd87..d97207baed8 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -87,7 +87,6 @@
typedef struct tGP_BrushEditData {
/* Current editor/region/etc. */
/* NOTE: This stuff is mainly needed to handle 3D view projection stuff... */
- Depsgraph *depsgraph;
struct Main *bmain;
Scene *scene;
Object *object;
@@ -1051,11 +1050,8 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
tGPSB_CloneBrushData *data = gso->customdata;
Object *ob = CTX_data_active_object(C);
- bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
-
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ Scene *scene = CTX_data_scene(C);
bGPDstroke *gps;
float delta[3];
@@ -1074,6 +1070,18 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
bGPDspoint *pt;
int i;
+ bGPDlayer *gpl = NULL;
+ /* Try to use original layer. */
+ if (gps->runtime.tmp_layerinfo != NULL) {
+ gpl = BLI_findstring(&gpd->layers, gps->runtime.tmp_layerinfo, offsetof(bGPDlayer, info));
+ }
+
+ /* if not available, use active layer. */
+ if (gpl == NULL) {
+ gpl = CTX_data_active_gpencil_layer(C);
+ }
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
+
/* Make a new stroke */
new_stroke = MEM_dupallocN(gps);
@@ -1088,10 +1096,10 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
BLI_addtail(&gpf->strokes, new_stroke);
/* Fix color references */
- Material *ma = BLI_ghash_lookup(data->new_colors, &new_stroke->mat_nr);
- gps->mat_nr = BKE_gpencil_object_material_get_index(ob, ma);
- if (!ma || gps->mat_nr) {
- gps->mat_nr = 0;
+ Material *ma = BLI_ghash_lookup(data->new_colors, POINTER_FROM_INT(new_stroke->mat_nr));
+ new_stroke->mat_nr = BKE_gpencil_object_material_get_index(ob, ma);
+ if (!ma || new_stroke->mat_nr < 0) {
+ new_stroke->mat_nr = 0;
}
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
@@ -1224,7 +1232,6 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
gso = MEM_callocN(sizeof(tGP_BrushEditData), "tGP_BrushEditData");
op->customdata = gso;
- gso->depsgraph = CTX_data_depsgraph(C);
gso->bmain = CTX_data_main(C);
/* store state */
gso->settings = gpsculpt_get_settings(scene);
@@ -1400,10 +1407,11 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
bGPdata *gpd = gso->gpd;
bGPDlayer *gpl;
- int cfra_eval = (int)DEG_get_ctime(gso->depsgraph);
+ Scene *scene = gso->scene;
+ int cfra = CFRA;
/* only try to add a new frame if this is the first stroke, or the frame has changed */
- if ((gpd == NULL) || (cfra_eval == gso->cfra)) {
+ if ((gpd == NULL) || (cfra == gso->cfra)) {
return;
}
@@ -1419,14 +1427,14 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
* spent too much time editing the wrong frame.
*/
// XXX: should this be allowed when framelock is enabled?
- if (gpf->framenum != cfra_eval) {
- BKE_gpencil_frame_addcopy(gpl, cfra_eval);
+ if (gpf->framenum != cfra) {
+ BKE_gpencil_frame_addcopy(gpl, cfra);
}
}
}
/* save off new current frame, so that next update works fine */
- gso->cfra = cfra_eval;
+ gso->cfra = cfra;
}
/* Apply ----------------------------------------------- */
@@ -1478,7 +1486,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
/* Skip if neither one is selected
* (and we are only allowed to edit/consider selected points) */
- if (gso->settings->flag & GP_SCULPT_SETT_FLAG_SELECT_MASK) {
+ if ((gso->settings->flag & GP_SCULPT_SETT_FLAG_SELECT_MASK) && (!gso->is_weight_mode)) {
if (!(pt1->flag & GP_SPOINT_SELECT) && !(pt2->flag & GP_SPOINT_SELECT)) {
include_last = false;
continue;
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 5afa379e04f..087d8540b03 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1274,10 +1274,9 @@ static void gp_layer_to_curve(bContext *C,
struct Main *bmain = CTX_data_main(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Collection *collection = CTX_data_collection(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV);
bGPDstroke *gps, *prev_gps = NULL;
Object *ob;
Curve *cu;
@@ -1406,8 +1405,7 @@ static void gp_layer_to_curve(bContext *C,
*/
static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
bGPDframe *gpf = NULL;
bGPDstroke *gps = NULL;
@@ -1416,7 +1414,7 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
int i;
bool valid = true;
- if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV)) ||
+ if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV)) ||
!(gps = gpf->strokes.first)) {
return false;
}
@@ -1468,8 +1466,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main),
static bool gp_convert_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
return false;
@@ -1484,7 +1481,7 @@ static bool gp_convert_poll(bContext *C)
* and if we are not in edit mode!
*/
return ((sa && sa->spacetype == SPACE_VIEW3D) && (gpl = BKE_gpencil_layer_getactive(gpd)) &&
- (gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV)) &&
+ (gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV)) &&
(gpf->strokes.first) && (!GPENCIL_ANY_EDIT_MODE(gpd)));
}
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 90a2b2d613c..0ee4fd20f0f 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -594,8 +594,7 @@ static int gp_frame_duplicate_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
int mode = RNA_enum_get(op->ptr, "mode");
@@ -605,12 +604,12 @@ static int gp_frame_duplicate_exec(bContext *C, wmOperator *op)
}
if (mode == 0) {
- BKE_gpencil_frame_addcopy(gpl, cfra_eval);
+ BKE_gpencil_frame_addcopy(gpl, CFRA);
}
else {
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
- BKE_gpencil_frame_addcopy(gpl, cfra_eval);
+ BKE_gpencil_frame_addcopy(gpl, CFRA);
}
}
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 0c1c24a9432..0fc051e4756 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1237,8 +1237,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); /* only use active for copy merge */
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
bGPDframe *gpf;
eGP_PasteMode type = RNA_enum_get(op->ptr, "type");
@@ -1329,7 +1328,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
* we are obliged to add a new frame if one
* doesn't exist already
*/
- gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
+ gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
if (gpf) {
/* Create new stroke */
bGPDstroke *new_stroke = MEM_dupallocN(gps);
@@ -1408,8 +1407,7 @@ static int gp_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *U
static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
bGPDlayer *target_layer = NULL;
ListBase strokes = {NULL, NULL};
int layer_num = RNA_enum_get(op->ptr, "layer");
@@ -1482,7 +1480,7 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
/* Paste them all in one go */
if (strokes.first) {
- bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, cfra_eval, GP_GETFRAME_ADD_NEW);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, CFRA, GP_GETFRAME_ADD_NEW);
BLI_movelisttolist(&gpf->strokes, &strokes);
BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL));
@@ -1545,8 +1543,8 @@ static bool UNUSED_FUNCTION(gp_blank_frame_add_poll)(bContext *C)
static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
+ int cfra = CFRA;
bGPDlayer *active_gpl = BKE_gpencil_layer_getactive(gpd);
@@ -1568,7 +1566,7 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
}
/* 1) Check for an existing frame on the current frame */
- bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, cfra_eval);
+ bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, cfra);
if (gpf) {
/* Shunt all frames after (and including) the existing one later by 1-frame */
for (; gpf; gpf = gpf->next) {
@@ -1577,7 +1575,7 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
}
/* 2) Now add a new frame, with nothing in it */
- gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
+ gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra, GP_GETFRAME_ADD_NEW);
}
CTX_DATA_END;
@@ -1627,10 +1625,9 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV);
/* if there's no existing Grease-Pencil data there, add some */
if (gpd == NULL) {
@@ -1681,14 +1678,13 @@ static bool gp_actframe_delete_all_poll(bContext *C)
static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
bool success = false;
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
/* try to get the "active" frame - but only if it actually occurs on this frame */
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV);
if (gpf == NULL) {
continue;
@@ -1940,9 +1936,11 @@ static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode)
*ndvert = *dvert;
ndvert->dw = MEM_dupallocN(dvert->dw);
ndvert++;
- dvert++;
}
}
+ if (gps->dvert != NULL) {
+ dvert++;
+ }
}
break;
case GP_DISSOLVE_BETWEEN:
@@ -1970,9 +1968,11 @@ static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode)
*ndvert = *dvert;
ndvert->dw = MEM_dupallocN(dvert->dw);
ndvert++;
- dvert++;
}
}
+ if (gps->dvert != NULL) {
+ dvert++;
+ }
}
/* copy last segment */
(gps->dvert != NULL) ? dvert = gps->dvert + last : NULL;
@@ -2001,9 +2001,11 @@ static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode)
*ndvert = *dvert;
ndvert->dw = MEM_dupallocN(dvert->dw);
ndvert++;
- dvert++;
}
}
+ if (gps->dvert != NULL) {
+ dvert++;
+ }
}
break;
}
@@ -3142,10 +3144,7 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a,
/* 3rd: add all points */
for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
- /* check if still room in buffer */
- if (gps_a->totpoints <= GP_STROKE_BUFFER_MAX - 2) {
- gpencil_stroke_copy_point(gps_a, pt, i, delta, pt->pressure, pt->strength, deltatime);
- }
+ gpencil_stroke_copy_point(gps_a, pt, i, delta, pt->pressure, pt->strength, deltatime);
}
}
@@ -3401,12 +3400,6 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
if (gps->flag & GP_STROKE_SELECT) {
bGPDspoint *pt;
int i;
- float inverse_diff_mat[4][4];
-
- /* Compute inverse matrix for unapplying parenting once instead of doing per-point */
- /* TODO: add this bit to the iteration macro? */
- invert_m4_m4(inverse_diff_mat, gpstroke_iter.diff_mat);
-
/* Adjust each point */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
float xy[2];
@@ -3493,7 +3486,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* Unapply parent corrections */
if (!ELEM(mode, GP_REPROJECT_FRONT, GP_REPROJECT_SIDE, GP_REPROJECT_TOP)) {
- mul_m4_v3(inverse_diff_mat, &pt->x);
+ mul_m4_v3(gpstroke_iter.inverse_diff_mat, &pt->x);
}
}
}
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index d914cdea442..1ac4471547e 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -135,7 +135,7 @@ typedef struct tGPDfill {
short fill_factor;
/** number of elements currently in cache */
- short sbuffer_size;
+ short sbuffer_used;
/** temporary points */
void *sbuffer;
/** depth array for reproject */
@@ -918,7 +918,7 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
{
tGPspoint *ptc;
ToolSettings *ts = tgpf->scene->toolsettings;
- int totpoints = tgpf->sbuffer_size;
+ int totpoints = tgpf->sbuffer_used;
int i = 0;
if (totpoints == 0) {
@@ -984,7 +984,7 @@ static void gpencil_points_from_stack(tGPDfill *tgpf)
return;
}
- tgpf->sbuffer_size = (short)totpoints;
+ tgpf->sbuffer_used = (short)totpoints;
tgpf->sbuffer = MEM_callocN(sizeof(tGPspoint) * totpoints, __func__);
point2D = tgpf->sbuffer;
@@ -1020,7 +1020,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
MDeformVert *dvert = NULL;
tGPspoint *point2D;
- if (tgpf->sbuffer_size == 0) {
+ if (tgpf->sbuffer_used == 0) {
return;
}
@@ -1041,8 +1041,8 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
gps->mat_nr = BKE_gpencil_object_material_ensure(tgpf->bmain, tgpf->ob, tgpf->mat);
/* allocate memory for storage points */
- gps->totpoints = tgpf->sbuffer_size;
- gps->points = MEM_callocN(sizeof(bGPDspoint) * tgpf->sbuffer_size, "gp_stroke_points");
+ gps->totpoints = tgpf->sbuffer_used;
+ gps->points = MEM_callocN(sizeof(bGPDspoint) * tgpf->sbuffer_used, "gp_stroke_points");
/* initialize triangle memory to dummy data */
gps->tot_triangles = 0;
@@ -1069,7 +1069,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
dvert = gps->dvert;
}
- for (int i = 0; i < tgpf->sbuffer_size && point2D; i++, point2D++, pt++) {
+ for (int i = 0; i < tgpf->sbuffer_used && point2D; i++, point2D++, pt++) {
/* convert screen-coordinates to 3D coordinates */
gp_stroke_convertcoords_tpoint(tgpf->scene,
tgpf->ar,
@@ -1120,7 +1120,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
}
/* if parented change position relative to parent object */
- for (int a = 0; a < tgpf->sbuffer_size; a++) {
+ for (int a = 0; a < tgpf->sbuffer_used; a++) {
pt = &gps->points[a];
gp_apply_parent_point(tgpf->depsgraph, tgpf->ob, tgpf->gpd, tgpf->gpl, pt);
}
@@ -1225,7 +1225,7 @@ static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op))
tgpf->lock_axis = ts->gp_sculpt.lock_axis;
tgpf->oldkey = -1;
- tgpf->sbuffer_size = 0;
+ tgpf->sbuffer_used = 0;
tgpf->sbuffer = NULL;
tgpf->depth_arr = NULL;
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index df9cb2e9a01..e28e83b23b0 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -378,8 +378,8 @@ typedef enum eGPencil_PaintModes {
GP_PAINTMODE_SET_CP,
} eGPencil_PaintModes;
-/* maximum sizes of gp-session buffer */
-#define GP_STROKE_BUFFER_MAX 5000
+/* chunk size for gp-session buffer (the total size is a multiple of this number) */
+#define GP_STROKE_BUFFER_CHUNK 2048
/* stroke editing ----- */
@@ -583,6 +583,7 @@ typedef enum ACTCONT_TYPES {
struct GP_EditableStrokes_Iter {
float diff_mat[4][4];
+ float inverse_diff_mat[4][4];
};
/**
@@ -607,6 +608,7 @@ struct GP_EditableStrokes_Iter {
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
ED_gpencil_parent_location(depsgraph_, obact_, gpd_, gpl, gpstroke_iter.diff_mat); \
+ invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
for (bGPDstroke *gps = gpf_->strokes.first; gps; gps = gps->next) { \
/* skip strokes that are invalid for current view */ \
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 4d5548dcdf3..698e508a2a5 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -511,8 +511,8 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
wmWindow *win = CTX_wm_window(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
+ int cfra = CFRA;
bGPDframe *actframe = gpl->actframe;
tGPDinterpolate *tgpi = NULL;
@@ -526,7 +526,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
}
/* cannot interpolate in extremes */
- if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) {
+ if (ELEM(cfra, actframe->framenum, actframe->next->framenum)) {
BKE_report(op->reports,
RPT_ERROR,
"Cannot interpolate as current frame already has existing grease pencil frames");
@@ -949,8 +949,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
+ int cfra = CFRA;
GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate;
eGP_Interpolate_SettingsFlag flag = ipo_settings->flag;
@@ -964,7 +964,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* cannot interpolate in extremes */
- if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) {
+ if (ELEM(cfra, actframe->framenum, actframe->next->framenum)) {
BKE_report(op->reports,
RPT_ERROR,
"Cannot interpolate as current frame already has existing grease pencil frames");
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c
index 93d8555e014..cb11bb4cd63 100644
--- a/source/blender/editors/gpencil/gpencil_merge.c
+++ b/source/blender/editors/gpencil/gpencil_merge.c
@@ -98,11 +98,10 @@ static void gpencil_insert_points_to_stroke(bGPDstroke *gps,
static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpoints)
{
ToolSettings *ts = CTX_data_tool_settings(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
Object *ob = CTX_data_active_object(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
const bool back = RNA_boolean_get(op->ptr, "back");
const bool additive = RNA_boolean_get(op->ptr, "additive");
@@ -124,7 +123,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo
else {
add_frame_mode = GP_GETFRAME_ADD_NEW;
}
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, add_frame_mode);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, add_frame_mode);
/* stroke */
bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index b49094c4fd6..5af355b908d 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -349,7 +349,7 @@ static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float mvalo[2
brush->gpencil_settings->flag &= ~GP_BRUSH_STABILIZE_MOUSE_TEMP;
/* if buffer is empty, just let this go through (i.e. so that dots will work) */
- if (p->gpd->runtime.sbuffer_size == 0) {
+ if (p->gpd->runtime.sbuffer_used == 0) {
return true;
}
/* if lazy mouse, check minimum distance */
@@ -486,7 +486,7 @@ static void gp_brush_jitter(bGPdata *gpd,
/* Jitter is applied perpendicular to the mouse movement vector (2D space) */
float mvec[2], svec[2];
/* mouse movement in ints -> floats */
- if (gpd->runtime.sbuffer_size > 1) {
+ if (gpd->runtime.sbuffer_used > 1) {
mvec[0] = (mval[0] - (pt - 1)->x);
mvec[1] = (mval[1] - (pt - 1)->y);
normalize_v2(mvec);
@@ -524,7 +524,7 @@ static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const floa
float v0[2] = {cos(angle), sin(angle)};
/* Apply to first point (only if there are 2 points because before no data to do it ) */
- if (gpd->runtime.sbuffer_size == 1) {
+ if (gpd->runtime.sbuffer_used == 1) {
mvec[0] = (mval[0] - (pt - 1)->x);
mvec[1] = (mval[1] - (pt - 1)->y);
normalize_v2(mvec);
@@ -537,7 +537,7 @@ static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const floa
}
/* apply from second point */
- if (gpd->runtime.sbuffer_size >= 1) {
+ if (gpd->runtime.sbuffer_used >= 1) {
mvec[0] = (mval[0] - (pt - 1)->x);
mvec[1] = (mval[1] - (pt - 1)->y);
normalize_v2(mvec);
@@ -563,7 +563,7 @@ static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const floa
static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
{
bGPdata *gpd = p->gpd;
- short num_points = gpd->runtime.sbuffer_size;
+ short num_points = gpd->runtime.sbuffer_used;
/* Do nothing if not enough points to smooth out */
if ((num_points < 3) || (idx < 3) || (inf == 0.0f)) {
@@ -626,7 +626,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
/* check painting mode */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only - i.e. only store start and end point in buffer */
- if (gpd->runtime.sbuffer_size == 0) {
+ if (gpd->runtime.sbuffer_used == 0) {
/* first point in buffer (start point) */
pt = (tGPspoint *)(gpd->runtime.sbuffer);
@@ -638,7 +638,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt->time = (float)(curtime - p->inittime);
/* increment buffer size */
- gpd->runtime.sbuffer_size++;
+ gpd->runtime.sbuffer_used++;
}
else {
/* just reset the endpoint to the latest value
@@ -654,20 +654,19 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt->time = (float)(curtime - p->inittime);
/* now the buffer has 2 points (and shouldn't be allowed to get any larger) */
- gpd->runtime.sbuffer_size = 2;
+ gpd->runtime.sbuffer_used = 2;
}
/* can keep carrying on this way :) */
return GP_STROKEADD_NORMAL;
}
else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */
- /* check if still room in buffer */
- if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX) {
- return GP_STROKEADD_OVERFLOW;
- }
+ /* check if still room in buffer or add more */
+ gpd->runtime.sbuffer = ED_gpencil_sbuffer_ensure(
+ gpd->runtime.sbuffer, &gpd->runtime.sbuffer_size, &gpd->runtime.sbuffer_used, false);
/* get pointer to destination point */
- pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size);
+ pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_used);
/* store settings */
/* pressure */
@@ -760,9 +759,9 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt->time = (float)(curtime - p->inittime);
/* point uv (only 3d view) */
- if ((p->sa->spacetype == SPACE_VIEW3D) && (gpd->runtime.sbuffer_size > 0)) {
+ if ((p->sa->spacetype == SPACE_VIEW3D) && (gpd->runtime.sbuffer_used > 0)) {
float pixsize = gp_style->texture_pixsize / 1000000.0f;
- tGPspoint *ptb = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1;
+ tGPspoint *ptb = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_used - 1;
bGPDspoint spt, spt2;
/* get origin to reproject point */
@@ -787,24 +786,18 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
}
/* increment counters */
- gpd->runtime.sbuffer_size++;
+ gpd->runtime.sbuffer_used++;
/* smooth while drawing previous points with a reduction factor for previous */
if (brush->gpencil_settings->active_smooth > 0.0f) {
for (int s = 0; s < 3; s++) {
gp_smooth_buffer(p,
brush->gpencil_settings->active_smooth * ((3.0f - s) / 3.0f),
- gpd->runtime.sbuffer_size - s);
+ gpd->runtime.sbuffer_used - s);
}
}
- /* check if another operation can still occur */
- if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX) {
- return GP_STROKEADD_FULL;
- }
- else {
- return GP_STROKEADD_NORMAL;
- }
+ return GP_STROKEADD_NORMAL;
}
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
@@ -832,7 +825,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
MDeformVert *dvert = NULL;
/* first time point is adding to temporary buffer -- need to allocate new point in stroke */
- if (gpd->runtime.sbuffer_size == 0) {
+ if (gpd->runtime.sbuffer_used == 0) {
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
if (gps->dvert != NULL) {
gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1));
@@ -889,8 +882,8 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
}
/* increment counters */
- if (gpd->runtime.sbuffer_size == 0) {
- gpd->runtime.sbuffer_size++;
+ if (gpd->runtime.sbuffer_used == 0) {
+ gpd->runtime.sbuffer_used++;
}
return GP_STROKEADD_NORMAL;
@@ -930,17 +923,17 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
* - drawing straight-lines only requires the endpoints
*/
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
- totelem = (gpd->runtime.sbuffer_size >= 2) ? 2 : gpd->runtime.sbuffer_size;
+ totelem = (gpd->runtime.sbuffer_used >= 2) ? 2 : gpd->runtime.sbuffer_used;
}
else {
- totelem = gpd->runtime.sbuffer_size;
+ totelem = gpd->runtime.sbuffer_used;
}
/* exit with error if no valid points from this stroke */
if (totelem == 0) {
if (G.debug & G_DEBUG) {
printf("Error: No valid points in stroke buffer to convert (tot=%d)\n",
- gpd->runtime.sbuffer_size);
+ gpd->runtime.sbuffer_used);
}
return;
}
@@ -1024,7 +1017,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (totelem == 2) {
/* last point if applicable */
- ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_size - 1);
+ ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_used - 1);
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
@@ -1105,9 +1098,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int interp_depth = 0;
int found_depth = 0;
- depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points");
+ depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_used, "depth_points");
- for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) {
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used; i++, ptc++, pt++) {
round_v2i_v2fl(mval_i, &ptc->x);
@@ -1125,7 +1118,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (found_depth == false) {
/* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
- for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) {
+ for (i = gpd->runtime.sbuffer_used - 1; i >= 0; i--) {
depth_arr[i] = 0.9999f;
}
}
@@ -1137,7 +1130,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int last_valid = 0;
/* find first valid contact point */
- for (i = 0; i < gpd->runtime.sbuffer_size; i++) {
+ for (i = 0; i < gpd->runtime.sbuffer_used; i++) {
if (depth_arr[i] != FLT_MAX) {
break;
}
@@ -1149,7 +1142,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
last_valid = first_valid;
}
else {
- for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) {
+ for (i = gpd->runtime.sbuffer_used - 1; i >= 0; i--) {
if (depth_arr[i] != FLT_MAX) {
break;
}
@@ -1158,7 +1151,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
/* invalidate any other point, to interpolate between
* first and last contact in an imaginary line between them */
- for (i = 0; i < gpd->runtime.sbuffer_size; i++) {
+ for (i = 0; i < gpd->runtime.sbuffer_used; i++) {
if ((i != first_valid) && (i != last_valid)) {
depth_arr[i] = FLT_MAX;
}
@@ -1167,7 +1160,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
if (interp_depth) {
- interp_sparse_array(depth_arr, gpd->runtime.sbuffer_size, FLT_MAX);
+ interp_sparse_array(depth_arr, gpd->runtime.sbuffer_used, FLT_MAX);
}
}
}
@@ -1176,7 +1169,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
dvert = gps->dvert;
/* convert all points (normal behavior) */
- for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && ptc;
+ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used && ptc;
i++, ptc++, pt++) {
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
@@ -1725,18 +1718,8 @@ static void gp_session_validatebuffer(tGPsdata *p)
Brush *brush = p->brush;
/* clear memory of buffer (or allocate it if starting a new session) */
- if (gpd->runtime.sbuffer) {
- /* printf("\t\tGP - reset sbuffer\n"); */
- memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
- }
- else {
- /* printf("\t\tGP - allocate sbuffer\n"); */
- gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX,
- "gp_session_strokebuffer");
- }
-
- /* reset indices */
- gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.sbuffer = ED_gpencil_sbuffer_ensure(
+ gpd->runtime.sbuffer, &gpd->runtime.sbuffer_size, &gpd->runtime.sbuffer_used, true);
/* reset flags */
gpd->runtime.sbuffer_sflag = 0;
@@ -2070,6 +2053,7 @@ static void gp_session_cleanup(tGPsdata *p)
}
/* clear flags */
+ gpd->runtime.sbuffer_used = 0;
gpd->runtime.sbuffer_size = 0;
gpd->runtime.sbuffer_sflag = 0;
p->inittime = 0.0;
@@ -2089,7 +2073,6 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
{
Scene *scene = p->scene;
ToolSettings *ts = scene->toolsettings;
- int cfra_eval = (int)DEG_get_ctime(p->depsgraph);
/* get active layer (or add a new one if non-existent) */
p->gpl = BKE_gpencil_layer_getactive(p->gpd);
@@ -2131,7 +2114,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
* -> If there are no strokes in that frame, don't add a new empty frame
*/
if (gpl->actframe && gpl->actframe->strokes.first) {
- gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_COPY);
+ gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
has_layer_to_erase = true;
}
@@ -2169,7 +2152,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
add_frame_mode = GP_GETFRAME_ADD_NEW;
}
- p->gpf = BKE_gpencil_layer_getframe(p->gpl, cfra_eval, add_frame_mode);
+ p->gpf = BKE_gpencil_layer_getframe(p->gpl, CFRA, add_frame_mode);
if (p->gpf == NULL) {
p->status = GP_STATUS_ERROR;
@@ -2624,14 +2607,14 @@ static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgra
p->opressure = p->pressure;
p->ocurtime = p->curtime;
- pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1;
+ pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_used - 1;
if (p->paintmode != GP_PAINTMODE_ERASER) {
ED_gpencil_toggle_brush_cursor(C, true, &pt->x);
}
}
else if ((p->brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) &&
- (gpd->runtime.sbuffer_size > 0)) {
- pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1;
+ (gpd->runtime.sbuffer_used > 0)) {
+ pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_used - 1;
if (p->paintmode != GP_PAINTMODE_ERASER) {
ED_gpencil_toggle_brush_cursor(C, true, &pt->x);
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index cca94925e6e..c79366e6a2b 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -114,16 +114,8 @@ static void gp_session_validatebuffer(tGPDprimitive *p)
bGPdata *gpd = p->gpd;
/* clear memory of buffer (or allocate it if starting a new session) */
- if (gpd->runtime.sbuffer) {
- memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
- }
- else {
- gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX,
- "gp_session_strokebuffer");
- }
-
- /* reset indices */
- gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.sbuffer = ED_gpencil_sbuffer_ensure(
+ gpd->runtime.sbuffer, &gpd->runtime.sbuffer_size, &gpd->runtime.sbuffer_used, true);
/* reset flags */
gpd->runtime.sbuffer_sflag = 0;
@@ -305,8 +297,8 @@ static void gpencil_primitive_allocate_memory(tGPDprimitive *tgpi)
/* Helper: Create internal strokes primitives data */
static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
+ int cfra = CFRA;
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
@@ -318,7 +310,7 @@ static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
/* create a new temporary frame */
tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
- tgpi->gpf->framenum = tgpi->cframe = cfra_eval;
+ tgpi->gpf->framenum = tgpi->cframe = cfra;
/* create new temp stroke */
bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "Temp bGPDstroke");
@@ -828,7 +820,7 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
}
/* Copy points to buffer */
- tGPspoint *tpt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size);
+ tGPspoint *tpt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_used);
/* Store original points */
float tmp_xyp[2];
@@ -927,10 +919,10 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
tpt->time = p2d->time;
/* point uv */
- if (gpd->runtime.sbuffer_size > 0) {
+ if (gpd->runtime.sbuffer_used > 0) {
MaterialGPencilStyle *gp_style = tgpi->mat->gp_style;
const float pixsize = gp_style->texture_pixsize / 1000000.0f;
- tGPspoint *tptb = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1;
+ tGPspoint *tptb = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_used - 1;
bGPDspoint spt, spt2;
/* get origin to reproject point */
@@ -958,7 +950,11 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
tpt->uv_rot = p2d->uv_rot;
- gpd->runtime.sbuffer_size++;
+ gpd->runtime.sbuffer_used++;
+
+ /* check if still room in buffer or add more */
+ gpd->runtime.sbuffer = ED_gpencil_sbuffer_ensure(
+ gpd->runtime.sbuffer, &gpd->runtime.sbuffer_size, &gpd->runtime.sbuffer_used, false);
/* add small offset to keep stroke over the surface */
if ((depth_arr) && (gpd->zdepth_offset > 0.0f)) {
@@ -1078,6 +1074,7 @@ static void gpencil_primitive_exit(bContext *C, wmOperator *op)
gpd->runtime.sbuffer = NULL;
/* clear flags */
+ gpd->runtime.sbuffer_used = 0;
gpd->runtime.sbuffer_size = 0;
gpd->runtime.sbuffer_sflag = 0;
}
@@ -1096,11 +1093,8 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
bGPdata *gpd = CTX_data_gpencil_data(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
Paint *paint = &ts->gp_paint->paint;
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
-
/* create temporary operator data */
tGPDprimitive *tgpi = MEM_callocN(sizeof(tGPDprimitive), "GPencil Primitive Data");
op->customdata = tgpi;
@@ -1122,7 +1116,7 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
tgpi->orign_type = RNA_enum_get(op->ptr, "type");
/* set current frame number */
- tgpi->cframe = cfra_eval;
+ tgpi->cframe = CFRA;
/* set GP datablock */
tgpi->gpd = gpd;
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index ba806022d3e..b1d9bcfbe16 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -302,11 +302,10 @@ typedef enum eGP_SelectGrouped {
/* On each visible layer, check for selected strokes - if found, select all others */
static void gp_select_same_layer(bContext *C)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV);
bGPDstroke *gps;
bool found = false;
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 065c133bf97..ac8196f5ed0 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1740,7 +1740,7 @@ static void gp_brush_cursor_draw(bContext *C, int x, int y, void *customdata)
}
/* while drawing hide */
- if ((gpd->runtime.sbuffer_size > 0) &&
+ if ((gpd->runtime.sbuffer_used > 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0)) {
return;
@@ -2525,3 +2525,37 @@ void ED_gpencil_select_toggle_all(bContext *C, int action)
CTX_DATA_END;
}
}
+
+/* Ensure the SBuffer (while drawing stroke) size is enough to save all points of the stroke */
+tGPspoint *ED_gpencil_sbuffer_ensure(tGPspoint *buffer_array,
+ short *buffer_size,
+ short *buffer_used,
+ const bool clear)
+{
+ tGPspoint *p = NULL;
+
+ /* By default a buffer is created with one block with a predefined number of free points,
+ * if the size is not enough, the cache is reallocated adding a new block of free points.
+ * This is done in order to keep cache small and improve speed. */
+ if (*buffer_used + 1 > *buffer_size) {
+ if ((*buffer_size == 0) || (buffer_array == NULL)) {
+ p = MEM_callocN(sizeof(struct tGPspoint) * GP_STROKE_BUFFER_CHUNK, "GPencil Sbuffer");
+ *buffer_size = GP_STROKE_BUFFER_CHUNK;
+ }
+ else {
+ *buffer_size += GP_STROKE_BUFFER_CHUNK;
+ p = MEM_recallocN(buffer_array, sizeof(struct tGPspoint) * *buffer_size);
+ }
+ buffer_array = p;
+ }
+
+ /* clear old data */
+ if (clear) {
+ *buffer_used = 0;
+ if (buffer_array != NULL) {
+ memset(buffer_array, 0, sizeof(tGPspoint) * *buffer_size);
+ }
+ }
+
+ return buffer_array;
+}
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 0e3204b30c7..6410e6630a7 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -35,6 +35,7 @@ struct bGPDlayer;
struct bGPDspoint;
struct bGPDstroke;
struct bGPdata;
+struct tGPspoint;
struct ARegion;
struct Depsgraph;
@@ -287,4 +288,9 @@ int ED_gpencil_select_stroke_segment(struct bGPDlayer *gpl,
void ED_gpencil_select_toggle_all(struct bContext *C, int action);
+/* Ensure stroke sbuffer size is enough */
+struct tGPspoint *ED_gpencil_sbuffer_ensure(struct tGPspoint *buffer_array,
+ short *buffer_size,
+ short *buffer_used,
+ const bool clear);
#endif /* __ED_GPENCIL_H__ */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index ebeeea3fa4c..72efea32c38 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -512,26 +512,6 @@ int view3d_opengl_select(struct ViewContext *vc,
eV3DSelectObjectFilter select_filter);
/* view3d_select.c */
-struct EDSelectID_Context;
-struct EDSelectID_Context *ED_view3d_select_id_context_create(struct ViewContext *vc,
- struct Base **bases,
- const uint bases_len,
- short select_mode);
-
-void ED_view3d_select_id_context_destroy(struct EDSelectID_Context *sel_id_ctx);
-void ED_view3d_select_id_validate_view_matrices(struct EDSelectID_Context *sel_id_ctx,
- struct ViewContext *vc);
-
-uint ED_view3d_select_id_context_offset_for_object_elem(
- const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type);
-
-uint ED_view3d_select_id_context_elem_len(const struct EDSelectID_Context *sel_id_ctx);
-bool ED_view3d_select_id_elem_get(struct EDSelectID_Context *sel_id_ctx,
- const uint sel_id,
- uint *r_elem,
- uint *r_base_index,
- char *r_elem_type);
-
float ED_view3d_select_dist_px(void);
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc);
void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 3b2a80c1e05..5ef3e5d8987 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -562,7 +562,8 @@ int UI_popover_panel_invoke(struct bContext *C,
bool keep_open,
struct ReportList *reports);
-uiPopover *UI_popover_begin(struct bContext *C, int menu_width) ATTR_NONNULL(1);
+uiPopover *UI_popover_begin(struct bContext *C, int menu_width, bool from_active_button)
+ ATTR_NONNULL(1);
void UI_popover_end(struct bContext *C, struct uiPopover *head, struct wmKeyMap *keymap);
struct uiLayout *UI_popover_layout(uiPopover *head);
void UI_popover_once_clear(uiPopover *pup);
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 7afdbe9d266..6a36bf364a3 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1606,6 +1606,11 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const
float sizey_solid = sizey * 0.25f;
float y1 = rect->ymin;
+ /* exit early if too narrow */
+ if (sizex <= 0) {
+ return;
+ }
+
GPUVertFormat *format = immVertexFormat();
pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a7fc0cfec25..d4e8b7548bc 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -10124,7 +10124,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
ui_region_winrct_get_no_margin(ar_temp, &winrct);
- if (BLI_rcti_isect_pt_v(&winrct, &event->x)) {
+ if (BLI_rcti_isect_pt_v(&winrct, &event->x) || ui_region_find_active_but(ar_temp)) {
BLI_assert(ar_temp->type->regionid == RGN_TYPE_TEMPORARY);
is_inside_menu = true;
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c
index 43afdc534ad..bba5103bc03 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.c
@@ -57,16 +57,32 @@
/* -------------------------------------------------------------------- */
/** \name Utilities
* \{ */
+struct HudRegionData {
+ short regionid;
+};
-static bool last_redo_poll(const bContext *C)
+static bool last_redo_poll(const bContext *C, short region_type)
{
wmOperator *op = WM_operator_last_redo(C);
if (op == NULL) {
return false;
}
+
bool success = false;
- if (WM_operator_repeat_check(C, op) && WM_operator_check_ui_empty(op->type) == false) {
- success = WM_operator_poll((bContext *)C, op->type);
+ {
+ /* Make sure that we are using the same region type as the originial
+ * operator call. Otherwise we would be polling the operator with the
+ * wrong context.
+ */
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar_op = (region_type != -1) ? BKE_area_find_region_type(sa, region_type) : NULL;
+ ARegion *ar_prev = CTX_wm_region(C);
+ CTX_wm_region_set((bContext *)C, ar_op);
+
+ if (WM_operator_repeat_check(C, op) && WM_operator_check_ui_empty(op->type) == false) {
+ success = WM_operator_poll((bContext *)C, op->type);
+ }
+ CTX_wm_region_set((bContext *)C, ar_prev);
}
return success;
}
@@ -87,7 +103,15 @@ static void hud_region_hide(ARegion *ar)
static bool hud_panel_operator_redo_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return last_redo_poll(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HUD);
+ if (ar != NULL) {
+ struct HudRegionData *hrd = ar->regiondata;
+ if (hrd != NULL) {
+ return last_redo_poll(C, hrd->regionid);
+ }
+ }
+ return false;
}
static void hud_panel_operator_redo_draw_header(const bContext *C, Panel *pa)
@@ -132,10 +156,6 @@ static void hud_panels_register(ARegionType *art, int space_type, int region_typ
/** \name Callbacks for Floating Region
* \{ */
-struct HudRegionData {
- short regionid;
-};
-
static void hud_region_init(wmWindowManager *wm, ARegion *ar)
{
ED_region_panels_init(wm, ar);
@@ -150,21 +170,8 @@ static void hud_region_free(ARegion *ar)
static void hud_region_layout(const bContext *C, ARegion *ar)
{
- bool ok = false;
-
- {
- struct HudRegionData *hrd = ar->regiondata;
- if (hrd != NULL) {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar_op = (hrd->regionid != -1) ? BKE_area_find_region_type(sa, hrd->regionid) : NULL;
- ARegion *ar_prev = CTX_wm_region(C);
- CTX_wm_region_set((bContext *)C, ar_op);
- ok = last_redo_poll(C);
- CTX_wm_region_set((bContext *)C, ar_prev);
- }
- }
-
- if (!ok) {
+ struct HudRegionData *hrd = ar->regiondata;
+ if (hrd == NULL || !last_redo_poll(C, hrd->regionid)) {
ED_region_tag_redraw(ar);
hud_region_hide(ar);
return;
@@ -301,7 +308,9 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
bool init = false;
bool was_hidden = ar == NULL || ar->visible == false;
- if (!last_redo_poll(C)) {
+ ARegion *ar_op = CTX_wm_region(C);
+ BLI_assert((ar_op == NULL) || (ar_op->regiontype != RGN_TYPE_HUD));
+ if (!last_redo_poll(C, ar_op ? ar_op->regiontype : -1)) {
if (ar) {
ED_region_tag_redraw(ar);
hud_region_hide(ar);
@@ -328,8 +337,6 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
}
{
- ARegion *ar_op = CTX_wm_region(C);
- BLI_assert((ar_op == NULL) || (ar_op->regiontype != RGN_TYPE_HUD));
struct HudRegionData *hrd = ar->regiondata;
if (hrd == NULL) {
hrd = MEM_callocN(sizeof(*hrd), __func__);
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index 53c96fb72a7..028d99ac052 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -72,6 +72,7 @@ struct uiPopover {
uiBlock *block;
uiLayout *layout;
uiBut *but;
+ ARegion *butregion;
/* Needed for keymap removal. */
wmWindow *window;
@@ -325,7 +326,7 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
block = pup->block;
}
else {
- uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x);
+ uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x, false);
layout = UI_popover_layout(pup);
UI_paneltype_draw(C, pt, layout);
UI_popover_end(C, pup, NULL);
@@ -346,8 +347,11 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
/**
* Only return handler, and set optional title.
+ *
+ * \param from_active_button: Use the active button for positioning,
+ * use when the popover is activated from an operator instead of directly from the button.
*/
-uiPopover *UI_popover_begin(bContext *C, int ui_size_x)
+uiPopover *UI_popover_begin(bContext *C, int ui_size_x, bool from_active_button)
{
uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
if (ui_size_x == 0) {
@@ -355,6 +359,20 @@ uiPopover *UI_popover_begin(bContext *C, int ui_size_x)
}
pup->ui_size_x = ui_size_x;
+ ARegion *butregion = NULL;
+ uiBut *but = NULL;
+
+ if (from_active_button) {
+ butregion = CTX_wm_region(C);
+ but = UI_region_active_but_get(butregion);
+ if (but == NULL) {
+ butregion = NULL;
+ }
+ }
+
+ pup->but = but;
+ pup->butregion = butregion;
+
/* Operator context default same as menus, change if needed. */
ui_popover_create_block(C, pup, WM_OP_EXEC_REGION_WIN);
@@ -387,7 +405,7 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
}
handle = ui_popup_block_create(
- C, NULL, NULL, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
+ C, pup->butregion, pup->but, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
/* Add handlers. */
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c
index 5164970198e..abc5224c4d6 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -68,9 +68,19 @@ typedef struct UndoLattice {
static void undolatt_to_editlatt(UndoLattice *ult, EditLatt *editlatt)
{
- int len = editlatt->latt->pntsu * editlatt->latt->pntsv * editlatt->latt->pntsw;
+ const int len_src = ult->pntsu * ult->pntsv * ult->pntsw;
+ const int len_dst = editlatt->latt->pntsu * editlatt->latt->pntsv * editlatt->latt->pntsw;
+ if (len_src != len_dst) {
+ MEM_freeN(editlatt->latt->def);
+ editlatt->latt->def = MEM_dupallocN(ult->def);
+ }
+ else {
+ memcpy(editlatt->latt->def, ult->def, sizeof(BPoint) * len_src);
+ }
- memcpy(editlatt->latt->def, ult->def, sizeof(BPoint) * len);
+ editlatt->latt->pntsu = ult->pntsu;
+ editlatt->latt->pntsv = ult->pntsv;
+ editlatt->latt->pntsw = ult->pntsw;
editlatt->latt->actbp = ult->actbp;
}
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 57bf67e825e..9a779db4812 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../blentranslation
../../bmesh
../../depsgraph
+ ../../draw
../../gpu
../../imbuf
../../makesdna
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 7b770f055b4..12b5a36c510 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -68,6 +68,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "DRW_engine.h"
+
#include "mesh_intern.h" /* own include */
/* use bmesh operator flags for a few operators */
@@ -197,15 +199,11 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
/** \name Back-Buffer OpenGL Selection
* \{ */
-static BMElem *EDBM_select_id_bm_elem_get(struct EDSelectID_Context *sel_id_ctx,
- Base **bases,
- const uint sel_id,
- uint *r_base_index)
+static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint *r_base_index)
{
uint elem_id;
char elem_type = 0;
- bool success = ED_view3d_select_id_elem_get(
- sel_id_ctx, sel_id, &elem_id, r_base_index, &elem_type);
+ bool success = DRW_select_elem_get(sel_id, &elem_id, r_base_index, &elem_type);
if (success) {
Object *obedit = bases[*r_base_index]->object;
@@ -335,20 +333,17 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
{
FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX);
- struct EDSelectID_Context *sel_id_ctx = ED_view3d_select_id_context_create(
- vc, bases, bases_len, select_mode);
+ DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, select_mode);
index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px);
if (index) {
- eve = (BMVert *)EDBM_select_id_bm_elem_get(sel_id_ctx, bases, index, &base_index);
+ eve = (BMVert *)edbm_select_id_bm_elem_get(bases, index, &base_index);
}
else {
eve = NULL;
}
- ED_view3d_select_id_context_destroy(sel_id_ctx);
-
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
@@ -564,20 +559,17 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
{
FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE);
- struct EDSelectID_Context *sel_id_ctx = ED_view3d_select_id_context_create(
- vc, bases, bases_len, select_mode);
+ DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, select_mode);
index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px);
if (index) {
- eed = (BMEdge *)EDBM_select_id_bm_elem_get(sel_id_ctx, bases, index, &base_index);
+ eed = (BMEdge *)edbm_select_id_bm_elem_get(bases, index, &base_index);
}
else {
eed = NULL;
}
- ED_view3d_select_id_context_destroy(sel_id_ctx);
-
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
@@ -777,20 +769,17 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
{
FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE);
- struct EDSelectID_Context *sel_id_ctx = ED_view3d_select_id_context_create(
- vc, bases, bases_len, select_mode);
+ DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, select_mode);
index = ED_select_buffer_sample_point(vc->mval);
if (index) {
- efa = (BMFace *)EDBM_select_id_bm_elem_get(sel_id_ctx, bases, index, &base_index);
+ efa = (BMFace *)edbm_select_id_bm_elem_get(bases, index, &base_index);
}
else {
efa = NULL;
}
- ED_view3d_select_id_context_destroy(sel_id_ctx);
-
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 919de4cdb20..3b5c8e9f101 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4593,7 +4593,8 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op)
/* Only reuse on redo because these settings need to match the current selection.
* We never want to use them on other geometry, repeat last for eg, see: T60777. */
- if ((op->flag & OP_IS_REPEAT_LAST) == 0 && RNA_property_is_set(op->ptr, prop_span)) {
+ if (((op->flag & OP_IS_INVOKE) || (op->flag & OP_IS_REPEAT_LAST) == 0) &&
+ RNA_property_is_set(op->ptr, prop_span)) {
span = RNA_property_int_get(op->ptr, prop_span);
span = min_ii(span, (clamp / 2) - 1);
calc_span = false;
@@ -8615,7 +8616,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
switch (mode) {
case EDBM_CLNOR_TOOLS_COPY:
- if (bm->totfacesel == 0 || bm->totvertsel == 0) {
+ if (bm->totfacesel == 0 && bm->totvertsel == 0) {
BM_loop_normal_editdata_array_free(lnors_ed_arr);
continue;
}
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index e823fb46140..7071258d8cf 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -699,7 +699,6 @@ typedef struct MeshUndoStep_Elem {
typedef struct MeshUndoStep {
UndoStep step;
- struct UndoIDPtrMap *id_map;
MeshUndoStep_Elem *elems;
uint elems_len;
} MeshUndoStep;
@@ -788,10 +787,6 @@ static void mesh_undosys_step_free(UndoStep *us_p)
undomesh_free_data(&elem->data);
}
MEM_freeN(us->elems);
-
- if (us->id_map != NULL) {
- BKE_undosys_ID_map_destroy(us->id_map);
- }
}
static void mesh_undosys_foreach_ID_ref(UndoStep *us_p,
@@ -804,10 +799,6 @@ static void mesh_undosys_foreach_ID_ref(UndoStep *us_p,
MeshUndoStep_Elem *elem = &us->elems[i];
foreach_ID_ref_fn(user_data, ((UndoRefID *)&elem->obedit_ref));
}
-
- if (us->id_map != NULL) {
- BKE_undosys_ID_map_foreach_ID_ref(us->id_map, foreach_ID_ref_fn, user_data);
- }
}
/* Export for ED_undo_sys. */
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 690bc270605..465a60ba75c 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -760,7 +760,7 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
static bool datalayout_transfer_poll(bContext *C)
{
- return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH)) ||
+ return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH), true) ||
data_transfer_poll(C));
}
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index c939cb0a61d..707489d588a 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -52,6 +52,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "RNA_define.h"
#include "RNA_access.h"
@@ -527,6 +528,7 @@ static int add_hook_object(const bContext *C,
int mode,
ReportList *reports)
{
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
ModifierData *md = NULL;
HookModifierData *hmd = NULL;
float cent[3];
@@ -601,11 +603,13 @@ static int add_hook_object(const bContext *C,
/* matrix calculus */
/* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
/* (parentinv ) */
- BKE_object_where_is_calc(CTX_data_depsgraph(C), scene, ob);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ BKE_object_transform_copy(ob_eval, ob);
+ BKE_object_where_is_calc(depsgraph, scene, ob_eval);
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob_eval->imat, ob_eval->obmat);
/* apparently this call goes from right to left... */
- mul_m4_series(hmd->parentinv, pose_mat, ob->imat, obedit->obmat);
+ mul_m4_series(hmd->parentinv, pose_mat, ob_eval->imat, obedit->obmat);
DEG_relations_tag_update(bmain);
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index b9350052093..e697c25b37f 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -137,7 +137,10 @@ void COLLECTION_OT_objects_add_active(struct wmOperatorType *ot);
void COLLECTION_OT_objects_remove_active(struct wmOperatorType *ot);
/* object_modifier.c */
-bool edit_modifier_poll_generic(struct bContext *C, struct StructRNA *rna_type, int obtype_flag);
+bool edit_modifier_poll_generic(struct bContext *C,
+ struct StructRNA *rna_type,
+ int obtype_flag,
+ const bool is_editmode_allowed);
bool edit_modifier_poll(struct bContext *C);
void edit_modifier_properties(struct wmOperatorType *ot);
int edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 08012842c37..d1d910021a6 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -99,7 +99,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *
BKE_object_eval_reset(ob_eval);
if (ob->type == OB_MESH) {
Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
- BKE_id_free(NULL, me_eval);
+ BKE_mesh_eval_delete(me_eval);
}
else if (ob->type == OB_LATTICE) {
BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval);
@@ -912,7 +912,10 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
/********** generic functions for operators using mod names and data context *********************/
-bool edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
+bool edit_modifier_poll_generic(bContext *C,
+ StructRNA *rna_type,
+ int obtype_flag,
+ const bool is_editmode_allowed)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
@@ -932,12 +935,17 @@ bool edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_fla
return (((ModifierData *)ptr.data)->flag & eModifierFlag_OverrideLibrary_Local) != 0;
}
+ if (!is_editmode_allowed && CTX_data_edit_object(C) != NULL) {
+ CTX_wm_operator_poll_msg_set(C, "This modifier operation is not allowed from Edit mode");
+ return 0;
+ }
+
return 1;
}
bool edit_modifier_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true);
}
void edit_modifier_properties(wmOperatorType *ot)
@@ -1274,7 +1282,7 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot)
static bool multires_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1 << OB_MESH));
+ return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1 << OB_MESH), true);
}
static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
@@ -1627,14 +1635,13 @@ static void modifier_skin_customdata_delete(Object *ob)
static bool skin_poll(bContext *C)
{
- return (!CTX_data_edit_object(C) &&
- edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
+ return (edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), false));
}
static bool skin_edit_poll(bContext *C)
{
return (CTX_data_edit_object(C) &&
- edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
+ edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true));
}
static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
@@ -1987,7 +1994,7 @@ void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
static bool correctivesmooth_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_CorrectiveSmoothModifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_CorrectiveSmoothModifier, 0, true);
}
static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
@@ -2065,7 +2072,7 @@ void OBJECT_OT_correctivesmooth_bind(wmOperatorType *ot)
static bool meshdeform_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0, true);
}
static int meshdeform_bind_exec(bContext *C, wmOperator *op)
@@ -2138,7 +2145,7 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
static bool explode_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0, true);
}
static int explode_refresh_exec(bContext *C, wmOperator *op)
@@ -2188,7 +2195,7 @@ void OBJECT_OT_explode_refresh(wmOperatorType *ot)
static bool ocean_bake_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0, true);
}
typedef struct OceanBakeJob {
@@ -2389,7 +2396,7 @@ void OBJECT_OT_ocean_bake(wmOperatorType *ot)
static bool laplaciandeform_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0, false);
}
static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
@@ -2464,7 +2471,7 @@ void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
static bool surfacedeform_bind_poll(bContext *C)
{
- return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0);
+ return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0, true);
}
static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index e6637265fbc..ff31cbc4590 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1582,6 +1582,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
id_us_plus(&ob_dst->instance_collection->id);
ob_dst->transflag |= OB_DUPLICOLLECTION;
}
+ DEG_id_tag_update(&ob_dst->id, ID_RECALC_COPY_ON_WRITE);
break;
case MAKE_LINKS_MODIFIERS:
BKE_object_link_modifiers(scene, ob_dst, ob_src);
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 9c98fdc2a2e..3f7d5dba149 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -856,6 +856,7 @@ static int apply_objects_internal(bContext *C,
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
if (ob->type == OB_ARMATURE) {
/* needed for bone parents */
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
BKE_pose_where_is(depsgraph, scene, ob_eval);
}
@@ -1229,6 +1230,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_transform_copy(ob_eval, ob);
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
BKE_pose_where_is(depsgraph, scene, ob_eval); /* needed for bone parents */
@@ -1370,6 +1372,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
if (ob->type == OB_ARMATURE) {
/* needed for bone parents */
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
BKE_pose_where_is(depsgraph, scene, ob_eval);
}
@@ -1398,6 +1401,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
BKE_object_where_is_calc(depsgraph, scene, ob_other_eval);
if (ob_other->type == OB_ARMATURE) {
/* needed for bone parents */
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
BKE_pose_where_is(depsgraph, scene, ob_other_eval);
}
ignore_parent_tx(bmain, depsgraph, scene, ob_other);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 4e6022cf18c..2f2516f2055 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -785,7 +785,7 @@ typedef struct KeyIterData {
static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
KeyIterData *iter_data = (KeyIterData *)iter_data_v;
PEData *data = iter_data->data;
@@ -855,7 +855,7 @@ static void foreach_mouse_hit_key(PEData *data, ForHitKeyMatFunc func, int selec
iter_data.selected = selected;
iter_data.func = func;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(0, edit->totpoint, &iter_data, foreach_mouse_hit_key_iter, &settings);
@@ -1152,7 +1152,7 @@ typedef struct DeflectEmitterIter {
static void deflect_emitter_iter(void *__restrict iter_data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
DeflectEmitterIter *iter_data = (DeflectEmitterIter *)iter_data_v;
PTCacheEdit *edit = iter_data->edit;
@@ -1246,7 +1246,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
iter_data.dist = dist;
iter_data.emitterdist = pset->emitterdist;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(0, edit->totpoint, &iter_data, deflect_emitter_iter, &settings);
@@ -1258,7 +1258,7 @@ typedef struct ApplyLengthsIterData {
static void apply_lengths_iter(void *__restrict iter_data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
ApplyLengthsIterData *iter_data = (ApplyLengthsIterData *)iter_data_v;
PTCacheEdit *edit = iter_data->edit;
@@ -1296,7 +1296,7 @@ static void PE_apply_lengths(Scene *scene, PTCacheEdit *edit)
ApplyLengthsIterData iter_data;
iter_data.edit = edit;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(0, edit->totpoint, &iter_data, apply_lengths_iter, &settings);
@@ -1309,7 +1309,7 @@ typedef struct IterateLengthsIterData {
static void iterate_lengths_iter(void *__restrict iter_data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
IterateLengthsIterData *iter_data = (IterateLengthsIterData *)iter_data_v;
PTCacheEdit *edit = iter_data->edit;
@@ -1371,7 +1371,7 @@ static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit)
iter_data.edit = edit;
iter_data.pset = pset;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
BLI_task_parallel_range(0, edit->totpoint, &iter_data, iterate_lengths_iter, &settings);
@@ -4116,7 +4116,7 @@ typedef struct BrushAddCountIterTLSData {
static void brush_add_count_iter(void *__restrict iter_data_v,
const int iter,
- const ParallelRangeTLS *__restrict tls_v)
+ const TaskParallelTLS *__restrict tls_v)
{
BrushAddCountIterData *iter_data = (BrushAddCountIterData *)iter_data_v;
Depsgraph *depsgraph = iter_data->depsgraph;
@@ -4272,7 +4272,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
BrushAddCountIterTLSData tls = {NULL};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC;
settings.userdata_chunk = &tls;
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index b03ec56c7e4..fcee2cde5b1 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -1090,7 +1090,6 @@ static bool copy_particle_systems_to_object(const bContext *C,
ModifierData *md;
ParticleSystem *psys_start = NULL, *psys, *psys_from;
ParticleSystem **tmp_psys;
- Mesh *final_mesh;
CustomData_MeshMasks cdmask = {0};
int i, totpsys;
@@ -1132,9 +1131,6 @@ static bool copy_particle_systems_to_object(const bContext *C,
*/
psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
- /* Get the evaluated mesh (psys and their modifiers have not been appended yet) */
- final_mesh = mesh_get_eval_final(depsgraph, scene, ob_to, &cdmask);
-
/* now append psys to the object and make modifiers */
for (i = 0, psys_from = PSYS_FROM_FIRST; i < totpsys;
++i, psys_from = PSYS_FROM_NEXT(psys_from)) {
@@ -1155,10 +1151,6 @@ static bool copy_particle_systems_to_object(const bContext *C,
modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
psmd->psys = psys;
- BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&psmd->mesh_final, LIB_ID_COPY_LOCALIZE);
-
- BKE_mesh_calc_normals(psmd->mesh_final);
- BKE_mesh_tessface_ensure(psmd->mesh_final);
if (psys_from->edit) {
copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index fbabdc2f3c1..c646ef12846 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -153,7 +153,6 @@ typedef struct ShaderPreview {
short *stop, *do_update;
Scene *scene;
- Depsgraph *depsgraph;
ID *id, *id_copy;
ID *parent;
MTex *slot;
@@ -185,7 +184,6 @@ typedef struct IconPreviewSize {
typedef struct IconPreview {
Main *bmain;
Scene *scene;
- Depsgraph *depsgraph;
void *owner;
ID *id, *id_copy;
ListBase sizes;
@@ -1229,7 +1227,6 @@ static void icon_preview_startjob_all_sizes(void *customdata,
/* construct shader preview from image size and previewcustomdata */
sp->scene = ip->scene;
- sp->depsgraph = ip->depsgraph;
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
@@ -1372,7 +1369,6 @@ void ED_preview_icon_job(const bContext *C,
/* customdata for preview thread */
ip->bmain = CTX_data_main(C);
ip->scene = CTX_data_scene(C);
- ip->depsgraph = CTX_data_depsgraph(C);
ip->owner = owner;
ip->id = id;
ip->id_copy = duplicate_ids(id);
@@ -1439,7 +1435,6 @@ void ED_preview_shader_job(const bContext *C,
/* customdata for preview thread */
sp->scene = scene;
- sp->depsgraph = CTX_data_depsgraph(C);
sp->owner = owner;
sp->sizex = sizex;
sp->sizey = sizey;
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index e59477fbe6e..dddc33e3ad0 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1457,6 +1457,8 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
{
Scene *scene = DEG_get_input_scene(depsgraph);
+ DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_TIME);
+
#ifdef DURIAN_CAMERA_SWITCH
void *camera = BKE_scene_camera_switch_find(scene);
if (camera && scene->camera != camera) {
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 23617e687ea..2a8ff9d4f78 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../../makesrna
../../render/extern/include
../../windowmanager
+ ../../../../intern/atomic
../../../../intern/glew-mx
../../../../intern/guardedalloc
)
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index ac74afce79e..576baf5794b 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -148,7 +148,7 @@ typedef struct LoadTexData {
static void load_tex_task_cb_ex(void *__restrict userdata,
const int j,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
LoadTexData *data = userdata;
Brush *br = data->br;
@@ -328,7 +328,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
.radius = radius,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
BLI_task_parallel_range(0, size, &data, load_tex_task_cb_ex, &settings);
@@ -385,7 +385,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
static void load_tex_cursor_task_cb(void *__restrict userdata,
const int j,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
LoadTexData *data = userdata;
Brush *br = data->br;
@@ -468,7 +468,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
.size = size,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, &settings);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 41dfd6f68c3..a0f578c04d0 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1246,8 +1246,7 @@ static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Paint *paint = BKE_paint_get_active(scene, view_layer);
+ Paint *paint = BKE_paint_get_active_from_context(C);
Brush *br = BKE_paint_brush(paint);
if (ups->flag & UNIFIED_PAINT_COLOR) {
@@ -1256,6 +1255,10 @@ static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
else if (br) {
swap_v3_v3(br->rgb, br->secondary_rgb);
}
+ else {
+ return OPERATOR_CANCELLED;
+ }
+
WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, br);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 474d3a8ceba..8f1156295a3 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -1251,7 +1251,7 @@ typedef struct Paint2DForeachData {
static void paint_2d_op_foreach_do(void *__restrict data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
Paint2DForeachData *data = (Paint2DForeachData *)data_v;
paint_2d_do_making_brush(data->s,
@@ -1360,7 +1360,7 @@ static int paint_2d_op(void *state,
data.tilex = tilex;
data.tilew = tilew;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
BLI_task_parallel_range(tiley, tileh + 1, &data, paint_2d_op_foreach_do, &settings);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 22de22e8e59..f768a66a41c 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -44,6 +44,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "atomic_ops.h"
+
#include "BLT_translation.h"
#include "IMB_imbuf.h"
@@ -366,7 +368,7 @@ typedef struct ProjPaintState {
int bucketMin[2];
int bucketMax[2];
/** must lock threads while accessing these. */
- int context_bucket_x, context_bucket_y;
+ int context_bucket_index;
struct CurveMapping *cavity_curve;
BlurKernel *blurkernel;
@@ -4712,11 +4714,8 @@ static bool project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
/* mouse outside the model areas? */
if (ps->bucketMin[0] == ps->bucketMax[0] || ps->bucketMin[1] == ps->bucketMax[1]) {
- return 0;
+ return false;
}
-
- ps->context_bucket_x = ps->bucketMin[0];
- ps->context_bucket_y = ps->bucketMin[1];
}
else { /* reproject: PROJ_SRC_* */
ps->bucketMin[0] = 0;
@@ -4724,11 +4723,10 @@ static bool project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
ps->bucketMax[0] = ps->buckets_x;
ps->bucketMax[1] = ps->buckets_y;
-
- ps->context_bucket_x = 0;
- ps->context_bucket_y = 0;
}
- return 1;
+
+ ps->context_bucket_index = ps->bucketMin[0] + ps->bucketMin[1] * ps->buckets_x;
+ return true;
}
static bool project_bucket_iter_next(ProjPaintState *ps,
@@ -4738,37 +4736,28 @@ static bool project_bucket_iter_next(ProjPaintState *ps,
{
const int diameter = 2 * ps->brush_size;
- if (ps->thread_tot > 1) {
- BLI_thread_lock(LOCK_CUSTOM1);
- }
-
- // printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y);
+ const int max_bucket_idx = ps->bucketMax[0] + (ps->bucketMax[1] - 1) * ps->buckets_x;
- for (; ps->context_bucket_y < ps->bucketMax[1]; ps->context_bucket_y++) {
- for (; ps->context_bucket_x < ps->bucketMax[0]; ps->context_bucket_x++) {
+ for (int bidx = atomic_fetch_and_add_int32(&ps->context_bucket_index, 1); bidx < max_bucket_idx;
+ bidx = atomic_fetch_and_add_int32(&ps->context_bucket_index, 1)) {
+ const int bucket_y = bidx / ps->buckets_x;
+ const int bucket_x = bidx - (bucket_y * ps->buckets_x);
+ BLI_assert(bucket_y >= ps->bucketMin[1] && bucket_y < ps->bucketMax[1]);
+ if (bucket_x >= ps->bucketMin[0] && bucket_x < ps->bucketMax[0]) {
/* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
- project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
+ project_bucket_bounds(ps, bucket_x, bucket_y, bucket_bounds);
if ((ps->source != PROJ_SRC_VIEW) ||
project_bucket_isect_circle(mval, (float)(diameter * diameter), bucket_bounds)) {
- *bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
- ps->context_bucket_x++;
-
- if (ps->thread_tot > 1) {
- BLI_thread_unlock(LOCK_CUSTOM1);
- }
+ *bucket_index = bidx;
- return 1;
+ return true;
}
}
- ps->context_bucket_x = ps->bucketMin[0];
}
- if (ps->thread_tot > 1) {
- BLI_thread_unlock(LOCK_CUSTOM1);
- }
- return 0;
+ return false;
}
/* Each thread gets one of these, also used as an argument to pass to project_paint_op */
@@ -5733,6 +5722,7 @@ void paint_proj_stroke(const bContext *C,
return;
}
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
ED_region_tag_redraw(ar);
return;
diff --git a/source/blender/editors/sculpt_paint/paint_image_undo.c b/source/blender/editors/sculpt_paint/paint_image_undo.c
index e7f100ebacb..2a1158ec804 100644
--- a/source/blender/editors/sculpt_paint/paint_image_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_image_undo.c
@@ -69,7 +69,10 @@ typedef struct UndoImageTile {
int x, y;
- Image *ima;
+ /* TODO(campbell): avoid storing the ID per tile,
+ * adds unnecessary overhead restoring undo steps when most tiles share the same image. */
+ UndoRefID_Image image_ref;
+
short source, use_float;
char gen_type;
bool valid;
@@ -245,7 +248,7 @@ void *image_undo_push_tile(ListBase *undo_tiles,
tile->source = ima->source;
tile->use_float = use_float;
tile->valid = true;
- tile->ima = ima;
+ tile->image_ref.ptr = ima;
if (valid) {
*valid = &tile->valid;
@@ -284,7 +287,7 @@ static void image_undo_restore_runtime(ListBase *lb)
tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect);
for (tile = lb->first; tile; tile = tile->next) {
- Image *ima = tile->ima;
+ Image *ima = tile->image_ref.ptr;
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
undo_copy_tile(tile, tmpibuf, ibuf, RESTORE);
@@ -304,19 +307,15 @@ static void image_undo_restore_runtime(ListBase *lb)
IMB_freeImBuf(tmpibuf);
}
-static void image_undo_restore_list(ListBase *lb, struct UndoIDPtrMap *id_map)
+static void image_undo_restore_list(ListBase *lb)
{
ImBuf *tmpibuf = IMB_allocImBuf(
IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect);
- /* Store last found image. */
- ID *image_prev[2] = {NULL};
-
for (UndoImageTile *tile = lb->first; tile; tile = tile->next) {
short use_float;
- Image *ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(id_map, &tile->ima->id, image_prev);
-
+ Image *ima = tile->image_ref.ptr;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima && ibuf && !STREQ(tile->ibufname, ibuf->name)) {
@@ -398,33 +397,8 @@ typedef struct ImageUndoStep {
ListBase tiles;
bool is_encode_init;
ePaintMode paint_mode;
-
- /* Use for all ID lookups (can be NULL). */
- struct UndoIDPtrMap *id_map;
} ImageUndoStep;
-static void image_undosys_step_encode_store_ids(ImageUndoStep *us)
-{
- us->id_map = BKE_undosys_ID_map_create();
-
- ID *image_prev = NULL;
- for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) {
- BKE_undosys_ID_map_add_with_prev(us->id_map, &tile->ima->id, &image_prev);
- }
-}
-
-/* Restore at runtime. */
-#if 0
-static void paint_undosys_step_decode_restore_ids(ImageUndoStep *us)
-{
- ID *image_prev[2] = {NULL};
- for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) {
- tile->ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(
- us->id_map, &tile->ima->id, image_prev);
- }
-}
-#endif
-
static bool image_undosys_poll(bContext *C)
{
Object *obact = CTX_data_active_object(C);
@@ -486,8 +460,6 @@ static bool image_undosys_step_encode(struct bContext *C,
us->paint_mode = paint_mode;
}
- image_undosys_step_encode_store_ids(us);
-
us_p->is_applied = true;
return true;
@@ -496,18 +468,18 @@ static bool image_undosys_step_encode(struct bContext *C,
static void image_undosys_step_decode_undo_impl(ImageUndoStep *us)
{
BLI_assert(us->step.is_applied == true);
- image_undo_restore_list(&us->tiles, us->id_map);
+ image_undo_restore_list(&us->tiles);
us->step.is_applied = false;
}
static void image_undosys_step_decode_redo_impl(ImageUndoStep *us)
{
BLI_assert(us->step.is_applied == false);
- image_undo_restore_list(&us->tiles, us->id_map);
+ image_undo_restore_list(&us->tiles);
us->step.is_applied = true;
}
-static void image_undosys_step_decode_undo(ImageUndoStep *us)
+static void image_undosys_step_decode_undo(ImageUndoStep *us, bool is_final)
{
ImageUndoStep *us_iter = us;
while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) {
@@ -516,8 +488,11 @@ static void image_undosys_step_decode_undo(ImageUndoStep *us)
}
us_iter = (ImageUndoStep *)us_iter->step.next;
}
- while (us_iter != us) {
+ while (us_iter != us || (!is_final && us_iter == us)) {
image_undosys_step_decode_undo_impl(us_iter);
+ if (us_iter == us) {
+ break;
+ }
us_iter = (ImageUndoStep *)us_iter->step.prev;
}
}
@@ -541,15 +516,11 @@ static void image_undosys_step_decode_redo(ImageUndoStep *us)
}
static void image_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool UNUSED(is_final))
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool is_final)
{
ImageUndoStep *us = (ImageUndoStep *)us_p;
-#if 0
- paint_undosys_step_decode_restore_ids(us);
-#endif
-
if (dir < 0) {
- image_undosys_step_decode_undo(us);
+ image_undosys_step_decode_undo(us, is_final);
}
else {
image_undosys_step_decode_redo(us);
@@ -567,7 +538,6 @@ static void image_undosys_step_free(UndoStep *us_p)
{
ImageUndoStep *us = (ImageUndoStep *)us_p;
image_undo_free_list(&us->tiles);
- BKE_undosys_ID_map_destroy(us->id_map);
}
static void image_undosys_foreach_ID_ref(UndoStep *us_p,
@@ -575,8 +545,8 @@ static void image_undosys_foreach_ID_ref(UndoStep *us_p,
void *user_data)
{
ImageUndoStep *us = (ImageUndoStep *)us_p;
- if (us->id_map != NULL) {
- BKE_undosys_ID_map_foreach_ID_ref(us->id_map, foreach_ID_ref_fn, user_data);
+ for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) {
+ foreach_ID_ref_fn(user_data, ((UndoRefID *)&tile->image_ref));
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index f60ea8410ef..c7e2b008d1f 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -101,7 +101,7 @@ typedef struct MaskTaskData {
static void mask_flood_fill_task_cb(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MaskTaskData *data = userdata;
@@ -159,7 +159,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
.value = value,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(
@@ -243,7 +243,7 @@ static void flip_plane(float out[4], const float in[4], const char symm)
static void mask_box_select_task_cb(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MaskTaskData *data = userdata;
@@ -328,7 +328,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *
.clip_planes_final = clip_planes_final,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) &&
totnode > SCULPT_THREADED_LIMIT);
@@ -405,7 +405,7 @@ static void mask_lasso_px_cb(int x, int x_end, int y, void *user_data)
static void mask_gesture_lasso_task_cb(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
LassoMaskData *lasso_data = userdata;
MaskTaskData *data = &lasso_data->task_data;
@@ -515,7 +515,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
data.task_data.mode = mode;
data.task_data.value = value;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) &&
(totnode > SCULPT_THREADED_LIMIT));
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 980b043bf8b..47fa2872ff9 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1713,7 +1713,7 @@ static float wpaint_get_active_weight(const MDeformVert *dv, const WeightPaintIn
static void do_wpaint_precompute_weight_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
const MDeformVert *dv = &data->me->dvert[n];
@@ -1737,7 +1737,7 @@ static void precompute_weight_values(
.me = me,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
BLI_task_parallel_range(0, me->totvert, &data, do_wpaint_precompute_weight_cb_ex, &settings);
@@ -1746,7 +1746,7 @@ static void precompute_weight_values(
static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -1838,7 +1838,7 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -1949,7 +1949,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2022,7 +2022,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
}
static void do_wpaint_brush_calc_average_weight_cb_ex(
- void *__restrict userdata, const int n, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2078,7 +2078,7 @@ static void calculate_average_weight(SculptThreadedTaskData *data,
struct WPaintAverageAccum *accum = MEM_mallocN(sizeof(*accum) * totnode, __func__);
data->custom_data = accum;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((data->sd->flags & SCULPT_USE_OPENMP) &&
totnode > SCULPT_THREADED_LIMIT);
@@ -2127,7 +2127,7 @@ static void wpaint_paint_leaves(bContext *C,
/* Use this so average can modify its weight without touching the brush. */
data.strength = BKE_brush_weight_get(scene, brush);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
/* NOTE: current mirroring code cannot be run in parallel */
settings.use_threading = !(me->editflag & ME_EDIT_MIRROR_X);
@@ -2706,7 +2706,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
}
static void do_vpaint_brush_calc_average_color_cb_ex(
- void *__restrict userdata, const int n, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2772,7 +2772,7 @@ static float tex_color_alpha_ubyte(SculptThreadedTaskData *data,
static void do_vpaint_brush_draw_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2871,7 +2871,7 @@ static void do_vpaint_brush_draw_task_cb_ex(void *__restrict userdata,
static void do_vpaint_brush_blur_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2989,7 +2989,7 @@ static void do_vpaint_brush_blur_task_cb_ex(void *__restrict userdata,
static void do_vpaint_brush_smear_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3139,7 +3139,7 @@ static void calculate_average_color(SculptThreadedTaskData *data,
struct VPaintAverageAccum *accum = MEM_mallocN(sizeof(*accum) * totnode, __func__);
data->custom_data = accum;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
BLI_task_parallel_range(0, totnode, data, do_vpaint_brush_calc_average_color_cb_ex, &settings);
@@ -3185,7 +3185,7 @@ static void vpaint_paint_leaves(bContext *C,
.lcol = (uint *)me->mloopcol,
.me = me,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
switch ((eBrushVertexPaintTool)brush->vertexpaint_tool) {
case VPAINT_TOOL_AVERAGE:
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 173d6ed5085..4b35fdbd2ed 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -368,7 +368,7 @@ static bool sculpt_stroke_is_dynamic_topology(const SculptSession *ss, const Bru
static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -438,7 +438,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
.nodes = nodes,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && !ss->bm &&
totnode > SCULPT_THREADED_LIMIT);
@@ -801,7 +801,7 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -961,7 +961,7 @@ static void calc_area_center(
};
BLI_mutex_init(&data.mutex);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
@@ -1018,7 +1018,7 @@ void sculpt_pbvh_calc_area_normal(const Brush *brush,
};
BLI_mutex_init(&data.mutex);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = use_threading;
BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
@@ -1063,7 +1063,7 @@ static void calc_area_normal_and_center(
};
BLI_mutex_init(&data.mutex);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
@@ -1758,7 +1758,7 @@ typedef struct {
static void do_smooth_brush_mesh_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -1813,7 +1813,7 @@ static void do_smooth_brush_mesh_task_cb_ex(void *__restrict userdata,
static void do_smooth_brush_bmesh_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -1868,7 +1868,7 @@ static void do_smooth_brush_bmesh_task_cb_ex(void *__restrict userdata,
static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -1925,7 +1925,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
static void do_smooth_brush_multires_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptDoBrushSmoothGridDataChunk *data_chunk = tls->userdata_chunk;
@@ -2115,7 +2115,7 @@ static void smooth(Sculpt *sd,
.strength = strength,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
@@ -2175,7 +2175,7 @@ static void bmesh_topology_rake(
.nodes = nodes,
.strength = factor,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
@@ -2191,7 +2191,7 @@ static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2233,7 +2233,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
.nodes = nodes,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_mask_brush_draw_task_cb_ex, &settings);
@@ -2256,7 +2256,7 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_draw_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2320,7 +2320,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
.offset = offset,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings);
@@ -2331,7 +2331,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
*/
static void do_crease_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2436,7 +2436,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
.flippedbstrength = flippedbstrength,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_crease_brush_task_cb_ex, &settings);
@@ -2444,7 +2444,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2498,7 +2498,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
.nodes = nodes,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings);
@@ -2506,7 +2506,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
static void do_grab_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2570,7 +2570,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
.grab_delta = grab_delta,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings);
@@ -2578,7 +2578,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2637,7 +2637,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
.cono = cono,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_nudge_brush_task_cb_ex, &settings);
@@ -2645,7 +2645,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2758,7 +2758,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
.grab_delta = grab_delta,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_snake_hook_brush_task_cb_ex, &settings);
@@ -2766,7 +2766,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2830,7 +2830,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
.cono = cono,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_thumb_brush_task_cb_ex, &settings);
@@ -2838,7 +2838,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2903,7 +2903,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
.angle = angle,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_rotate_brush_task_cb_ex, &settings);
@@ -2911,7 +2911,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3000,7 +3000,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
BLI_mutex_init(&data.mutex);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings);
@@ -3010,7 +3010,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3068,7 +3068,7 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
.nodes = nodes,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_inflate_brush_task_cb_ex, &settings);
@@ -3184,7 +3184,7 @@ static float get_offset(Sculpt *sd, SculptSession *ss)
static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3266,7 +3266,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
.area_co = area_co,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_flatten_brush_task_cb_ex, &settings);
@@ -3274,7 +3274,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
static void do_clay_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3364,7 +3364,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
.area_co = area_co,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_clay_brush_task_cb_ex, &settings);
@@ -3372,7 +3372,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3494,7 +3494,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
.mat = mat,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_clay_strips_brush_task_cb_ex, &settings);
@@ -3502,7 +3502,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
static void do_fill_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3587,7 +3587,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
.area_co = area_co,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_fill_brush_task_cb_ex, &settings);
@@ -3595,7 +3595,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3679,7 +3679,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
.area_co = area_co,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_scrape_brush_task_cb_ex, &settings);
@@ -3687,7 +3687,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
static void do_gravity_task_cb_ex(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3748,7 +3748,7 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl
.offset = offset,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, do_gravity_task_cb_ex, &settings);
@@ -3862,7 +3862,7 @@ static void sculpt_topology_update(Sculpt *sd,
static void do_brush_action_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
@@ -3896,7 +3896,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
.nodes = nodes,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
@@ -4021,7 +4021,7 @@ static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd)
static void sculpt_combine_proxies_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -4093,7 +4093,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
.nodes = nodes,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
@@ -4130,7 +4130,7 @@ static void sculpt_update_keyblock(Object *ob)
static void sculpt_flush_stroke_deform_task_cb(void *__restrict userdata,
const int n,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -4186,7 +4186,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
.vertCos = vertCos,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, sculpt_flush_stroke_deform_task_cb, &settings);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 81bb9c35817..e9d17b11ccc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -323,7 +323,7 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode)
}
static void sculpt_undo_bmesh_restore_generic_task_cb(
- void *__restrict userdata, const int n, const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
PBVHNode **nodes = userdata;
@@ -351,7 +351,7 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 7cc222ea529..9e2634b183a 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -1199,9 +1199,14 @@ static void select_moreless_action_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+
+ /* TODO: other types. */
+ if (ale->datatype != ALE_FCURVE) {
+ continue;
+ }
/* only continue if F-Curve has keyframes */
+ FCurve *fcu = (FCurve *)ale->key_data;
if (fcu->bezt == NULL) {
continue;
}
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
index ef5de1acee3..3f705aad89a 100644
--- a/source/blender/editors/space_clip/clip_graph_draw.c
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -48,6 +48,7 @@
#include "clip_intern.h" // own include
typedef struct TrackMotionCurveUserData {
+ SpaceClip *sc;
MovieTrackingTrack *act_track;
bool sel;
float xscale, yscale, hsize;
@@ -57,24 +58,43 @@ typedef struct TrackMotionCurveUserData {
static void tracking_segment_point_cb(void *userdata,
MovieTrackingTrack *UNUSED(track),
MovieTrackingMarker *UNUSED(marker),
- int UNUSED(coord),
+ eClipCurveValueSource value_source,
int scene_framenr,
float val)
{
TrackMotionCurveUserData *data = (TrackMotionCurveUserData *)userdata;
+ if (!clip_graph_value_visible(data->sc, value_source)) {
+ return;
+ }
+
immVertex2f(data->pos, scene_framenr, val);
}
static void tracking_segment_start_cb(void *userdata,
MovieTrackingTrack *track,
- int coord,
+ eClipCurveValueSource value_source,
bool is_point)
{
TrackMotionCurveUserData *data = (TrackMotionCurveUserData *)userdata;
+ SpaceClip *sc = data->sc;
float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- col[coord] = 1.0f;
+ if (!clip_graph_value_visible(sc, value_source)) {
+ return;
+ }
+
+ switch (value_source) {
+ case CLIP_VALUE_SOURCE_SPEED_X:
+ col[0] = 1.0f;
+ break;
+ case CLIP_VALUE_SOURCE_SPEED_Y:
+ col[1] = 1.0f;
+ break;
+ case CLIP_VALUE_SOURCE_REPROJECTION_ERROR:
+ col[2] = 1.0f;
+ break;
+ }
if (track == data->act_track) {
col[3] = 1.0f;
@@ -96,15 +116,20 @@ static void tracking_segment_start_cb(void *userdata,
}
}
-static void tracking_segment_end_cb(void *UNUSED(userdata), int UNUSED(coord))
+static void tracking_segment_end_cb(void *userdata, eClipCurveValueSource value_source)
{
+ TrackMotionCurveUserData *data = (TrackMotionCurveUserData *)userdata;
+ SpaceClip *sc = data->sc;
+ if (!clip_graph_value_visible(sc, value_source)) {
+ return;
+ }
immEnd();
}
static void tracking_segment_knot_cb(void *userdata,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
- int coord,
+ eClipCurveValueSource value_source,
int scene_framenr,
float val)
{
@@ -114,8 +139,11 @@ static void tracking_segment_knot_cb(void *userdata,
if (track != data->act_track) {
return;
}
+ if (!ELEM(value_source, CLIP_VALUE_SOURCE_SPEED_X, CLIP_VALUE_SOURCE_SPEED_Y)) {
+ return;
+ }
- sel_flag = coord == 0 ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y;
+ sel_flag = value_source == CLIP_VALUE_SOURCE_SPEED_X ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y;
sel = (marker->flag & sel_flag) ? 1 : 0;
if (sel == data->sel) {
@@ -131,34 +159,39 @@ static void tracking_segment_knot_cb(void *userdata,
}
}
-static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc, unsigned int pos)
+static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, unsigned int pos)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
- int width, height;
- TrackMotionCurveUserData userdata;
+ const bool draw_knots = (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) != 0;
+ int width, height;
BKE_movieclip_get_size(clip, &sc->user, &width, &height);
-
if (!width || !height) {
return;
}
- /* non-selected knot handles */
+ TrackMotionCurveUserData userdata;
+ userdata.sc = sc;
userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
userdata.sel = false;
userdata.act_track = act_track;
userdata.pos = pos;
- UI_view2d_scale_get(v2d, &userdata.xscale, &userdata.yscale);
- clip_graph_tracking_values_iterate(sc,
- (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
- (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
- &userdata,
- tracking_segment_knot_cb,
- NULL,
- NULL);
- /* draw graph lines */
+
+ /* Non-selected knot handles. */
+ if (draw_knots) {
+ UI_view2d_scale_get(v2d, &userdata.xscale, &userdata.yscale);
+ clip_graph_tracking_values_iterate(sc,
+ (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
+ (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
+ &userdata,
+ tracking_segment_knot_cb,
+ NULL,
+ NULL);
+ }
+
+ /* Draw graph lines. */
GPU_blend(true);
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
@@ -169,138 +202,19 @@ static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc, unsigned int p
tracking_segment_end_cb);
GPU_blend(false);
- /* selected knot handles on top of curves */
- userdata.sel = true;
- clip_graph_tracking_values_iterate(sc,
- (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
- (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
- &userdata,
- tracking_segment_knot_cb,
- NULL,
- NULL);
-}
-
-typedef struct TrackErrorCurveUserData {
- MovieClip *clip;
- MovieTracking *tracking;
- MovieTrackingObject *tracking_object;
- MovieTrackingTrack *active_track;
- bool matrix_initialized;
- int matrix_frame;
- float projection_matrix[4][4];
- int width, height;
- float aspy;
- unsigned int pos;
-} TrackErrorCurveUserData;
-
-static void tracking_error_segment_point_cb(void *userdata,
- MovieTrackingTrack *track,
- MovieTrackingMarker *marker,
- int coord,
- int scene_framenr,
- float UNUSED(value))
-{
- if (coord == 1) {
- TrackErrorCurveUserData *data = (TrackErrorCurveUserData *)userdata;
- float reprojected_position[4], bundle_position[4], marker_position[2], delta[2];
- float reprojection_error;
- float weight = BKE_tracking_track_get_weight_for_marker(data->clip, track, marker);
-
- if (!data->matrix_initialized || data->matrix_frame != scene_framenr) {
- BKE_tracking_get_projection_matrix(data->tracking,
- data->tracking_object,
- scene_framenr,
- data->width,
- data->height,
- data->projection_matrix);
- }
-
- copy_v3_v3(bundle_position, track->bundle_pos);
- bundle_position[3] = 1;
-
- mul_v4_m4v4(reprojected_position, data->projection_matrix, bundle_position);
- reprojected_position[0] = (reprojected_position[0] / (reprojected_position[3] * 2.0f) + 0.5f) *
- data->width;
- reprojected_position[1] = (reprojected_position[1] / (reprojected_position[3] * 2.0f) + 0.5f) *
- data->height * data->aspy;
-
- BKE_tracking_distort_v2(data->tracking, reprojected_position, reprojected_position);
-
- marker_position[0] = (marker->pos[0] + track->offset[0]) * data->width;
- marker_position[1] = (marker->pos[1] + track->offset[1]) * data->height * data->aspy;
-
- sub_v2_v2v2(delta, reprojected_position, marker_position);
- reprojection_error = len_v2(delta) * weight;
-
- immVertex2f(data->pos, scene_framenr, reprojection_error);
- }
-}
-
-static void tracking_error_segment_start_cb(void *userdata,
- MovieTrackingTrack *track,
- int coord,
- bool is_point)
-{
- if (coord == 1) {
- TrackErrorCurveUserData *data = (TrackErrorCurveUserData *)userdata;
- float col[4] = {0.0f, 0.0f, 1.0f, 1.0f};
-
- if (track == data->active_track) {
- col[3] = 1.0f;
- GPU_line_width(2.0f);
- }
- else {
- col[3] = 0.5f;
- GPU_line_width(1.0f);
- }
-
- immUniformColor4fv(col);
-
- if (is_point) { /* This probably never happens here, but just in case... */
- immBeginAtMost(GPU_PRIM_POINTS, 1);
- }
- else {
- /* Graph can be composed of smaller segments, if any marker is disabled */
- immBeginAtMost(GPU_PRIM_LINE_STRIP, track->markersnr);
- }
- }
-}
-
-static void tracking_error_segment_end_cb(void *UNUSED(userdata), int coord)
-{
- if (coord == 1) {
- immEnd();
+ /* Selected knot handles on top of curves. */
+ if (draw_knots) {
+ userdata.sel = true;
+ clip_graph_tracking_values_iterate(sc,
+ (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
+ (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
+ &userdata,
+ tracking_segment_knot_cb,
+ NULL,
+ NULL);
}
}
-static void draw_tracks_error_curves(SpaceClip *sc, unsigned int pos)
-{
- MovieClip *clip = ED_space_clip_get_clip(sc);
- MovieTracking *tracking = &clip->tracking;
- TrackErrorCurveUserData data;
-
- data.clip = clip;
- data.tracking = tracking;
- data.tracking_object = BKE_tracking_object_get_active(tracking);
- data.active_track = BKE_tracking_track_get_active(tracking);
- data.matrix_initialized = false;
- data.pos = pos;
- BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height);
- data.aspy = 1.0f / tracking->camera.pixel_aspect;
-
- if (!data.width || !data.height) {
- return;
- }
-
- clip_graph_tracking_values_iterate(sc,
- (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
- (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
- &data,
- tracking_error_segment_point_cb,
- tracking_error_segment_start_cb,
- tracking_error_segment_end_cb);
-}
-
static void draw_frame_curves(SpaceClip *sc, unsigned int pos)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -350,12 +264,8 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
GPU_point_size(3.0f);
- if (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) {
- draw_tracks_motion_curves(v2d, sc, pos);
- }
-
- if (sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR) {
- draw_tracks_error_curves(sc, pos);
+ if (sc->flag & (SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_TRACKS_ERROR)) {
+ draw_tracks_motion_and_error_curves(v2d, sc, pos);
}
if (sc->flag & SC_SHOW_GRAPH_FRAMES) {
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index a3722433e33..58a00d2e6b9 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -64,7 +64,7 @@ static bool clip_graph_knots_poll(bContext *C)
if (ED_space_clip_graph_poll(C)) {
SpaceClip *sc = CTX_wm_space_clip(C);
- return (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) != 0;
+ return (sc->flag & (SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_TRACKS_ERROR)) != 0;
}
return false;
}
@@ -93,13 +93,14 @@ static void toggle_selection_cb(void *userdata, MovieTrackingMarker *marker)
/******************** mouse select operator ********************/
typedef struct {
- int coord; /* coordinate index of found entuty (0 = X-axis, 1 = Y-axis) */
+ SpaceClip *sc;
+ eClipCurveValueSource value_source;
bool has_prev; /* if there's valid coordinate of previous point of curve segment */
- float min_dist_sq, /* minimal distance between mouse and currently found entity */
- mouse_co[2], /* mouse coordinate */
- prev_co[2], /* coordinate of previeous point of segment */
- min_co[2]; /* coordinate of entity with minimal distance */
+ float min_dist_sq; /* minimal distance between mouse and currently found entity */
+ float mouse_co[2]; /* mouse coordinate */
+ float prev_co[2]; /* coordinate of previous point of segment */
+ float min_co[2]; /* coordinate of entity with minimal distance */
MovieTrackingTrack *track; /* nearest found track */
MovieTrackingMarker *marker; /* nearest found marker */
@@ -108,20 +109,24 @@ typedef struct {
static void find_nearest_tracking_segment_cb(void *userdata,
MovieTrackingTrack *track,
MovieTrackingMarker *UNUSED(marker),
- int coord,
+ eClipCurveValueSource value_source,
int scene_framenr,
float val)
{
MouseSelectUserData *data = userdata;
float co[2] = {scene_framenr, val};
+ if (!clip_graph_value_visible(data->sc, value_source)) {
+ return;
+ }
+
if (data->has_prev) {
float dist_sq = dist_squared_to_line_segment_v2(data->mouse_co, data->prev_co, co);
if (data->track == NULL || dist_sq < data->min_dist_sq) {
data->track = track;
data->min_dist_sq = dist_sq;
- data->coord = coord;
+ data->value_source = value_source;
copy_v2_v2(data->min_co, co);
}
}
@@ -130,7 +135,8 @@ static void find_nearest_tracking_segment_cb(void *userdata,
copy_v2_v2(data->prev_co, co);
}
-static void find_nearest_tracking_segment_end_cb(void *userdata, int UNUSED(coord))
+static void find_nearest_tracking_segment_end_cb(void *userdata,
+ eClipCurveValueSource UNUSED(source_value))
{
MouseSelectUserData *data = userdata;
@@ -140,7 +146,7 @@ static void find_nearest_tracking_segment_end_cb(void *userdata, int UNUSED(coor
static void find_nearest_tracking_knot_cb(void *userdata,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
- int coord,
+ eClipCurveValueSource value_source,
int scene_framenr,
float val)
{
@@ -148,20 +154,26 @@ static void find_nearest_tracking_knot_cb(void *userdata,
float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]};
float dist_sq = len_squared_v2(mdiff);
+ if (!clip_graph_value_visible(data->sc, value_source)) {
+ return;
+ }
+
if (data->marker == NULL || dist_sq < data->min_dist_sq) {
float co[2] = {scene_framenr, val};
data->track = track;
data->marker = marker;
data->min_dist_sq = dist_sq;
- data->coord = coord;
+ data->value_source = value_source;
copy_v2_v2(data->min_co, co);
}
}
-static void mouse_select_init_data(MouseSelectUserData *userdata, const float co[2])
+static void mouse_select_init_data(bContext *C, MouseSelectUserData *userdata, const float co[2])
{
+ SpaceClip *sc = CTX_wm_space_clip(C);
memset(userdata, 0, sizeof(MouseSelectUserData));
+ userdata->sc = sc;
userdata->min_dist_sq = FLT_MAX;
copy_v2_v2(userdata->mouse_co, co);
}
@@ -179,7 +191,7 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend)
if (act_track) {
MouseSelectUserData userdata;
- mouse_select_init_data(&userdata, co);
+ mouse_select_init_data(C, &userdata, co);
clip_graph_tracking_values_iterate_track(
sc, act_track, &userdata, find_nearest_tracking_knot_cb, NULL, NULL);
@@ -199,7 +211,7 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend)
toggle_selection_cb);
}
- if (userdata.coord == 0) {
+ if (userdata.value_source == CLIP_VALUE_SOURCE_SPEED_X) {
if (extend && (userdata.marker->flag & MARKER_GRAPH_SEL_X) != 0) {
userdata.marker->flag &= ~MARKER_GRAPH_SEL_X;
}
@@ -207,7 +219,7 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend)
userdata.marker->flag |= MARKER_GRAPH_SEL_X;
}
}
- else {
+ else if (userdata.value_source == CLIP_VALUE_SOURCE_SPEED_Y) {
if (extend && (userdata.marker->flag & MARKER_GRAPH_SEL_Y) != 0) {
userdata.marker->flag &= ~MARKER_GRAPH_SEL_Y;
}
@@ -232,7 +244,7 @@ static bool mouse_select_curve(bContext *C, float co[2], bool extend)
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
MouseSelectUserData userdata;
- mouse_select_init_data(&userdata, co);
+ mouse_select_init_data(C, &userdata, co);
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
@@ -281,7 +293,7 @@ static int mouse_select(bContext *C, float co[2], bool extend)
sel = mouse_select_knot(C, co, extend);
if (!sel) {
- /* if there's no close enough knot to mouse osition, select nearest curve */
+ /* if there's no close enough knot to mouse position, select nearest curve */
sel = mouse_select_curve(C, co, extend);
}
@@ -356,16 +368,19 @@ typedef struct BoxSelectuserData {
static void box_select_cb(void *userdata,
MovieTrackingTrack *UNUSED(track),
MovieTrackingMarker *marker,
- int coord,
+ eClipCurveValueSource value_source,
int scene_framenr,
float val)
{
BoxSelectuserData *data = (BoxSelectuserData *)userdata;
+ if (!ELEM(value_source, CLIP_VALUE_SOURCE_SPEED_X, CLIP_VALUE_SOURCE_SPEED_Y)) {
+ return;
+ }
if (BLI_rctf_isect_pt(&data->rect, scene_framenr, val)) {
int flag = 0;
- if (coord == 0) {
+ if (value_source == CLIP_VALUE_SOURCE_SPEED_X) {
flag = MARKER_GRAPH_SEL_X;
}
else {
@@ -591,7 +606,7 @@ typedef struct {
static void view_all_cb(void *userdata,
MovieTrackingTrack *UNUSED(track),
MovieTrackingMarker *UNUSED(marker),
- int UNUSED(coord),
+ eClipCurveValueSource UNUSED(value_source),
int UNUSED(scene_framenr),
float val)
{
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 7683823a79f..8599de9f16f 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -112,35 +112,44 @@ void CLIP_OT_cursor_set(struct wmOperatorType *ot);
struct ARegion *ED_clip_has_properties_region(struct ScrArea *sa);
/* clip_utils.c */
-void clip_graph_tracking_values_iterate_track(
- struct SpaceClip *sc,
- struct MovieTrackingTrack *track,
- void *userdata,
- void (*func)(void *userdata,
- struct MovieTrackingTrack *track,
- struct MovieTrackingMarker *marker,
- int coord,
- int scene_framenr,
- float val),
- void (*segment_start)(
- void *userdata, struct MovieTrackingTrack *track, int coord, bool is_point),
- void (*segment_end)(void *userdata, int coord));
+
+typedef enum {
+ CLIP_VALUE_SOURCE_SPEED_X,
+ CLIP_VALUE_SOURCE_SPEED_Y,
+ CLIP_VALUE_SOURCE_REPROJECTION_ERROR,
+} eClipCurveValueSource;
+
+typedef void (*ClipTrackValueCallback)(void *userdata,
+ struct MovieTrackingTrack *track,
+ struct MovieTrackingMarker *marker,
+ eClipCurveValueSource value_source,
+ int scene_framenr,
+ float val);
+
+typedef void (*ClipTrackValueSegmentStartCallback)(void *userdata,
+ struct MovieTrackingTrack *track,
+ eClipCurveValueSource value_source,
+ bool is_point);
+
+typedef void (*ClipTrackValueSegmentEndCallback)(void *userdata,
+ eClipCurveValueSource value_source);
+
+bool clip_graph_value_visible(struct SpaceClip *sc, eClipCurveValueSource value_source);
+
+void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc,
+ struct MovieTrackingTrack *track,
+ void *userdata,
+ ClipTrackValueCallback func,
+ ClipTrackValueSegmentStartCallback segment_start,
+ ClipTrackValueSegmentEndCallback segment_end);
void clip_graph_tracking_values_iterate(struct SpaceClip *sc,
bool selected_only,
bool include_hidden,
void *userdata,
- void (*func)(void *userdata,
- struct MovieTrackingTrack *track,
- struct MovieTrackingMarker *marker,
- int coord,
- int scene_framenr,
- float val),
- void (*segment_start)(void *userdata,
- struct MovieTrackingTrack *track,
- int coord,
- bool is_point),
- void (*segment_end)(void *userdata, int coord));
+ ClipTrackValueCallback func,
+ ClipTrackValueSegmentStartCallback segment_start,
+ ClipTrackValueSegmentEndCallback segment_end);
void clip_graph_tracking_iterate(struct SpaceClip *sc,
bool selected_only,
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 45479c4253d..e1af9728685 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -1434,7 +1434,7 @@ static void proxy_endjob(void *pjv)
if (pj->clip->source == MCLIP_SRC_MOVIE) {
/* Timecode might have changed, so do a full reload to deal with this. */
- BKE_movieclip_reload(pj->main, pj->clip);
+ DEG_id_tag_update(&pj->clip->id, ID_RECALC_SOURCE);
}
else {
/* For image sequences we'll preserve original cache. */
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index 3dfe529f8e8..48f788e2e3a 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -27,6 +27,7 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
@@ -52,18 +53,28 @@
#include "clip_intern.h" // own include
-void clip_graph_tracking_values_iterate_track(
+bool clip_graph_value_visible(SpaceClip *sc, eClipCurveValueSource value_source)
+{
+ if (ELEM(value_source, CLIP_VALUE_SOURCE_SPEED_X, CLIP_VALUE_SOURCE_SPEED_Y)) {
+ if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) {
+ return false;
+ }
+ }
+ else if (value_source == CLIP_VALUE_SOURCE_REPROJECTION_ERROR) {
+ if ((sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR) == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void clip_graph_tracking_values_iterate_track_speed_values(
SpaceClip *sc,
MovieTrackingTrack *track,
void *userdata,
- void (*func)(void *userdata,
- MovieTrackingTrack *track,
- MovieTrackingMarker *marker,
- int coord,
- int scene_framenr,
- float val),
- void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord, bool is_point),
- void (*segment_end)(void *userdata, int coord))
+ ClipTrackValueCallback func,
+ ClipTrackValueSegmentStartCallback segment_start,
+ ClipTrackValueSegmentEndCallback segment_end)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
int width, height, coord;
@@ -71,6 +82,8 @@ void clip_graph_tracking_values_iterate_track(
BKE_movieclip_get_size(clip, &sc->user, &width, &height);
for (coord = 0; coord < 2; coord++) {
+ eClipCurveValueSource value_source = (coord == 0) ? CLIP_VALUE_SOURCE_SPEED_X :
+ CLIP_VALUE_SOURCE_SPEED_Y;
int i, prevfra = track->markers[0].framenr;
bool open = false;
float prevval = 0.0f;
@@ -82,7 +95,7 @@ void clip_graph_tracking_values_iterate_track(
if (marker->flag & MARKER_DISABLED) {
if (open) {
if (segment_end) {
- segment_end(userdata, coord);
+ segment_end(userdata, value_source);
}
open = false;
@@ -94,10 +107,11 @@ void clip_graph_tracking_values_iterate_track(
if (!open) {
if (segment_start) {
if ((i + 1) == track->markersnr) {
- segment_start(userdata, track, coord, true);
+ segment_start(userdata, track, value_source, true);
}
else {
- segment_start(userdata, track, coord, (track->markers[i + 1].flag & MARKER_DISABLED));
+ segment_start(
+ userdata, track, value_source, (track->markers[i + 1].flag & MARKER_DISABLED));
}
}
@@ -112,7 +126,7 @@ void clip_graph_tracking_values_iterate_track(
if (func) {
int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
- func(userdata, track, marker, coord, scene_framenr, val);
+ func(userdata, track, marker, value_source, scene_framenr, val);
}
prevval = marker->pos[coord];
@@ -121,25 +135,139 @@ void clip_graph_tracking_values_iterate_track(
if (open) {
if (segment_end) {
- segment_end(userdata, coord);
+ segment_end(userdata, value_source);
}
}
}
}
-void clip_graph_tracking_values_iterate(
+static float calculate_reprojection_error_at_marker(MovieClip *clip,
+ MovieTracking *tracking,
+ MovieTrackingObject *tracking_object,
+ MovieTrackingTrack *track,
+ MovieTrackingMarker *marker,
+ const int clip_width,
+ const int clip_height,
+ const int scene_framenr)
+{
+ float reprojected_position[4], bundle_position[4], marker_position[2], delta[2];
+ float weight = BKE_tracking_track_get_weight_for_marker(clip, track, marker);
+ const float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+ float projection_matrix[4][4];
+ BKE_tracking_get_projection_matrix(
+ tracking, tracking_object, scene_framenr, clip_width, clip_height, projection_matrix);
+
+ copy_v3_v3(bundle_position, track->bundle_pos);
+ bundle_position[3] = 1;
+
+ mul_v4_m4v4(reprojected_position, projection_matrix, bundle_position);
+ reprojected_position[0] = (reprojected_position[0] / (reprojected_position[3] * 2.0f) + 0.5f) *
+ clip_width;
+ reprojected_position[1] = (reprojected_position[1] / (reprojected_position[3] * 2.0f) + 0.5f) *
+ clip_height * aspy;
+
+ BKE_tracking_distort_v2(tracking, reprojected_position, reprojected_position);
+
+ marker_position[0] = (marker->pos[0] + track->offset[0]) * clip_width;
+ marker_position[1] = (marker->pos[1] + track->offset[1]) * clip_height * aspy;
+
+ sub_v2_v2v2(delta, reprojected_position, marker_position);
+ return len_v2(delta) * weight;
+}
+
+static void clip_graph_tracking_values_iterate_track_reprojection_error_values(
SpaceClip *sc,
- bool selected_only,
- bool include_hidden,
+ MovieTrackingTrack *track,
void *userdata,
- void (*func)(void *userdata,
- MovieTrackingTrack *track,
- MovieTrackingMarker *marker,
- int coord,
- int scene_framenr,
- float val),
- void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord, bool is_point),
- void (*segment_end)(void *userdata, int coord))
+ ClipTrackValueCallback func,
+ ClipTrackValueSegmentStartCallback segment_start,
+ ClipTrackValueSegmentEndCallback segment_end)
+{
+ /* Tracks without bundle can not have any reprojection error curve. */
+ if ((track->flag & TRACK_HAS_BUNDLE) == 0) {
+ return;
+ }
+
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
+
+ int clip_width, clip_height;
+ BKE_movieclip_get_size(clip, &sc->user, &clip_width, &clip_height);
+
+ /* Iterate over segments. */
+ bool is_segment_open = false;
+ for (int marker_index = 0; marker_index < track->markersnr; marker_index++) {
+ MovieTrackingMarker *marker = &track->markers[marker_index];
+
+ /* End of tracked segment, no reprojection error can be calculated here since the ground truth
+ * 2D position is not known. */
+ if (marker->flag & MARKER_DISABLED) {
+ if (is_segment_open) {
+ if (segment_end != NULL) {
+ segment_end(userdata, CLIP_VALUE_SOURCE_REPROJECTION_ERROR);
+ }
+ is_segment_open = false;
+ }
+ continue;
+ }
+
+ /* Begin new segment if it is not open yet. */
+ if (!is_segment_open) {
+ if (segment_start != NULL) {
+ if ((marker_index + 1) == track->markersnr) {
+ segment_start(userdata, track, CLIP_VALUE_SOURCE_REPROJECTION_ERROR, true);
+ }
+ else {
+ segment_start(userdata,
+ track,
+ CLIP_VALUE_SOURCE_REPROJECTION_ERROR,
+ (track->markers[marker_index + 1].flag & MARKER_DISABLED));
+ }
+ }
+ is_segment_open = true;
+ }
+
+ if (func != NULL) {
+ const int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
+ const float reprojection_error = calculate_reprojection_error_at_marker(
+ clip, tracking, tracking_object, track, marker, clip_width, clip_height, scene_framenr);
+ func(userdata,
+ track,
+ marker,
+ CLIP_VALUE_SOURCE_REPROJECTION_ERROR,
+ scene_framenr,
+ reprojection_error);
+ }
+ }
+
+ if (is_segment_open && segment_end != NULL) {
+ segment_end(userdata, CLIP_VALUE_SOURCE_REPROJECTION_ERROR);
+ }
+}
+
+void clip_graph_tracking_values_iterate_track(SpaceClip *sc,
+ MovieTrackingTrack *track,
+ void *userdata,
+ ClipTrackValueCallback func,
+ ClipTrackValueSegmentStartCallback segment_start,
+ ClipTrackValueSegmentEndCallback segment_end)
+{
+ clip_graph_tracking_values_iterate_track_speed_values(
+ sc, track, userdata, func, segment_start, segment_end);
+
+ clip_graph_tracking_values_iterate_track_reprojection_error_values(
+ sc, track, userdata, func, segment_start, segment_end);
+}
+
+void clip_graph_tracking_values_iterate(SpaceClip *sc,
+ bool selected_only,
+ bool include_hidden,
+ void *userdata,
+ ClipTrackValueCallback func,
+ ClipTrackValueSegmentStartCallback segment_start,
+ ClipTrackValueSegmentEndCallback segment_end)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index d8d50ba72b5..1375b99bdaa 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1894,6 +1894,7 @@ static int tracking_object_new_exec(bContext *C, wmOperator *UNUSED(op))
BKE_tracking_object_add(tracking, "Object");
+ DEG_id_tag_update(&clip->id, ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
return OPERATOR_FINISHED;
@@ -1932,6 +1933,7 @@ static int tracking_object_remove_exec(bContext *C, wmOperator *op)
BKE_tracking_object_delete(tracking, object);
+ DEG_id_tag_update(&clip->id, ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_clip/tracking_ops_solve.c b/source/blender/editors/space_clip/tracking_ops_solve.c
index 4490655393e..806df4dbaff 100644
--- a/source/blender/editors/space_clip/tracking_ops_solve.c
+++ b/source/blender/editors/space_clip/tracking_ops_solve.c
@@ -122,8 +122,14 @@ static void solve_camera_freejob(void *scv)
solved = BKE_tracking_reconstruction_finish(scj->context, tracking);
if (!solved) {
- BKE_report(
- scj->reports, RPT_WARNING, "Some data failed to reconstruct (see console for details)");
+ const char *error_message = BKE_tracking_reconstruction_error_message_get(scj->context);
+ if (error_message[0]) {
+ BKE_report(scj->reports, RPT_ERROR, error_message);
+ }
+ else {
+ BKE_report(
+ scj->reports, RPT_WARNING, "Some data failed to reconstruct (see console for details)");
+ }
}
else {
BKE_reportf(scj->reports,
@@ -146,6 +152,7 @@ static void solve_camera_freejob(void *scv)
int width, height;
BKE_movieclip_get_size(clip, &scj->user, &width, &height);
BKE_tracking_camera_to_blender(tracking, scene, camera, width, height);
+ DEG_id_tag_update(&camera->id, ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_OBJECT, camera);
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 9004eaa7bf6..e06ee620ea7 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -1317,6 +1317,9 @@ static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size)
cache->size = cache_size;
cache->flags = FLC_IS_INIT;
+
+ /* We cannot translate from non-main thread, so init translated strings once from here. */
+ IMB_thumb_ensure_translations();
}
static void filelist_cache_free(FileListEntryCache *cache)
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 89eb3b9d953..f9905cc4fcd 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -747,6 +747,7 @@ static void clear_animdata_cb(int UNUSED(event),
void *UNUSED(arg))
{
BKE_animdata_free(tselem->id, true);
+ DEG_id_tag_update(tselem->id, ID_RECALC_ANIMATION);
}
static void unlinkact_animdata_cb(int UNUSED(event),
@@ -756,6 +757,7 @@ static void unlinkact_animdata_cb(int UNUSED(event),
{
/* just set action to NULL */
BKE_animdata_set_action(NULL, tselem->id, NULL);
+ DEG_id_tag_update(tselem->id, ID_RECALC_ANIMATION);
}
static void cleardrivers_animdata_cb(int UNUSED(event),
@@ -767,6 +769,7 @@ static void cleardrivers_animdata_cb(int UNUSED(event),
/* just free drivers - stored as a list of F-Curves */
free_fcurves(&iat->adt->drivers);
+ DEG_id_tag_update(tselem->id, ID_RECALC_ANIMATION);
}
static void refreshdrivers_animdata_cb(int UNUSED(event),
@@ -1899,7 +1902,6 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
SpaceOutliner *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
eOutliner_AnimDataOps event;
- short updateDeps = 0;
/* check for invalid states */
if (soops == NULL) {
@@ -1943,7 +1945,6 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
// ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */
- updateDeps = 1;
break;
case OUTLINER_ANIMOP_CLEAR_DRV:
@@ -1952,7 +1953,6 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
ED_undo_push(C, "Clear Drivers");
- updateDeps = 1;
break;
default: // invalid
@@ -1960,10 +1960,7 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
}
/* update dependencies */
- if (updateDeps) {
- /* rebuild depsgraph for the new deps */
- DEG_relations_tag_update(CTX_data_main(C));
- }
+ DEG_relations_tag_update(CTX_data_main(C));
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index 2aebc6c97fb..c55d77800ff 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -452,7 +452,7 @@ typedef struct MakeHistogramViewData {
static void make_histogram_view_from_ibuf_byte_cb_ex(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
MakeHistogramViewData *data = userdata;
const ImBuf *ibuf = data->ibuf;
@@ -498,7 +498,7 @@ static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf)
.ibuf = ibuf,
.bins = bins,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (ibuf->y >= 256);
settings.userdata_chunk = bins;
@@ -553,7 +553,7 @@ BLI_INLINE int get_bin_float(float f)
static void make_histogram_view_from_ibuf_float_cb_ex(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
const MakeHistogramViewData *data = userdata;
const ImBuf *ibuf = data->ibuf;
@@ -584,7 +584,7 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
.ibuf = ibuf,
.bins = bins,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (ibuf->y >= 256);
settings.userdata_chunk = bins;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 8d8b314e525..84012ee26cc 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -803,13 +803,19 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, bool a
GPU_depth_test(true);
+ /* Needed in cases the view-port isn't already setup. */
+ WM_draw_region_viewport_ensure(ar, SPACE_VIEW3D);
+ WM_draw_region_viewport_bind(ar);
+
GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
/* When Blender is starting, a click event can trigger a depth test while the viewport is not
* yet available. */
if (viewport != NULL) {
- DRW_draw_depth_loop(depsgraph, ar, v3d, viewport);
+ DRW_draw_depth_loop(depsgraph, ar, v3d, viewport, false);
}
+ WM_draw_region_viewport_unbind(ar);
+
if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_disable();
}
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 386c3164843..4c03995307a 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -155,11 +155,13 @@ void ED_view3d_clipping_enable(void)
/**
* \note Only use in object mode.
*/
-static void validate_object_select_id(
- struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, Object *obact)
+static void validate_object_select_id(struct Depsgraph *depsgraph,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ARegion *ar,
+ View3D *v3d,
+ Object *obact)
{
- RegionView3D *rv3d = ar->regiondata;
- Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
@@ -186,19 +188,8 @@ static void validate_object_select_id(
}
if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
- uint dummy_vert_ofs, dummy_edge_ofs, dummy_face_ofs;
- DRW_framebuffer_select_id_setup(ar, true);
- DRW_draw_select_id_object(scene_eval,
- rv3d,
- obact_eval,
- scene->toolsettings->selectmode,
- false,
- 1,
- &dummy_vert_ofs,
- &dummy_edge_ofs,
- &dummy_face_ofs);
-
- DRW_framebuffer_select_id_release(ar);
+ DRW_draw_select_id_object(
+ depsgraph, view_layer, ar, v3d, obact, scene->toolsettings->selectmode);
}
/* TODO: Create a flag in `DRW_manager` because the drawing is no longer
@@ -233,7 +224,8 @@ void ED_view3d_select_id_validate(ViewContext *vc)
/* TODO: Create a flag in `DRW_manager` because the drawing is no longer
* made on the backbuffer in this case. */
if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
- validate_object_select_id(vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact);
+ validate_object_select_id(
+ vc->depsgraph, vc->scene, vc->view_layer, vc->ar, vc->v3d, vc->obact);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 7c4b35507b9..fd0d9c6891f 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2924,12 +2924,12 @@ static int viewselected_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- bGPdata *gpd = CTX_data_gpencil_data(C);
- const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
- const bool is_face_map = ((is_gp_edit == false) && ar->gizmo_map &&
- WM_gizmomap_is_any_selected(ar->gizmo_map));
Object *ob_eval = OBACT(view_layer_eval);
Object *obedit = CTX_data_edit_object(C);
+ const bGPdata *gpd_eval = ob_eval && (ob_eval->type == OB_GPENCIL) ? ob_eval->data : NULL;
+ const bool is_gp_edit = gpd_eval ? GPENCIL_ANY_MODE(gpd_eval) : false;
+ const bool is_face_map = ((is_gp_edit == false) && ar->gizmo_map &&
+ WM_gizmomap_is_any_selected(ar->gizmo_map));
float min[3], max[3];
bool ok = false, ok_dist = true;
const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 61de61c8e31..754c8359d28 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -111,192 +111,6 @@
// #include "PIL_time_utildefines.h"
/* -------------------------------------------------------------------- */
-/** \name Selection Utilities
- * \{ */
-
-struct EDBaseOffset {
- /* For convenience only. */
- union {
- uint offset;
- uint face_start;
- };
- union {
- uint face;
- uint edge_start;
- };
- union {
- uint edge;
- uint vert_start;
- };
- uint vert;
-};
-
-struct EDSelectID_Context {
- struct EDBaseOffset *base_array_index_offsets;
- /** Borrow from caller (not freed). */
- struct Base **bases;
- uint bases_len;
- /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */
- uint base_array_index_len;
- /** Used to check for changes. (Use depsgraph instead?). */
- float persmat[4][4];
- short select_mode;
-};
-
-static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt)
-{
- if (select_mode & SCE_SELECT_FACE) {
- if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) {
- return true;
- }
- if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) {
- return true;
- }
- if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
- /* Since we can't deduce face selection when edges aren't visible - show dots. */
- return true;
- }
- }
- return false;
-}
-
-static void ed_select_id_draw_bases(struct EDSelectID_Context *sel_id_ctx,
- ViewContext *vc,
- short select_mode)
-{
- Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id);
- DRW_framebuffer_select_id_setup(vc->ar, true);
-
- uint offset = 1;
- for (uint base_index = 0; base_index < sel_id_ctx->bases_len; base_index++) {
- Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph,
- sel_id_ctx->bases[base_index]->object);
-
- struct EDBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index];
- bool draw_facedot = check_ob_drawface_dot(select_mode, vc->v3d, ob_eval->dt);
-
- DRW_draw_select_id_object(scene_eval,
- vc->rv3d,
- ob_eval,
- select_mode,
- draw_facedot,
- offset,
- &base_ofs->vert,
- &base_ofs->edge,
- &base_ofs->face);
-
- base_ofs->offset = offset;
- offset = base_ofs->vert;
- }
-
- sel_id_ctx->base_array_index_len = offset;
-
- DRW_framebuffer_select_id_release(vc->ar);
-}
-
-void ED_view3d_select_id_validate_view_matrices(struct EDSelectID_Context *sel_id_ctx,
- ViewContext *vc)
-{
- if (!compare_m4m4(sel_id_ctx->persmat, vc->rv3d->persmat, FLT_EPSILON)) {
- ed_select_id_draw_bases(sel_id_ctx, vc, sel_id_ctx->select_mode);
- }
-}
-
-uint ED_view3d_select_id_context_offset_for_object_elem(
- const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type)
-{
- struct EDBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index];
- if (elem_type == SCE_SELECT_VERTEX) {
- return base_ofs->vert_start - 1;
- }
- if (elem_type == SCE_SELECT_EDGE) {
- return base_ofs->edge_start - 1;
- }
- if (elem_type == SCE_SELECT_FACE) {
- return base_ofs->face_start - 1;
- }
- BLI_assert(0);
- return 0;
-}
-
-uint ED_view3d_select_id_context_elem_len(const struct EDSelectID_Context *sel_id_ctx)
-{
- return sel_id_ctx->base_array_index_len;
-}
-
-struct EDSelectID_Context *ED_view3d_select_id_context_create(ViewContext *vc,
- Base **bases,
- const uint bases_len,
- short select_mode)
-{
- struct EDSelectID_Context *sel_id_ctx = MEM_mallocN(sizeof(*sel_id_ctx), __func__);
- sel_id_ctx->base_array_index_offsets = MEM_mallocN(sizeof(struct EDBaseOffset) * bases_len,
- __func__);
- sel_id_ctx->bases = bases;
- sel_id_ctx->bases_len = bases_len;
- copy_m4_m4(sel_id_ctx->persmat, vc->rv3d->persmat);
- sel_id_ctx->select_mode = select_mode;
- ed_select_id_draw_bases(sel_id_ctx, vc, select_mode);
-
- return sel_id_ctx;
-}
-
-void ED_view3d_select_id_context_destroy(struct EDSelectID_Context *sel_id_ctx)
-{
- MEM_freeN(sel_id_ctx->base_array_index_offsets);
- MEM_freeN(sel_id_ctx);
-}
-
-bool ED_view3d_select_id_elem_get(struct EDSelectID_Context *sel_id_ctx,
- const uint sel_id,
- uint *r_elem,
- uint *r_base_index,
- char *r_elem_type)
-{
- char elem_type = 0;
- uint elem_id;
- uint base_index = 0;
-
- while (true) {
- struct EDBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index];
- if (base_ofs->face > sel_id) {
- elem_id = sel_id - base_ofs->face_start;
- elem_type = SCE_SELECT_FACE;
- break;
- }
- if (base_ofs->edge > sel_id) {
- elem_id = sel_id - base_ofs->edge_start;
- elem_type = SCE_SELECT_EDGE;
- break;
- }
- if (base_ofs->vert > sel_id) {
- elem_id = sel_id - base_ofs->vert_start;
- elem_type = SCE_SELECT_VERTEX;
- break;
- }
-
- base_index++;
- if (base_index >= sel_id_ctx->bases_len) {
- return false;
- }
- }
-
- *r_elem = elem_id;
-
- if (r_base_index) {
- *r_base_index = base_index;
- }
-
- if (r_elem_type) {
- *r_elem_type = elem_type;
- }
-
- return true;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Public Utilities
* \{ */
@@ -385,7 +199,6 @@ static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
struct EditSelectBuf_Cache {
Base **bases;
uint bases_len;
- struct EDSelectID_Context *sel_id_ctx;
BLI_bitmap *select_bitmap;
};
@@ -407,8 +220,12 @@ static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, ViewCont
esel->bases_len = 0;
}
}
- esel->sel_id_ctx = ED_view3d_select_id_context_create(
- vc, esel->bases, esel->bases_len, vc->scene->toolsettings->selectmode);
+ DRW_draw_select_id(vc->depsgraph,
+ vc->ar,
+ vc->v3d,
+ esel->bases,
+ esel->bases_len,
+ vc->scene->toolsettings->selectmode);
for (int i = 0; i < esel->bases_len; i++) {
esel->bases[i]->object->runtime.select_id = i;
}
@@ -416,9 +233,6 @@ static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, ViewCont
static void editselect_buf_cache_free(struct EditSelectBuf_Cache *esel)
{
- if (esel->sel_id_ctx) {
- ED_view3d_select_id_context_destroy(esel->sel_id_ctx);
- }
MEM_SAFE_FREE(esel->select_bitmap);
MEM_SAFE_FREE(esel->bases);
}
@@ -455,8 +269,7 @@ static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
- uint index = ED_view3d_select_id_context_offset_for_object_elem(
- esel->sel_id_ctx, ob->runtime.select_id, SCE_SELECT_VERTEX);
+ uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_VERTEX);
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
@@ -483,8 +296,7 @@ static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
- uint index = ED_view3d_select_id_context_offset_for_object_elem(
- esel->sel_id_ctx, ob->runtime.select_id, SCE_SELECT_EDGE);
+ uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_EDGE);
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -511,8 +323,7 @@ static bool edbm_backbuf_check_and_select_faces(struct EditSelectBuf_Cache *esel
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
- uint index = ED_view3d_select_id_context_offset_for_object_elem(
- esel->sel_id_ctx, ob->runtime.select_id, SCE_SELECT_FACE);
+ uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_FACE);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
@@ -1017,7 +828,7 @@ static bool do_lasso_select_mesh(ViewContext *vc,
if (wm_userdata->data == NULL) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect);
}
}
@@ -1036,10 +847,8 @@ static bool do_lasso_select_mesh(ViewContext *vc,
struct LassoSelectUserData_ForMeshEdge data_for_edge = {
.data = &data,
.esel = use_zbuf ? esel : NULL,
- .backbuf_offset = use_zbuf ? ED_view3d_select_id_context_offset_for_object_elem(
- esel->sel_id_ctx,
- vc->obedit->runtime.select_id,
- SCE_SELECT_EDGE) :
+ .backbuf_offset = use_zbuf ? DRW_select_context_offset_for_object_elem(
+ vc->obedit->runtime.select_id, SCE_SELECT_EDGE) :
0,
};
mesh_foreachScreenEdge(
@@ -1327,7 +1136,7 @@ static bool do_lasso_select_paintvert(ViewContext *vc,
if (wm_userdata->data == NULL) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect);
}
}
@@ -1386,7 +1195,7 @@ static bool do_lasso_select_paintface(ViewContext *vc,
if (esel == NULL) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect);
}
@@ -2742,7 +2551,7 @@ static bool do_paintvert_box_select(ViewContext *vc,
if (wm_userdata->data == NULL) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect);
}
if (esel->select_bitmap != NULL) {
@@ -2797,7 +2606,7 @@ static bool do_paintface_box_select(ViewContext *vc,
if (wm_userdata->data == NULL) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect);
}
if (esel->select_bitmap != NULL) {
@@ -2995,7 +2804,7 @@ static bool do_mesh_box_select(ViewContext *vc,
if (wm_userdata->data == NULL) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect);
}
}
@@ -3014,10 +2823,8 @@ static bool do_mesh_box_select(ViewContext *vc,
struct BoxSelectUserData_ForMeshEdge cb_data = {
.data = &data,
.esel = use_zbuf ? esel : NULL,
- .backbuf_offset = use_zbuf ? ED_view3d_select_id_context_offset_for_object_elem(
- esel->sel_id_ctx,
- vc->obedit->runtime.select_id,
- SCE_SELECT_EDGE) :
+ .backbuf_offset = use_zbuf ? DRW_select_context_offset_for_object_elem(
+ vc->obedit->runtime.select_id, SCE_SELECT_EDGE) :
0,
};
mesh_foreachScreenEdge(
@@ -3582,8 +3389,7 @@ static bool mesh_circle_select(ViewContext *vc,
struct EditSelectBuf_Cache *esel = wm_userdata->data;
if (use_zbuf) {
- ED_view3d_select_id_validate_view_matrices(esel->sel_id_ctx, vc);
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f));
}
@@ -3660,7 +3466,7 @@ static bool paint_facesel_circle_select(ViewContext *vc,
{
struct EditSelectBuf_Cache *esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f));
if (esel->select_bitmap != NULL) {
changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op);
@@ -3715,7 +3521,7 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
if (use_zbuf) {
struct EditSelectBuf_Cache *esel = wm_userdata->data;
- const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx);
+ const uint buffer_len = DRW_select_context_elem_len();
esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f));
if (esel->select_bitmap != NULL) {
changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index a316567fc63..d8dd6aa97b5 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -2157,16 +2157,6 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
- /* do we check for parameter? */
- if (transformModeUseSnap(t)) {
- if (t->modifiers & MOD_SNAP) {
- ts->snap_flag |= SCE_SNAP;
- }
- else {
- ts->snap_flag &= ~SCE_SNAP;
- }
- }
-
if (t->spacetype == SPACE_VIEW3D) {
if ((prop = RNA_struct_find_property(op->ptr, "orient_type")) &&
!RNA_property_is_set(op->ptr, prop) &&
@@ -2180,6 +2170,18 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
+ if (t->flag & T_MODAL) {
+ /* do we check for parameter? */
+ if (transformModeUseSnap(t)) {
+ if (t->modifiers & MOD_SNAP) {
+ ts->snap_flag |= SCE_SNAP;
+ }
+ else {
+ ts->snap_flag &= ~SCE_SNAP;
+ }
+ }
+ }
+
if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
RNA_property_boolean_set(op->ptr, prop, proportional & PROP_EDIT_USE);
RNA_boolean_set(op->ptr, "use_proportional_connected", proportional & PROP_EDIT_CONNECTED);
@@ -4581,17 +4583,42 @@ static void ElementRotation(
ElementRotation_ex(t, tc, td, mat, center);
}
-static void applyRotationValue(TransInfo *t, float angle, float axis[3])
+static float large_rotation_limit(float angle)
+{
+ /* Limit rotation to 1001 turns max
+ * (otherwise iterative handling of 'large' rotations would become too slow). */
+ const float angle_max = (float)(M_PI * 2000.0);
+ if (fabsf(angle) > angle_max) {
+ const float angle_sign = angle < 0.0f ? -1.0f : 1.0f;
+ angle = angle_sign * (fmodf(fabsf(angle), (float)(M_PI * 2.0)) + angle_max);
+ }
+ return angle;
+}
+
+static void applyRotationValue(TransInfo *t,
+ float angle,
+ float axis[3],
+ const bool is_large_rotation)
{
float mat[3][3];
int i;
+ const float angle_sign = angle < 0.0f ? -1.0f : 1.0f;
+ /* We cannot use something too close to 180°, or 'continuous' rotation may fail
+ * due to computing error... */
+ const float angle_step = angle_sign * (float)(0.9 * M_PI);
+
+ if (is_large_rotation) {
+ /* Just in case, calling code should have already done that in practice
+ * (for UI feedback reasons). */
+ angle = large_rotation_limit(angle);
+ }
+
axis_angle_normalized_to_mat3(mat, axis, angle);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
-
if (td->flag & TD_NOACTION) {
break;
}
@@ -4600,14 +4627,32 @@ static void applyRotationValue(TransInfo *t, float angle, float axis[3])
continue;
}
+ float angle_final = angle;
if (t->con.applyRot) {
t->con.applyRot(t, tc, td, axis, NULL);
- axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
+ angle_final = angle * td->factor;
}
else if (t->flag & T_PROP_EDIT) {
- axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
+ angle_final = angle * td->factor;
}
+ /* Rotation is very likely to be above 180°, we need to do rotation by steps.
+ * Note that this is only needed when doing 'absolute' rotation
+ * (i.e. from initial rotation again, typically when using numinput).
+ * regular incremental rotation (from mouse/widget/...) will be called often enough,
+ * hence steps are small enough to be properly handled without that complicated trick. */
+ if (is_large_rotation) {
+ copy_v3_v3(td->ext->rot, td->ext->irot);
+ for (float angle_progress = angle_step; fabsf(angle_progress) < fabsf(angle_final);
+ angle_progress += angle_step) {
+ axis_angle_normalized_to_mat3(mat, axis, angle_progress);
+ ElementRotation(t, tc, td, mat, t->around);
+ }
+ axis_angle_normalized_to_mat3(mat, axis, angle_final);
+ }
+ else if (angle_final != angle) {
+ axis_angle_normalized_to_mat3(mat, axis, angle_final);
+ }
ElementRotation(t, tc, td, mat, t->around);
}
}
@@ -4632,15 +4677,18 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
applySnapping(t, &final);
- /* Used to clamp final result in [-PI, PI[ range, no idea why,
- * inheritance from 2.4x area, see T48998. */
- applyNumInput(&t->num, &final);
+ if (applyNumInput(&t->num, &final)) {
+ /* We have to limit the amount of turns to a reasonable number here,
+ * to avoid things getting *very* slow, see how applyRotationValue() handles those... */
+ final = large_rotation_limit(final);
+ }
t->values[0] = final;
headerRotation(t, str, final);
- applyRotationValue(t, final, axis_final);
+ const bool is_large_rotation = hasNumInput(&t->num);
+ applyRotationValue(t, final, axis_final, is_large_rotation);
recalcData(t);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index cb539c8d1a5..3a204d0d157 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -235,8 +235,7 @@ static void axisProjection(const TransInfo *t,
normalize_v3_v3_length(out, axis, -factor);
}
else {
- float v[3], i1[3], i2[3];
- float v2[3], v4[3];
+ float v[3];
float norm_center[3];
float plane[3];
@@ -261,14 +260,16 @@ static void axisProjection(const TransInfo *t,
}
}
else {
- add_v3_v3v3(v2, t_con_center, axis);
- add_v3_v3v3(v4, v, norm);
-
- isect_line_line_v3(t_con_center, v2, v, v4, i1, i2);
-
- sub_v3_v3v3(v, i2, v);
-
- sub_v3_v3v3(out, i1, t_con_center);
+ /* Use ray-ray intersection instead of line-line because this gave
+ * precision issues adding small values to large numbers. */
+ float mul;
+ if (isect_ray_ray_v3(t_con_center, axis, v, norm, &mul, NULL)) {
+ mul_v3_v3fl(out, axis, mul);
+ }
+ else {
+ /* In practice this should never fail. */
+ BLI_assert(0);
+ }
/* possible some values become nan when
* viewpoint and object are both zero */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index d13c0f8e8f1..5626e9b5c81 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -6133,6 +6133,8 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c
MEM_freeN(custom_data->data);
custom_data->data = NULL;
}
+
+ DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
}
static void createTransSeqData(bContext *C, TransInfo *t)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
index 54218da9eb5..e0139eac6b2 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
@@ -85,6 +85,21 @@ static bool dependsOnTime(GpencilModifierData *md)
return (mmd->flag & GP_NOISE_USE_RANDOM) != 0;
}
+/* Get the lower number of frame for all layers. */
+static int get_lower_frame(bGPdata *gpd)
+{
+ int init = 99999;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if (gpl->frames.first) {
+ bGPDframe *gpf = gpl->frames.first;
+ if (gpf->framenum < init) {
+ init = gpf->framenum;
+ }
+ }
+ }
+ return init;
+}
+
/* aply noise effect based on stroke direction */
static void deformStroke(
GpencilModifierData *md, Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDstroke *gps)
@@ -103,6 +118,7 @@ static void deformStroke(
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
GpencilModifierData *md_eval = BKE_gpencil_modifiers_findByName(object_eval, md->name);
NoiseGpencilModifierData *mmd_eval = (NoiseGpencilModifierData *)md_eval;
+ bGPdata *gpd = (bGPdata *)ob->data;
/* Random generator, only init once. (it uses eval to get same value in render) */
if (mmd_eval->rng == NULL) {
@@ -110,6 +126,9 @@ static void deformStroke(
rng_seed ^= POINTER_AS_UINT(mmd);
mmd_eval->rng = BLI_rng_new(rng_seed);
mmd->rng = mmd_eval->rng;
+ /* Get lower frame number */
+ mmd_eval->scene_frame = get_lower_frame(gpd);
+ mmd->scene_frame = mmd_eval->scene_frame;
}
if (!is_stroke_affected_by_modifier(ob,
@@ -176,19 +195,17 @@ static void deformStroke(
sub_v3_v3v3(vec1, &pt1->x, &pt0->x);
}
vran = len_v3(vec1);
- /* vector orthogonal to normal */
+ /* Vector orthogonal to normal. */
cross_v3_v3v3(vec2, vec1, normal);
normalize_v3(vec2);
- /* use random noise */
+ /* Use random noise */
if (mmd->flag & GP_NOISE_USE_RANDOM) {
- sc_diff = abs(mmd->scene_frame - sc_frame);
- /* only recalc if the gp frame change or the number of scene frames is bigger than step */
- if ((!gpl->actframe) || (mmd->gp_frame != gpl->actframe->framenum) ||
- (sc_diff >= mmd->step)) {
+ sc_diff = abs(sc_frame - mmd->scene_frame) % mmd->step;
+ /* Only recalc if the gp frame change or is a step. */
+ if ((mmd->gp_frame != sc_frame) && (sc_diff == 0)) {
vran = mmd->vrand1 = BLI_rng_get_float(mmd->rng);
vdir = mmd->vrand2 = BLI_rng_get_float(mmd->rng);
- mmd->gp_frame = gpl->actframe->framenum;
- mmd->scene_frame = sc_frame;
+ mmd->gp_frame = sc_frame;
}
else {
vran = mmd->vrand1;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index f30eff1484b..c620644a5f8 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -221,9 +221,6 @@ data_to_c_simple(shaders/gpu_shader_2D_edituvs_edges_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_edituvs_faces_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_edituvs_stretch_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_3D_selection_id_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_selection_id_frag.glsl SRC)
-
data_to_c_simple(shaders/gpu_shader_text_simple_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_simple_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index cae2392e503..124f1f1ff8a 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -355,11 +355,8 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_2D_UV_FACES,
GPU_SHADER_2D_UV_FACES_STRETCH_AREA,
GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE,
- /* Selection */
- GPU_SHADER_3D_FLAT_SELECT_ID,
- GPU_SHADER_3D_UNIFORM_SELECT_ID,
} eGPUBuiltinShader;
-#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_3D_UNIFORM_SELECT_ID + 1)
+#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE + 1)
/** Support multiple configurations. */
typedef enum eGPUShaderConfig {
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index c142d8ccba2..3e930d19696 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -139,9 +139,6 @@ extern char datatoc_gpu_shader_2D_edituvs_edges_vert_glsl[];
extern char datatoc_gpu_shader_2D_edituvs_faces_vert_glsl[];
extern char datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl[];
-extern char datatoc_gpu_shader_3D_selection_id_vert_glsl[];
-extern char datatoc_gpu_shader_selection_id_frag_glsl[];
-
extern char datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl[];
extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[];
extern char datatoc_gpu_shader_2D_line_dashed_geom_glsl[];
@@ -1312,18 +1309,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.defs = "#define STRETCH_ANGLE\n",
},
- [GPU_SHADER_3D_FLAT_SELECT_ID] =
- {
- .vert = datatoc_gpu_shader_3D_selection_id_vert_glsl,
- .frag = datatoc_gpu_shader_selection_id_frag_glsl,
- },
- [GPU_SHADER_3D_UNIFORM_SELECT_ID] =
- {
- .vert = datatoc_gpu_shader_3D_selection_id_vert_glsl,
- .frag = datatoc_gpu_shader_selection_id_frag_glsl,
- .defs = "#define UNIFORM_ID\n",
- },
-
[GPU_SHADER_GPENCIL_STROKE] =
{
.vert = datatoc_gpu_shader_gpencil_stroke_vert_glsl,
@@ -1370,9 +1355,7 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
GPU_SHADER_3D_GROUNDLINE,
GPU_SHADER_3D_GROUNDPOINT,
GPU_SHADER_DISTANCE_LINES,
- GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR,
- GPU_SHADER_3D_FLAT_SELECT_ID,
- GPU_SHADER_3D_UNIFORM_SELECT_ID) ||
+ GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR) ||
ELEM(shader,
GPU_SHADER_3D_FLAT_COLOR,
GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR,
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl
deleted file mode 100644
index 0d58909efd8..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl
+++ /dev/null
@@ -1,26 +0,0 @@
-
-uniform mat4 ModelViewProjectionMatrix;
-
-in vec3 pos;
-
-#ifndef UNIFORM_ID
-uniform uint offset;
-in uint color;
-
-flat out uint id;
-#endif
-
-void main()
-{
-#ifndef UNIFORM_ID
- id = offset + color;
-#endif
-
- vec4 pos_4d = vec4(pos, 1.0);
- gl_Position = ModelViewProjectionMatrix * pos_4d;
-
-#ifdef USE_WORLD_CLIP_PLANES
- /* Warning: ModelMatrix is typically used but select drawing is different. */
- world_clip_planes_calc_clip_distance(pos);
-#endif
-}
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index bac408e869b..5c7a60bbdcf 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -59,27 +59,34 @@ typedef enum ThumbSource {
#define THUMB_DEFAULT_HASH "00000000000000000000000000000000"
/* create thumbnail for file and returns new imbuf for thumbnail */
-ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, ImBuf *ibuf);
+struct ImBuf *IMB_thumb_create(const char *path,
+ ThumbSize size,
+ ThumbSource source,
+ struct ImBuf *ibuf);
/* read thumbnail for file and returns new imbuf for thumbnail */
-ImBuf *IMB_thumb_read(const char *path, ThumbSize size);
+struct ImBuf *IMB_thumb_read(const char *path, ThumbSize size);
/* delete all thumbs for the file */
void IMB_thumb_delete(const char *path, ThumbSize size);
/* return the state of the thumb, needed to determine how to manage the thumb */
-ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source);
+struct ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source);
/* create the necessary dirs to store the thumbnails */
void IMB_thumb_makedirs(void);
/* special function for loading a thumbnail embedded into a blend file */
-ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id);
+struct ImBuf *IMB_thumb_load_blend(const char *blen_path,
+ const char *blen_group,
+ const char *blen_id);
void IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float aspect);
/* special function for previewing fonts */
-ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y);
+struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y);
bool IMB_thumb_load_font_get_hash(char *r_hash);
+void IMB_thumb_clear_translations(void);
+void IMB_thumb_ensure_translations(void);
/* Threading */
void IMB_thumb_locks_acquire(void);
diff --git a/source/blender/imbuf/intern/thumbs_font.c b/source/blender/imbuf/intern/thumbs_font.c
index 1213927d329..ddb1eb62006 100644
--- a/source/blender/imbuf/intern/thumbs_font.c
+++ b/source/blender/imbuf/intern/thumbs_font.c
@@ -32,14 +32,28 @@
#include "../../blenfont/BLF_api.h"
#include "../../blentranslation/BLT_translation.h"
-static const char *thumb_str[] = {
- N_("AaBbCc"),
+#define THUMB_TXT_ITEMS \
+ N_("AaBbCc"), N_("The quick"), N_("brown fox"), N_("jumps over"), N_("the lazy dog"),
- N_("The quick"),
- N_("brown fox"),
- N_("jumps over"),
- N_("the lazy dog"),
-};
+static const char *thumb_str[] = {THUMB_TXT_ITEMS};
+
+static const char *i18n_thumb_str[] = {THUMB_TXT_ITEMS};
+
+#undef THUMB_TXT_ITEMS
+
+void IMB_thumb_clear_translations(void)
+{
+ for (int i = ARRAY_SIZE(thumb_str); i-- > 0;) {
+ i18n_thumb_str[i] = NULL;
+ }
+}
+
+void IMB_thumb_ensure_translations(void)
+{
+ for (int i = ARRAY_SIZE(thumb_str); i-- > 0;) {
+ i18n_thumb_str[i] = BLT_translate_do(BLT_I18NCONTEXT_DEFAULT, thumb_str[i]);
+ }
+}
struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y)
{
@@ -62,6 +76,7 @@ struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned
BLF_thumb_preview(filename,
thumb_str,
+ i18n_thumb_str,
ARRAY_SIZE(thumb_str),
font_color,
font_size,
@@ -87,8 +102,9 @@ bool IMB_thumb_load_font_get_hash(char *r_hash)
len += BLI_strncpy_rlen(str + len, THUMB_DEFAULT_HASH, sizeof(buf) - len);
for (i = 0; (i < draw_str_lines) && (len < sizeof(buf)); i++) {
- len += BLI_strncpy_rlen(
- str + len, BLT_translate_do(BLT_I18NCONTEXT_DEFAULT, thumb_str[i]), sizeof(buf) - len);
+ len += BLI_strncpy_rlen(str + len,
+ i18n_thumb_str[i] != NULL ? i18n_thumb_str[i] : thumb_str[i],
+ sizeof(buf) - len);
}
BLI_hash_md5_buffer(str, len, digest);
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index cad1af8eb50..ef9069acb78 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -616,6 +616,15 @@ typedef enum IDRecalcFlag {
ID_RECALC_PARAMETERS = (1 << 21),
+ /* Makes it so everything what depends on time.
+ * Basically, the same what changing frame in a timeline will do. */
+ ID_RECALC_TIME = (1 << 22),
+
+ /* Input has changed and datablock is to be reload from disk.
+ * Applies to movie clips to inform that copy-on-written version is to be refreshed for the new
+ * input file or for color space changes. */
+ ID_RECALC_SOURCE = (1 << 23),
+
/***************************************************************************
* Pseudonyms, to have more semantic meaning in the actual code without
* using too much low-level and implementation specific tags. */
diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h
index c7f3ef4156d..af543864536 100644
--- a/source/blender/makesdna/DNA_collection_types.h
+++ b/source/blender/makesdna/DNA_collection_types.h
@@ -57,7 +57,9 @@ typedef struct Collection {
float instance_offset[3];
short flag;
- char _pad[6];
+ /* Runtime-only, always cleared on file load. */
+ short tag;
+ char _pad[4];
/* Runtime. Cache of objects in this collection and all its
* children. This is created on demand when e.g. some physics
@@ -84,4 +86,12 @@ enum {
COLLECTION_IS_MASTER = (1 << 5), /* Is master collection embedded in the scene. */
};
+/* Collection->tag */
+enum {
+ /* That code (BKE_main_collections_parent_relations_rebuild and the like)
+ * is called from very low-level places, like e.g ID remapping...
+ * Using a generic tag like LIB_TAG_DOIT for this is just impossible, we need our very own. */
+ COLLECTION_TAG_RELATION_REBUILD = (1 << 0),
+};
+
#endif /* __DNA_COLLECTION_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 8b756ff2937..c2a9d3cf296 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -92,7 +92,7 @@ typedef struct NoiseGpencilModifierData {
int step;
/** Last gp frame used. */
int gp_frame;
- /** Last scene frame used. */
+ /** First scene frame used. */
int scene_frame;
/** Random values. */
float vrand1, vrand2;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 307a6f2fe16..9134e603a87 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -412,7 +412,7 @@ typedef enum eGPLayerBlendModes {
typedef struct bGPdata_Runtime {
/** Last region where drawing was originated. */
struct ARegion *ar;
- /** Stroke buffer (can hold GP_STROKE_BUFFER_MAX). */
+ /** Stroke buffer. */
void *sbuffer;
/* GP Object drawing */
@@ -431,11 +431,13 @@ typedef struct bGPdata_Runtime {
* - buffer must be initialized before use, but freed after
* whole paint operation is over
*/
- /** Number of elements currently in cache. */
- short sbuffer_size;
+ /** Number of elements currently used in cache. */
+ short sbuffer_used;
/** Flags for stroke that cache represents. */
short sbuffer_sflag;
- char _pad[6];
+ /** Number of total elements available in cache. */
+ short sbuffer_size;
+ char _pad[4];
/** Number of control-points for stroke. */
int tot_cp_points;
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 43df1d8e1aa..d221b7005f6 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -597,7 +597,7 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain,
else if (GS(id->name) == ID_MC) {
MovieClip *clip = (MovieClip *)id;
- BKE_movieclip_reload(bmain, clip);
+ DEG_id_tag_update(&clip->id, ID_RECALC_SOURCE);
BKE_sequence_invalidate_movieclip_strips(bmain, clip);
WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, &clip->id);
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 92a32ec8ab5..743bac2b709 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -332,6 +332,7 @@ static void rna_def_metaball(BlenderRNA *brna)
/* number values */
prop = RNA_def_property(srna, "resolution", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "wiresize");
+ RNA_def_property_float_default(prop, 0.4f);
RNA_def_property_range(prop, 0.005f, 10000.0f);
RNA_def_property_ui_range(prop, 0.05f, 1000.0f, 2.5f, 3);
RNA_def_property_ui_text(prop, "Wire Size", "Polygonization resolution in the 3D viewport");
@@ -339,6 +340,7 @@ static void rna_def_metaball(BlenderRNA *brna)
prop = RNA_def_property(srna, "render_resolution", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "rendersize");
+ RNA_def_property_float_default(prop, 0.2f);
RNA_def_property_range(prop, 0.005f, 10000.0f);
RNA_def_property_ui_range(prop, 0.025f, 1000.0f, 2.5f, 3);
RNA_def_property_ui_text(prop, "Render Size", "Polygonization resolution in rendering");
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index 247c4c69019..10e19b92dda 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -51,12 +51,11 @@
# include "DNA_screen_types.h"
# include "DNA_space_types.h"
-static void rna_MovieClip_reload_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_MovieClip_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
MovieClip *clip = (MovieClip *)ptr->id.data;
- BKE_movieclip_reload(bmain, clip);
- DEG_id_tag_update(&clip->id, 0);
+ DEG_id_tag_update(&clip->id, ID_RECALC_SOURCE);
}
static void rna_MovieClip_size_get(PointerRNA *ptr, int *values)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index d3b532dd11d..7fa1544d809 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -441,7 +441,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value, struct Report
return;
}
- if ((id->tag & LIB_TAG_NO_MAIN) != (ob->id.tag & LIB_TAG_NO_MAIN)) {
+ if (id && ((id->tag & LIB_TAG_NO_MAIN) != (ob->id.tag & LIB_TAG_NO_MAIN))) {
BKE_report(reports,
RPT_ERROR,
"Can only assign evaluated data to evaluated object, or original data to "
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 1fea87df10c..d9306ba7a65 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -471,12 +471,12 @@ static void rna_PopMenuEnd(bContext *C, PointerRNA *handle)
}
/* popover wrapper */
-static PointerRNA rna_PopoverBegin(bContext *C, int ui_units_x)
+static PointerRNA rna_PopoverBegin(bContext *C, int ui_units_x, bool from_active_button)
{
PointerRNA r_ptr;
void *data;
- data = (void *)UI_popover_begin(C, U.widget_unit * ui_units_x);
+ data = (void *)UI_popover_begin(C, U.widget_unit * ui_units_x, from_active_button);
RNA_pointer_create(NULL, &RNA_UIPopover, data, &r_ptr);
@@ -821,6 +821,8 @@ void RNA_api_wm(StructRNA *srna)
parm = RNA_def_pointer(func, "menu", "UIPopover", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
RNA_def_function_return(func, parm);
+ RNA_def_boolean(
+ func, "from_active_button", 0, "Use Button", "Use the active button for positioning");
/* wrap UI_popover_end */
func = RNA_def_function(srna, "popover_end__internal", "rna_PopoverEnd");
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 50447ae0376..ac0d72214c8 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -169,7 +169,7 @@ typedef struct DisplaceUserdata {
static void displaceModifier_do_task(void *__restrict userdata,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
DisplaceUserdata *data = (DisplaceUserdata *)userdata;
DisplaceModifierData *dmd = data->dmd;
@@ -348,7 +348,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
data.pool = BKE_image_pool_new();
BKE_texture_fetch_images_for_pool(tex_target, data.pool);
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (numVerts > 512);
BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, &settings);
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index e27d2786751..abb4c5cae32 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -671,8 +671,9 @@ static void LaplacianDeformModifier_do(
&lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) {
- modifier_setError(
- &lmd->modifier, "Vertex group '%s' is not valid", sys->anchor_grp_name);
+ modifier_setError(&lmd->modifier,
+ "Vertex group '%s' is not valid, or maybe empty",
+ sys->anchor_grp_name);
}
}
}
@@ -683,7 +684,8 @@ static void LaplacianDeformModifier_do(
}
else {
if (!isValidVertexGroup(lmd, ob, mesh)) {
- modifier_setError(&lmd->modifier, "Vertex group '%s' is not valid", lmd->anchor_grp_name);
+ modifier_setError(
+ &lmd->modifier, "Vertex group '%s' is not valid, or maybe empty", lmd->anchor_grp_name);
lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
}
else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index d89a47f4cf3..da261b4f835 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -259,7 +259,7 @@ typedef struct MeshdeformUserdata {
static void meshdeform_vert_task(void *__restrict userdata,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
MeshdeformUserdata *data = userdata;
/*const*/ MeshDeformModifierData *mmd = data->mmd;
@@ -435,7 +435,7 @@ static void meshdeformModifier_do(ModifierData *md,
data.icagemat = icagemat;
/* Do deformation. */
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 16;
BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task, &settings);
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 5cded96efe2..aff5b8b071b 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -196,7 +196,7 @@ typedef struct GenerateOceanGeometryData {
static void generate_ocean_geometry_vertices(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
GenerateOceanGeometryData *gogd = userdata;
int x;
@@ -212,7 +212,7 @@ static void generate_ocean_geometry_vertices(void *__restrict userdata,
static void generate_ocean_geometry_polygons(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
GenerateOceanGeometryData *gogd = userdata;
int x;
@@ -241,7 +241,7 @@ static void generate_ocean_geometry_polygons(void *__restrict userdata,
static void generate_ocean_geometry_uvs(void *__restrict userdata,
const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
GenerateOceanGeometryData *gogd = userdata;
int x;
@@ -301,7 +301,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd)
gogd.mpolys = result->mpoly;
gogd.mloops = result->mloop;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = use_threading;
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 47c0114f02f..c428325e42b 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -796,7 +796,7 @@ BLI_INLINE float computeNormalDisplacement(const float point_co[3],
static void bindVert(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SDefBindCalcData *const data = (SDefBindCalcData *)userdata;
float point_co[3];
@@ -1076,7 +1076,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd,
mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (numverts > 10000);
BLI_task_parallel_range(0, numverts, &data, bindVert, &settings);
@@ -1116,7 +1116,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd,
static void deformVert(void *__restrict userdata,
const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const SDefDeformData *const data = (SDefDeformData *)userdata;
const SDefBind *sdbind = data->bind_verts[index].binds;
@@ -1247,7 +1247,7 @@ static void surfacedeformModifier_do(ModifierData *md,
mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
}
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (numverts > 10000);
BLI_task_parallel_range(0, numverts, &data, deformVert, &settings);
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index 995f3d06fcb..2c5f4b66c23 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -98,7 +98,7 @@ typedef struct UVWarpData {
static void uv_warp_compute(void *__restrict userdata,
const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
const UVWarpData *data = userdata;
@@ -202,7 +202,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
.axis_u = axis_u,
.axis_v = axis_v,
};
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (numPolys > 1000);
BLI_task_parallel_range(0, numPolys, &data, uv_warp_compute, &settings);
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 37f25fd7c89..86d1b310d0c 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -92,7 +92,7 @@ typedef struct Vert2GeomDataChunk {
*/
static void vert2geom_task_cb_ex(void *__restrict userdata,
const int iter,
- const ParallelRangeTLS *__restrict tls)
+ const TaskParallelTLS *__restrict tls)
{
Vert2GeomData *data = userdata;
Vert2GeomDataChunk *data_chunk = tls->userdata_chunk;
@@ -188,7 +188,7 @@ static void get_vert2geom_distance(int numVerts,
data.dist[1] = dist_e;
data.dist[2] = dist_f;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (numVerts > 10000);
settings.userdata_chunk = &data_chunk;
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 92ba7704b19..b8a83d0588d 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -184,6 +184,49 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
return PyC_UnicodeFromByte(path ? path : "");
}
+PyDoc_STRVAR(bpy_system_resource_doc,
+ ".. function:: system_resource(type, path=\"\")\n"
+ "\n"
+ " Return a system resource path.\n"
+ "\n"
+ " :arg type: string in ['DATAFILES', 'SCRIPTS', 'PYTHON'].\n"
+ " :type type: string\n"
+ " :arg path: Optional subdirectory.\n"
+ " :type path: string\n");
+static PyObject *bpy_system_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ const char *type;
+ const char *subdir = NULL;
+ int folder_id;
+
+ const char *path;
+
+ static const char *_keywords[] = {"type", "path", NULL};
+ static _PyArg_Parser _parser = {"s|s:system_resource", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &type, &subdir)) {
+ return NULL;
+ }
+
+ /* stupid string compare */
+ if (STREQ(type, "DATAFILES")) {
+ folder_id = BLENDER_SYSTEM_DATAFILES;
+ }
+ else if (STREQ(type, "SCRIPTS")) {
+ folder_id = BLENDER_SYSTEM_SCRIPTS;
+ }
+ else if (STREQ(type, "PYTHON")) {
+ folder_id = BLENDER_SYSTEM_PYTHON;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "invalid resource argument");
+ return NULL;
+ }
+
+ path = BKE_appdir_folder_id(folder_id, subdir);
+
+ return PyC_UnicodeFromByte(path ? path : "");
+}
+
PyDoc_STRVAR(
bpy_resource_path_doc,
".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
@@ -292,6 +335,12 @@ static PyMethodDef meth_bpy_user_resource = {
METH_VARARGS | METH_KEYWORDS,
NULL,
};
+static PyMethodDef meth_bpy_system_resource = {
+ "system_resource",
+ (PyCFunction)bpy_system_resource,
+ METH_VARARGS | METH_KEYWORDS,
+ bpy_system_resource_doc,
+};
static PyMethodDef meth_bpy_resource_path = {
"resource_path",
(PyCFunction)bpy_resource_path,
@@ -398,6 +447,9 @@ void BPy_init_modules(void)
meth_bpy_user_resource.ml_name,
(PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
PyModule_AddObject(mod,
+ meth_bpy_system_resource.ml_name,
+ (PyObject *)PyCFunction_New(&meth_bpy_system_resource, NULL));
+ PyModule_AddObject(mod,
meth_bpy_resource_path.ml_name,
(PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
PyModule_AddObject(mod,
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index c9c9e4adafb..06d8b645ac7 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -143,7 +143,6 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset)
/* no traceback available when SyntaxError.
* python has no api's to this. reference parse_syntax_error() from pythonrun.c */
PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
- PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
if (value) { /* should always be true */
PyObject *message;
@@ -165,6 +164,7 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset)
*lineno = -1;
}
}
+ PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
}
else {
PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index ab8146c6626..63c6245ced5 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -895,7 +895,7 @@ typedef struct SampleCallbackData {
static void point_density_sample_func(void *__restrict data_v,
const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
SampleCallbackData *data = (SampleCallbackData *)data_v;
@@ -966,7 +966,7 @@ void RE_point_density_sample(Depsgraph *depsgraph,
data.min = min;
data.dim = dim;
data.values = values;
- ParallelRangeSettings settings;
+ TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (resolution > 32);
BLI_task_parallel_range(0, resolution, &data, point_density_sample_func, &settings);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index f3a4bce392f..6fc73268a38 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -747,6 +747,10 @@ void *WM_draw_cb_activate(struct wmWindow *win,
void WM_draw_cb_exit(struct wmWindow *win, void *handle);
void WM_redraw_windows(struct bContext *C);
+void WM_draw_region_viewport_ensure(struct ARegion *ar, short space_type);
+void WM_draw_region_viewport_bind(struct ARegion *ar);
+void WM_draw_region_viewport_unbind(struct ARegion *ar);
+
/* Region drawing */
void WM_draw_region_free(struct ARegion *ar);
struct GPUViewport *WM_draw_region_get_viewport(struct ARegion *ar, int view);
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 534474a6221..ee96515c27f 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -973,7 +973,8 @@ bool WM_gizmomap_cursor_set(const wmGizmoMap *gzmap, wmWindow *win)
bool wm_gizmomap_highlight_set(wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz, int part)
{
if ((gz != gzmap->gzmap_context.highlight) || (gz && part != gz->highlight_part)) {
- const bool init_last_cursor = (gzmap->gzmap_context.highlight == NULL);
+ const bool init_last_cursor = !(gzmap->gzmap_context.highlight &&
+ gzmap->gzmap_context.last_cursor != -1);
if (gzmap->gzmap_context.highlight) {
gzmap->gzmap_context.highlight->state &= ~WM_GIZMO_STATE_HIGHLIGHT;
gzmap->gzmap_context.highlight->highlight_part = -1;
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 8e15eb71395..b0b89fa074f 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -240,9 +240,14 @@ static void wm_region_test_render_do_draw(const Scene *scene,
}
}
+static bool wm_region_use_viewport_by_type(short space_type, short region_type)
+{
+ return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE) && region_type == RGN_TYPE_WINDOW);
+}
+
static bool wm_region_use_viewport(ScrArea *sa, ARegion *ar)
{
- return (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && ar->regiontype == RGN_TYPE_WINDOW);
+ return wm_region_use_viewport_by_type(sa->spacetype, ar->regiontype);
}
/********************** draw all **************************/
@@ -1065,3 +1070,31 @@ void WM_redraw_windows(bContext *C)
CTX_wm_area_set(C, area_prev);
CTX_wm_region_set(C, ar_prev);
}
+
+/* -------------------------------------------------------------------- */
+/** \name Region Viewport Drawing
+ *
+ * This is needed for viewport drawing for operator use
+ * (where the viewport may not have drawn yet).
+ *
+ * Otherwise avoid using these sine they're exposing low level logic externally.
+ *
+ * \{ */
+
+void WM_draw_region_viewport_ensure(ARegion *ar, short space_type)
+{
+ bool use_viewport = wm_region_use_viewport_by_type(space_type, ar->regiontype);
+ wm_draw_region_buffer_create(ar, false, use_viewport);
+}
+
+void WM_draw_region_viewport_bind(ARegion *ar)
+{
+ wm_draw_region_bind(ar, 0);
+}
+
+void WM_draw_region_viewport_unbind(ARegion *ar)
+{
+ wm_draw_region_unbind(ar, 0);
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 48b09b0d329..3e965fc2f55 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -605,7 +605,6 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* assume automated tasks with background, don't write recent file list */
const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
bool success = false;
- int retval;
/* so we can get the error message */
errno = 0;
@@ -619,7 +618,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* first try to append data from exotic file formats... */
/* it throws error box when file doesn't exist and returns -1 */
/* note; it should set some error message somewhere... (ton) */
- retval = wm_read_exotic(filepath);
+ const int retval = wm_read_exotic(filepath);
/* we didn't succeed, now try to read Blender file */
if (retval == BKE_READ_EXOTIC_OK_BLEND) {
@@ -632,7 +631,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* confusing this global... */
G.relbase_valid = 1;
- retval = BKE_blendfile_read(
+ success = BKE_blendfile_read(
C,
filepath,
/* Loading preferences when the user intended to load a regular file is a security risk,
@@ -668,7 +667,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
WM_check(C); /* opens window(s), checks keymaps */
- if (retval != BKE_BLENDFILE_READ_FAIL) {
+ if (success) {
if (do_history) {
wm_history_file_update();
}
@@ -677,8 +676,6 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
const bool use_data = true;
const bool use_userdef = false;
wm_file_read_post(C, false, false, use_data, use_userdef, false);
-
- success = true;
}
#if 0
else if (retval == BKE_READ_EXOTIC_OK_OTHER) {
@@ -941,7 +938,7 @@ void wm_homefile_read(bContext *C,
.is_startup = true,
.skip_flags = skip_flags,
},
- NULL) != BKE_BLENDFILE_READ_FAIL;
+ NULL);
}
if (BLI_listbase_is_empty(&U.themes)) {
if (G.debug & G_DEBUG) {
@@ -1053,7 +1050,7 @@ void wm_homefile_read(bContext *C,
wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
}
- if (use_factory_settings) {
+ if (use_userdef) {
/* Clear keymaps because the current default keymap may have been initialized
* from user preferences, which have been reset. */
for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
@@ -2956,7 +2953,8 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat
wmWindow *win = CTX_wm_window(C);
UI_popup_block_close(C, win, arg_block);
- if (save_images_when_file_is_closed) {
+ int modified_images_count = ED_image_save_all_modified_info(C, NULL);
+ if (modified_images_count > 0 && save_images_when_file_is_closed) {
if (ED_image_should_save_modified(C)) {
ReportList *reports = CTX_wm_reports(C);
ED_image_save_all_modified(C, reports);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 6d8c7d045c0..df14609d29b 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -80,6 +80,8 @@
#include "RE_engine.h"
#include "RE_pipeline.h" /* RE_ free stuff */
+#include "IMB_thumbs.h"
+
#ifdef WITH_PYTHON
# include "BPY_extern.h"
#endif
@@ -302,6 +304,9 @@ void WM_init(bContext *C, int argc, const char **argv)
/* Call again to set from userpreferences... */
BLT_lang_set(NULL);
+ /* That one is generated on demand, we need to be sure it's clear on init. */
+ IMB_thumb_clear_translations();
+
if (!G.background) {
#ifdef WITH_INPUT_NDOF
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
index c471cb6f922..f22b5d07686 100644
--- a/source/blender/windowmanager/intern/wm_operator_props.c
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -340,8 +340,11 @@ void WM_operator_properties_gesture_box_ex(wmOperatorType *ot, bool deselect, bo
*/
void WM_operator_properties_use_cursor_init(wmOperatorType *ot)
{
- PropertyRNA *prop = RNA_def_boolean(
- ot->srna, "use_cursor_init", true, "Cursor Init", "Use initial cursor position");
+ PropertyRNA *prop = RNA_def_boolean(ot->srna,
+ "use_cursor_init",
+ true,
+ "Use Mouse Position",
+ "Allow the initial mouse position to be used");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 7637f327617..dcf5682099e 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -1056,6 +1056,12 @@ unset(LIB)
setup_liblinks(blender)
+# vcpkg substitutes our libs with theirs, which will cause issues when you
+# you run these builds on other systems due to missing dlls. So we opt out
+# the use of vcpkg
+if (WIN32)
+ set_target_properties(blender PROPERTIES VS_GLOBAL_VcpkgEnabled "false")
+endif()
# -----------------------------------------------------------------------------
# Setup launcher