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:
authorClément Foucault <foucault.clem@gmail.com>2019-12-02 03:40:58 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-12-02 03:40:58 +0300
commita35c635edb3db548e11555024ec3a384f93ce352 (patch)
treeae0c0c9435c2e7daed4cbd916e0be90df7898b51
parent7164e63fefcfa26caf387a2ad04a8c51b533c32b (diff)
parentf1ac64921b49eaea8658d144754a1a532198c720 (diff)
Merge branch 'master' into tmp-overlay-enginetmp-overlay-engine
# Conflicts: # source/blender/draw/modes/paint_texture_mode.c
-rw-r--r--CMakeLists.txt121
-rw-r--r--build_files/buildbot/slave_pack.py25
-rw-r--r--build_files/cmake/Modules/GTestTesting.cmake36
-rw-r--r--build_files/cmake/config/blender_full.cmake17
-rw-r--r--build_files/cmake/config/blender_lite.cmake9
-rw-r--r--build_files/cmake/config/blender_release.cmake17
-rw-r--r--build_files/cmake/packaging.cmake2
-rwxr-xr-xbuild_files/package_spec/build_archive.py10
-rw-r--r--intern/cycles/blender/blender_util.h11
-rw-r--r--intern/cycles/bvh/bvh_optix.cpp2
-rw-r--r--intern/cycles/device/device.h2
-rw-r--r--intern/cycles/device/device_multi.cpp12
-rw-r--r--intern/cycles/device/device_optix.cpp36
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h35
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h12
-rw-r--r--intern/cycles/kernel/kernel_passes.h12
-rw-r--r--intern/cycles/kernel/svm/svm_types.h6
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl10
-rw-r--r--intern/opencolorio/ocio_capi.h6
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc4
-rw-r--r--release/datafiles/blender_icons.svg27
-rw-r--r--release/datafiles/blender_icons16/icon16_ndof_dom.datbin1048 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ndof_fly.datbin1048 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ndof_trans.datbin1048 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ndof_turn.datbin1048 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ndof_dom.datbin4120 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ndof_fly.datbin4120 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ndof_trans.datbin4120 -> 0 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ndof_turn.datbin4120 -> 0 bytes
-rw-r--r--release/datafiles/userdef/userdef_default.c12
-rw-r--r--release/scripts/modules/console_python.py31
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py2
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py16
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py8
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py9
-rw-r--r--release/scripts/startup/bl_ui/space_nla.py8
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py6
-rw-r--r--release/scripts/startup/bl_ui/space_time.py9
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py57
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py21
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py8
-rw-r--r--source/blender/alembic/ABC_alembic.h2
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc4
-rw-r--r--source/blender/alembic/intern/abc_exporter.h2
-rw-r--r--source/blender/alembic/intern/abc_transform.cc5
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc2
-rw-r--r--source/blender/blenkernel/BKE_action.h9
-rw-r--r--source/blender/blenkernel/BKE_animsys.h15
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_brush.h4
-rw-r--r--source/blender/blenkernel/BKE_colortools.h4
-rw-r--r--source/blender/blenkernel/BKE_kelvinlet.h77
-rw-r--r--source/blender/blenkernel/BKE_material.h1
-rw-r--r--source/blender/blenkernel/BKE_modifier.h8
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h8
-rw-r--r--source/blender/blenkernel/BKE_sound.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c34
-rw-r--r--source/blender/blenkernel/intern/armature.c39
-rw-r--r--source/blender/blenkernel/intern/brush.c33
-rw-r--r--source/blender/blenkernel/intern/colortools.c68
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c6
-rw-r--r--source/blender/blenkernel/intern/kelvinlet.c215
-rw-r--r--source/blender/blenkernel/intern/material.c5
-rw-r--r--source/blender/blenkernel/intern/paint.c16
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenkernel/intern/workspace.c7
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c4
-rw-r--r--source/blender/blenloader/intern/versioning_280.c329
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c13
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c226
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h10
-rw-r--r--source/blender/depsgraph/CMakeLists.txt18
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc544
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc101
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h55
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc49
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h58
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc61
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h (renamed from source/blender/editors/include/BIF_gl.h)42
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc182
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h59
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.cc28
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h37
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc82
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h58
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc58
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h47
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc72
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h49
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc64
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h47
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/DRW_engine.h8
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c36
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c7
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c12
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h29
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c271
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c278
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c21
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c4
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl64
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl4
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl4
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl4
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c94
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h14
-rw-r--r--source/blender/draw/intern/draw_manager.c4
-rw-r--r--source/blender/editors/animation/anim_markers.c98
-rw-r--r--source/blender/editors/curve/editfont.c34
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt4
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c11
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c4
-rw-r--r--source/blender/editors/include/ED_mesh.h9
-rw-r--r--source/blender/editors/include/UI_icons.h8
-rw-r--r--source/blender/editors/interface/interface_draw.c4
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c7
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/io/io_alembic.c10
-rw-r--r--source/blender/editors/mesh/editface.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c17
-rw-r--r--source/blender/editors/mesh/editmesh_select.c35
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c7
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c1
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c8
-rw-r--r--source/blender/editors/object/object_edit.c2
-rw-r--r--source/blender/editors/render/render_internal.c2
-rw-r--r--source/blender/editors/render/render_opengl.c14
-rw-r--r--source/blender/editors/render/render_preview.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c485
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h4
-rw-r--r--source/blender/editors/space_action/space_action.c8
-rw-r--r--source/blender/editors/space_graph/space_graph.c7
-rw-r--r--source/blender/editors/space_info/info_stats.c4
-rw-r--r--source/blender/editors/space_nla/space_nla.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c5
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c68
-rw-r--r--source/blender/editors/transform/transform.c4
-rw-r--r--source/blender/editors/util/CMakeLists.txt1
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c10
-rw-r--r--source/blender/gpu/GPU_viewport.h1
-rw-r--r--source/blender/gpu/intern/gpu_batch.c19
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c11
-rw-r--r--source/blender/makesdna/DNA_action_types.h12
-rw-r--r--source/blender/makesdna/DNA_color_types.h23
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h8
-rw-r--r--source/blender/makesdna/DNA_movieclip_types.h8
-rw-r--r--source/blender/makesdna/DNA_scene_types.h33
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h8
-rw-r--r--source/blender/makesdna/DNA_space_types.h10
-rw-r--r--source/blender/makesdna/DNA_view3d_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_color.c99
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c11
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_space.c60
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c4
-rw-r--r--source/blender/python/intern/bpy_rna.c2
-rw-r--r--source/blender/windowmanager/WM_api.h3
-rw-r--r--source/blender/windowmanager/WM_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c3
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c3
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c4
-rw-r--r--source/blender/windowmanager/intern/wm_tooltip.c32
-rw-r--r--tests/gtests/CMakeLists.txt1
-rw-r--r--tests/gtests/blenloader/CMakeLists.txt90
-rw-r--r--tests/gtests/blenloader/blendfile_load_test.cc31
-rw-r--r--tests/gtests/blenloader/blendfile_loading_base_test.cc172
-rw-r--r--tests/gtests/blenloader/blendfile_loading_base_test.h64
-rwxr-xr-xtests/python/alembic_tests.py14
191 files changed, 4005 insertions, 2026 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e6e0abe1ab8..0af6d200c6e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -131,76 +131,6 @@ get_blender_version()
#-----------------------------------------------------------------------------
-# Platform Specific Defaults
-
-# list of var-names
-set(_init_vars)
-
-# initialize to ON
-macro(option_defaults_init)
- foreach(_var ${ARGV})
- set(${_var} ON)
- list(APPEND _init_vars "${_var}")
- endforeach()
- unset(_var)
-endmacro()
-
-# remove from namespace
-macro(option_defaults_clear)
- foreach(_var ${_init_vars})
- unset(${_var})
- endforeach()
- unset(_var)
- unset(_init_vars)
-endmacro()
-
-
-# values to initialize WITH_****
-option_defaults_init(
- _init_BUILDINFO
- _init_CODEC_FFMPEG
- _init_CYCLES_OSL
- _init_IMAGE_OPENEXR
- _init_INPUT_NDOF
- _init_JACK
- _init_OPENCOLLADA
- _init_OPENCOLORIO
- _init_SDL
- _init_FFTW3
- _init_OPENSUBDIV
-)
-
-# TBB malloc is only supported on for windows currently
-if(WIN32)
- set(_init_TBB_MALLOC_PROXY ON)
-else()
- set(_init_TBB_MALLOC_PROXY OFF)
-endif()
-
-
-# customize...
-if(UNIX AND NOT APPLE)
- # some of these libraries are problematic on Linux
- # disable less important dependencies by default
- set(_init_CODEC_FFMPEG OFF)
- set(_init_CYCLES_OSL OFF)
- set(_init_IMAGE_OPENEXR OFF)
- set(_init_JACK OFF)
- set(_init_OPENCOLLADA OFF)
- set(_init_OPENCOLORIO OFF)
- set(_init_SDL OFF)
- set(_init_FFTW3 OFF)
- set(_init_OPENSUBDIV OFF)
- set(_init_OPENVDB OFF)
- set(_init_OPENIMAGEDENOISE OFF)
-elseif(WIN32)
- set(_init_JACK OFF)
-elseif(APPLE)
- set(_init_JACK OFF)
-endif()
-
-
-#-----------------------------------------------------------------------------
# Options
# First platform specific non-cached vars
@@ -226,7 +156,7 @@ if(APPLE)
option(WITH_PYTHON_FRAMEWORK "Enable building using the Python available in the framework (OSX only)" OFF)
endif()
-option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ${_init_BUILDINFO})
+option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
if(${CMAKE_VERSION} VERSION_LESS 2.8.8)
# add_library OBJECT arg unsupported
set(WITH_BUILDINFO OFF)
@@ -240,20 +170,20 @@ mark_as_advanced(BUILDINFO_OVERRIDE_TIME)
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
-option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke, ocean sim, and audio effects)" ${_init_FFTW3})
+option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke, ocean sim, and audio effects)" ON)
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" )
mark_as_advanced(WITH_SYSTEM_BULLET)
-option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
+option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
# Compositor
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
-option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" ${_init_OPENIMAGEDENOISE})
+option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" ON)
-option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ${_init_OPENSUBDIV})
+option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ON)
-option(WITH_OPENVDB "Enable features relying on OpenVDB" ${_init_OPENVDB})
-option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" ${_init_OPENVDB})
+option(WITH_OPENVDB "Enable features relying on OpenVDB" ON)
+option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" ON)
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE)
@@ -315,11 +245,11 @@ endif()
option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON)
option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
-option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF)
+option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" ON)
# Image format support
option(WITH_OPENIMAGEIO "Enable OpenImageIO Support (http://www.openimageio.org)" ON)
-option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ${_init_IMAGE_OPENEXR})
+option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
@@ -328,23 +258,25 @@ option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
# Audio/Video format support
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
-option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ${_init_CODEC_FFMPEG})
-option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
+option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ON)
+option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" ON)
# Alembic support
-option(WITH_ALEMBIC "Enable Alembic Support" OFF)
+option(WITH_ALEMBIC "Enable Alembic Support" ON)
option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF)
# 3D format support
# Disable opencollada when we don't have precompiled libs
-option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ${_init_OPENCOLLADA})
+option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON)
# Sound output
-option(WITH_SDL "Enable SDL for sound and joystick support" ${_init_SDL})
+option(WITH_SDL "Enable SDL for sound and joystick support" ON)
option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
-option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" ${_init_JACK})
-if(UNIX AND NOT APPLE)
- option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF)
+if(NOT WIN32)
+ option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" ON)
+ if(UNIX AND NOT APPLE)
+ option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF)
+ endif()
endif()
if(UNIX AND NOT APPLE)
option(WITH_SDL_DYNLOAD "Enable runtime dynamic SDL libraries loading" OFF)
@@ -360,7 +292,7 @@ option(WITH_DRACO "Enable Draco mesh compression Python module (used for
# Camera/motion tracking
option(WITH_LIBMV "Enable Libmv structure from motion library" ON)
-option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." OFF)
+option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
mark_as_advanced(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
# Logging/unbit test libraries.
@@ -376,7 +308,7 @@ option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
if(WIN32)
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
endif()
-option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ${_init_INPUT_NDOF})
+option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
@@ -412,7 +344,7 @@ mark_as_advanced(WITH_CPU_SSE)
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
-option(WITH_CYCLES_OSL "Build Cycles with OSL support" ${_init_CYCLES_OSL})
+option(WITH_CYCLES_OSL "Build Cycles with OSL support" ON)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" OFF)
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
@@ -468,7 +400,11 @@ mark_as_advanced(WITH_ASSERT_ABORT)
option(WITH_BOOST "Enable features depending on boost" ON)
option(WITH_TBB "Enable features depending on TBB (OpenVDB, OpenImageDenoise, sculpt multithreading)" ON)
-option(WITH_TBB_MALLOC_PROXY "Enable the TBB malloc replacement" ${_init_TBB_MALLOC_PROXY})
+
+# TBB malloc is only supported on for windows currently
+if(WIN32)
+ option(WITH_TBB_MALLOC_PROXY "Enable the TBB malloc replacement" ON)
+endif()
# Unit testsing
option(WITH_GTESTS "Enable GTest unit testing" OFF)
@@ -591,9 +527,6 @@ endif()
option(POSTINSTALL_SCRIPT "Run given CMake script after installation process" OFF)
mark_as_advanced(POSTINSTALL_SCRIPT)
-# avoid using again
-option_defaults_clear()
-
# end option(...)
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index 19dac236762..bbacedca0ce 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -64,7 +64,7 @@ def create_buildbot_upload_zip(builder, package_files):
sys.stderr.write('Create buildbot_upload.zip failed: ' + str(ex) + '\n')
sys.exit(1)
-def create_tar_bz2(src, dest, package_name):
+def create_tar_xz(src, dest, package_name):
# One extra to remove leading os.sep when cleaning root for package_root
ln = len(src) + 1
flist = list()
@@ -75,9 +75,20 @@ def create_tar_bz2(src, dest, package_name):
flist.extend([(os.path.join(root, file), os.path.join(package_root, file)) for file in files])
import tarfile
- package = tarfile.open(dest, 'w:bz2')
+
+ # Set UID/GID of archived files to 0, otherwise they'd be owned by whatever
+ # user compiled the package. If root then unpacks it to /usr/local/ you get
+ # a security issue.
+ def _fakeroot(tarinfo):
+ tarinfo.gid = 0
+ tarinfo.gname = "root"
+ tarinfo.uid = 0
+ tarinfo.uname = "root"
+ return tarinfo
+
+ package = tarfile.open(dest, 'w:xz', preset=9)
for entry in flist:
- package.add(entry[0], entry[1], recursive=False)
+ package.add(entry[0], entry[1], recursive=False, filter=_fakeroot)
package.close()
def cleanup_files(dirpath, extension):
@@ -163,11 +174,11 @@ def pack_linux(builder):
# Construct package name
platform_name = 'linux-' + blender_glibc + '-' + blender_arch
package_name = get_package_name(builder, platform_name)
- package_filename = package_name + ".tar.bz2"
+ package_filename = package_name + ".tar.xz"
- print("Creating .tar.bz2 archive")
- package_filepath = builder.install_dir + '.tar.bz2'
- create_tar_bz2(builder.install_dir, package_filepath, package_name)
+ print("Creating .tar.xz archive")
+ package_filepath = builder.install_dir + '.tar.xz'
+ create_tar_xz(builder.install_dir, package_filepath, package_name)
# Create buildbot_upload.zip
create_buildbot_upload_zip(builder, [(package_filepath, package_filename)])
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake
index a93e829e6b0..2a05b92ba3f 100644
--- a/build_files/cmake/Modules/GTestTesting.cmake
+++ b/build_files/cmake/Modules/GTestTesting.cmake
@@ -12,9 +12,14 @@
#
#=============================================================================
-macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
+macro(BLENDER_SRC_GTEST_EX)
if(WITH_GTESTS)
- set(TARGET_NAME ${NAME}_test)
+ set(options SKIP_ADD_TEST)
+ set(oneValueArgs NAME)
+ set(multiValueArgs SRC EXTRA_LIBS COMMAND_ARGS)
+ cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ set(TARGET_NAME ${ARG_NAME}_test)
get_property(_current_include_directories
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
PROPERTY INCLUDE_DIRECTORIES)
@@ -30,11 +35,11 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
)
unset(_current_include_directories)
- add_executable(${TARGET_NAME} ${SRC})
+ add_executable(${TARGET_NAME} ${ARG_SRC})
target_include_directories(${TARGET_NAME} PUBLIC "${TEST_INC}")
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC "${TEST_INC_SYS}")
target_link_libraries(${TARGET_NAME}
- ${EXTRA_LIBS}
+ ${ARG_EXTRA_LIBS}
${PLATFORM_LINKLIBS}
bf_testing_main
bf_intern_eigen
@@ -60,8 +65,11 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${TESTS_OUTPUT_DIR}")
- if(${DO_ADD_TEST})
- add_test(NAME ${TARGET_NAME} COMMAND ${TESTS_OUTPUT_DIR}/${TARGET_NAME} WORKING_DIRECTORY ${TEST_INSTALL_DIR})
+ if(NOT ARG_SKIP_ADD_TEST)
+ add_test(
+ NAME ${TARGET_NAME}
+ COMMAND ${TESTS_OUTPUT_DIR}/${TARGET_NAME} ${ARG_COMMAND_ARGS}
+ WORKING_DIRECTORY ${TEST_INSTALL_DIR})
# Don't fail tests on leaks since these often happen in external libraries
# that we can't fix.
@@ -74,13 +82,23 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
endmacro()
macro(BLENDER_SRC_GTEST NAME SRC EXTRA_LIBS)
- BLENDER_SRC_GTEST_EX("${NAME}" "${SRC}" "${EXTRA_LIBS}" "TRUE")
+ BLENDER_SRC_GTEST_EX(
+ NAME "${NAME}"
+ SRC "${SRC}"
+ EXTRA_LIBS "${EXTRA_LIBS}")
endmacro()
macro(BLENDER_TEST NAME EXTRA_LIBS)
- BLENDER_SRC_GTEST_EX("${NAME}" "${NAME}_test.cc" "${EXTRA_LIBS}" "TRUE")
+ BLENDER_SRC_GTEST_EX(
+ NAME "${NAME}"
+ SRC "${NAME}_test.cc"
+ EXTRA_LIBS "${EXTRA_LIBS}")
endmacro()
macro(BLENDER_TEST_PERFORMANCE NAME EXTRA_LIBS)
- BLENDER_SRC_GTEST_EX("${NAME}" "${NAME}_test.cc" "${EXTRA_LIBS}" "FALSE")
+ BLENDER_SRC_GTEST_EX(
+ NAME "${NAME}"
+ SRC "${NAME}_test.cc"
+ EXTRA_LIBS "${EXTRA_LIBS}"
+ SKIP_ADD_TEST)
endmacro()
diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake
index 56b970c349d..fae15ea979b 100644
--- a/build_files/cmake/config/blender_full.cmake
+++ b/build_files/cmake/config/blender_full.cmake
@@ -18,7 +18,6 @@ set(WITH_LIBMV ON CACHE BOOL "" FORCE)
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
-set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
@@ -29,7 +28,6 @@ set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
-set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_LZMA ON CACHE BOOL "" FORCE)
set(WITH_LZO ON CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
@@ -49,20 +47,17 @@ set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
set(WITH_QUADRIFLOW ON CACHE BOOL "" FORCE)
set(WITH_SDL ON CACHE BOOL "" FORCE)
set(WITH_TBB ON CACHE BOOL "" FORCE)
-set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
-set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
# platform dependent options
-if(UNIX AND NOT APPLE)
+if(NOT WIN32)
set(WITH_JACK ON CACHE BOOL "" FORCE)
+endif()
+if(UNIX AND NOT APPLE)
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
-elseif(WIN32)
- set(WITH_JACK OFF CACHE BOOL "" FORCE)
-elseif(APPLE)
- set(WITH_JACK ON CACHE BOOL "" FORCE)
-
-# include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
+ set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
+ set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
+ set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
endif()
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index 2a1f4a59c15..3a67836d253 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -24,7 +24,6 @@ set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
set(WITH_LLVM OFF CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
-set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
@@ -54,5 +53,9 @@ set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
set(WITH_SDL OFF CACHE BOOL "" FORCE)
set(WITH_TBB OFF CACHE BOOL "" FORCE)
-set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
-set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)
+
+if(UNIX AND NOT APPLE)
+ set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
+ set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
+ set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)
+endif()
diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake
index af089834295..07d95a84112 100644
--- a/build_files/cmake/config/blender_release.cmake
+++ b/build_files/cmake/config/blender_release.cmake
@@ -19,7 +19,6 @@ set(WITH_LIBMV ON CACHE BOOL "" FORCE)
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
-set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
@@ -30,7 +29,6 @@ set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
-set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_LZMA ON CACHE BOOL "" FORCE)
set(WITH_LZO ON CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
@@ -50,8 +48,6 @@ set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
set(WITH_QUADRIFLOW ON CACHE BOOL "" FORCE)
set(WITH_SDL ON CACHE BOOL "" FORCE)
set(WITH_TBB ON CACHE BOOL "" FORCE)
-set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
-set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
@@ -60,13 +56,12 @@ set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
# platform dependent options
-if(UNIX AND NOT APPLE)
+if(NOT WIN32)
set(WITH_JACK ON CACHE BOOL "" FORCE)
+endif()
+if(UNIX AND NOT APPLE)
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
-elseif(WIN32)
- set(WITH_JACK OFF CACHE BOOL "" FORCE)
-elseif(APPLE)
- set(WITH_JACK ON CACHE BOOL "" FORCE)
-
-# include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
+ set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
+ set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
+ set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
endif()
diff --git a/build_files/cmake/packaging.cmake b/build_files/cmake/packaging.cmake
index 5ace42646c5..0e530463659 100644
--- a/build_files/cmake/packaging.cmake
+++ b/build_files/cmake/packaging.cmake
@@ -135,7 +135,7 @@ elseif(UNIX)
add_package_archive(
"${PROJECT_NAME}-${BLENDER_VERSION}-${BUILD_REV}-${PACKAGE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}"
- "tar.bz2")
+ "tar.xz")
endif()
unset(MAJOR_VERSION)
diff --git a/build_files/package_spec/build_archive.py b/build_files/package_spec/build_archive.py
index 5ca2f319d87..d8d3c29ea48 100755
--- a/build_files/package_spec/build_archive.py
+++ b/build_files/package_spec/build_archive.py
@@ -49,15 +49,19 @@ try:
if not os.path.exists(output_dir):
os.mkdir(output_dir)
+ archive_env = os.environ.copy()
+
if extension == 'zip':
archive_cmd = ['zip', '-9', '-r', package_archive, package_dir]
- elif extension == 'tar.bz2':
- archive_cmd = ['tar', 'cjf', package_archive, package_dir]
+ elif extension == 'tar.xz':
+ archive_cmd = ['tar', '-cf', package_archive, '--owner=0', '--group=0',
+ '--use-compress-program=xz', package_dir]
+ archive_env['XZ_OPT'] = '-9'
else:
sys.stderr.write('Unknown archive extension: ' + extension)
sys.exit(-1)
- subprocess.call(archive_cmd)
+ subprocess.check_call(archive_cmd, env=archive_env)
except Exception as ex:
sys.stderr.write('Failed to create package archive: ' + str(ex) + '\n')
sys.exit(1)
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 3625dd45ae2..cbe61e367fa 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -159,7 +159,7 @@ static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &
data.resize(size);
for (int i = 0; i < size; i++) {
float t = (float)i / (float)(size - 1);
- data[i] = curve.evaluate(t);
+ data[i] = cumap.evaluate(curve, t);
}
}
@@ -197,15 +197,16 @@ static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
BL::CurveMap mapI = cumap.curves[3];
for (int i = 0; i < size; i++) {
const float t = min_x + (float)i / (float)(size - 1) * range_x;
- data[i] = make_float3(mapR.evaluate(mapI.evaluate(t)),
- mapG.evaluate(mapI.evaluate(t)),
- mapB.evaluate(mapI.evaluate(t)));
+ data[i] = make_float3(cumap.evaluate(mapR, cumap.evaluate(mapI, t)),
+ cumap.evaluate(mapG, cumap.evaluate(mapI, t)),
+ cumap.evaluate(mapB, cumap.evaluate(mapI, t)));
}
}
else {
for (int i = 0; i < size; i++) {
float t = min_x + (float)i / (float)(size - 1) * range_x;
- data[i] = make_float3(mapR.evaluate(t), mapG.evaluate(t), mapB.evaluate(t));
+ data[i] = make_float3(
+ cumap.evaluate(mapR, t), cumap.evaluate(mapG, t), cumap.evaluate(mapB, t));
}
}
}
diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp
index b3a9aab3266..86d755ab06a 100644
--- a/intern/cycles/bvh/bvh_optix.cpp
+++ b/intern/cycles/bvh/bvh_optix.cpp
@@ -49,7 +49,7 @@ void BVHOptiX::copy_to_device(Progress &progress, DeviceScene *dscene)
progress.set_status("Updating Scene BVH", "Building OptiX acceleration structure");
Device *const device = dscene->bvh_nodes.device;
- if (!device->build_optix_bvh(this, dscene->bvh_nodes))
+ if (!device->build_optix_bvh(this))
progress.set_error("Failed to build OptiX acceleration structure");
}
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 672d93c2581..66fcac921d3 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -407,7 +407,7 @@ class Device {
const DeviceDrawParams &draw_params);
/* acceleration structure building */
- virtual bool build_optix_bvh(BVH *, device_memory &)
+ virtual bool build_optix_bvh(BVH *)
{
return false;
}
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index ac71be9dbea..b8587eb0a62 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -153,21 +153,13 @@ class MultiDevice : public Device {
return result;
}
- bool build_optix_bvh(BVH *bvh, device_memory &mem)
+ bool build_optix_bvh(BVH *bvh)
{
- device_ptr key = unique_key++;
-
// Broadcast acceleration structure build to all devices
foreach (SubDevice &sub, devices) {
- mem.device = sub.device;
- if (!sub.device->build_optix_bvh(bvh, mem))
+ if (!sub.device->build_optix_bvh(bvh))
return false;
- sub.ptr_map[key] = mem.device_pointer;
}
-
- mem.device = this;
- mem.device_pointer = key;
- stats.mem_alloc(mem.device_size);
return true;
}
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index e10bab5a0d8..ae3ab7e1fc2 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -174,7 +174,7 @@ class OptiXDevice : public Device {
device_vector<SbtRecord> sbt_data;
device_vector<TextureInfo> texture_info;
device_only_memory<KernelParams> launch_params;
- vector<device_only_memory<uint8_t>> blas;
+ vector<device_only_memory<uint8_t>> as_mem;
OptixTraversableHandle tlas_handle = 0;
// TODO(pmours): This is copied from device_cuda.cpp, so move to common code eventually
@@ -268,8 +268,8 @@ class OptiXDevice : public Device {
// Stop processing any more tasks
task_pool.stop();
- // Clean up all memory before destroying context
- blas.clear();
+ // Free all acceleration structures
+ as_mem.clear();
sbt_data.free();
texture_info.free();
@@ -290,8 +290,8 @@ class OptiXDevice : public Device {
optixPipelineDestroy(pipelines[i]);
// Destroy launch streams
- for (int i = 0; i < info.cpu_threads; ++i)
- cuStreamDestroy(cuda_stream[i]);
+ for (CUstream stream : cuda_stream)
+ cuStreamDestroy(stream);
// Destroy OptiX and CUDA context
optixDeviceContextDestroy(context);
@@ -881,15 +881,16 @@ class OptiXDevice : public Device {
return true;
}
- bool build_optix_bvh(BVH *bvh, device_memory &out_data) override
+ bool build_optix_bvh(BVH *bvh) override
{
assert(bvh->params.top_level);
unsigned int num_instances = 0;
unordered_map<Mesh *, vector<OptixTraversableHandle>> meshes;
+ meshes.reserve(bvh->meshes.size());
- // Clear all previous AS
- blas.clear();
+ // Free all previous acceleration structure
+ as_mem.clear();
// Build bottom level acceleration structures (BLAS)
// Note: Always keep this logic in sync with bvh_optix.cpp!
@@ -900,6 +901,7 @@ class OptiXDevice : public Device {
Mesh *const mesh = ob->mesh;
vector<OptixTraversableHandle> handles;
+ handles.reserve(2);
// Build BLAS for curve primitives
if (bvh->params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
@@ -966,9 +968,9 @@ class OptiXDevice : public Device {
build_input.aabbArray.primitiveIndexOffset = mesh->prim_offset;
// Allocate memory for new BLAS and build it
- blas.emplace_back(this, "blas");
+ as_mem.emplace_back(this, "blas");
handles.emplace_back();
- if (!build_optix_bvh(build_input, num_motion_steps, blas.back(), handles.back()))
+ if (!build_optix_bvh(build_input, num_motion_steps, as_mem.back(), handles.back()))
return false;
}
@@ -1032,9 +1034,9 @@ class OptiXDevice : public Device {
build_input.triangleArray.primitiveIndexOffset = mesh->prim_offset + mesh->num_segments();
// Allocate memory for new BLAS and build it
- blas.emplace_back(this, "blas");
+ as_mem.emplace_back(this, "blas");
handles.emplace_back();
- if (!build_optix_bvh(build_input, num_motion_steps, blas.back(), handles.back()))
+ if (!build_optix_bvh(build_input, num_motion_steps, as_mem.back(), handles.back()))
return false;
}
@@ -1051,6 +1053,7 @@ class OptiXDevice : public Device {
// Skip non-traceable objects
if (!ob->is_traceable())
continue;
+
// Create separate instance for triangle/curve meshes of an object
for (OptixTraversableHandle handle : meshes[ob->mesh]) {
OptixAabb &aabb = aabbs[num_instances];
@@ -1078,8 +1081,8 @@ class OptiXDevice : public Device {
// Insert motion traversable if object has motion
if (motion_blur && ob->use_motion()) {
- blas.emplace_back(this, "motion_transform");
- device_only_memory<uint8_t> &motion_transform_gpu = blas.back();
+ as_mem.emplace_back(this, "motion_transform");
+ device_only_memory<uint8_t> &motion_transform_gpu = as_mem.back();
motion_transform_gpu.alloc_to_device(sizeof(OptixSRTMotionTransform) +
(max(ob->motion.size(), 2) - 2) *
sizeof(OptixSRTData));
@@ -1157,7 +1160,7 @@ class OptiXDevice : public Device {
instances.resize(num_instances);
instances.copy_to_device();
- // Build top-level acceleration structure
+ // Build top-level acceleration structure (TLAS)
OptixBuildInput build_input = {};
build_input.type = OPTIX_BUILD_INPUT_TYPE_INSTANCES;
build_input.instanceArray.instances = instances.device_pointer;
@@ -1165,7 +1168,8 @@ class OptiXDevice : public Device {
build_input.instanceArray.aabbs = aabbs.device_pointer;
build_input.instanceArray.numAabbs = num_instances;
- return build_optix_bvh(build_input, 0 /* TLAS has no motion itself */, out_data, tlas_handle);
+ as_mem.emplace_back(this, "tlas");
+ return build_optix_bvh(build_input, 0, as_mem.back(), tlas_handle);
}
void update_texture_info()
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 2f73434706c..2884ea62a18 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -37,6 +37,7 @@ CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct MicrofacetExtra {
float3 color, cspec0;
+ float3 fresnel_color;
float clearcoat;
} MicrofacetExtra;
@@ -276,6 +277,22 @@ ccl_device_forceinline float D_GTR1(float NdotH, float alpha)
return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t);
}
+ccl_device_forceinline void bsdf_microfacet_fresnel_color(const ShaderData *sd,
+ MicrofacetBsdf *bsdf)
+{
+ kernel_assert(CLOSURE_IS_BSDF_MICROFACET_FRESNEL(bsdf->type));
+
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ bsdf->extra->fresnel_color = interpolate_fresnel_color(
+ sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0);
+
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ bsdf->extra->fresnel_color *= 0.25f * bsdf->extra->clearcoat;
+ }
+
+ bsdf->sample_weight *= average(bsdf->extra->fresnel_color);
+}
+
/* GGX microfacet with Smith shadow-masking from:
*
* Microfacet Models for Refraction through Rough Surfaces
@@ -305,15 +322,13 @@ ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const Sha
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
-
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID;
+ bsdf_microfacet_fresnel_color(sd, bsdf);
+
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
@@ -321,15 +336,13 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(MicrofacetBsdf *bsdf, const S
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= 0.25f * bsdf->extra->clearcoat * F;
-
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
+ bsdf_microfacet_fresnel_color(sd, bsdf);
+
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
@@ -364,15 +377,13 @@ ccl_device int bsdf_microfacet_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, con
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
-
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID;
+ bsdf_microfacet_fresnel_color(sd, bsdf);
+
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 9780dd87415..a5fe989bcd1 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -402,9 +402,7 @@ ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsd
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ bsdf_microfacet_fresnel_color(sd, bsdf);
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
@@ -424,9 +422,7 @@ ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf, con
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ bsdf_microfacet_fresnel_color(sd, bsdf);
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
@@ -582,9 +578,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsd
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;
- float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
- float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
- bsdf->sample_weight *= F;
+ bsdf_microfacet_fresnel_color(sd, bsdf);
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index c1d74dddc2a..3e423e42573 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -145,7 +145,17 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg,
normal += sc->N * sc->sample_weight;
sum_weight += sc->sample_weight;
if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
- albedo += sc->weight;
+ float3 closure_albedo = sc->weight;
+ /* Closures that include a Fresnel term typically have weights close to 1 even though their
+ * actual contribution is significantly lower.
+ * To account for this, we scale their weight by the average fresnel factor (the same is also
+ * done for the sample weight in the BSDF setup, so we don't need to scale that here). */
+ if (CLOSURE_IS_BSDF_MICROFACET_FRESNEL(sc->type)) {
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
+ closure_albedo *= bsdf->extra->fresnel_color;
+ }
+
+ albedo += closure_albedo;
sum_nonspecular_weight += sc->sample_weight;
}
}
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 01710f713ac..aa4dfdca2d1 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -552,6 +552,12 @@ typedef enum ClosureType {
(type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && \
type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) || \
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID))
+#define CLOSURE_IS_BSDF_MICROFACET_FRESNEL(type) \
+ (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID || \
+ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID || \
+ type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || \
+ type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID || \
+ type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID)
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
#define CLOSURE_IS_BSSRDF(type) \
(type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
index 04e96e8ed3c..9787398e2ae 100644
--- a/intern/opencolorio/gpu_shader_display_transform.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -16,7 +16,7 @@ out vec4 fragColor;
*/
uniform sampler1D curve_mapping_texture;
uniform int curve_mapping_lut_size;
-uniform ivec4 use_curve_mapping_extend_extrapolate;
+uniform int use_curve_mapping_extend_extrapolate;
uniform vec4 curve_mapping_mintable;
uniform vec4 curve_mapping_range;
uniform vec4 curve_mapping_ext_in_x;
@@ -42,8 +42,8 @@ float read_curve_mapping(int table, int index)
float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
{
if (x <= first[0]) {
- if (use_curve_mapping_extend_extrapolate[table] == 0) {
- /* no extrapolate */
+ if (use_curve_mapping_extend_extrapolate == 0) {
+ /* horizontal extrapolation */
return first[1];
}
else {
@@ -55,8 +55,8 @@ float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
}
}
else if (x >= last[0]) {
- if (use_curve_mapping_extend_extrapolate[table] == 0) {
- /* no extrapolate */
+ if (use_curve_mapping_extend_extrapolate == 0) {
+ /* horizontal extrapolation */
return last[1];
}
else {
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 9ba2d8fb8f9..5670b37f892 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -73,10 +73,10 @@ typedef struct OCIO_CurveMappingSettings {
int lut_size;
/* Extend extrapolation flags for all the tables.
- * if use_extend_extrapolate[T] != 0 means extrapolation for
- * table T is needed.
+ * if use_extend_extrapolate != 0 means extrapolation for
+ * curve.
*/
- int use_extend_extrapolate[4];
+ int use_extend_extrapolate;
/* Minimal X value of the curve mapping tables. */
float mintable[4];
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 99d59c8d989..a80e29a2dec 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -499,8 +499,8 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
if (use_curve_mapping) {
immUniform1i("curve_mapping_texture", 2);
immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
- immUniform4iv("use_curve_mapping_extend_extrapolate",
- curve_mapping_settings->use_extend_extrapolate);
+ immUniform1i("use_curve_mapping_extend_extrapolate",
+ curve_mapping_settings->use_extend_extrapolate);
immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index f317b346eb8..6a87ac0adaa 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -1048,9 +1048,6 @@
</linearGradient>
- <filter color-interpolation-filters="sRGB" inkscape:collect="always" id="filter15613" x="-0.092011765" width="1.1840235" y="-0.097762503" height="1.1955251">
- <feGaussianBlur inkscape:collect="always" stdDeviation="0.65175" id="feGaussianBlur15615"/>
- </filter>
<linearGradient id="linearGradient37542-55">
<stop id="stop37544-61" offset="0" style="stop-color:#000000;stop-opacity:1;"/>
<stop id="stop37546-03" offset="1" style="stop-color:#ffffff;stop-opacity:1;"/>
@@ -1065,9 +1062,6 @@
</linearGradient>
- <filter color-interpolation-filters="sRGB" inkscape:collect="always" id="filter15613-8" x="-0.092011765" width="1.1840235" y="-0.097762503" height="1.1955251">
- <feGaussianBlur inkscape:collect="always" stdDeviation="0.65175" id="feGaussianBlur15615-1"/>
- </filter>
<filter color-interpolation-filters="sRGB" inkscape:label="Greyscale" id="filter15388">
@@ -1327,14 +1321,6 @@
<radialGradient inkscape:collect="always" xlink:href="#linearGradient16595" id="radialGradient52883-6-8-3" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-362.22886,-161.73912)" cx="-302.79681" cy="462.0358" fx="-302.79681" fy="462.0358" r="8"/>
- <filter style="color-interpolation-filters:sRGB" inkscape:collect="always" id="filter15613-7" x="-0.092011765" width="1.1840235" y="-0.097762503" height="1.1955251">
- <feGaussianBlur inkscape:collect="always" stdDeviation="0.65175" id="feGaussianBlur15615-4"/>
- </filter>
-
-
- <filter style="color-interpolation-filters:sRGB" inkscape:collect="always" id="filter15613-8-8" x="-0.092011765" width="1.1840235" y="-0.097762503" height="1.1955251">
- <feGaussianBlur inkscape:collect="always" stdDeviation="0.65175" id="feGaussianBlur15615-1-5"/>
- </filter>
<filter style="color-interpolation-filters:sRGB" inkscape:label="Greyscale" id="filter15388-0">
@@ -3746,14 +3732,6 @@
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 449.50391,369 c -0.27613,3e-5 -0.49997,0.22387 -0.5,0.5 v 11 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 H 455 c 1.08333,0 2.07323,-0.26796 2.8125,-0.85938 C 458.55177,379.54921 459,378.625 459,377.5 c 0,-1.125 -0.44823,-2.04921 -1.1875,-2.64062 -0.49098,-0.39279 -1.11527,-0.59695 -1.78125,-0.72071 C 456.61178,373.63193 457,372.89881 457,372 c 0,-0.96354 -0.41934,-1.76349 -1.07422,-2.26758 C 455.27091,369.22833 454.41324,369 453.5,369 Z m 0.5,1 H 453.5 c 0.74361,0 1.38549,0.19369 1.81641,0.52539 0.43091,0.3317 0.68359,0.7813 0.68359,1.47461 0,0.69331 -0.25268,1.14291 -0.68359,1.47461 C 454.88549,373.80631 454.24361,374 453.5,374 h -3.49609 z m 0,5 h 3.46093 0.0352 1.5 c 0.91667,0 1.67677,0.23204 2.1875,0.64062 0.51073,0.40859 0.8125,0.98438 0.8125,1.85938 0,0.875 -0.30177,1.45079 -0.8125,1.85938 C 456.67677,379.76796 455.91667,380 455,380 h -4.99609 z" id="path10949-7" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccscsccscsccscscscccccscscscc"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 408.50391,369 a 0.50005,0.50005 0 0 0 -0.5,0.5 v 5.91992 a 0.50005,0.50005 0 0 0 0,0.16211 V 380.5 a 0.50005,0.50005 0 1 0 1,0 V 376 h 3.25586 l 3.84961,4.8125 a 0.50024018,0.50024018 0 1 0 0.78124,-0.625 l -3.49414,-4.36914 c 1.48603,-0.40423 2.60743,-1.70768 2.60743,-3.31836 0,-1.92707 -1.57293,-3.5 -3.5,-3.5 z m 0.5,1 h 3.5 c 1.38662,0 2.5,1.11337 2.5,2.5 0,1.38663 -1.11338,2.5 -2.5,2.5 a 0.50005,0.50005 0 0 0 -0.004,0 h -3.49609 z" id="path13132" inkscape:connector-curvature="0"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="M 431.51758,369.26562 C 429.42795,369.91461 428,371.85293 428,374.04102 V 376 c 0,1.78552 0.9537,3.43731 2.5,4.33008 1.54631,0.89277 3.45369,0.89277 5,0 1.5463,-0.89277 2.5,-2.54456 2.5,-4.33008 v -0.5 a 0.50004997,0.50004997 0 0 0 -0.5,-0.5 h -4 a 0.50004997,0.50004997 0 1 0 0,1 h 3.5 c 0,1.42986 -0.7617,2.74991 -2,3.46484 -1.23829,0.71494 -2.76171,0.71494 -4,0 -1.2383,-0.71493 -2,-2.03498 -2,-3.46484 v -1.95898 c 0,-1.75422 1.13918,-3.30002 2.81445,-3.82032 1.69498,-0.52641 3.36746,-0.003 4.25196,1.5293 a 0.50050004,0.50050004 0 1 0 0.86718,-0.5 c -1.1155,-1.93212 -3.34609,-2.62724 -5.41601,-1.98438 z" id="path13141" inkscape:connector-curvature="0"/>
- <g style="display:inline;fill:#ffffff;enable-background:new" id="g13321" transform="translate(-42.000002,21.000005)">
- <g id="g13309" style="fill:#ffffff">
- <path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 365.49219,94.992188 a 0.50005,0.50005 0 0 0 -0.38867,0.195312 0.50005,0.50005 0 0 0 -0.004,0.0059 l -1.95313,1.953125 a 0.50005,0.50005 0 1 0 0.70704,0.707032 L 365,96.707031 V 98.5 a 0.50005,0.50005 0 1 0 1,0 v -1.792969 l 1.14648,1.146485 a 0.50005,0.50005 0 1 0 0.70704,-0.707032 l -1.95704,-1.957031 a 0.50005,0.50005 0 0 0 -0.40429,-0.197265 z m 9.05859,1.941406 a 0.50005,0.50005 0 0 0 -0.0586,0.0059 h -2.93164 a 0.50005,0.50005 0 1 0 0,1 h 1.79297 l -3.14649,3.146486 a 0.50005,0.50005 0 1 0 0.70703,0.70703 l 3.14649,-3.146485 v 1.792965 a 0.50005,0.50005 0 1 0 1,0 v -2.931637 a 0.50005,0.50005 0 0 0 -0.50977,-0.574218 z m -0.0566,7.060546 a 0.50005,0.50005 0 0 0 -0.34766,0.85938 L 375.29297,106 H 371.5 a 0.50005,0.50005 0 1 0 0,1 h 3.79297 l -1.14649,1.14648 a 0.50005,0.50005 0 1 0 0.70704,0.70704 l 1.95703,-1.95704 a 0.50005,0.50005 0 0 0 0.002,-0.79296 0.50005,0.50005 0 0 0 -0.006,-0.004 l -1.95312,-1.95313 a 0.50005,0.50005 0 0 0 -0.35938,-0.15234 z" id="path13047-6" inkscape:connector-curvature="0"/>
- </g>
- <g id="g13313" style="fill:#ffffff">
- <path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.98000004;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 324.5,121 c -1.14583,0 -1.86235,0.56478 -2.18359,1.12695 C 321.99517,122.68912 322,123.25 322,123.25 V 125 h -0.5 c -0.27613,3e-5 -0.49997,0.22387 -0.5,0.5 v 4 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 h 6 c 0.27613,-3e-5 0.49997,-0.22387 0.5,-0.5 v -4 c -3e-5,-0.27613 -0.22387,-0.49997 -0.5,-0.5 H 327 v -1.75 c 0,0 0.005,-0.56088 -0.31641,-1.12305 C 326.36235,121.56478 325.64583,121 324.5,121 Z m 0,1 c 0.85417,0 1.13765,0.31022 1.31641,0.62305 C 325.99517,122.93588 326,123.25 326,123.25 V 125 h -3 v -1.75 c 0,0 0.005,-0.31412 0.18359,-0.62695 C 323.36235,122.31022 323.64583,122 324.5,122 Z m -0.5,4 h 1 v 2 h -1 z" transform="translate(42.000002,-21.000005)" id="rect13261" inkscape:connector-curvature="0"/>
- </g>
- </g>
<g inkscape:export-ydpi="96" inkscape:export-xdpi="96" inkscape:export-filename="C:\Users\Andrzej Ambroż\Desktop\mtrx.png" id="g13337" style="display:inline;opacity:0.98999999;fill:#ffffff;enable-background:new" transform="matrix(-1,0,0,1,1458,302.99979)">
<path style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.3;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 1262.5,-278.49979 h -13 v -13 h 13 v 13" id="path14450" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc"/>
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 1257.5039,-287 c -0.191,-10e-4 -0.3661,0.1063 -0.4512,0.27734 l -3,6 c -0.1652,0.33223 0.076,0.72231 0.4473,0.72266 h 6 c 0.371,-3.5e-4 0.6125,-0.39043 0.4473,-0.72266 l -3,-6 c -0.084,-0.16853 -0.2552,-0.27571 -0.4434,-0.27734 z" id="path13331" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccc"/>
@@ -3831,11 +3809,6 @@
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 237.49219,305 a 0.50005,0.50005 0 0 0 -0.5,0.5 v 2 a 0.50005,0.50005 0 1 0 1,0 V 306 h 3 v 12 h -1.5 a 0.50005,0.50005 0 1 0 0,1 h 4 a 0.50005,0.50005 0 1 0 0,-1 h -1.5 v -12 h 3 v 1.5 a 0.50005,0.50005 0 1 0 1,0 v -2 a 0.50005,0.50005 0 0 0 -0.5,-0.5 z m 7,6 a 0.50005,0.50005 0 0 0 -0.5,0.5 v 1 a 0.50005,0.50005 0 1 0 1,0 V 312 h 2 v 6 h -0.5 a 0.50005,0.50005 0 1 0 0,1 h 2 a 0.50005,0.50005 0 1 0 0,-1 h -0.5 v -6 h 2 v 0.5 a 0.50005,0.50005 0 1 0 1,0 v -1 a 0.50005,0.50005 0 0 0 -0.5,-0.5 z" id="path6924-7" inkscape:connector-curvature="0"/>
</g>
<path inkscape:connector-curvature="0" d="m 353,628 h 1 v 1 h -1 z m -3,0 h 1 v 1 h -1 z m -3,0 h 1 v 1 h -1 z m -3,0 h 1 v 1 h -1 z m 9,-3 h 1 v 1 h -1 z m -3,0 h 1 v 1 h -1 z m -3,0 h 1 v 1 h -1 z m -3,0 h 1 v 1 h -1 z" style="display:inline;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;enable-background:new" id="path14337"/>
- <path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 374.4375,121.17773 c -0.55229,-0.19531 -1.19407,-0.23097 -1.84766,0.002 -0.65359,0.23293 -1.30733,0.71399 -1.9707,1.49609 -0.28137,0.33173 -0.45085,0.79694 -0.61914,1.24219 -0.17701,-0.45587 -0.36207,-0.94012 -0.61914,-1.24219 -0.66249,-0.77846 -1.31558,-1.25837 -1.96875,-1.49023 -0.65317,-0.23186 -1.2953,-0.19616 -1.84766,-0.002 -1.10471,0.38842 -1.89002,1.32506 -2.44922,1.9961 a 0.50064603,0.50064603 0 1 0 0.76954,0.64062 c 0.54481,-0.65377 1.26345,-1.43095 2.00976,-1.69336 0.37316,-0.1312 0.7444,-0.1559 1.18359,0 0.4392,0.1559 0.95757,0.51168 1.54102,1.19727 0.19894,0.23376 0.56603,0.91963 0.64063,1.27734 A 0.50005,0.50005 0 0 0 369.75,125 h 0.5 a 0.50005,0.50005 0 0 0 0.49023,-0.40234 c 0.0736,-0.37229 0.37785,-0.96363 0.64063,-1.27344 0.58467,-0.68931 1.10595,-1.04668 1.54492,-1.20313 0.43897,-0.15644 0.80714,-0.13175 1.17969,0 0.74509,0.2635 1.46354,1.04375 2.00976,1.69922 a 0.50064603,0.50064603 0 1 0 0.76954,-0.64062 c -0.55904,-0.67084 -1.34269,-1.61133 -2.44727,-2.00196 z" id="path17826-1" inkscape:connector-curvature="0"/>
- <g style="display:inline;fill:#ffffff;enable-background:new" id="g14433" transform="rotate(-90,380.52904,134)">
- <path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 390.04688,140.46484 a 0.50005,0.50005 0 0 0 -0.41797,0.20704 l -2.95508,3.93945 a 0.50005,0.50005 0 0 0 -0.01,0.70703 l 2.96485,3.95312 a 0.50019216,0.50019216 0 1 0 0.80078,-0.5996 l -2.40039,-3.20118 h 7.1914 l -0.63867,1.27735 a 0.50005635,0.50005635 0 1 0 0.89453,0.44726 l 0.96875,-1.93554 a 0.50005,0.50005 0 0 0 -0.006,-0.58399 l -0.96289,-1.92773 a 0.50005635,0.50005635 0 1 0 -0.89453,0.44726 l 0.63867,1.27539 h -7.1914 l 2.40039,-3.19922 a 0.50005,0.50005 0 0 0 -0.38281,-0.80664 z" id="path17796-5" inkscape:connector-curvature="0"/>
- </g>
- <path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:7.40000248;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 348.5,120 c -1.47879,0 -2.81353,0.43206 -3.80469,1.06641 C 343.70416,121.70075 343,122.54357 343,123.5 c 0,1.02778 0.79097,1.88608 1.87891,2.49805 1.08228,0.60878 2.52394,0.99597 4.09765,1 0.0129,9.4e-4 3.75669,0.27336 6.02344,-2.21094 V 127.5 a 0.50005,0.50005 0 1 0 1,0 v -4 a 0.50005,0.50005 0 0 0 -0.5,-0.5 h -4.25 a 0.50005,0.50005 0 1 0 0,1 h 3.10156 c -1.87731,2.16501 -5.32031,2 -5.32031,2 A 0.50005,0.50005 0 0 0 349,126 c -1.41667,0 -2.71684,-0.36001 -3.62891,-0.87305 C 344.45903,124.61392 344,123.97222 344,123.5 c 0,-0.41012 0.41561,-1.06779 1.23438,-1.5918 C 346.05313,121.38419 347.21846,121 348.5,121 a 0.50005,0.50005 0 1 0 0,-1 z" id="path18766-5" inkscape:connector-curvature="0"/>
<g style="display:inline;fill:#ffffff;enable-background:new" id="g12950" transform="translate(-42.000002,4.4999696e-6)">
<g id="g12531-9" transform="translate(-209.00718,-44.00717)" style="display:inline;opacity:0.6;fill:#ffffff;enable-background:new">
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 446.5,161 c -0.27613,3e-5 -0.49997,0.22387 -0.5,0.5 v 8 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 h 7 c 0.67616,0.01 0.67616,-1.00956 0,-1 H 447 v -7 h 0.5 4.9707 1.0293 c 0.67616,0.01 0.67616,-1.00956 0,-1 H 452.4707 447.5 Z m 4.50718,10.00717 L 451,173 h -1.5 c -0.67616,-0.01 -0.67616,1.00956 0,1 h 1.91992 c 0.0537,0.009 0.10843,0.009 0.16211,0 H 453.5 c 0.67616,0.01 0.67616,-1.00956 0,-1 H 452 l 0.007,-1.99283 z" id="path12529-5" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccccccccccccccc"/>
diff --git a/release/datafiles/blender_icons16/icon16_ndof_dom.dat b/release/datafiles/blender_icons16/icon16_ndof_dom.dat
deleted file mode 100644
index e6ecd80d5a9..00000000000
--- a/release/datafiles/blender_icons16/icon16_ndof_dom.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ndof_fly.dat b/release/datafiles/blender_icons16/icon16_ndof_fly.dat
deleted file mode 100644
index 84b672bdf9f..00000000000
--- a/release/datafiles/blender_icons16/icon16_ndof_fly.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ndof_trans.dat b/release/datafiles/blender_icons16/icon16_ndof_trans.dat
deleted file mode 100644
index f74edd6f8b0..00000000000
--- a/release/datafiles/blender_icons16/icon16_ndof_trans.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ndof_turn.dat b/release/datafiles/blender_icons16/icon16_ndof_turn.dat
deleted file mode 100644
index 5b0cee02b49..00000000000
--- a/release/datafiles/blender_icons16/icon16_ndof_turn.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ndof_dom.dat b/release/datafiles/blender_icons32/icon32_ndof_dom.dat
deleted file mode 100644
index 9c7e6fdfc99..00000000000
--- a/release/datafiles/blender_icons32/icon32_ndof_dom.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ndof_fly.dat b/release/datafiles/blender_icons32/icon32_ndof_fly.dat
deleted file mode 100644
index a328f8dc1ca..00000000000
--- a/release/datafiles/blender_icons32/icon32_ndof_fly.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ndof_trans.dat b/release/datafiles/blender_icons32/icon32_ndof_trans.dat
deleted file mode 100644
index 553752dda40..00000000000
--- a/release/datafiles/blender_icons32/icon32_ndof_trans.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ndof_turn.dat b/release/datafiles/blender_icons32/icon32_ndof_turn.dat
deleted file mode 100644
index 3f43546cdbf..00000000000
--- a/release/datafiles/blender_icons32/icon32_ndof_turn.dat
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c
index d8b87480f29..3856a03b1ba 100644
--- a/release/datafiles/userdef/userdef_default.c
+++ b/release/datafiles/userdef/userdef_default.c
@@ -150,10 +150,16 @@ const UserDef U_default = {
.tablet_api = USER_TABLET_AUTOMATIC,
.pressure_threshold_max = 1.0,
.pressure_softness = 0.0,
- .ndof_sensitivity = 1.0,
- .ndof_orbit_sensitivity = 1.0,
+ .ndof_sensitivity = 4.0,
+ .ndof_orbit_sensitivity = 4.0,
.ndof_deadzone = 0.1,
- .ndof_flag = (NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE),
+ .ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
+ NDOF_SHOULD_ROTATE |
+ /* Software from the driver authors follows this convention
+ * so invert this by default, see: T67579. */
+ NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS |
+ NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS |
+ NDOF_ZOOM_INVERT),
.ogl_multisamples = 0,
.image_draw_method = IMAGE_DRAW_METHOD_AUTO,
.glalphaclip = 0.004,
diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index f264de5b140..5106010b555 100644
--- a/release/scripts/modules/console_python.py
+++ b/release/scripts/modules/console_python.py
@@ -341,23 +341,20 @@ def banner(context):
sc = context.space_data
version_string = sys.version.strip().replace('\n', ' ')
- add_scrollback("PYTHON INTERACTIVE CONSOLE %s" % version_string, 'OUTPUT')
- add_scrollback("", 'OUTPUT')
- add_scrollback("Command History: Up/Down Arrow", 'OUTPUT')
- add_scrollback("Cursor: Left/Right Home/End", 'OUTPUT')
- add_scrollback("Remove: Backspace/Delete", 'OUTPUT')
- add_scrollback("Execute: Enter", 'OUTPUT')
- add_scrollback("Autocomplete: Ctrl-Space", 'OUTPUT')
- add_scrollback("Zoom: Ctrl +/-, Ctrl-Wheel", 'OUTPUT')
- add_scrollback("Builtin Modules: bpy, bpy.data, bpy.ops, "
- "bpy.props, bpy.types, bpy.context, bpy.utils, "
- "bgl, blf, mathutils",
- 'OUTPUT')
- add_scrollback("Convenience Imports: from mathutils import *; "
- "from math import *", 'OUTPUT')
- add_scrollback("Convenience Variables: C = bpy.context, D = bpy.data",
- 'OUTPUT')
- add_scrollback("", 'OUTPUT')
+ message = (
+ "PYTHON INTERACTIVE CONSOLE %s" % version_string,
+ "",
+ "Builtin Modules: "
+ "bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, blf, mathutils",
+
+ "Convenience Imports: from mathutils import *; from math import *",
+ "Convenience Variables: C = bpy.context, D = bpy.data",
+ "",
+ )
+
+ for line in message:
+ add_scrollback(line, 'OUTPUT')
+
sc.prompt = PROMPT
return {'FINISHED'}
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 3a7a142e310..06fac16292d 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -392,7 +392,7 @@ def km_window(params):
),
# NDOF settings
- op_menu("USERPREF_MT_ndof_settings", {"type": 'NDOF_BUTTON_MENU', "value": 'PRESS'}),
+ op_panel("USERPREF_PT_ndof_settings", {"type": 'NDOF_BUTTON_MENU', "value": 'PRESS'}),
("wm.context_scale_float", {"type": 'NDOF_BUTTON_PLUS', "value": 'PRESS'},
{"properties": [("data_path", 'preferences.inputs.ndof_sensitivity'), ("value", 1.1)]}),
("wm.context_scale_float", {"type": 'NDOF_BUTTON_MINUS', "value": 'PRESS'},
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index dc62b6bba68..6bf9a60a3d7 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -196,7 +196,7 @@ def km_window(params):
op_menu("SCREEN_MT_user_menu", {"type": 'TAB', "value": 'PRESS', "shift": True}),
# NDOF settings
- op_menu("USERPREF_MT_ndof_settings", {"type": 'NDOF_BUTTON_MENU', "value": 'PRESS'}),
+ op_panel("USERPREF_PT_ndof_settings", {"type": 'NDOF_BUTTON_MENU', "value": 'PRESS'}),
("wm.context_scale_float", {"type": 'NDOF_BUTTON_PLUS', "value": 'PRESS'},
{"properties": [("data_path", 'preferences.inputs.ndof_sensitivity'), ("value", 1.1)]}),
("wm.context_scale_float", {"type": 'NDOF_BUTTON_MINUS', "value": 'PRESS'},
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 98e812cf02d..7c28095259e 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -296,11 +296,11 @@ def brush_basic_wpaint_settings(layout, context, brush, *, compact=False):
row = layout.row(align=True)
UnifiedPaintPanel.prop_unified_size(row, context, brush, "size", slider=True)
- UnifiedPaintPanel.prop_unified_size(row, context, brush, "use_pressure_size", text="")
+ row.prop(brush, "use_pressure_size", text="")
row = layout.row(align=True)
UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength")
- UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="")
+ row.prop(brush, "use_pressure_strength", text="")
layout.prop(brush, "blend", text="" if compact else "Blend")
@@ -310,11 +310,11 @@ def brush_basic_vpaint_settings(layout, context, brush, *, compact=False):
row = layout.row(align=True)
UnifiedPaintPanel.prop_unified_size(row, context, brush, "size", slider=True)
- UnifiedPaintPanel.prop_unified_size(row, context, brush, "use_pressure_size", text="")
+ row.prop(brush, "use_pressure_size", text="")
row = layout.row(align=True)
UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength")
- UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="")
+ row.prop(brush, "use_pressure_strength", text="")
if capabilities.has_color:
layout.prop(brush, "blend", text="" if compact else "Blend")
@@ -326,12 +326,12 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False):
if capabilities.has_radius:
row = layout.row(align=True)
UnifiedPaintPanel.prop_unified_size(row, context, brush, "size", slider=True)
- UnifiedPaintPanel.prop_unified_size(row, context, brush, "use_pressure_size", text="")
+ row.prop(brush, "use_pressure_size", text="")
row = layout.row(align=True)
UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength")
- UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="")
+ row.prop(brush, "use_pressure_strength", text="")
if capabilities.has_color:
layout.prop(brush, "blend", text="" if compact else "Blend")
@@ -352,7 +352,7 @@ def brush_basic_sculpt_settings(layout, context, brush, *, compact=False):
else:
UnifiedPaintPanel.prop_unified_size(row, context, brush, "size", slider=True)
- UnifiedPaintPanel.prop_unified_size(row, context, brush, "use_pressure_size", text="")
+ row.prop(brush, "use_pressure_size", text="")
# strength, use_strength_pressure, and use_strength_attenuation
row = layout.row(align=True)
@@ -360,7 +360,7 @@ def brush_basic_sculpt_settings(layout, context, brush, *, compact=False):
UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength")
if capabilities.has_strength_pressure:
- UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="")
+ row.prop(brush, "use_pressure_strength", text="")
# direction
if not capabilities.has_direction:
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index fac8ff238c0..3b498b834bf 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -288,7 +288,8 @@ class DOPESHEET_MT_editor_menus(Menu):
layout.menu("DOPESHEET_MT_view")
layout.menu("DOPESHEET_MT_select")
- layout.menu("DOPESHEET_MT_marker")
+ if st.show_markers:
+ layout.menu("DOPESHEET_MT_marker")
if st.mode == 'DOPESHEET' or (st.mode == 'ACTION' and st.action is not None):
layout.menu("DOPESHEET_MT_channel")
@@ -322,9 +323,12 @@ class DOPESHEET_MT_view(Menu):
layout.prop(st, "show_group_colors")
layout.prop(st, "show_interpolation")
layout.prop(st, "show_extremes")
- layout.prop(st, "show_marker_lines")
layout.prop(st, "use_auto_merge_keyframes")
+ layout.separator()
+ layout.prop(st, "show_markers")
+
+ layout.separator()
layout.prop(st, "show_seconds")
layout.prop(st, "show_locked_time")
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 15ef7b0ef82..188741956ab 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -94,10 +94,12 @@ class GRAPH_MT_editor_menus(Menu):
bl_label = ""
def draw(self, _context):
+ st = _context.space_data
layout = self.layout
layout.menu("GRAPH_MT_view")
layout.menu("GRAPH_MT_select")
- layout.menu("GRAPH_MT_marker")
+ if st.mode != 'DRIVERS' and st.show_markers:
+ layout.menu("GRAPH_MT_marker")
layout.menu("GRAPH_MT_channel")
layout.menu("GRAPH_MT_key")
@@ -117,9 +119,12 @@ class GRAPH_MT_view(Menu):
layout.prop(st, "show_cursor")
layout.prop(st, "show_sliders")
layout.prop(st, "show_group_colors")
- layout.prop(st, "show_marker_lines")
layout.prop(st, "use_auto_merge_keyframes")
+ if st.mode != 'DRIVERS':
+ layout.separator()
+ layout.prop(st, "show_markers")
+
layout.separator()
layout.prop(st, "use_beauty_drawing")
diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index 825e4b41609..24d6f65d9b9 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -71,10 +71,12 @@ class NLA_MT_editor_menus(Menu):
bl_label = ""
def draw(self, _context):
+ st = _context.space_data
layout = self.layout
layout.menu("NLA_MT_view")
layout.menu("NLA_MT_select")
- layout.menu("NLA_MT_marker")
+ if st.show_markers:
+ layout.menu("NLA_MT_marker")
layout.menu("NLA_MT_edit")
layout.menu("NLA_MT_add")
@@ -96,8 +98,10 @@ class NLA_MT_view(Menu):
layout.prop(st, "show_locked_time")
layout.prop(st, "show_strip_curves")
+
+ layout.separator()
+ layout.prop(st, "show_markers")
layout.prop(st, "show_local_markers")
- layout.prop(st, "show_marker_lines")
layout.separator()
layout.operator("anim.previewrange_set")
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 4d9a4646f5f..b4f841d2eb8 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -134,7 +134,8 @@ class SEQUENCER_MT_editor_menus(Menu):
if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
layout.menu("SEQUENCER_MT_select")
- layout.menu("SEQUENCER_MT_marker")
+ if st.show_markers:
+ layout.menu("SEQUENCER_MT_marker")
layout.menu("SEQUENCER_MT_add")
layout.menu("SEQUENCER_MT_strip")
@@ -268,7 +269,8 @@ class SEQUENCER_MT_view(Menu):
layout.prop(st, "show_seconds")
layout.prop(st, "show_strip_offset")
- layout.prop(st, "show_marker_lines")
+ layout.separator()
+ layout.prop(st, "show_markers")
if is_preview:
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index 04a904edde3..6d60c67ded0 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -90,6 +90,7 @@ class TIME_MT_editor_menus(Menu):
def draw(self, _context):
layout = self.layout
horizontal = (layout.direction == 'VERTICAL')
+ st = _context.space_data
if horizontal:
row = layout.row()
sub = row.row(align=True)
@@ -109,7 +110,8 @@ class TIME_MT_editor_menus(Menu):
sub = row.row(align=True)
sub.menu("TIME_MT_view")
- sub.menu("TIME_MT_marker")
+ if st.show_markers:
+ sub.menu("TIME_MT_marker")
class TIME_MT_marker(Menu):
@@ -135,7 +137,10 @@ class TIME_MT_view(Menu):
layout.separator()
- layout.prop(st, "show_marker_lines")
+ layout.prop(st, "show_markers")
+
+ layout.separator()
+
layout.prop(scene, "show_keys_from_selected_only")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 7c6a7ecbcee..387acbec625 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -1409,20 +1409,24 @@ class USERPREF_PT_saveload_file_browser(PreferencePanel, Panel):
flow.prop(paths, "hide_system_bookmarks")
-class USERPREF_MT_ndof_settings(Menu):
- # accessed from the window key-bindings in C (only)
+class USERPREF_PT_ndof_settings(Panel):
bl_label = "3D Mouse Settings"
+ bl_space_type = 'TOPBAR' # dummy.
+ bl_region_type = 'HEADER'
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
input_prefs = context.preferences.inputs
is_view3d = context.space_data.type == 'VIEW_3D'
- layout.prop(input_prefs, "ndof_sensitivity")
- layout.prop(input_prefs, "ndof_orbit_sensitivity")
- layout.prop(input_prefs, "ndof_deadzone")
+ col = layout.column(align=True)
+ col.prop(input_prefs, "ndof_sensitivity")
+ col.prop(input_prefs, "ndof_orbit_sensitivity")
+ col.prop(input_prefs, "ndof_deadzone")
if is_view3d:
layout.separator()
@@ -1430,20 +1434,39 @@ class USERPREF_MT_ndof_settings(Menu):
layout.separator()
layout.label(text="Orbit Style")
- layout.row().prop(input_prefs, "ndof_view_navigate_method", text="")
- layout.row().prop(input_prefs, "ndof_view_rotate_method", text="")
+ layout.row().prop(input_prefs, "ndof_view_navigate_method", text="Navigate")
+ layout.row().prop(input_prefs, "ndof_view_rotate_method", text="Orbit")
layout.separator()
+
layout.label(text="Orbit Options")
- layout.prop(input_prefs, "ndof_rotx_invert_axis")
- layout.prop(input_prefs, "ndof_roty_invert_axis")
- layout.prop(input_prefs, "ndof_rotz_invert_axis")
+ split = layout.split(factor=0.6)
+ row = split.row()
+ row.alignment = 'RIGHT'
+ row.label(text="Invert Axis")
+ row = split.row(align=True)
+ for text, attr in (
+ ("X", "ndof_rotx_invert_axis"),
+ ("Y", "ndof_roty_invert_axis"),
+ ("Z", "ndof_rotz_invert_axis"),
+ ):
+ row.prop(input_prefs, attr, text=text, toggle=True)
# view2d use pan/zoom
layout.separator()
layout.label(text="Pan Options")
- layout.prop(input_prefs, "ndof_panx_invert_axis")
- layout.prop(input_prefs, "ndof_pany_invert_axis")
- layout.prop(input_prefs, "ndof_panz_invert_axis")
+
+ split = layout.split(factor=0.6)
+ row = split.row()
+ row.alignment = 'RIGHT'
+ row.label(text="Invert Axis")
+ row = split.row(align=True)
+ for text, attr in (
+ ("X", "ndof_panx_invert_axis"),
+ ("Y", "ndof_pany_invert_axis"),
+ ("Z", "ndof_panz_invert_axis"),
+ ):
+ row.prop(input_prefs, attr, text=text, toggle=True)
+
layout.prop(input_prefs, "ndof_pan_yz_swap_axis")
layout.label(text="Zoom Options")
@@ -1452,8 +1475,8 @@ class USERPREF_MT_ndof_settings(Menu):
if is_view3d:
layout.separator()
layout.label(text="Fly/Walk Options")
- layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY')
- layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
+ layout.prop(input_prefs, "ndof_fly_helicopter")
+ layout.prop(input_prefs, "ndof_lock_horizon")
class USERPREF_PT_input_keyboard(PreferencePanel, Panel):
@@ -2255,7 +2278,6 @@ classes = (
USERPREF_PT_saveload_autorun,
USERPREF_PT_saveload_file_browser,
- USERPREF_MT_ndof_settings,
USERPREF_MT_keyconfigs,
USERPREF_PT_input_keyboard,
@@ -2278,6 +2300,9 @@ classes = (
USERPREF_PT_experimental_all,
+ # Popovers.
+ USERPREF_PT_ndof_settings,
+
# Add dynamically generated editor theme panels last,
# so they show up last in the theme section.
*ThemeGenericClassGenerator.generate_panel_classes_from_theme_areas(),
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 113274ce166..9f04dc4627a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -5466,6 +5466,26 @@ class VIEW3D_PT_shading_options_ssao(Panel):
col.prop(scene.display, "matcap_ssao_attenuation")
+class VIEW3D_PT_shading_render_pass(Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'HEADER'
+ bl_label = "Render Pass"
+ bl_parent_id = 'VIEW3D_PT_shading'
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.space_data.shading.type == 'MATERIAL'
+ or (context.engine in cls.COMPAT_ENGINES
+ and context.space_data.shading.type == 'RENDERED'))
+
+ def draw(self, context):
+ shading = context.space_data.shading
+
+ layout = self.layout
+ layout.prop(shading, "render_pass", text="")
+
+
class VIEW3D_PT_gizmo_display(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@@ -6909,6 +6929,7 @@ classes = (
VIEW3D_PT_shading_options,
VIEW3D_PT_shading_options_shadow,
VIEW3D_PT_shading_options_ssao,
+ VIEW3D_PT_shading_render_pass,
VIEW3D_PT_gizmo_display,
VIEW3D_PT_overlay,
VIEW3D_PT_overlay_guides,
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 724264fe494..718365ec99d 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1193,7 +1193,8 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
if sculpt.detail_type_method in {'CONSTANT', 'MANUAL'}:
row = sub.row(align=True)
row.prop(sculpt, "constant_detail_resolution")
- row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
+ props = row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
+ props.mode = 'DYNTOPO'
elif (sculpt.detail_type_method == 'BRUSH'):
sub.prop(sculpt, "detail_percent")
else:
@@ -1252,7 +1253,10 @@ class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel):
col = layout.column()
mesh = context.active_object.data
- col.prop(mesh, "remesh_voxel_size")
+ row = col.row(align=True)
+ row.prop(mesh, "remesh_voxel_size")
+ props = row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
+ props.mode = 'VOXEL'
col.prop(mesh, "remesh_voxel_adaptivity")
col.prop(mesh, "use_remesh_fix_poles")
col.prop(mesh, "use_remesh_smooth_normals")
diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index 7c5efaf309d..878dbfc2a53 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -59,7 +59,7 @@ struct AlembicExportParams {
bool apply_subdiv;
bool curves_as_mesh;
bool flatten_hierarchy;
- bool visible_layers_only;
+ bool visible_objects_only;
bool renderable_only;
bool face_sets;
bool use_subdiv_schema;
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index cbc8fd769b7..d422a3c023e 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -74,7 +74,7 @@ ExportSettings::ExportSettings()
depsgraph(NULL),
logger(),
selected_only(false),
- visible_layers_only(false),
+ visible_objects_only(false),
renderable_only(false),
frame_start(1),
frame_end(1),
@@ -161,7 +161,7 @@ static bool export_object(const ExportSettings *const settings,
}
// FIXME Sybren: handle these cleanly (maybe just remove code),
// now using active scene layer instead.
- if (settings->visible_layers_only && !BASE_VISIBLE(v3d, base)) {
+ if (settings->visible_objects_only && !BASE_VISIBLE(v3d, base)) {
return false;
}
}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index a73289fcf95..923fe0ca29f 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -49,7 +49,7 @@ struct ExportSettings {
SimpleLogger logger;
bool selected_only;
- bool visible_layers_only;
+ bool visible_objects_only;
bool renderable_only;
double frame_start, frame_end;
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index 9b12fe86d59..585d4178e41 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -27,6 +27,7 @@
extern "C" {
#include "DNA_object_types.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_animsys.h"
@@ -131,9 +132,9 @@ Imath::Box3d AbcTransformWriter::bounds()
return Imath::transform(bounds, m_matrix);
}
-bool AbcTransformWriter::hasAnimation(Object *ob) const
+bool AbcTransformWriter::hasAnimation(Object * /*ob*/) const
{
- return BKE_animdata_id_is_animated(&ob->id);
+ return true;
}
/* ************************************************************************** */
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 1034c5b319f..5efa8c8a446 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -365,7 +365,7 @@ bool ABC_export(Scene *scene,
/* TODO(Sybren): visible_layer & renderable only is ignored for now,
* to be replaced with collections later in the 2.8 dev process
* (also see note above). */
- job->settings.visible_layers_only = params->visible_layers_only;
+ job->settings.visible_objects_only = params->visible_objects_only;
job->settings.renderable_only = params->renderable_only;
job->settings.use_subdiv_schema = params->use_subdiv_schema;
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index b7139d5bbf6..fdfea95937b 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -25,6 +25,10 @@
* \brief Blender kernel action and pose functionality.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "DNA_listBase.h"
/* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */
@@ -38,11 +42,6 @@ struct bPose;
struct bPoseChannel;
struct bPoseChannel_Runtime;
-/* Kernel prototypes */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Action Lib Stuff ----------------- */
/* Allocate a new bAction with the given name */
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index d0249cb2b38..963e3158d46 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -24,6 +24,10 @@
* \ingroup bke
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct AnimData;
struct Depsgraph;
struct FCurve;
@@ -33,6 +37,7 @@ struct KeyingSet;
struct ListBase;
struct Main;
struct NlaKeyframingContext;
+struct PathResolvedRNA;
struct PointerRNA;
struct PropertyRNA;
struct ReportList;
@@ -244,6 +249,9 @@ typedef enum eAnimData_Recalc {
ADT_RECALC_ALL = (ADT_RECALC_DRIVERS | ADT_RECALC_ANIM),
} eAnimData_Recalc;
+bool BKE_animsys_read_rna_setting(struct PathResolvedRNA *anim_rna, float *r_value);
+bool BKE_animsys_write_rna_setting(struct PathResolvedRNA *anim_rna, const float value);
+
/* Evaluation loop for evaluating animation data */
void BKE_animsys_evaluate_animdata(struct Scene *scene,
struct ID *id,
@@ -258,9 +266,6 @@ void BKE_animsys_evaluate_all_animation(struct Main *main,
struct Scene *scene,
float ctime);
-/* TODO(sergey): This is mainly a temp public function. */
-bool BKE_animsys_execute_fcurve(struct PointerRNA *ptr, struct FCurve *fcu, float curval);
-
/* ------------ Specialized API --------------- */
/* There are a few special tools which require these following functions. They are NOT to be used
* for standard animation evaluation UNDER ANY CIRCUMSTANCES!
@@ -297,4 +302,8 @@ void BKE_animsys_update_driver_array(struct ID *id);
/* ************************************* */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BKE_ANIMSYS_H__*/
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index dd1fff9ce47..f1c45ac0b45 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -27,7 +27,7 @@
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 282
-#define BLENDER_SUBVERSION 1
+#define BLENDER_SUBVERSION 3
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 70741831727..c7f6c09b886 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -111,8 +111,8 @@ float BKE_brush_weight_get(const struct Scene *scene, const struct Brush *brush)
void BKE_brush_weight_set(const struct Scene *scene, struct Brush *brush, float value);
bool BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush);
-bool BKE_brush_use_alpha_pressure(const struct Scene *scene, const struct Brush *brush);
-bool BKE_brush_use_size_pressure(const struct Scene *scene, const struct Brush *brush);
+bool BKE_brush_use_alpha_pressure(const struct Brush *brush);
+bool BKE_brush_use_size_pressure(const struct Brush *brush);
bool BKE_brush_sculpt_has_secondary_color(const struct Brush *brush);
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 643073b3470..e4ea1dad086 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -68,7 +68,9 @@ void BKE_curvemapping_initialize(struct CurveMapping *cumap);
/* keep these (const CurveMap) - to help with thread safety */
/* single curve, no table check */
-float BKE_curvemap_evaluateF(const struct CurveMap *cuma, float value);
+float BKE_curvemap_evaluateF(const struct CurveMapping *cumap,
+ const struct CurveMap *cuma,
+ float value);
/* single curve, with table check */
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value);
void BKE_curvemapping_evaluate3F(const struct CurveMapping *cumap,
diff --git a/source/blender/blenkernel/BKE_kelvinlet.h b/source/blender/blenkernel/BKE_kelvinlet.h
new file mode 100644
index 00000000000..fbf7d3ede1f
--- /dev/null
+++ b/source/blender/blenkernel/BKE_kelvinlet.h
@@ -0,0 +1,77 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ */
+#ifndef __BKE_KELVINLET_H__
+#define __BKE_KELVINLET_H__
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BLI_math.h"
+
+/* Regularized Kelvinlets: Sculpting Brushes based on Fundamental Solutions of Elasticity
+ * Pixar Technical Memo #17-03 */
+
+#define KELVINLET_MAX_ITERATIONS 3
+
+typedef struct KelvinletParams {
+ float a;
+ float b;
+ float c;
+
+ float f;
+
+ float radius_scaled[KELVINLET_MAX_ITERATIONS];
+} KelvinletParams;
+
+/* Initialize KelvinletParams to store the parameters that will affect the deformation produced by
+ * a Kelvinlet */
+void BKE_kelvinlet_init_params(
+ KelvinletParams *params, float radius, float force, float shear_modulus, float poisson_ratio);
+
+/* Regularized Kelvinlets */
+/* All these functions output the displacement that should be applied to each element. */
+/* The initial coordinates of that element should not be modified during the transformation */
+void BKE_kelvinlet_grab(float r_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3]);
+void BKE_kelvinlet_grab_biscale(float r_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3]);
+void BKE_kelvinlet_grab_triscale(float r_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3]);
+void BKE_kelvinlet_scale(float r_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float surface_normal[3]);
+void BKE_kelvinlet_twist(float r_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float surface_normal[3]);
+
+#endif
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 7ff9c4e6376..d7b037a8189 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -95,6 +95,7 @@ bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
bool BKE_object_material_slot_used(struct ID *id, short actcol);
struct Material *BKE_material_gpencil_get(struct Object *ob, short act);
+struct Material *BKE_material_gpencil_default_get(void);
struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob, short act);
void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 07dee83e5ca..1e549849989 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -20,6 +20,10 @@
* \ingroup bke
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "DNA_modifier_types.h" /* needed for all enum typdefs */
#include "BLI_compiler_attrs.h"
#include "BKE_customdata.h"
@@ -461,4 +465,8 @@ void modwrap_deformVertsEM(ModifierData *md,
struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval,
const bool get_cage_mesh);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index c1bb60737ff..1ae1772e094 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -24,6 +24,10 @@
* \ingroup bke
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct Depsgraph;
struct Editing;
struct GPUOffScreen;
@@ -599,4 +603,8 @@ void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 1567985bd53..6807d81daa3 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -23,6 +23,10 @@
* \ingroup bke
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define SOUND_WAVE_SAMPLES_PER_SECOND 250
#if defined(WITH_AUDASPACE)
@@ -190,4 +194,8 @@ struct Depsgraph;
void BKE_sound_evaluate(struct Depsgraph *depsgraph, struct Main *bmain, struct bSound *sound);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 883518b7a9d..88a3629ea3f 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -129,6 +129,7 @@ set(SRC
intern/image_gen.c
intern/image_save.c
intern/ipo.c
+ intern/kelvinlet.c
intern/key.c
intern/keyconfig.c
intern/lattice.c
@@ -292,6 +293,7 @@ set(SRC
BKE_image.h
BKE_image_save.h
BKE_ipo.h
+ BKE_kelvinlet.h
BKE_key.h
BKE_keyconfig.h
BKE_lattice.h
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index eea71d52ab6..32420e2e894 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1717,7 +1717,7 @@ static bool animsys_store_rna_setting(PointerRNA *ptr,
/* less than 1.0 evaluates to false, use epsilon to avoid float error */
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
-static bool animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
+bool BKE_animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
{
PropertyRNA *prop = anim_rna->prop;
PointerRNA *ptr = &anim_rna->ptr;
@@ -1780,7 +1780,7 @@ static bool animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
}
/* Write the given value to a setting using RNA, and return success */
-static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
+bool BKE_animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
{
PropertyRNA *prop = anim_rna->prop;
PointerRNA *ptr = &anim_rna->ptr;
@@ -1791,7 +1791,7 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
/* Check whether value is new. Otherwise we skip all the updates. */
float old_value;
- if (!animsys_read_rna_setting(anim_rna, &old_value)) {
+ if (!BKE_animsys_read_rna_setting(anim_rna, &old_value)) {
return false;
}
if (old_value == value) {
@@ -1845,20 +1845,6 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
return true;
}
-/* Simple replacement based data-setting of the FCurve using RNA */
-bool BKE_animsys_execute_fcurve(PointerRNA *ptr, FCurve *fcu, float curval)
-{
- PathResolvedRNA anim_rna;
- bool ok = false;
-
- if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- ok = animsys_write_rna_setting(&anim_rna, curval);
- }
-
- /* return whether we were successful */
- return ok;
-}
-
static bool animsys_construct_orig_pointer_rna(const PointerRNA *ptr, PointerRNA *ptr_orig)
{
*ptr_orig = *ptr;
@@ -1895,7 +1881,7 @@ static void animsys_write_orig_anim_rna(PointerRNA *ptr,
PathResolvedRNA orig_anim_rna;
/* TODO(sergey): Should be possible to cache resolved path in dependency graph somehow. */
if (animsys_store_rna_setting(&ptr_orig, rna_path, array_index, &orig_anim_rna)) {
- animsys_write_rna_setting(&orig_anim_rna, value);
+ BKE_animsys_write_rna_setting(&orig_anim_rna, value);
}
}
@@ -1926,7 +1912,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- animsys_write_rna_setting(&anim_rna, curval);
+ BKE_animsys_write_rna_setting(&anim_rna, curval);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
}
@@ -1960,7 +1946,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- ok = animsys_write_rna_setting(&anim_rna, curval);
+ ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
}
/* set error-flag if evaluation failed */
@@ -2039,7 +2025,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- animsys_write_rna_setting(&anim_rna, curval);
+ BKE_animsys_write_rna_setting(&anim_rna, curval);
}
}
}
@@ -3333,7 +3319,7 @@ void nladata_flush_channels(PointerRNA *ptr,
if (nec->is_array) {
rna.prop_index = i;
}
- animsys_write_rna_setting(&rna, value);
+ BKE_animsys_write_rna_setting(&rna, value);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value);
}
@@ -3818,7 +3804,7 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
for (aor = adt->overrides.first; aor; aor = aor->next) {
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, aor->rna_path, aor->array_index, &anim_rna)) {
- animsys_write_rna_setting(&anim_rna, aor->value);
+ BKE_animsys_write_rna_setting(&anim_rna, aor->value);
}
}
}
@@ -4143,7 +4129,7 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu
/* Evaluate driver, and write results to COW-domain destination */
const float ctime = DEG_get_ctime(depsgraph);
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- ok = animsys_write_rna_setting(&anim_rna, curval);
+ ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
/* Flush results & status codes to original data for UI (T59984) */
if (ok && DEG_is_active(depsgraph)) {
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 58b0c9b41ea..a694a335069 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -281,22 +281,22 @@ static void armature_transform_recurse(ListBase *bonebase,
{
for (Bone *bone = bonebase->first; bone; bone = bone->next) {
- /* Transform the bone's roll. */
- if (bone_parent == NULL) {
-
- float roll_mat[3][3];
- {
- float delta[3];
- sub_v3_v3v3(delta, bone->tail, bone->head);
- vec_roll_to_mat3(delta, bone->roll, roll_mat);
+ /* Store the initial bone roll in a matrix, this is needed even for child bones
+ * so any change in head/tail doesn't cause the roll to change.
+ *
+ * Logic here is different to edit-mode because
+ * this is calculated in relative to the parent. */
+ float roll_mat3_pre[3][3];
+ {
+ float delta[3];
+ sub_v3_v3v3(delta, bone->tail, bone->head);
+ vec_roll_to_mat3(delta, bone->roll, roll_mat3_pre);
+ if (bone->parent == NULL) {
+ mul_m3_m3m3(roll_mat3_pre, mat3, roll_mat3_pre);
}
-
- /* Transform the roll matrix. */
- mul_m3_m3m3(roll_mat, mat3, roll_mat);
-
- /* Apply the transformed roll back. */
- mat3_to_vec_roll(roll_mat, NULL, &bone->roll);
}
+ /* Optional, use this for predictable results since the roll is re-calculated below anyway. */
+ bone->roll = 0.0f;
mul_m4_v3(mat, bone->arm_head);
mul_m4_v3(mat, bone->arm_tail);
@@ -314,6 +314,17 @@ static void armature_transform_recurse(ListBase *bonebase,
copy_v3_v3(bone->tail, bone->arm_tail);
}
+ /* Now the head/tail have been updated, set the roll back, matching 'roll_mat3_pre'. */
+ {
+ float roll_mat3_post[3][3], delta_mat3[3][3];
+ float delta[3];
+ sub_v3_v3v3(delta, bone->tail, bone->head);
+ vec_roll_to_mat3(delta, 0.0f, roll_mat3_post);
+ invert_m3(roll_mat3_post);
+ mul_m3_m3m3(delta_mat3, roll_mat3_post, roll_mat3_pre);
+ bone->roll = atan2f(delta_mat3[2][0], delta_mat3[2][2]);
+ }
+
BKE_armature_where_is_bone(bone, bone_parent, false);
{
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 4d496fe758b..8b90eafdddf 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -931,7 +931,9 @@ void BKE_brush_sculpt_reset(Brush *br)
br->alpha = 1.0f;
break;
case SCULPT_TOOL_CLAY:
- br->spacing = 6;
+ br->flag |= BRUSH_SIZE_PRESSURE;
+ br->spacing = 3;
+ br->autosmooth_factor = 0.25f;
br->normal_radius_factor = 0.75f;
break;
case SCULPT_TOOL_CLAY_STRIPS:
@@ -1069,18 +1071,19 @@ void BKE_brush_sculpt_reset(Brush *br)
*/
void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset)
{
- CurveMap *cm = NULL;
+ CurveMapping *cumap = NULL;
+ CurveMap *cuma = NULL;
if (!b->curve) {
b->curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
}
+ cumap = b->curve;
+ cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ cumap->preset = preset;
- cm = b->curve->cm;
- cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
-
- b->curve->preset = preset;
- BKE_curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
- BKE_curvemapping_changed(b->curve, false);
+ cuma = b->curve->cm;
+ BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_NEGATIVE);
+ BKE_curvemapping_changed(cumap, false);
}
/* Generic texture sampler for 3D painting systems. point has to be either in
@@ -1398,20 +1401,14 @@ bool BKE_brush_use_locked_size(const Scene *scene, const Brush *brush)
(brush->flag & BRUSH_LOCK_SIZE);
}
-bool BKE_brush_use_size_pressure(const Scene *scene, const Brush *brush)
+bool BKE_brush_use_size_pressure(const Brush *brush)
{
- const short us_flag = scene->toolsettings->unified_paint_settings.flag;
-
- return (us_flag & UNIFIED_PAINT_SIZE) ? (us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
- (brush->flag & BRUSH_SIZE_PRESSURE);
+ return brush->flag & BRUSH_SIZE_PRESSURE;
}
-bool BKE_brush_use_alpha_pressure(const Scene *scene, const Brush *brush)
+bool BKE_brush_use_alpha_pressure(const Brush *brush)
{
- const short us_flag = scene->toolsettings->unified_paint_settings.flag;
-
- return (us_flag & UNIFIED_PAINT_ALPHA) ? (us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
- (brush->flag & BRUSH_ALPHA_PRESSURE);
+ return brush->flag & BRUSH_ALPHA_PRESSURE;
}
bool BKE_brush_sculpt_has_secondary_color(const Brush *brush)
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 8166bbea962..2ec04ee2747 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -54,7 +54,7 @@ void BKE_curvemapping_set_defaults(
int a;
float clipminx, clipminy, clipmaxx, clipmaxy;
- cumap->flag = CUMA_DO_CLIP;
+ cumap->flag = CUMA_DO_CLIP | CUMA_EXTEND_EXTRAPOLATE;
if (tot == 4) {
cumap->cur = 3; /* rhms, hack for 'col' curve? */
}
@@ -71,7 +71,6 @@ void BKE_curvemapping_set_defaults(
cumap->bwmul[0] = cumap->bwmul[1] = cumap->bwmul[2] = 1.0f;
for (a = 0; a < tot; a++) {
- cumap->cm[a].flag = CUMA_EXTEND_EXTRAPOLATE;
cumap->cm[a].totpoint = 2;
cumap->cm[a].curve = MEM_callocN(2 * sizeof(CurveMapPoint), "curve points");
@@ -591,14 +590,15 @@ static void calchandle_curvemap(BezTriple *bezt, const BezTriple *prev, const Be
/* in X, out Y.
* X is presumed to be outside first or last */
-static float curvemap_calc_extend(const CurveMap *cuma,
+static float curvemap_calc_extend(const CurveMapping *cumap,
+ const CurveMap *cuma,
float x,
const float first[2],
const float last[2])
{
if (x <= first[0]) {
- if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
- /* no extrapolate */
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
+ /* extrapolate horizontally */
return first[1];
}
else {
@@ -611,8 +611,8 @@ static float curvemap_calc_extend(const CurveMap *cuma,
}
}
else if (x >= last[0]) {
- if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
- /* no extrapolate */
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
+ /* extrapolate horizontally */
return last[1];
}
else {
@@ -628,8 +628,9 @@ static float curvemap_calc_extend(const CurveMap *cuma,
}
/* only creates a table for a single channel in CurveMapping */
-static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
+static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
{
+ const rctf *clipr = &cumap->clipr;
CurveMapPoint *cmp = cuma->curve;
BezTriple *bezt;
@@ -782,7 +783,7 @@ static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
}
else {
/* Extrapolate values that lie outside the start and end point. */
- cmp[a].y = curvemap_calc_extend(cuma, cur_x, firstpoint, lastpoint);
+ cmp[a].y = curvemap_calc_extend(cumap, cuma, cur_x, firstpoint, lastpoint);
}
}
else {
@@ -829,7 +830,7 @@ void BKE_curvemapping_premultiply(CurveMapping *cumap, int restore)
/* verify and copy */
for (a = 0; a < 3; a++) {
if (cumap->cm[a].table == NULL) {
- curvemap_make_table(cumap->cm + a, &cumap->clipr);
+ curvemap_make_table(cumap, cumap->cm + a);
}
cumap->cm[a].premultable = cumap->cm[a].table;
cumap->cm[a].table = MEM_mallocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "premul table");
@@ -838,14 +839,15 @@ void BKE_curvemapping_premultiply(CurveMapping *cumap, int restore)
}
if (cumap->cm[3].table == NULL) {
- curvemap_make_table(cumap->cm + 3, &cumap->clipr);
+ curvemap_make_table(cumap, cumap->cm + 3);
}
/* premul */
for (a = 0; a < 3; a++) {
int b;
for (b = 0; b <= CM_TABLE; b++) {
- cumap->cm[a].table[b].y = BKE_curvemap_evaluateF(cumap->cm + 3, cumap->cm[a].table[b].y);
+ cumap->cm[a].table[b].y = BKE_curvemap_evaluateF(
+ cumap, cumap->cm + 3, cumap->cm[a].table[b].y);
}
copy_v2_v2(cumap->cm[a].premul_ext_in, cumap->cm[a].ext_in);
@@ -949,7 +951,7 @@ void BKE_curvemapping_changed(CurveMapping *cumap, const bool rem_doubles)
BKE_curvemap_remove(cuma, 2);
}
}
- curvemap_make_table(cuma, clipr);
+ curvemap_make_table(cumap, cuma);
}
void BKE_curvemapping_changed_all(CurveMapping *cumap)
@@ -967,7 +969,7 @@ void BKE_curvemapping_changed_all(CurveMapping *cumap)
}
/* table should be verified */
-float BKE_curvemap_evaluateF(const CurveMap *cuma, float value)
+float BKE_curvemap_evaluateF(const CurveMapping *cumap, const CurveMap *cuma, float value)
{
float fi;
int i;
@@ -978,7 +980,7 @@ float BKE_curvemap_evaluateF(const CurveMap *cuma, float value)
/* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
if (fi < 0.0f || fi > CM_TABLE) {
- return curvemap_calc_extend(cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x);
+ return curvemap_calc_extend(cumap, cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x);
}
else {
if (i < 0) {
@@ -997,7 +999,7 @@ float BKE_curvemap_evaluateF(const CurveMap *cuma, float value)
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
{
const CurveMap *cuma = cumap->cm + cur;
- float val = BKE_curvemap_evaluateF(cuma, value);
+ float val = BKE_curvemap_evaluateF(cumap, cuma, value);
/* account for clipping */
if (cumap->flag & CUMA_DO_CLIP) {
@@ -1015,9 +1017,9 @@ float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value
/* vector case */
void BKE_curvemapping_evaluate3F(const CurveMapping *cumap, float vecout[3], const float vecin[3])
{
- vecout[0] = BKE_curvemap_evaluateF(&cumap->cm[0], vecin[0]);
- vecout[1] = BKE_curvemap_evaluateF(&cumap->cm[1], vecin[1]);
- vecout[2] = BKE_curvemap_evaluateF(&cumap->cm[2], vecin[2]);
+ vecout[0] = BKE_curvemap_evaluateF(cumap, &cumap->cm[0], vecin[0]);
+ vecout[1] = BKE_curvemap_evaluateF(cumap, &cumap->cm[1], vecin[1]);
+ vecout[2] = BKE_curvemap_evaluateF(cumap, &cumap->cm[2], vecin[2]);
}
/* RGB case, no black/white points, no premult */
@@ -1025,12 +1027,12 @@ void BKE_curvemapping_evaluateRGBF(const CurveMapping *cumap,
float vecout[3],
const float vecin[3])
{
- vecout[0] = BKE_curvemap_evaluateF(&cumap->cm[0],
- BKE_curvemap_evaluateF(&cumap->cm[3], vecin[0]));
- vecout[1] = BKE_curvemap_evaluateF(&cumap->cm[1],
- BKE_curvemap_evaluateF(&cumap->cm[3], vecin[1]));
- vecout[2] = BKE_curvemap_evaluateF(&cumap->cm[2],
- BKE_curvemap_evaluateF(&cumap->cm[3], vecin[2]));
+ vecout[0] = BKE_curvemap_evaluateF(
+ cumap, &cumap->cm[0], BKE_curvemap_evaluateF(cumap, &cumap->cm[3], vecin[0]));
+ vecout[1] = BKE_curvemap_evaluateF(
+ cumap, &cumap->cm[1], BKE_curvemap_evaluateF(cumap, &cumap->cm[3], vecin[1]));
+ vecout[2] = BKE_curvemap_evaluateF(
+ cumap, &cumap->cm[2], BKE_curvemap_evaluateF(cumap, &cumap->cm[3], vecin[2]));
}
static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap,
@@ -1042,8 +1044,8 @@ static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap,
const float v1in = vecin[channel_offset[1]];
const float v2in = vecin[channel_offset[2]];
- const float v0 = BKE_curvemap_evaluateF(&cumap->cm[channel_offset[0]], v0in);
- const float v2 = BKE_curvemap_evaluateF(&cumap->cm[channel_offset[2]], v2in);
+ const float v0 = BKE_curvemap_evaluateF(cumap, &cumap->cm[channel_offset[0]], v0in);
+ const float v2 = BKE_curvemap_evaluateF(cumap, &cumap->cm[channel_offset[2]], v2in);
const float v1 = v2 + ((v0 - v2) * (v1in - v2in) / (v0in - v2in));
vecout[channel_offset[0]] = v0;
@@ -1074,9 +1076,9 @@ void BKE_curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap,
switch (cumap->tone) {
default:
case CURVE_TONE_STANDARD: {
- vecout[0] = BKE_curvemap_evaluateF(&cumap->cm[0], r);
- vecout[1] = BKE_curvemap_evaluateF(&cumap->cm[1], g);
- vecout[2] = BKE_curvemap_evaluateF(&cumap->cm[2], b);
+ vecout[0] = BKE_curvemap_evaluateF(cumap, &cumap->cm[0], r);
+ vecout[1] = BKE_curvemap_evaluateF(cumap, &cumap->cm[1], g);
+ vecout[2] = BKE_curvemap_evaluateF(cumap, &cumap->cm[2], b);
break;
}
case CURVE_TONE_FILMLIKE: {
@@ -1099,8 +1101,8 @@ void BKE_curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap,
else {
/* Case 4: r >= g == b */
copy_v2_fl2(vecout,
- BKE_curvemap_evaluateF(&cumap->cm[0], r),
- BKE_curvemap_evaluateF(&cumap->cm[1], g));
+ BKE_curvemap_evaluateF(cumap, &cumap->cm[0], r),
+ BKE_curvemap_evaluateF(cumap, &cumap->cm[1], g));
vecout[2] = vecout[1];
}
}
@@ -1208,7 +1210,7 @@ void BKE_curvemapping_initialize(CurveMapping *cumap)
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].table == NULL) {
- curvemap_make_table(cumap->cm + a, &cumap->clipr);
+ curvemap_make_table(cumap, cumap->cm + a);
}
}
}
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index 9618ef8c78e..33f9b5b1012 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -417,12 +417,12 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
mti->deformMatrices(md, &mectx, me_eval, deformedVerts, defmats, me_eval->totvert);
}
else {
+ /* More complex handling will continue in BKE_crazyspace_build_sculpt.
+ * Exiting the loop on a non-deform modifier causes issues - T71213. */
+ BLI_assert(crazyspace_modifier_supports_deform(md));
break;
}
}
- else {
- break;
- }
}
for (; md; md = md->next) {
diff --git a/source/blender/blenkernel/intern/kelvinlet.c b/source/blender/blenkernel/intern/kelvinlet.c
new file mode 100644
index 00000000000..a7b48107873
--- /dev/null
+++ b/source/blender/blenkernel/intern/kelvinlet.c
@@ -0,0 +1,215 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BKE_kelvinlet.h"
+
+/* Regularized Kelvinlets: Sculpting Brushes based on Fundamental Solutions of Elasticity
+ * Pixar Technical Memo #17-03 */
+
+void BKE_kelvinlet_init_params(
+ KelvinletParams *params, float radius, float force, float shear_modulus, float poisson_ratio)
+{
+ params->a = 1.0f / (4.0f * (float)M_PI * shear_modulus);
+ params->b = params->a / (4.0f * (1.0f - poisson_ratio));
+ params->c = 2 * (3.0f * params->a - 2.0f * params->b);
+
+ /* Used in scale and twist. */
+ params->f = force;
+
+ /* This can be exposed if needed */
+ const float radius_e[KELVINLET_MAX_ITERATIONS] = {1.0f, 2.0f, 2.0f};
+ params->radius_scaled[0] = radius * radius_e[0];
+ params->radius_scaled[1] = params->radius_scaled[0] * radius_e[1];
+ params->radius_scaled[2] = params->radius_scaled[1] * radius_e[2];
+}
+
+static void init_kelvinlet_grab(float radius_e[3],
+ float kelvinlet[3],
+ const float radius,
+ const KelvinletParams *params,
+ const int num_iterations)
+{
+ const float a = params->a;
+ const float b = params->b;
+ const float *radius_scaled = params->radius_scaled;
+
+ for (int i = 0; i < num_iterations; i++) {
+ radius_e[i] = sqrtf(pow2f(radius) + pow2f(params->radius_scaled[i]));
+ }
+
+ /* Regularized Kelvinlets: Formula (6) */
+ for (int i = 0; i < num_iterations; i++) {
+ kelvinlet[i] = ((a - b) / radius_e[i]) + ((b * pow2f(radius)) / pow3f(radius_e[i])) +
+ ((a * pow2f(radius_scaled[i])) / (2.0f * pow3f(radius_e[i])));
+ }
+}
+
+void BKE_kelvinlet_grab(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3])
+{
+ float radius_e[3], kelvinlet[3];
+ const float c = params->c;
+ const float radius = len_v3v3(brush_location, elem_orig_co);
+
+ init_kelvinlet_grab(radius_e, kelvinlet, radius, params, 1);
+
+ const float fade = kelvinlet[0] * c;
+
+ mul_v3_v3fl(radius_elem_disp, brush_delta, fade);
+}
+
+void BKE_kelvinlet_grab_biscale(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3])
+{
+ float radius_e[3], kelvinlet[3];
+ const float c = params->c;
+ const float *radius_scaled = params->radius_scaled;
+ float radius = len_v3v3(brush_location, elem_orig_co);
+
+ init_kelvinlet_grab(radius_e, kelvinlet, radius, params, 2);
+
+ const float u = kelvinlet[0] - kelvinlet[1];
+ const float fade = u * c / ((1.0f / radius_scaled[0]) - (1.0f / radius_scaled[1]));
+
+ mul_v3_v3fl(radius_elem_disp, brush_delta, fade);
+}
+
+void BKE_kelvinlet_grab_triscale(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3])
+{
+ float radius_e[3], kelvinlet[3], weights[3];
+ const float c = params->c;
+ const float *radius_scaled = params->radius_scaled;
+ const float radius = len_v3v3(brush_location, elem_orig_co);
+
+ init_kelvinlet_grab(radius_e, kelvinlet, radius, params, 3);
+
+ weights[0] = 1.0f;
+ weights[1] = -((pow2f(radius_scaled[2]) - pow2f(radius_scaled[0])) /
+ (pow2f(radius_scaled[2]) - pow2f(radius_scaled[1])));
+ weights[2] = ((pow2f(radius_scaled[1]) - pow2f(radius_scaled[0])) /
+ (pow2f(radius_scaled[2]) - pow2f(radius_scaled[1])));
+
+ const float u = weights[0] * kelvinlet[0] + weights[1] * kelvinlet[1] +
+ weights[2] * kelvinlet[2];
+ const float fade = u * c /
+ (weights[0] / radius_scaled[0] + weights[1] / radius_scaled[1] +
+ weights[2] / radius_scaled[2]);
+
+ mul_v3_v3fl(radius_elem_disp, brush_delta, fade);
+}
+
+typedef void (*kelvinlet_fn)(
+ float[3], const float *, const float *, const float *, const KelvinletParams *);
+
+static void sculpt_kelvinet_integrate(kelvinlet_fn kelvinlet,
+ float r_disp[3],
+ const float vertex_co[3],
+ const float location[3],
+ const float normal[3],
+ const KelvinletParams *p)
+{
+ float k[4][3], k_it[4][3];
+ kelvinlet(k[0], vertex_co, location, normal, p);
+ copy_v3_v3(k_it[0], k[0]);
+ mul_v3_fl(k_it[0], 0.5f);
+ add_v3_v3v3(k_it[0], vertex_co, k_it[0]);
+ kelvinlet(k[1], k_it[0], location, normal, p);
+ copy_v3_v3(k_it[1], k[1]);
+ mul_v3_fl(k_it[1], 0.5f);
+ add_v3_v3v3(k_it[1], vertex_co, k_it[1]);
+ kelvinlet(k[2], k_it[1], location, normal, p);
+ copy_v3_v3(k_it[2], k[2]);
+ add_v3_v3v3(k_it[2], vertex_co, k_it[2]);
+ sub_v3_v3v3(k_it[2], k_it[2], location);
+ kelvinlet(k[3], k_it[2], location, normal, p);
+ copy_v3_v3(r_disp, k[0]);
+ madd_v3_v3fl(r_disp, k[1], 2.0f);
+ madd_v3_v3fl(r_disp, k[2], 2.0f);
+ add_v3_v3(r_disp, k[3]);
+ mul_v3_fl(r_disp, 1.0f / 6.0f);
+}
+
+/* Regularized Kelvinlets: Formula (16) */
+static void kelvinlet_scale(float disp[3],
+ const float vertex_co[3],
+ const float location[3],
+ const float UNUSED(normal[3]),
+ const KelvinletParams *p)
+{
+ float radius_vertex[3];
+ sub_v3_v3v3(radius_vertex, vertex_co, location);
+ const float radius = len_v3(radius_vertex);
+ const float radius_e = sqrtf(pow2f(radius) + pow2f(p->radius_scaled[0]));
+ const float u = (2.0f * p->b - p->a) * ((1.0f / pow3f(radius_e))) +
+ ((3.0f * pow2f(p->radius_scaled[0])) / (2.0f * pow5f(radius_e)));
+ const float fade = u * p->c;
+ mul_v3_v3fl(disp, radius_vertex, fade * p->f);
+}
+
+void BKE_kelvinlet_scale(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float surface_normal[3])
+{
+ sculpt_kelvinet_integrate(
+ kelvinlet_scale, radius_elem_disp, elem_orig_co, brush_location, surface_normal, params);
+}
+
+/* Regularized Kelvinlets: Formula (15) */
+static void kelvinlet_twist(float disp[3],
+ const float vertex_co[3],
+ const float location[3],
+ const float normal[3],
+ const KelvinletParams *p)
+{
+ float radius_vertex[3], q_r[3];
+ sub_v3_v3v3(radius_vertex, vertex_co, location);
+ const float radius = len_v3(radius_vertex);
+ const float radius_e = sqrtf(pow2f(radius) + pow2f(p->radius_scaled[0]));
+ const float u = -p->a * ((1.0f / pow3f(radius_e))) +
+ ((3.0f * pow2f(p->radius_scaled[0])) / (2.0f * pow5f(radius_e)));
+ const float fade = u * p->c;
+ cross_v3_v3v3(q_r, normal, radius_vertex);
+ mul_v3_v3fl(disp, q_r, fade * p->f);
+}
+
+void BKE_kelvinlet_twist(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float surface_normal[3])
+{
+ sculpt_kelvinet_integrate(
+ kelvinlet_twist, radius_elem_disp, elem_orig_co, brush_location, surface_normal, params);
+}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 73c278a0ab6..54432c8da74 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -598,6 +598,11 @@ Material *BKE_material_gpencil_get(Object *ob, short act)
}
}
+struct Material *BKE_material_gpencil_default_get(void)
+{
+ return &defgpencil_material;
+}
+
MaterialGPencilStyle *BKE_material_gpencil_settings_get(Object *ob, short act)
{
Material *ma = give_current_material(ob, act);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 46ef24be5e9..e7c20ca4fb2 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -655,19 +655,19 @@ bool BKE_paint_select_elem_test(Object *ob)
void BKE_paint_cavity_curve_preset(Paint *p, int preset)
{
- CurveMap *cm = NULL;
+ CurveMapping *cumap = NULL;
+ CurveMap *cuma = NULL;
if (!p->cavity_curve) {
p->cavity_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
}
+ cumap = p->cavity_curve;
+ cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ cumap->preset = preset;
- cm = p->cavity_curve->cm;
- cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
-
- p->cavity_curve->preset = preset;
- BKE_curvemap_reset(
- cm, &p->cavity_curve->clipr, p->cavity_curve->preset, CURVEMAP_SLOPE_POSITIVE);
- BKE_curvemapping_changed(p->cavity_curve, false);
+ cuma = cumap->cm;
+ BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
+ BKE_curvemapping_changed(cumap, false);
}
eObjectMode BKE_paint_object_mode_from_paintmode(ePaintMode mode)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 9dcebbba56e..ab72b7d3b0d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1284,6 +1284,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
mesh,
(&(struct BMeshToMeshParams){
.calc_object_remap = true,
+ .update_shapekey_indices = true,
}));
DEG_id_tag_update(&mesh->id, 0);
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index f4e89160487..b1ae71c609f 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -558,7 +558,7 @@ void BKE_texture_pointdensity_init_data(PointDensity *pd)
pd->falloff_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
pd->falloff_curve->preset = CURVE_PRESET_LINE;
- pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ pd->falloff_curve->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemap_reset(pd->falloff_curve->cm,
&pd->falloff_curve->clipr,
pd->falloff_curve->preset,
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index dd2b182474e..3e449fa6b25 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -26,6 +26,7 @@
#include "BLI_string_utils.h"
#include "BLI_listbase.h"
+#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -202,8 +203,10 @@ WorkSpaceInstanceHook *BKE_workspace_instance_hook_create(const Main *bmain)
}
void BKE_workspace_instance_hook_free(const Main *bmain, WorkSpaceInstanceHook *hook)
{
- /* workspaces should never be freed before wm (during which we call this function) */
- BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces));
+ /* workspaces should never be freed before wm (during which we call this function).
+ * However, when running in background mode, loading a blend file may allocate windows (that need
+ * to be freed) without creating workspaces. This happens in BlendfileLoadingBaseTest. */
+ BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces) || G.background);
/* Free relations for this hook */
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 4c86b9d3396..85c6425bb2f 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -58,6 +58,10 @@ MINLINE float pow4f(float x)
{
return pow2f(pow2f(x));
}
+MINLINE float pow5f(float x)
+{
+ return pow4f(x) * x;
+}
MINLINE float pow7f(float x)
{
return pow2f(pow3f(x)) * x;
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 0cb68cfd7fe..6c8b14ad5c7 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -37,10 +37,14 @@
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curveprofile_types.h"
+#include "DNA_freestyle_types.h"
#include "DNA_gpu_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_gpencil_modifier_types.h"
#include "DNA_light_types.h"
#include "DNA_layer_types.h"
#include "DNA_lightprobe_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -50,12 +54,12 @@
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "DNA_genfile.h"
-#include "DNA_gpencil_types.h"
#include "DNA_workspace_types.h"
#include "DNA_key_types.h"
#include "DNA_curve_types.h"
#include "DNA_armature_types.h"
#include "DNA_text_types.h"
+#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BKE_animsys.h"
@@ -861,6 +865,232 @@ static void do_versions_local_collection_bits_set(LayerCollection *layer_collect
}
}
+static void do_version_curvemapping_flag_extend_extrapolate(CurveMapping *cumap)
+{
+#define CUMA_EXTEND_EXTRAPOLATE_OLD 1
+ for (int curve_map_index = 0; curve_map_index < 4; curve_map_index++) {
+ CurveMap *cuma = &cumap->cm[curve_map_index];
+ if (cuma->flag & CUMA_EXTEND_EXTRAPOLATE_OLD) {
+ cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
+ return;
+ }
+ }
+#undef CUMA_EXTEND_EXTRAPOLATE_OLD
+}
+
+/* Util version to walk over all CurveMappings in the given `bmain` */
+static void do_version_curvemapping_walker(Main *bmain, void (*callback)(CurveMapping *cumap))
+{
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ callback(&scene->r.mblur_shutter_curve);
+
+ if (scene->view_settings.curve_mapping) {
+ callback(scene->view_settings.curve_mapping);
+ }
+
+ if (scene->ed != NULL) {
+ LISTBASE_FOREACH (Sequence *, seq, &scene->ed->seqbase) {
+ LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
+ const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+
+ if (smti) {
+ if (smd->type == seqModifierType_Curves) {
+ CurvesModifierData *cmd = (CurvesModifierData *)smd;
+ callback(&cmd->curve_mapping);
+ }
+ else if (smd->type == seqModifierType_HueCorrect) {
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
+ callback(&hcmd->curve_mapping);
+ }
+ }
+ }
+ }
+ }
+
+ // toolsettings
+ ToolSettings *ts = scene->toolsettings;
+ if (ts->vpaint) {
+ callback(ts->vpaint->paint.cavity_curve);
+ }
+ if (ts->wpaint) {
+ callback(ts->wpaint->paint.cavity_curve);
+ }
+ if (ts->sculpt) {
+ callback(ts->sculpt->paint.cavity_curve);
+ }
+ if (ts->uvsculpt) {
+ callback(ts->uvsculpt->paint.cavity_curve);
+ }
+ if (ts->gp_paint) {
+ callback(ts->gp_paint->paint.cavity_curve);
+ }
+ if (ts->gp_interpolate.custom_ipo) {
+ callback(ts->gp_interpolate.custom_ipo);
+ }
+ if (ts->gp_sculpt.cur_falloff) {
+ callback(ts->gp_sculpt.cur_falloff);
+ }
+ if (ts->gp_sculpt.cur_primitive) {
+ callback(ts->gp_sculpt.cur_primitive);
+ }
+ callback(ts->imapaint.paint.cavity_curve);
+ }
+
+ FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
+ LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
+ if (ELEM(node->type,
+ SH_NODE_CURVE_VEC,
+ SH_NODE_CURVE_RGB,
+ CMP_NODE_CURVE_VEC,
+ CMP_NODE_CURVE_RGB,
+ CMP_NODE_TIME,
+ CMP_NODE_HUECORRECT,
+ TEX_NODE_CURVE_RGB,
+ TEX_NODE_CURVE_TIME)) {
+ callback((CurveMapping *)node->storage);
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+
+ LISTBASE_FOREACH (Light *, light, &bmain->lights) {
+ if (light->curfalloff) {
+ callback(light->curfalloff);
+ }
+ }
+
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ if (brush->curve) {
+ callback(brush->curve);
+ }
+ if (brush->gpencil_settings) {
+ if (brush->gpencil_settings->curve_sensitivity) {
+ callback(brush->gpencil_settings->curve_sensitivity);
+ }
+ if (brush->gpencil_settings->curve_strength) {
+ callback(brush->gpencil_settings->curve_strength);
+ }
+ if (brush->gpencil_settings->curve_jitter) {
+ callback(brush->gpencil_settings->curve_jitter);
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (ParticleSettings *, part, &bmain->particles) {
+ if (part->clumpcurve) {
+ callback(part->clumpcurve);
+ }
+ if (part->roughcurve) {
+ callback(part->roughcurve);
+ }
+ if (part->twistcurve) {
+ callback(part->twistcurve);
+ }
+ }
+
+ /* Object */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ /* Object modifiers */
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+ if (md->type == eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData *)md;
+
+ if (hmd->curfalloff) {
+ callback(hmd->curfalloff);
+ }
+ }
+ else if (md->type == eModifierType_Warp) {
+ WarpModifierData *tmd = (WarpModifierData *)md;
+ if (tmd->curfalloff) {
+ callback(tmd->curfalloff);
+ }
+ }
+ else if (md->type == eModifierType_WeightVGEdit) {
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
+
+ if (wmd->cmap_curve) {
+ callback(wmd->cmap_curve);
+ }
+ }
+ }
+ /* Grease pencil modifiers */
+ LISTBASE_FOREACH (ModifierData *, md, &ob->greasepencil_modifiers) {
+ if (md->type == eGpencilModifierType_Thick) {
+ ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
+
+ if (gpmd->curve_thickness) {
+ callback(gpmd->curve_thickness);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Hook) {
+ HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md;
+
+ if (gpmd->curfalloff) {
+ callback(gpmd->curfalloff);
+ }
+ }
+ }
+ }
+
+ /* Free Style */
+ LISTBASE_FOREACH (struct FreestyleLineStyle *, linestyle, &bmain->linestyles) {
+ LISTBASE_FOREACH (LineStyleModifier *, m, &linestyle->thickness_modifiers) {
+ switch (m->type) {
+ case LS_MODIFIER_ALONG_STROKE:
+ callback(((LineStyleAlphaModifier_AlongStroke *)m)->curve);
+ break;
+ case LS_MODIFIER_DISTANCE_FROM_CAMERA:
+ callback(((LineStyleAlphaModifier_DistanceFromCamera *)m)->curve);
+ break;
+ case LS_MODIFIER_DISTANCE_FROM_OBJECT:
+ callback(((LineStyleAlphaModifier_DistanceFromObject *)m)->curve);
+ break;
+ case LS_MODIFIER_MATERIAL:
+ callback(((LineStyleAlphaModifier_Material *)m)->curve);
+ break;
+ case LS_MODIFIER_TANGENT:
+ callback(((LineStyleAlphaModifier_Tangent *)m)->curve);
+ break;
+ case LS_MODIFIER_NOISE:
+ callback(((LineStyleAlphaModifier_Noise *)m)->curve);
+ break;
+ case LS_MODIFIER_CREASE_ANGLE:
+ callback(((LineStyleAlphaModifier_CreaseAngle *)m)->curve);
+ break;
+ case LS_MODIFIER_CURVATURE_3D:
+ callback(((LineStyleAlphaModifier_Curvature_3D *)m)->curve);
+ break;
+ }
+ }
+
+ LISTBASE_FOREACH (LineStyleModifier *, m, &linestyle->thickness_modifiers) {
+ switch (m->type) {
+ case LS_MODIFIER_ALONG_STROKE:
+ callback(((LineStyleThicknessModifier_AlongStroke *)m)->curve);
+ break;
+ case LS_MODIFIER_DISTANCE_FROM_CAMERA:
+ callback(((LineStyleThicknessModifier_DistanceFromCamera *)m)->curve);
+ break;
+ case LS_MODIFIER_DISTANCE_FROM_OBJECT:
+ callback(((LineStyleThicknessModifier_DistanceFromObject *)m)->curve);
+ break;
+ case LS_MODIFIER_MATERIAL:
+ callback(((LineStyleThicknessModifier_Material *)m)->curve);
+ break;
+ case LS_MODIFIER_TANGENT:
+ callback(((LineStyleThicknessModifier_Tangent *)m)->curve);
+ break;
+ case LS_MODIFIER_CREASE_ANGLE:
+ callback(((LineStyleThicknessModifier_CreaseAngle *)m)->curve);
+ break;
+ case LS_MODIFIER_CURVATURE_3D:
+ callback(((LineStyleThicknessModifier_Curvature_3D *)m)->curve);
+ break;
+ }
+ }
+ }
+}
+
void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
{
bool use_collection_compat_28 = true;
@@ -910,11 +1140,10 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
}
}
- /* We need to assign lib pointer to generated hidden collections *after* all have been created,
- * otherwise we'll end up with several data-blocks sharing same name/library,
- * which is FORBIDDEN!
- * Note: we need this to be recursive,
- * since a child collection may be sorted before its parent in bmain. */
+ /* We need to assign lib pointer to generated hidden collections *after* all have been
+ * created, otherwise we'll end up with several data-blocks sharing same name/library,
+ * which is FORBIDDEN! Note: we need this to be recursive, since a child collection may be
+ * sorted before its parent in bmain. */
for (Collection *collection = bmain->collections.first; collection != NULL;
collection = collection->id.next) {
do_version_collection_propagate_lib_to_children(collection);
@@ -1218,7 +1447,8 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
}
if (!MAIN_VERSION_ATLEAST(bmain, 280, 38)) {
- /* Ensure we get valid rigidbody object/constraint data in relevant collections' objects. */
+ /* Ensure we get valid rigidbody object/constraint data in relevant collections' objects.
+ */
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
RigidBodyWorld *rbw = scene->rigidbody_world;
@@ -1431,7 +1661,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (error & NTREE_DOVERSION_NEED_OUTPUT) {
BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console");
printf(
- "You need to connect Principled and Eevee Specular shader nodes to new material output "
+ "You need to connect Principled and Eevee Specular shader nodes to new material "
+ "output "
"nodes.\n");
}
@@ -3163,19 +3394,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- if (!MAIN_VERSION_ATLEAST(bmain, 280, 45)) {
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
- for (ScrArea *area = screen->areabase.first; area; area = area->next) {
- for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_SEQ) {
- SpaceSeq *sseq = (SpaceSeq *)sl;
- sseq->flag |= SEQ_SHOW_MARKER_LINES;
- }
- }
- }
- }
- }
-
if (!MAIN_VERSION_ATLEAST(bmain, 280, 46)) {
/* Add wireframe color. */
if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "wire_color_type")) {
@@ -3931,8 +4149,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- {
- /* Versioning code until next subversion bump goes here. */
+ if (!MAIN_VERSION_ATLEAST(bmain, 282, 2)) {
+ do_version_curvemapping_walker(bmain, do_version_curvemapping_flag_extend_extrapolate);
+
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
sa->flag &= ~AREA_FLAG_UNUSED_6;
@@ -3972,11 +4191,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
/* Pose brush smooth iterations */
- if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "pose_smooth_itereations")) {
+ if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "pose_smooth_iterations")) {
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
br->pose_smooth_iterations = 4;
}
}
+
/* Cloth pressure */
for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
@@ -3988,4 +4208,65 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 282, 3)) {
+ /* Remove Unified pressure/size and pressure/alpha */
+ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ ToolSettings *ts = scene->toolsettings;
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->flag &= ~(UNIFIED_PAINT_FLAG_UNUSED_0 | UNIFIED_PAINT_FLAG_UNUSED_1);
+ }
+
+ /* Set the default render pass in the viewport to Combined. */
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "int", "render_pass")) {
+ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ scene->display.shading.render_pass = SCE_PASS_COMBINED;
+ }
+
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->shading.render_pass = SCE_PASS_COMBINED;
+ }
+ }
+ }
+ }
+ }
+
+ /* Make markers region visible by default. */
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ for (ScrArea *area = screen->areabase.first; area; area = area->next) {
+ for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
+ switch (sl->spacetype) {
+ case SPACE_SEQ: {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+ sseq->flag |= SEQ_SHOW_MARKERS;
+ break;
+ }
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
+ saction->flag |= SACTION_SHOW_MARKERS;
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+ sipo->flag |= SIPO_SHOW_MARKERS;
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = (SpaceNla *)sl;
+ snla->flag |= SNLA_SHOW_MARKERS;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ {
+ /* Versioning code until next subversion bump goes here. */
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index f2d6db886d3..1c88f6b00af 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -150,10 +150,9 @@ static void blo_update_defaults_screen(bScreen *screen,
}
}
else if (sa->spacetype == SPACE_ACTION) {
- /* Show marker lines, hide channels and collapse summary in timelines. */
+ /* Show markers region, hide channels and collapse summary in timelines. */
SpaceAction *saction = sa->spacedata.first;
- saction->flag |= SACTION_SHOW_MARKER_LINES;
-
+ saction->flag |= SACTION_SHOW_MARKERS;
if (saction->mode == SACTCONT_TIMELINE) {
saction->ads.flag |= ADS_FLAG_SUMMARY_COLLAPSED;
@@ -166,11 +165,15 @@ static void blo_update_defaults_screen(bScreen *screen,
}
else if (sa->spacetype == SPACE_GRAPH) {
SpaceGraph *sipo = sa->spacedata.first;
- sipo->flag |= SIPO_MARKER_LINES;
+ sipo->flag |= SIPO_SHOW_MARKERS;
}
else if (sa->spacetype == SPACE_NLA) {
SpaceNla *snla = sa->spacedata.first;
- snla->flag |= SNLA_SHOW_MARKER_LINES;
+ snla->flag |= SNLA_SHOW_MARKERS;
+ }
+ else if (sa->spacetype == SPACE_SEQ) {
+ SpaceSeq *seq = sa->spacedata.first;
+ seq->flag |= SEQ_SHOW_MARKERS;
}
else if (sa->spacetype == SPACE_TEXT) {
/* Show syntax and line numbers in Script workspace text editor. */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 9bab959f0a2..1ecbfccab74 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -91,7 +91,7 @@
#include "BKE_key.h"
#include "bmesh.h"
-#include "intern/bmesh_private.h" /* for element checking */
+#include "intern/bmesh_private.h" /* For element checking. */
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
{
@@ -202,7 +202,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
if (!me || !me->totvert) {
- if (me && is_new) { /*no verts? still copy customdata layout*/
+ if (me && is_new) { /* No verts? still copy custom-data layout. */
CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_ASSIGN, 0);
CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_ASSIGN, 0);
CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_ASSIGN, 0);
@@ -213,7 +213,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
}
- return; /* sanity check */
+ return; /* Sanity check. */
}
if (is_new) {
@@ -254,9 +254,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
if (tot_shape_keys) {
if (is_new) {
- /* check if we need to generate unique ids for the shapekeys.
- * this also exists in the file reading code, but is here for
- * a sanity check */
+ /* Check if we need to generate unique ids for the shape-keys.
+ * This also exists in the file reading code, but is here for a sanity check. */
if (!me->key->uidgen) {
fprintf(stderr,
"%s had to generate shape key uid's in a situation we shouldn't need to! "
@@ -310,10 +309,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
v = vtable[i] = BM_vert_create(bm, keyco ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
- /* transfer flag */
+ /* Transfer flag. */
v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT);
- /* this is necessary for selection counts to work properly */
+ /* This is necessary for selection counts to work properly. */
if (mvert->flag & SELECT) {
BM_vert_select_set(bm, v, true);
}
@@ -327,12 +326,12 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
}
- /* set shape key original index */
+ /* Set shape key original index. */
if (cd_shape_keyindex_offset != -1) {
BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
}
- /* set shapekey data */
+ /* Set shape-key data. */
if (tot_shape_keys) {
float(*co_dst)[3] = BM_ELEM_CD_GET_VOID_P(v, cd_shape_key_offset);
for (int j = 0; j < tot_shape_keys; j++, co_dst++) {
@@ -341,7 +340,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
}
if (is_new) {
- bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
+ bm->elem_index_dirty &= ~BM_VERT; /* Added in order, clear dirty flag. */
}
etable = MEM_mallocN(sizeof(BMEdge **) * me->totedge, __func__);
@@ -352,10 +351,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm, vtable[medge->v1], vtable[medge->v2], NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(e, i); /* set_ok */
- /* transfer flags */
+ /* Transfer flags. */
e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT);
- /* this is necessary for selection counts to work properly */
+ /* This is necessary for selection counts to work properly. */
if (medge->flag & SELECT) {
BM_edge_select_set(bm, e, true);
}
@@ -371,10 +370,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
}
if (is_new) {
- bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
+ bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */
}
- /* only needed for selection. */
+ /* Only needed for selection. */
if (me->mselect && me->totselect != 0) {
ftable = MEM_mallocN(sizeof(BMFace **) * me->totpoly, __func__);
}
@@ -400,13 +399,13 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
continue;
}
- /* don't use 'i' since we may have skipped the face */
+ /* Don't use 'i' since we may have skipped the face. */
BM_elem_index_set(f, bm->totface - 1); /* set_ok */
- /* transfer flag */
+ /* Transfer flag. */
f->head.hflag = BM_face_flag_from_mflag(mp->flag & ~ME_FACE_SEL);
- /* this is necessary for selection counts to work properly */
+ /* This is necessary for selection counts to work properly. */
if (mp->flag & ME_FACE_SEL) {
BM_face_select_set(bm, f, true);
}
@@ -419,7 +418,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
int j = mp->loopstart;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- /* don't use 'j' since we may have skipped some faces, hence some loops. */
+ /* Don't use 'j' since we may have skipped some faces, hence some loops. */
BM_elem_index_set(l_iter, totloops++); /* set_ok */
/* Save index of corresponding #MLoop. */
@@ -434,7 +433,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
}
if (is_new) {
- bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* added in order, clear dirty flag */
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* Added in order, clear dirty flag. */
}
/* -------------------------------------------------------------------- */
@@ -489,7 +488,7 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
int i = 0;
BMIter iter;
- /* caller needs to ensure this */
+ /* Caller needs to ensure this. */
BLI_assert(ototvert > 0);
vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap");
@@ -497,7 +496,7 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
if ((keyi != ORIGINDEX_NONE) && (keyi < ototvert) &&
- /* not fool-proof, but chances are if we have many verts with the same index,
+ /* Not fool-proof, but chances are if we have many verts with the same index,
* we will want to use the first one,
* since the second is more likely to be a duplicate. */
(vertMap[keyi] == NULL)) {
@@ -520,8 +519,9 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
}
/**
- * returns customdata shapekey index from a keyblock or -1
- * \note could split this out into a more generic function */
+ * Returns custom-data shapekey index from a keyblock or -1
+ * \note could split this out into a more generic function.
+ */
static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey)
{
int i;
@@ -540,12 +540,12 @@ static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey)
BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
{
- /* this is a cheap way to set the edge draw, its not precise and will
+ /* This is a cheap way to set the edge draw, its not precise and will
* pick the first 2 faces an edge uses.
* The dot comparison is a little arbitrary, but set so that a 5 subd
- * IcoSphere won't vanish but subd 6 will (as with pre-bmesh blender) */
+ * IcoSphere won't vanish but subd 6 will (as with pre-bmesh Blender). */
- if (/* (med->flag & ME_EDGEDRAW) && */ /* assume to be true */
+ if (/* (med->flag & ME_EDGEDRAW) && */ /* Assume to be true. */
(e->l && (e->l != e->l->radial_next)) &&
(dot_v3v3(e->l->f->no, e->l->radial_next->f->no) > 0.9995f)) {
med->flag &= ~ME_EDGEDRAW;
@@ -561,73 +561,49 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
*/
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
- MLoop *mloop;
- MPoly *mpoly;
- MVert *mvert, *oldverts;
- MEdge *med, *medge;
+ MEdge *med;
BMVert *v, *eve;
BMEdge *e;
BMFace *f;
BMIter iter;
- int i, j, ototvert;
+ int i, j;
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+ const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
- ototvert = me->totvert;
-
- /* new vertex block */
- if (bm->totvert == 0) {
- mvert = NULL;
- }
- else {
- mvert = MEM_callocN(bm->totvert * sizeof(MVert), "loadeditbMesh vert");
- }
-
- /* new edge block */
- if (bm->totedge == 0) {
- medge = NULL;
- }
- else {
- medge = MEM_callocN(bm->totedge * sizeof(MEdge), "loadeditbMesh edge");
- }
+ MVert *oldverts = NULL;
+ const int ototvert = me->totvert;
- /* new ngon face block */
- if (bm->totface == 0) {
- mpoly = NULL;
- }
- else {
- mpoly = MEM_callocN(bm->totface * sizeof(MPoly), "loadeditbMesh poly");
- }
+ if (me->key && (cd_shape_keyindex_offset != -1)) {
+ /* Keep the old verts in case we are working on* a key, which is done at the end. */
- /* new loop block */
- if (bm->totloop == 0) {
- mloop = NULL;
- }
- else {
- mloop = MEM_callocN(bm->totloop * sizeof(MLoop), "loadeditbMesh loop");
- }
-
- /* lets save the old verts just in case we are actually working on
- * a key ... we now do processing of the keys at the end */
+ /* Use the array in-place instead of duplicating the array. */
+#if 0
oldverts = MEM_dupallocN(me->mvert);
+#else
+ oldverts = me->mvert;
+ me->mvert = NULL;
+ CustomData_update_typemap(&me->vdata);
+ CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
+#endif
+ }
- /* free custom data */
+ /* Free custom data. */
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
CustomData_free(&me->ldata, me->totloop);
CustomData_free(&me->pdata, me->totpoly);
- /* add new custom data */
+ /* Add new custom data. */
me->totvert = bm->totvert;
me->totedge = bm->totedge;
me->totloop = bm->totloop;
me->totpoly = bm->totface;
- /* will be overwritten with a valid value if 'dotess' is set, otherwise we
- * end up with 'me->totface' and me->mface == NULL which can crash [#28625]
- */
+ /* Will be overwritten with a valid value if 'dotess' is set, otherwise we
+ * end up with 'me->totface' and me->mface == NULL which can crash T28625. */
me->totface = 0;
me->act_face = -1;
@@ -640,6 +616,11 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
}
+ MVert *mvert = bm->totvert ? MEM_callocN(sizeof(MVert) * bm->totvert, "bm_to_me.vert") : NULL;
+ MEdge *medge = bm->totedge ? MEM_callocN(sizeof(MEdge) * bm->totedge, "bm_to_me.edge") : NULL;
+ MLoop *mloop = bm->totloop ? MEM_callocN(sizeof(MLoop) * bm->totloop, "bm_to_me.loop") : NULL;
+ MPoly *mpoly = bm->totface ? MEM_callocN(sizeof(MPoly) * bm->totface, "bm_to_me.poly") : NULL;
+
CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
@@ -647,7 +628,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
- /* this is called again, 'dotess' arg is used there */
+ /* This is called again, 'dotess' arg is used there. */
BKE_mesh_update_customdata_pointers(me, 0);
i = 0;
@@ -659,7 +640,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_elem_index_set(v, i); /* set_inline */
- /* copy over customdat */
+ /* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
if (cd_vert_bweight_offset != -1) {
@@ -683,7 +664,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_elem_index_set(e, i); /* set_inline */
- /* copy over customdata */
+ /* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
bmesh_quick_edgedraw_flag(med, e);
@@ -715,7 +696,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
mloop->e = BM_elem_index_get(l_iter->e);
mloop->v = BM_elem_index_get(l_iter->v);
- /* copy over customdata */
+ /* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
j++;
@@ -729,7 +710,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
me->act_face = i;
}
- /* copy over customdata */
+ /* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
i++;
@@ -737,7 +718,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_CHECK_ELEMENT(f);
}
- /* patch hook indices and vertex parents */
+ /* Patch hook indices and vertex parents. */
if (params->calc_object_remap && (ototvert > 0)) {
BLI_assert(bmain != NULL);
Object *ob;
@@ -829,19 +810,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
}
- /* see comment below, this logic is in twice */
+ /* See comment below, this logic is in twice. */
if (me->key) {
- const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
-
KeyBlock *currkey;
KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1);
float(*ofs)[3] = NULL;
- /* go through and find any shapekey customdata layers
- * that might not have corresponding KeyBlocks, and add them if
- * necessary */
+ /* Go through and find any shape-key custom-data layers
+ * that might not have corresponding KeyBlocks, and add them if necessary. */
j = 0;
for (i = 0; i < bm->vdata.totlayer; i++) {
if (bm->vdata.layers[i].type != CD_SHAPEKEY) {
@@ -862,30 +840,39 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
j++;
}
- /* editing the base key should update others */
- if ((me->key->type == KEY_RELATIVE) && /* only need offsets for relative shape keys */
- (actkey != NULL) && /* unlikely, but the active key may not be valid if the
- * bmesh and the mesh are out of sync */
- (oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */
- {
+ /* Editing the base key should update others. */
+ if (/* Only need offsets for relative shape keys. */
+ (me->key->type == KEY_RELATIVE) &&
+
+ /* Unlikely, but the active key may not be valid if the
+ * BMesh and the mesh are out of sync. */
+ (actkey != NULL) &&
+
+ /* Not used here, but 'oldverts' is used later for applying 'ofs'. */
+ (oldverts != NULL) &&
+
+ /* Needed for referencing oldverts. */
+ (cd_shape_keyindex_offset != -1)) {
+
const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1);
- /* active key is a base */
- if (act_is_basis && (cd_shape_keyindex_offset != -1)) {
- float(*fp)[3] = actkey->data;
+ /* Active key is a base. */
+ if (act_is_basis) {
+ const float(*fp)[3] = actkey->data;
ofs = MEM_callocN(sizeof(float) * 3 * bm->totvert, "currkey->data");
mvert = me->mvert;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
- if (keyi != ORIGINDEX_NONE) {
+ /* Could use 'eve->co' or 'mvert->co', they're the same at this point. */
+ if (keyi != ORIGINDEX_NONE && keyi < actkey->totelem) {
sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]);
}
else {
- /* if there are new vertices in the mesh, we can't propagate the offset
+ /* If there are new vertices in the mesh, we can't propagate the offset
* because it will only work for the existing vertices and not the new
- * ones, creating a mess when doing e.g. subdivide + translate */
+ * ones, creating a mess when doing e.g. subdivide + translate. */
MEM_freeN(ofs);
ofs = NULL;
break;
@@ -901,7 +888,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
(bm->shapenr - 1 == currkey->relative));
int cd_shape_offset;
int keyi;
- float(*ofs_pt)[3] = ofs;
+ const float(*ofs_pt)[3] = ofs;
float *newkey, (*oldkey)[3], *fp;
j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
@@ -916,11 +903,11 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (currkey == actkey) {
copy_v3_v3(fp, eve->co);
- if (actkey != me->key->refkey) { /* important see bug [#30771] */
+ if (actkey != me->key->refkey) { /* Important see bug T30771. */
if (cd_shape_keyindex_offset != -1) {
if (oldverts) {
keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
- if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* valid old vertex */
+ if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* Valid old vertex. */
copy_v3_v3(mvert->co, oldverts[keyi].co);
}
}
@@ -928,29 +915,29 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
}
else if (j != -1) {
- /* in most cases this runs */
+ /* In most cases this runs. */
copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset));
}
else if ((oldkey != NULL) && (cd_shape_keyindex_offset != -1) &&
((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) &&
(keyi < currkey->totelem)) {
- /* old method of reconstructing keys via vertice's original key indices,
- * currently used if the new method above fails (which is theoretically
- * possible in certain cases of undo) */
+ /* Old method of reconstructing keys via vertice's original key indices,
+ * currently used if the new method above fails
+ * (which is theoretically possible in certain cases of undo). */
copy_v3_v3(fp, oldkey[keyi]);
}
else {
- /* fail! fill in with dummy value */
+ /* Fail! fill in with dummy value. */
copy_v3_v3(fp, mvert->co);
}
- /* propagate edited basis offsets to other shapes */
+ /* Propagate edited basis offsets to other shapes. */
if (apply_offset) {
add_v3_v3(fp, *ofs_pt++);
- /* Apply back new coordinates of offsetted shapekeys into BMesh.
+ /* Apply back new coordinates of offsetted shape-keys into BMesh.
* Otherwise, in case we call again BM_mesh_bm_to_me on same BMesh,
* we'll apply diff from previous call to BM_mesh_bm_to_me,
- * to shapekey values from *original creation of the BMesh*. See T50524. */
+ * to shape-key values from *original creation of the BMesh*. See T50524. */
copy_v3_v3(BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset), fp);
}
@@ -970,14 +957,25 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
}
+ /* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */
+ if (params->update_shapekey_indices) {
+ /* We have written a new shape key, if this mesh is _not_ going to be freed,
+ * update the shape key indices to match the newly updated. */
+ if (cd_shape_keyindex_offset != -1) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ BM_ELEM_CD_SET_INT(eve, cd_shape_keyindex_offset, i);
+ }
+ }
+ }
+
if (oldverts != NULL) {
MEM_freeN(oldverts);
}
- /* topology could be changed, ensure mdisps are ok */
+ /* Topology could be changed, ensure mdisps are ok. */
multires_topology_changed(me);
- /* to be removed as soon as COW is enabled by default. */
+ /* To be removed as soon as COW is enabled by default.. */
BKE_mesh_runtime_clear_geometry(me);
}
@@ -1000,7 +998,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
*/
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
{
- /* must be an empty mesh. */
+ /* Must be an empty mesh. */
BLI_assert(me->totvert == 0);
BLI_assert(cd_mask_extra == NULL || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0);
@@ -1019,8 +1017,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, bm->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, bm->totface);
- /* don't process shapekeys, we only feed them through the modifier stack as needed,
- * e.g. for applying modifiers or the like*/
+ /* Don't process shape-keys, we only feed them through the modifier stack as needed,
+ * e.g. for applying modifiers or the like. */
CustomData_MeshMasks mask = CD_MASK_DERIVEDMESH;
if (cd_mask_extra != NULL) {
CustomData_MeshMasks_update(&mask, cd_mask_extra);
@@ -1050,7 +1048,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
me->runtime.deformed_only = true;
- /* don't add origindex layer if one already exists */
+ /* Don't add origindex layer if one already exists. */
add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
index = CustomData_get_layer(&me->vdata, CD_ORIGINDEX);
@@ -1089,8 +1087,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
med->flag = BM_edge_flag_to_mflag(eed);
- /* handle this differently to editmode switching,
- * only enable draw for single user edges rather then calculating angle */
+ /* Handle this differently to editmode switching,
+ * only enable draw for single user edges rather then calculating angle. */
if ((med->flag & ME_EDGEDRAW) == 0) {
if (eed->l && eed->l == eed->l->radial_next) {
med->flag |= ME_EDGEDRAW;
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index f0302764a5f..65d5c6d5494 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -48,6 +48,16 @@ void BM_mesh_bm_from_me(BMesh *bm, const struct Mesh *me, const struct BMeshFrom
struct BMeshToMeshParams {
/** Update object hook indices & vertex parents. */
uint calc_object_remap : 1;
+ /**
+ * This re-assigns shape-key indices. Only do if the BMesh will have continued use
+ * to update the mesh & shape key in the future.
+ * In the case the BMesh is freed immediately, this can be left false.
+ *
+ * This is needed when flushing changes from edit-mode into object mode,
+ * so a second flush or edit-mode exit doesn't run with indices
+ * that have become invalid from updating the shape-key, see T71865.
+ */
+ uint update_shapekey_indices : 1;
struct CustomData_MeshMasks cd_mask_extra;
};
void BM_mesh_bm_to_me(struct Main *bmain,
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 21ab148496c..4abeec19645 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -58,6 +58,15 @@ set(SRC
intern/eval/deg_eval.cc
intern/eval/deg_eval_copy_on_write.cc
intern/eval/deg_eval_flush.cc
+ intern/eval/deg_eval_runtime_backup.cc
+ intern/eval/deg_eval_runtime_backup_modifier.cc
+ intern/eval/deg_eval_runtime_backup_movieclip.cc
+ intern/eval/deg_eval_runtime_backup_object.cc
+ intern/eval/deg_eval_runtime_backup_pose.cc
+ intern/eval/deg_eval_runtime_backup_scene.cc
+ intern/eval/deg_eval_runtime_backup_sequence.cc
+ intern/eval/deg_eval_runtime_backup_sequencer.cc
+ intern/eval/deg_eval_runtime_backup_sound.cc
intern/eval/deg_eval_stats.cc
intern/node/deg_node.cc
intern/node/deg_node_component.cc
@@ -98,6 +107,15 @@ set(SRC
intern/eval/deg_eval.h
intern/eval/deg_eval_copy_on_write.h
intern/eval/deg_eval_flush.h
+ intern/eval/deg_eval_runtime_backup.h
+ intern/eval/deg_eval_runtime_backup_modifier.h
+ intern/eval/deg_eval_runtime_backup_movieclip.h
+ intern/eval/deg_eval_runtime_backup_object.h
+ intern/eval/deg_eval_runtime_backup_pose.h
+ intern/eval/deg_eval_runtime_backup_scene.h
+ intern/eval/deg_eval_runtime_backup_sequence.h
+ intern/eval/deg_eval_runtime_backup_sequencer.h
+ intern/eval/deg_eval_runtime_backup_sound.h
intern/eval/deg_eval_stats.h
intern/node/deg_node.h
intern/node/deg_node_component.h
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 8a33453b923..3a2cf35f4d5 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -21,7 +21,7 @@
* \ingroup depsgraph
*/
-/* Enable special; trickery to treat nested owned IDs (such as nodetree of
+/* Enable special trickery to treat nested owned IDs (such as nodetree of
* material) to be handled in same way as "real" data-blocks, even tho some
* internal BKE routines doesn't treat them like that.
*
@@ -95,6 +95,7 @@ extern "C" {
#include "intern/depsgraph.h"
#include "intern/builder/deg_builder.h"
#include "intern/builder/deg_builder_nodes.h"
+#include "intern/eval/deg_eval_runtime_backup.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_id.h"
@@ -945,545 +946,6 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
return deg_expand_copy_on_write_datablock(depsgraph, id_node, node_builder, create_placeholders);
}
-namespace {
-
-/* Backup of sequencer strips runtime data. */
-
-/* Backup of a single strip. */
-class SequenceBackup {
- public:
- SequenceBackup()
- {
- reset();
- }
-
- inline void reset()
- {
- scene_sound = NULL;
- }
-
- void init_from_sequence(Sequence *sequence)
- {
- scene_sound = sequence->scene_sound;
-
- sequence->scene_sound = NULL;
- }
-
- void restore_to_sequence(Sequence *sequence)
- {
- sequence->scene_sound = scene_sound;
- reset();
- }
-
- inline bool isEmpty() const
- {
- return (scene_sound == NULL);
- }
-
- void *scene_sound;
-};
-
-class SequencerBackup {
- public:
- SequencerBackup();
-
- void init_from_scene(Scene *scene);
- void restore_to_scene(Scene *scene);
-
- typedef map<Sequence *, SequenceBackup> SequencesBackupMap;
- SequencesBackupMap sequences_backup;
-};
-
-SequencerBackup::SequencerBackup()
-{
-}
-
-void SequencerBackup::init_from_scene(Scene *scene)
-{
- Sequence *sequence;
- SEQ_BEGIN (scene->ed, sequence) {
- SequenceBackup sequence_backup;
- sequence_backup.init_from_sequence(sequence);
- if (!sequence_backup.isEmpty()) {
- sequences_backup.insert(make_pair(sequence->orig_sequence, sequence_backup));
- }
- }
- SEQ_END;
-}
-
-void SequencerBackup::restore_to_scene(Scene *scene)
-{
- Sequence *sequence;
- SEQ_BEGIN (scene->ed, sequence) {
- SequencesBackupMap::iterator it = sequences_backup.find(sequence->orig_sequence);
- if (it == sequences_backup.end()) {
- continue;
- }
- SequenceBackup &sequence_backup = it->second;
- sequence_backup.restore_to_sequence(sequence);
- }
- SEQ_END;
- /* Cleanup audio while the scene is still known. */
- for (SequencesBackupMap::value_type &it : sequences_backup) {
- SequenceBackup &sequence_backup = it.second;
- if (sequence_backup.scene_sound != NULL) {
- BKE_sound_remove_scene_sound(scene, sequence_backup.scene_sound);
- }
- }
-}
-
-/* Backup of scene runtime data. */
-
-class SceneBackup {
- public:
- SceneBackup();
-
- void reset();
-
- void init_from_scene(Scene *scene);
- void restore_to_scene(Scene *scene);
-
- /* Sound/audio related pointers of the scene itself.
- *
- * NOTE: Scene can not disappear after relations update, because otherwise the entire dependency
- * graph will be gone. This means we don't need to compare original scene pointer, or worry about
- * freeing those if they cant' be restored: we just copy them over to a new scene. */
- void *sound_scene;
- void *playback_handle;
- void *sound_scrub_handle;
- void *speaker_handles;
- float rigidbody_last_time;
-
- SequencerBackup sequencer_backup;
-};
-
-SceneBackup::SceneBackup()
-{
- reset();
-}
-
-void SceneBackup::reset()
-{
- sound_scene = NULL;
- playback_handle = NULL;
- sound_scrub_handle = NULL;
- speaker_handles = NULL;
- rigidbody_last_time = -1;
-}
-
-void SceneBackup::init_from_scene(Scene *scene)
-{
- sound_scene = scene->sound_scene;
- playback_handle = scene->playback_handle;
- sound_scrub_handle = scene->sound_scrub_handle;
- speaker_handles = scene->speaker_handles;
-
- if (scene->rigidbody_world != NULL) {
- rigidbody_last_time = scene->rigidbody_world->ltime;
- }
-
- /* Clear pointers stored in the scene, so they are not freed when copied-on-written datablock
- * is freed for re-allocation. */
- scene->sound_scene = NULL;
- scene->playback_handle = NULL;
- scene->sound_scrub_handle = NULL;
- scene->speaker_handles = NULL;
-
- sequencer_backup.init_from_scene(scene);
-}
-
-void SceneBackup::restore_to_scene(Scene *scene)
-{
- scene->sound_scene = sound_scene;
- scene->playback_handle = playback_handle;
- scene->sound_scrub_handle = sound_scrub_handle;
- scene->speaker_handles = speaker_handles;
-
- if (scene->rigidbody_world != NULL) {
- scene->rigidbody_world->ltime = rigidbody_last_time;
- }
-
- sequencer_backup.restore_to_scene(scene);
-
- reset();
-}
-
-/* Backup of sound datablocks runtime data. */
-
-class SoundBackup {
- public:
- SoundBackup();
-
- void reset();
-
- void init_from_sound(bSound *sound);
- void restore_to_sound(bSound *sound);
-
- void *cache;
- void *waveform;
- void *playback_handle;
-};
-
-SoundBackup::SoundBackup()
-{
- reset();
-}
-
-void SoundBackup::reset()
-{
- cache = NULL;
- waveform = NULL;
- playback_handle = NULL;
-}
-
-void SoundBackup::init_from_sound(bSound *sound)
-{
- cache = sound->cache;
- waveform = sound->waveform;
- playback_handle = sound->playback_handle;
-
- sound->cache = NULL;
- sound->waveform = NULL;
- sound->playback_handle = NULL;
-}
-
-void SoundBackup::restore_to_sound(bSound *sound)
-{
- sound->cache = cache;
- sound->waveform = waveform;
- sound->playback_handle = playback_handle;
-
- reset();
-}
-
-/* Identifier used to match modifiers to backup/restore their runtime data.
- * Identification is happening using original modifier data pointer and the
- * modifier type.
- * It is not enough to only pointer, since it's possible to have a situation
- * when modifier is removed and a new one added, and due to memory allocation
- * policy they might have same pointer.
- * By adding type into matching we are at least ensuring that modifier will not
- * try to interpret runtime data created by another modifier type. */
-class ModifierDataBackupID {
- public:
- ModifierDataBackupID() : ModifierDataBackupID(NULL, eModifierType_None)
- {
- }
-
- ModifierDataBackupID(ModifierData *modifier_data, ModifierType type)
- : modifier_data(modifier_data), type(type)
- {
- }
-
- bool operator<(const ModifierDataBackupID &other) const
- {
- if (modifier_data < other.modifier_data) {
- return true;
- }
- if (modifier_data == other.modifier_data) {
- return static_cast<int>(type) < static_cast<int>(other.type);
- }
- return false;
- }
-
- ModifierData *modifier_data;
- ModifierType type;
-};
-
-/* Storage for backed up runtime modifier data. */
-typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
-
-/* Storage for backed up pose channel runtime data. */
-typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
-
-class ObjectRuntimeBackup {
- public:
- ObjectRuntimeBackup() : base_flag(0), base_local_view_bits(0)
- {
- /* TODO(sergey): Use something like BKE_object_runtime_reset(). */
- memset(&runtime, 0, sizeof(runtime));
- }
-
- /* Make a backup of object's evaluation runtime data, additionally
- * make object to be safe for free without invalidating backed up
- * pointers. */
- void init_from_object(Object *object);
- void backup_modifier_runtime_data(Object *object);
- void backup_pose_channel_runtime_data(Object *object);
-
- /* Restore all fields to the given object. */
- void restore_to_object(Object *object);
- /* NOTE: Will free all runtime data which has not been restored. */
- void restore_modifier_runtime_data(Object *object);
- void restore_pose_channel_runtime_data(Object *object);
-
- Object_Runtime runtime;
- short base_flag;
- unsigned short base_local_view_bits;
- ModifierRuntimeDataBackup modifier_runtime_data;
- PoseChannelRuntimeDataBackup pose_channel_runtime_data;
-};
-
-void ObjectRuntimeBackup::init_from_object(Object *object)
-{
- /* Store evaluated mesh and curve_cache, and make sure we don't free it. */
- Mesh *mesh_eval = object->runtime.mesh_eval;
- runtime = object->runtime;
- BKE_object_runtime_reset(object);
- /* Keep bbox (for now at least). */
- object->runtime.bb = runtime.bb;
- /* Object update will override actual object->data to an evaluated version.
- * Need to make sure we don't have data set to evaluated one before free
- * anything. */
- if (mesh_eval != NULL && object->data == mesh_eval) {
- object->data = runtime.mesh_orig;
- }
- /* Make a backup of base flags. */
- base_flag = object->base_flag;
- base_local_view_bits = object->base_local_view_bits;
- /* Backup tuntime data of all modifiers. */
- backup_modifier_runtime_data(object);
- /* Backup runtime data of all pose channels. */
- backup_pose_channel_runtime_data(object);
-}
-
-inline ModifierDataBackupID create_modifier_data_id(const ModifierData *modifier_data)
-{
- return ModifierDataBackupID(modifier_data->orig_modifier_data,
- static_cast<ModifierType>(modifier_data->type));
-}
-
-void ObjectRuntimeBackup::backup_modifier_runtime_data(Object *object)
-{
- LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
- if (modifier_data->runtime == NULL) {
- continue;
- }
- BLI_assert(modifier_data->orig_modifier_data != NULL);
- ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
- modifier_runtime_data.insert(make_pair(modifier_data_id, modifier_data->runtime));
- modifier_data->runtime = NULL;
- }
-}
-
-void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
-{
- if (object->pose != NULL) {
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- /* This is NULL in Edit mode. */
- if (pchan->orig_pchan != NULL) {
- pose_channel_runtime_data[pchan->orig_pchan] = pchan->runtime;
- BKE_pose_channel_runtime_reset(&pchan->runtime);
- }
- }
- }
-}
-
-void ObjectRuntimeBackup::restore_to_object(Object *object)
-{
- Mesh *mesh_orig = object->runtime.mesh_orig;
- BoundBox *bb = object->runtime.bb;
- object->runtime = runtime;
- object->runtime.mesh_orig = mesh_orig;
- object->runtime.bb = bb;
- if (object->type == OB_MESH && object->runtime.mesh_eval != NULL) {
- if (object->id.recalc & ID_RECALC_GEOMETRY) {
- /* If geometry is tagged for update it means, that part of
- * evaluated mesh are not valid anymore. In this case we can not
- * have any "persistent" pointers to point to an invalid data.
- *
- * We restore object's data datablock to an original copy of
- * that datablock. */
- object->data = mesh_orig;
-
- /* After that, immediately free the invalidated caches. */
- BKE_object_free_derived_caches(object);
- }
- else {
- Mesh *mesh_eval = object->runtime.mesh_eval;
- /* Do same thing as object update: override actual object data
- * pointer with evaluated datablock. */
- object->data = mesh_eval;
- /* Evaluated mesh simply copied edit_mesh pointer from
- * original mesh during update, need to make sure no dead
- * pointers are left behind. */
- mesh_eval->edit_mesh = mesh_orig->edit_mesh;
- }
- }
- object->base_flag = base_flag;
- object->base_local_view_bits = base_local_view_bits;
- /* Restore modifier's runtime data.
- * NOTE: Data of unused modifiers will be freed there. */
- restore_modifier_runtime_data(object);
- restore_pose_channel_runtime_data(object);
-}
-
-void ObjectRuntimeBackup::restore_modifier_runtime_data(Object *object)
-{
- LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
- BLI_assert(modifier_data->orig_modifier_data != NULL);
- ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
- ModifierRuntimeDataBackup::iterator runtime_data_iterator = modifier_runtime_data.find(
- modifier_data_id);
- if (runtime_data_iterator != modifier_runtime_data.end()) {
- modifier_data->runtime = runtime_data_iterator->second;
- runtime_data_iterator->second = NULL;
- }
- }
- for (ModifierRuntimeDataBackup::value_type value : modifier_runtime_data) {
- const ModifierDataBackupID modifier_data_id = value.first;
- void *runtime = value.second;
- if (value.second == NULL) {
- continue;
- }
- const ModifierTypeInfo *modifier_type_info = modifierType_getInfo(modifier_data_id.type);
- BLI_assert(modifier_type_info != NULL);
- modifier_type_info->freeRuntimeData(runtime);
- }
-}
-
-void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
-{
- if (object->pose != NULL) {
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- /* This is NULL in Edit mode. */
- if (pchan->orig_pchan != NULL) {
- PoseChannelRuntimeDataBackup::iterator runtime_data_iterator =
- pose_channel_runtime_data.find(pchan->orig_pchan);
- if (runtime_data_iterator != pose_channel_runtime_data.end()) {
- pchan->runtime = runtime_data_iterator->second;
- pose_channel_runtime_data.erase(runtime_data_iterator);
- }
- }
- }
- }
- for (PoseChannelRuntimeDataBackup::value_type &value : pose_channel_runtime_data) {
- BKE_pose_channel_runtime_free(&value.second);
- }
-}
-
-/* Backup of movie clip runtime data. */
-
-class MovieClipBackup {
- public:
- MovieClipBackup();
-
- void reset();
-
- void init_from_movieclip(MovieClip *movieclip);
- void restore_to_movieclip(MovieClip *movieclip);
-
- struct anim *anim;
- struct MovieClipCache *cache;
-};
-
-MovieClipBackup::MovieClipBackup()
-{
- reset();
-}
-
-void MovieClipBackup::reset()
-{
- anim = NULL;
- cache = NULL;
-}
-
-void MovieClipBackup::init_from_movieclip(MovieClip *movieclip)
-{
- anim = movieclip->anim;
- cache = movieclip->cache;
- /* Clear pointers stored in the movie clip, so they are not freed when copied-on-written
- * datablock is freed for re-allocation. */
- movieclip->anim = NULL;
- movieclip->cache = NULL;
-}
-
-void MovieClipBackup::restore_to_movieclip(MovieClip *movieclip)
-{
- movieclip->anim = anim;
- movieclip->cache = cache;
-
- reset();
-}
-
-class RuntimeBackup {
- public:
- RuntimeBackup() : drawdata_ptr(NULL)
- {
- drawdata_backup.first = drawdata_backup.last = NULL;
- }
-
- /* NOTE: Will reset all runbtime fields which has been backed up to NULL. */
- void init_from_id(ID *id);
-
- /* Restore fields to the given ID. */
- void restore_to_id(ID *id);
-
- SceneBackup scene_backup;
- SoundBackup sound_backup;
- ObjectRuntimeBackup object_backup;
- DrawDataList drawdata_backup;
- DrawDataList *drawdata_ptr;
- MovieClipBackup movieclip_backup;
-};
-
-void RuntimeBackup::init_from_id(ID *id)
-{
- if (!check_datablock_expanded(id)) {
- return;
- }
- const ID_Type id_type = GS(id->name);
- switch (id_type) {
- case ID_OB:
- object_backup.init_from_object(reinterpret_cast<Object *>(id));
- break;
- case ID_SCE:
- scene_backup.init_from_scene(reinterpret_cast<Scene *>(id));
- break;
- case ID_SO:
- sound_backup.init_from_sound(reinterpret_cast<bSound *>(id));
- break;
- case ID_MC:
- movieclip_backup.init_from_movieclip(reinterpret_cast<MovieClip *>(id));
- break;
- default:
- break;
- }
- /* Note that we never free GPU draw data from here since that's not
- * safe for threading and draw data is likely to be re-used. */
- drawdata_ptr = DRW_drawdatalist_from_id(id);
- if (drawdata_ptr != NULL) {
- drawdata_backup = *drawdata_ptr;
- drawdata_ptr->first = drawdata_ptr->last = NULL;
- }
-}
-
-void RuntimeBackup::restore_to_id(ID *id)
-{
- const ID_Type id_type = GS(id->name);
- switch (id_type) {
- case ID_OB:
- object_backup.restore_to_object(reinterpret_cast<Object *>(id));
- break;
- case ID_SCE:
- scene_backup.restore_to_scene(reinterpret_cast<Scene *>(id));
- break;
- case ID_SO:
- sound_backup.restore_to_sound(reinterpret_cast<bSound *>(id));
- break;
- case ID_MC:
- movieclip_backup.restore_to_movieclip(reinterpret_cast<MovieClip *>(id));
- break;
- default:
- break;
- }
- if (drawdata_ptr != NULL) {
- *drawdata_ptr = drawdata_backup;
- }
-}
-
-} // namespace
-
ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode *id_node)
{
const ID *id_orig = id_node->id_orig;
@@ -1492,7 +954,7 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode
if (!deg_copy_on_write_is_needed(id_orig)) {
return id_cow;
}
- RuntimeBackup backup;
+ RuntimeBackup backup(depsgraph);
backup.init_from_id(id_cow);
deg_free_copy_on_write_datablock(id_cow);
deg_expand_copy_on_write_datablock(depsgraph, id_node);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
new file mode 100644
index 00000000000..88390ab412f
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
@@ -0,0 +1,101 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2017 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup.h"
+
+#include "intern/eval/deg_eval_copy_on_write.h"
+
+#include "BLI_utildefines.h"
+
+#include "DRW_engine.h"
+
+namespace DEG {
+
+RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
+ : scene_backup(depsgraph),
+ sound_backup(depsgraph),
+ object_backup(depsgraph),
+ drawdata_ptr(NULL),
+ movieclip_backup(depsgraph)
+{
+ drawdata_backup.first = drawdata_backup.last = NULL;
+}
+
+void RuntimeBackup::init_from_id(ID *id)
+{
+ if (!deg_copy_on_write_is_expanded(id)) {
+ return;
+ }
+
+ const ID_Type id_type = GS(id->name);
+ switch (id_type) {
+ case ID_OB:
+ object_backup.init_from_object(reinterpret_cast<Object *>(id));
+ break;
+ case ID_SCE:
+ scene_backup.init_from_scene(reinterpret_cast<Scene *>(id));
+ break;
+ case ID_SO:
+ sound_backup.init_from_sound(reinterpret_cast<bSound *>(id));
+ break;
+ case ID_MC:
+ movieclip_backup.init_from_movieclip(reinterpret_cast<MovieClip *>(id));
+ break;
+ default:
+ break;
+ }
+
+ /* Note that we never free GPU draw data from here since that's not
+ * safe for threading and draw data is likely to be re-used. */
+ drawdata_ptr = DRW_drawdatalist_from_id(id);
+ if (drawdata_ptr != NULL) {
+ drawdata_backup = *drawdata_ptr;
+ drawdata_ptr->first = drawdata_ptr->last = NULL;
+ }
+}
+
+void RuntimeBackup::restore_to_id(ID *id)
+{
+ const ID_Type id_type = GS(id->name);
+ switch (id_type) {
+ case ID_OB:
+ object_backup.restore_to_object(reinterpret_cast<Object *>(id));
+ break;
+ case ID_SCE:
+ scene_backup.restore_to_scene(reinterpret_cast<Scene *>(id));
+ break;
+ case ID_SO:
+ sound_backup.restore_to_sound(reinterpret_cast<bSound *>(id));
+ break;
+ case ID_MC:
+ movieclip_backup.restore_to_movieclip(reinterpret_cast<MovieClip *>(id));
+ break;
+ default:
+ break;
+ }
+ if (drawdata_ptr != NULL) {
+ *drawdata_ptr = drawdata_backup;
+ }
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
new file mode 100644
index 00000000000..31ae3164e37
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "DNA_ID.h"
+
+#include "intern/eval/deg_eval_runtime_backup_movieclip.h"
+#include "intern/eval/deg_eval_runtime_backup_object.h"
+#include "intern/eval/deg_eval_runtime_backup_scene.h"
+#include "intern/eval/deg_eval_runtime_backup_sound.h"
+
+namespace DEG {
+
+struct Depsgraph;
+
+class RuntimeBackup {
+ public:
+ explicit RuntimeBackup(const Depsgraph *depsgraph);
+
+ /* NOTE: Will reset all runtime fields which has been backed up to NULL. */
+ void init_from_id(ID *id);
+
+ /* Restore fields to the given ID. */
+ void restore_to_id(ID *id);
+
+ SceneBackup scene_backup;
+ SoundBackup sound_backup;
+ ObjectRuntimeBackup object_backup;
+ DrawDataList drawdata_backup;
+ DrawDataList *drawdata_ptr;
+ MovieClipBackup movieclip_backup;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
new file mode 100644
index 00000000000..c5744533083
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_modifier.h"
+
+namespace DEG {
+
+ModifierDataBackupID::ModifierDataBackupID(const Depsgraph * /*depsgraph*/)
+ : ModifierDataBackupID(NULL, eModifierType_None)
+{
+}
+
+ModifierDataBackupID::ModifierDataBackupID(ModifierData *modifier_data, ModifierType type)
+ : modifier_data(modifier_data), type(type)
+{
+}
+
+bool ModifierDataBackupID::operator<(const ModifierDataBackupID &other) const
+{
+ if (modifier_data < other.modifier_data) {
+ return true;
+ }
+ if (modifier_data == other.modifier_data) {
+ return static_cast<int>(type) < static_cast<int>(other.type);
+ }
+ return false;
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
new file mode 100644
index 00000000000..4b3d46126f3
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "BKE_modifier.h"
+
+#include "intern/depsgraph_type.h"
+
+struct ModifierData;
+
+namespace DEG {
+
+struct Depsgraph;
+
+/* Identifier used to match modifiers to backup/restore their runtime data.
+ * Identification is happening using original modifier data pointer and the
+ * modifier type.
+ * It is not enough to only pointer, since it's possible to have a situation
+ * when modifier is removed and a new one added, and due to memory allocation
+ * policy they might have same pointer.
+ * By adding type into matching we are at least ensuring that modifier will not
+ * try to interpret runtime data created by another modifier type. */
+class ModifierDataBackupID {
+ public:
+ ModifierDataBackupID(const Depsgraph *depsgraph);
+ ModifierDataBackupID(ModifierData *modifier_data, ModifierType type);
+
+ bool operator<(const ModifierDataBackupID &other) const;
+
+ ModifierData *modifier_data;
+ ModifierType type;
+};
+
+/* Storage for backed up runtime modifier data. */
+typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc
new file mode 100644
index 00000000000..54838475bbf
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_movieclip.h"
+
+#include "DNA_movieclip_types.h"
+
+#include "BLI_utildefines.h"
+
+namespace DEG {
+
+MovieClipBackup::MovieClipBackup(const Depsgraph * /*depsgraph*/)
+{
+ reset();
+}
+
+void MovieClipBackup::reset()
+{
+ anim = NULL;
+ cache = NULL;
+}
+
+void MovieClipBackup::init_from_movieclip(MovieClip *movieclip)
+{
+ anim = movieclip->anim;
+ cache = movieclip->cache;
+ /* Clear pointers stored in the movie clip, so they are not freed when copied-on-written
+ * datablock is freed for re-allocation. */
+ movieclip->anim = NULL;
+ movieclip->cache = NULL;
+}
+
+void MovieClipBackup::restore_to_movieclip(MovieClip *movieclip)
+{
+ movieclip->anim = anim;
+ movieclip->cache = cache;
+
+ reset();
+}
+
+} // namespace DEG
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h
index 84820c3c564..a9d528a254c 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h
@@ -13,32 +13,36 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
- * os dependent include locations of gl.h
*/
/** \file
- * \ingroup editorui
+ * \ingroup depsgraph
*/
-#ifndef __BIF_GL_H__
-#define __BIF_GL_H__
+#pragma once
-#include "GPU_glew.h"
-#include "BLI_utildefines.h"
+struct anim;
+struct MovieClip;
+struct MovieClipCache;
-/* hacking pointsize and linewidth */
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
-# define glPointSize(f) \
- glPointSize(U.pixelsize *_Generic((f), double : (float)(f), default : (f)))
-# define glLineWidth(f) \
- glLineWidth(U.pixelsize *_Generic((f), double : (float)(f), default : (f)))
-#else
-# define glPointSize(f) glPointSize(U.pixelsize *(f))
-# define glLineWidth(f) glLineWidth(U.pixelsize *(f))
-#endif /* C11 */
+namespace DEG {
-#define GLA_PIXEL_OFS 0.375f
+struct Depsgraph;
-#endif /* #ifdef __BIF_GL_H__ */
+/* Backup of movie clip runtime data. */
+class MovieClipBackup {
+ public:
+ MovieClipBackup(const Depsgraph *depsgraph);
+
+ void reset();
+
+ void init_from_movieclip(MovieClip *movieclip);
+ void restore_to_movieclip(MovieClip *movieclip);
+
+ struct anim *anim;
+ struct MovieClipCache *cache;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
new file mode 100644
index 00000000000..a6a042f3e7b
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
@@ -0,0 +1,182 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_object.h"
+
+#include <cstring>
+
+#include "DNA_mesh_types.h"
+
+#include "BLI_listbase.h"
+
+#include "BKE_action.h"
+#include "BKE_object.h"
+
+namespace DEG {
+
+ObjectRuntimeBackup::ObjectRuntimeBackup(const Depsgraph * /*depsgraph*/)
+ : base_flag(0), base_local_view_bits(0)
+{
+ /* TODO(sergey): Use something like BKE_object_runtime_reset(). */
+ memset(&runtime, 0, sizeof(runtime));
+}
+
+void ObjectRuntimeBackup::init_from_object(Object *object)
+{
+ /* Store evaluated mesh and curve_cache, and make sure we don't free it. */
+ Mesh *mesh_eval = object->runtime.mesh_eval;
+ runtime = object->runtime;
+ BKE_object_runtime_reset(object);
+ /* Keep bbox (for now at least). */
+ object->runtime.bb = runtime.bb;
+ /* Object update will override actual object->data to an evaluated version.
+ * Need to make sure we don't have data set to evaluated one before free
+ * anything. */
+ if (mesh_eval != NULL && object->data == mesh_eval) {
+ object->data = runtime.mesh_orig;
+ }
+ /* Make a backup of base flags. */
+ base_flag = object->base_flag;
+ base_local_view_bits = object->base_local_view_bits;
+ /* Backup tuntime data of all modifiers. */
+ backup_modifier_runtime_data(object);
+ /* Backup runtime data of all pose channels. */
+ backup_pose_channel_runtime_data(object);
+}
+
+inline ModifierDataBackupID create_modifier_data_id(const ModifierData *modifier_data)
+{
+ return ModifierDataBackupID(modifier_data->orig_modifier_data,
+ static_cast<ModifierType>(modifier_data->type));
+}
+
+void ObjectRuntimeBackup::backup_modifier_runtime_data(Object *object)
+{
+ LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
+ if (modifier_data->runtime == NULL) {
+ continue;
+ }
+ BLI_assert(modifier_data->orig_modifier_data != NULL);
+ ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
+ modifier_runtime_data.insert(make_pair(modifier_data_id, modifier_data->runtime));
+ modifier_data->runtime = NULL;
+ }
+}
+
+void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
+{
+ if (object->pose != NULL) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ /* This is NULL in Edit mode. */
+ if (pchan->orig_pchan != NULL) {
+ pose_channel_runtime_data[pchan->orig_pchan] = pchan->runtime;
+ BKE_pose_channel_runtime_reset(&pchan->runtime);
+ }
+ }
+ }
+}
+
+void ObjectRuntimeBackup::restore_to_object(Object *object)
+{
+ Mesh *mesh_orig = object->runtime.mesh_orig;
+ BoundBox *bb = object->runtime.bb;
+ object->runtime = runtime;
+ object->runtime.mesh_orig = mesh_orig;
+ object->runtime.bb = bb;
+ if (object->type == OB_MESH && object->runtime.mesh_eval != NULL) {
+ if (object->id.recalc & ID_RECALC_GEOMETRY) {
+ /* If geometry is tagged for update it means, that part of
+ * evaluated mesh are not valid anymore. In this case we can not
+ * have any "persistent" pointers to point to an invalid data.
+ *
+ * We restore object's data datablock to an original copy of
+ * that datablock. */
+ object->data = mesh_orig;
+
+ /* After that, immediately free the invalidated caches. */
+ BKE_object_free_derived_caches(object);
+ }
+ else {
+ Mesh *mesh_eval = object->runtime.mesh_eval;
+ /* Do same thing as object update: override actual object data
+ * pointer with evaluated datablock. */
+ object->data = mesh_eval;
+ /* Evaluated mesh simply copied edit_mesh pointer from
+ * original mesh during update, need to make sure no dead
+ * pointers are left behind. */
+ mesh_eval->edit_mesh = mesh_orig->edit_mesh;
+ }
+ }
+ object->base_flag = base_flag;
+ object->base_local_view_bits = base_local_view_bits;
+ /* Restore modifier's runtime data.
+ * NOTE: Data of unused modifiers will be freed there. */
+ restore_modifier_runtime_data(object);
+ restore_pose_channel_runtime_data(object);
+}
+
+void ObjectRuntimeBackup::restore_modifier_runtime_data(Object *object)
+{
+ LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
+ BLI_assert(modifier_data->orig_modifier_data != NULL);
+ ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
+ ModifierRuntimeDataBackup::iterator runtime_data_iterator = modifier_runtime_data.find(
+ modifier_data_id);
+ if (runtime_data_iterator != modifier_runtime_data.end()) {
+ modifier_data->runtime = runtime_data_iterator->second;
+ runtime_data_iterator->second = NULL;
+ }
+ }
+ for (ModifierRuntimeDataBackup::value_type value : modifier_runtime_data) {
+ const ModifierDataBackupID modifier_data_id = value.first;
+ void *runtime = value.second;
+ if (value.second == NULL) {
+ continue;
+ }
+ const ModifierTypeInfo *modifier_type_info = modifierType_getInfo(modifier_data_id.type);
+ BLI_assert(modifier_type_info != NULL);
+ modifier_type_info->freeRuntimeData(runtime);
+ }
+}
+
+void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
+{
+ if (object->pose != NULL) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ /* This is NULL in Edit mode. */
+ if (pchan->orig_pchan != NULL) {
+ PoseChannelRuntimeDataBackup::iterator runtime_data_iterator =
+ pose_channel_runtime_data.find(pchan->orig_pchan);
+ if (runtime_data_iterator != pose_channel_runtime_data.end()) {
+ pchan->runtime = runtime_data_iterator->second;
+ pose_channel_runtime_data.erase(runtime_data_iterator);
+ }
+ }
+ }
+ }
+ for (PoseChannelRuntimeDataBackup::value_type &value : pose_channel_runtime_data) {
+ BKE_pose_channel_runtime_free(&value.second);
+ }
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
new file mode 100644
index 00000000000..e5c3d6a967a
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
@@ -0,0 +1,59 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "DNA_object_types.h"
+
+#include "intern/eval/deg_eval_runtime_backup_modifier.h"
+#include "intern/eval/deg_eval_runtime_backup_pose.h"
+
+struct Object;
+
+namespace DEG {
+
+class ObjectRuntimeBackup {
+ public:
+ ObjectRuntimeBackup(const Depsgraph *depsgraph);
+
+ /* Make a backup of object's evaluation runtime data, additionally
+ * make object to be safe for free without invalidating backed up
+ * pointers. */
+ void init_from_object(Object *object);
+ void backup_modifier_runtime_data(Object *object);
+ void backup_pose_channel_runtime_data(Object *object);
+
+ /* Restore all fields to the given object. */
+ void restore_to_object(Object *object);
+ /* NOTE: Will free all runtime data which has not been restored. */
+ void restore_modifier_runtime_data(Object *object);
+ void restore_pose_channel_runtime_data(Object *object);
+
+ Object_Runtime runtime;
+ short base_flag;
+ unsigned short base_local_view_bits;
+ ModifierRuntimeDataBackup modifier_runtime_data;
+ PoseChannelRuntimeDataBackup pose_channel_runtime_data;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.cc
new file mode 100644
index 00000000000..821cc21f359
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.cc
@@ -0,0 +1,28 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_pose.h"
+
+namespace DEG {
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h
new file mode 100644
index 00000000000..53a2c4c0784
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h
@@ -0,0 +1,37 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "intern/depsgraph_type.h"
+
+#include "DNA_action_types.h"
+
+struct bPoseChannel;
+
+namespace DEG {
+
+/* Storage for backed up pose channel runtime data. */
+typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
new file mode 100644
index 00000000000..a288fb6ab92
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
@@ -0,0 +1,82 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_scene.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_rigidbody_types.h"
+
+namespace DEG {
+
+SceneBackup::SceneBackup(const Depsgraph *depsgraph) : sequencer_backup(depsgraph)
+{
+ reset();
+}
+
+void SceneBackup::reset()
+{
+ sound_scene = NULL;
+ playback_handle = NULL;
+ sound_scrub_handle = NULL;
+ speaker_handles = NULL;
+ rigidbody_last_time = -1;
+}
+
+void SceneBackup::init_from_scene(Scene *scene)
+{
+ sound_scene = scene->sound_scene;
+ playback_handle = scene->playback_handle;
+ sound_scrub_handle = scene->sound_scrub_handle;
+ speaker_handles = scene->speaker_handles;
+
+ if (scene->rigidbody_world != NULL) {
+ rigidbody_last_time = scene->rigidbody_world->ltime;
+ }
+
+ /* Clear pointers stored in the scene, so they are not freed when copied-on-written datablock
+ * is freed for re-allocation. */
+ scene->sound_scene = NULL;
+ scene->playback_handle = NULL;
+ scene->sound_scrub_handle = NULL;
+ scene->speaker_handles = NULL;
+
+ sequencer_backup.init_from_scene(scene);
+}
+
+void SceneBackup::restore_to_scene(Scene *scene)
+{
+ scene->sound_scene = sound_scene;
+ scene->playback_handle = playback_handle;
+ scene->sound_scrub_handle = sound_scrub_handle;
+ scene->speaker_handles = speaker_handles;
+
+ if (scene->rigidbody_world != NULL) {
+ scene->rigidbody_world->ltime = rigidbody_last_time;
+ }
+
+ sequencer_backup.restore_to_scene(scene);
+
+ reset();
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
new file mode 100644
index 00000000000..751bc4208d2
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "intern/eval/deg_eval_runtime_backup_sequencer.h"
+
+struct Scene;
+
+namespace DEG {
+
+struct Depsgraph;
+
+/* Backup of scene runtime data. */
+class SceneBackup {
+ public:
+ SceneBackup(const Depsgraph *depsgraph);
+
+ void reset();
+
+ void init_from_scene(Scene *scene);
+ void restore_to_scene(Scene *scene);
+
+ /* Sound/audio related pointers of the scene itself.
+ *
+ * NOTE: Scene can not disappear after relations update, because otherwise the entire dependency
+ * graph will be gone. This means we don't need to compare original scene pointer, or worry about
+ * freeing those if they cant' be restored: we just copy them over to a new scene. */
+ void *sound_scene;
+ void *playback_handle;
+ void *sound_scrub_handle;
+ void *speaker_handles;
+ float rigidbody_last_time;
+
+ SequencerBackup sequencer_backup;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc
new file mode 100644
index 00000000000..0150281a4ef
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_sequence.h"
+
+#include "DNA_sequence_types.h"
+
+namespace DEG {
+
+SequenceBackup::SequenceBackup(const Depsgraph * /*depsgraph*/)
+{
+ reset();
+}
+
+void SequenceBackup::reset()
+{
+ scene_sound = NULL;
+}
+
+void SequenceBackup::init_from_sequence(Sequence *sequence)
+{
+ scene_sound = sequence->scene_sound;
+
+ sequence->scene_sound = NULL;
+}
+
+void SequenceBackup::restore_to_sequence(Sequence *sequence)
+{
+ sequence->scene_sound = scene_sound;
+ reset();
+}
+
+bool SequenceBackup::isEmpty() const
+{
+ return (scene_sound == NULL);
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h
new file mode 100644
index 00000000000..8a762a2785e
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+struct Sequence;
+
+namespace DEG {
+
+struct Depsgraph;
+
+/* Backup of a single strip. */
+class SequenceBackup {
+ public:
+ SequenceBackup(const Depsgraph *depsgraph);
+
+ void reset();
+
+ void init_from_sequence(Sequence *sequence);
+ void restore_to_sequence(Sequence *sequence);
+
+ bool isEmpty() const;
+
+ void *scene_sound;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
new file mode 100644
index 00000000000..08c2697aab3
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
@@ -0,0 +1,72 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_sequencer.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
+
+#include "BKE_sequencer.h"
+#include "BKE_sound.h"
+
+namespace DEG {
+
+SequencerBackup::SequencerBackup(const Depsgraph *depsgraph) : depsgraph(depsgraph)
+{
+}
+
+void SequencerBackup::init_from_scene(Scene *scene)
+{
+ Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ SequenceBackup sequence_backup(depsgraph);
+ sequence_backup.init_from_sequence(sequence);
+ if (!sequence_backup.isEmpty()) {
+ sequences_backup.insert(make_pair(sequence->orig_sequence, sequence_backup));
+ }
+ }
+ SEQ_END;
+}
+
+void SequencerBackup::restore_to_scene(Scene *scene)
+{
+ Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ SequencesBackupMap::iterator it = sequences_backup.find(sequence->orig_sequence);
+ if (it == sequences_backup.end()) {
+ continue;
+ }
+ SequenceBackup &sequence_backup = it->second;
+ sequence_backup.restore_to_sequence(sequence);
+ }
+ SEQ_END;
+ /* Cleanup audio while the scene is still known. */
+ for (SequencesBackupMap::value_type &it : sequences_backup) {
+ SequenceBackup &sequence_backup = it.second;
+ if (sequence_backup.scene_sound != NULL) {
+ BKE_sound_remove_scene_sound(scene, sequence_backup.scene_sound);
+ }
+ }
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
new file mode 100644
index 00000000000..57b533a1b84
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "intern/eval/deg_eval_runtime_backup_sequence.h"
+#include "intern/depsgraph_type.h"
+
+struct Scene;
+
+namespace DEG {
+
+struct Depsgraph;
+
+/* Backup of sequencer strips runtime data. */
+class SequencerBackup {
+ public:
+ SequencerBackup(const Depsgraph *depsgraph);
+
+ void init_from_scene(Scene *scene);
+ void restore_to_scene(Scene *scene);
+
+ const Depsgraph *depsgraph;
+
+ typedef map<Sequence *, SequenceBackup> SequencesBackupMap;
+ SequencesBackupMap sequences_backup;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc
new file mode 100644
index 00000000000..0c54032e32c
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_sound.h"
+
+#include "BLI_utildefines.h"
+
+#include "DNA_sound_types.h"
+
+namespace DEG {
+
+SoundBackup::SoundBackup(const Depsgraph * /*depsgraph*/)
+{
+ reset();
+}
+
+void SoundBackup::reset()
+{
+ cache = NULL;
+ waveform = NULL;
+ playback_handle = NULL;
+}
+
+void SoundBackup::init_from_sound(bSound *sound)
+{
+ cache = sound->cache;
+ waveform = sound->waveform;
+ playback_handle = sound->playback_handle;
+
+ sound->cache = NULL;
+ sound->waveform = NULL;
+ sound->playback_handle = NULL;
+}
+
+void SoundBackup::restore_to_sound(bSound *sound)
+{
+ sound->cache = cache;
+ sound->waveform = waveform;
+ sound->playback_handle = playback_handle;
+
+ reset();
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h
new file mode 100644
index 00000000000..87783146701
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+struct bSound;
+
+namespace DEG {
+
+struct Depsgraph;
+
+/* Backup of sound datablocks runtime data. */
+class SoundBackup {
+ public:
+ SoundBackup(const Depsgraph *depsgraph);
+
+ void reset();
+
+ void init_from_sound(bSound *sound);
+ void restore_to_sound(bSound *sound);
+
+ void *cache;
+ void *waveform;
+ void *playback_handle;
+};
+
+} // namespace DEG
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 9527c6c9612..7d996f3c535 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -85,6 +85,7 @@ set(SRC
engines/eevee/eevee_motion_blur.c
engines/eevee/eevee_occlusion.c
engines/eevee/eevee_render.c
+ engines/eevee/eevee_renderpasses.c
engines/eevee/eevee_sampling.c
engines/eevee/eevee_screen_raytrace.c
engines/eevee/eevee_shaders.c
@@ -224,6 +225,7 @@ data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index c5ee4e12b40..5edfadd7f41 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -23,6 +23,10 @@
#ifndef __DRW_ENGINE_H__
#define __DRW_ENGINE_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "BLI_sys_types.h" /* for bool */
struct ARegion;
@@ -168,4 +172,8 @@ void DRW_deferred_shader_remove(struct GPUMaterial *mat);
struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id);
void DRW_drawdata_free(struct ID *id);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index d59d1f56e92..824ea69ea73 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -136,8 +136,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
const float *viewport_size = DRW_viewport_size_get();
int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -172,7 +170,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
- if (DRW_state_is_image_render() && !minimal && (view_layer->passflag & SCE_PASS_NORMAL) != 0) {
+ if (!minimal && (stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index a1096390bce..603a4787dba 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -27,6 +27,8 @@
#include "BKE_object.h"
#include "BKE_global.h" /* for G.debug_value */
+#include "DEG_depsgraph_query.h"
+
#include "DNA_world_types.h"
#include "eevee_private.h"
@@ -81,7 +83,9 @@ static void eevee_engine_init(void *ved)
&sldata->common_data);
}
- /* EEVEE_effects_init needs to go first for TAA */
+ /* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
+ * `EEVEE_effects_init` needs to go second for TAA. */
+ EEVEE_renderpasses_init(vedata);
EEVEE_effects_init(sldata, vedata, camera, false);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_shadows_init(sldata);
@@ -147,6 +151,8 @@ static void eevee_cache_finish(void *vedata)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_PrivateData *g_data = ((EEVEE_Data *)vedata)->stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
EEVEE_volumes_cache_finish(sldata, vedata);
EEVEE_materials_cache_finish(sldata, vedata);
@@ -156,6 +162,14 @@ static void eevee_cache_finish(void *vedata)
EEVEE_effects_draw_init(sldata, vedata);
EEVEE_volumes_draw_init(sldata, vedata);
+ uint tot_samples = scene_eval->eevee.taa_render_samples;
+ if (tot_samples == 0) {
+ /* use a high number of samples so the outputs accum buffers
+ * will have the highest possible precision */
+ tot_samples = 1024;
+ }
+ EEVEE_renderpasses_output_init(sldata, vedata, tot_samples);
+
/* Restart taa if a shader has finish compiling. */
/* HACK We should use notification of some sort from the compilation job instead. */
if (g_data->queued_shaders_count != g_data->queued_shaders_count_prev) {
@@ -306,6 +320,8 @@ static void eevee_draw_background(void *vedata)
EEVEE_draw_effects(sldata, vedata);
DRW_stats_group_end();
+ EEVEE_renderpasses_output_accumulate(sldata, vedata);
+
DRW_view_set_active(NULL);
if (DRW_state_is_image_render() && (stl->effects->enabled_effects & EFFECT_SSR) &&
@@ -319,14 +335,19 @@ static void eevee_draw_background(void *vedata)
}
}
- /* Tonemapping and transfer result to default framebuffer. */
- bool use_render_settings = stl->g_data->use_color_render_settings;
+ if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) {
+ /* Tonemapping and transfer result to default framebuffer. */
+ bool use_render_settings = stl->g_data->use_color_render_settings;
- GPU_framebuffer_bind(dfbl->default_fb);
- DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings);
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings);
- /* Draw checkerboard with alpha under. */
- EEVEE_draw_alpha_checker(vedata);
+ /* Draw checkerboard with alpha under. */
+ EEVEE_draw_alpha_checker(vedata);
+ }
+ else {
+ EEVEE_renderpasses_draw(sldata, vedata);
+ }
/* Debug : Output buffer to view. */
switch (G.debug_value) {
@@ -483,6 +504,7 @@ static void eevee_engine_free(void)
EEVEE_screen_raytrace_free();
EEVEE_subsurface_free();
EEVEE_volumes_free();
+ EEVEE_renderpasses_free();
}
static const DrawEngineDataSize eevee_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data);
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index 7209651a1d4..c9b56a6d551 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -49,6 +49,7 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PassList *psl = vedata->psl;
+ EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
Scene *scene = draw_ctx->scene;
@@ -74,8 +75,10 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->mist_accum)});
/* Clear texture. */
- GPU_framebuffer_bind(fbl->mist_accum_fb);
- GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear);
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->mist_accum_fb);
+ GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear);
+ }
/* Mist settings. */
if (scene && scene->world) {
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 48e9b5bcc13..6ba518b3a28 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -131,7 +131,7 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
return 0;
}
-void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
@@ -143,18 +143,22 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
+ const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
+
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Should be enough precision for many samples. */
- DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, GPU_R32F, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0);
GPU_framebuffer_ensure_config(&fbl->ao_accum_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)});
/* Clear texture. */
- GPU_framebuffer_bind(fbl->ao_accum_fb);
- GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->ao_accum_fb);
+ GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
+ }
/* Accumulation pass */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 7d02aacfac7..97bde2e5f2e 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -271,6 +271,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *update_noise_pass;
struct DRWPass *lookdev_glossy_pass;
struct DRWPass *lookdev_diffuse_pass;
+ struct DRWPass *renderpass_pass;
} EEVEE_PassList;
typedef struct EEVEE_FramebufferList {
@@ -295,6 +296,7 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *screen_tracing_fb;
struct GPUFrameBuffer *refract_fb;
struct GPUFrameBuffer *mist_accum_fb;
+ struct GPUFrameBuffer *renderpass_fb;
struct GPUFrameBuffer *ao_accum_fb;
struct GPUFrameBuffer *velocity_resolve_fb;
@@ -341,6 +343,8 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *maxzbuffer;
+ struct GPUTexture *renderpass;
+
struct GPUTexture *color; /* R16_G16_B16 */
struct GPUTexture *color_double_buffer;
struct GPUTexture *depth_double_buffer;
@@ -799,6 +803,10 @@ typedef struct EEVEE_PrivateData {
float studiolight_glossy_clamp;
float studiolight_filter_quality;
+ /* Renderpasses */
+ /* Bitmask containing the active render_passes */
+ eScenePassType render_passes;
+
/** For rendering shadows. */
struct DRWView *cube_views[6];
/** For rendering probes. */
@@ -988,7 +996,9 @@ void EEVEE_bloom_free(void);
/* eevee_occlusion.c */
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
-void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata,
@@ -1009,7 +1019,9 @@ void EEVEE_screen_raytrace_free(void);
void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
-void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint sss_id,
@@ -1035,6 +1047,19 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_mist_free(void);
+/* eevee_renderpasses.c */
+void EEVEE_renderpasses_init(EEVEE_Data *vedata);
+void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ eScenePassType renderpass_type);
+void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_renderpasses_free(void);
+bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata);
+
/* eevee_temporal_sampling.c */
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata);
int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 75e837f140b..ba5704f14e5 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -130,7 +130,9 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
DRW_view_default_set(view);
DRW_view_set_active(view);
- /* EEVEE_effects_init needs to go first for TAA */
+ /* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
+ * `EEVEE_effects_init` needs to go second for TAA. */
+ EEVEE_renderpasses_init(vedata);
EEVEE_effects_init(sldata, vedata, ob_camera_eval, false);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_shadows_init(sldata);
@@ -202,79 +204,60 @@ void EEVEE_render_cache(void *vedata,
}
}
-static void eevee_render_result_combined(RenderLayer *rl,
- const char *viewname,
- const rcti *rect,
- EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata))
+static void eevee_render_color_result(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ const char *render_pass_name,
+ int num_channels,
+ GPUFrameBuffer *framebuffer,
+ EEVEE_Data *vedata)
{
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
-
- GPU_framebuffer_bind(vedata->stl->effects->final_fb);
- GPU_framebuffer_read_color(vedata->stl->effects->final_fb,
+ RenderPass *rp = RE_pass_find_by_name(rl, render_pass_name, viewname);
+ GPU_framebuffer_bind(framebuffer);
+ GPU_framebuffer_read_color(framebuffer,
vedata->stl->g_data->overscan_pixels + rect->xmin,
vedata->stl->g_data->overscan_pixels + rect->ymin,
BLI_rcti_size_x(rect),
BLI_rcti_size_y(rect),
- 4,
+ num_channels,
0,
rp->rect);
}
+static void eevee_render_result_combined(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_COMBINED, 4, vedata->stl->effects->final_fb, vedata);
+}
+
static void eevee_render_result_subsurface(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata),
- int render_samples)
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
-
if (vedata->fbl->sss_accum_fb == NULL) {
/* SSS is not enabled. */
return;
}
- if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->sss_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 1,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i++) {
- rp->rect[i] /= (float)render_samples;
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_COLOR) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_COLOR);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_SUBSURFACE_COLOR, 3, vedata->fbl->renderpass_fb, vedata);
}
- if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->sss_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 0,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i++) {
- rp->rect[i] /= (float)render_samples;
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_DIRECT);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_SUBSURFACE_DIRECT, 3, vedata->fbl->renderpass_fb, vedata);
}
- if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
/* Do nothing as all the lighting is in the direct pass.
* TODO : Separate Direct from indirect lighting. */
}
@@ -284,54 +267,19 @@ static void eevee_render_result_normal(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata))
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- EEVEE_StorageList *stl = vedata->stl;
- EEVEE_PrivateData *g_data = stl->g_data;
+ const int current_sample = vedata->stl->effects->taa_current_sample;
/* Only read the center texel. */
- if (stl->effects->taa_current_sample > 1) {
+ if (current_sample > 1) {
return;
}
- if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->main_fb);
- GPU_framebuffer_read_color(vedata->fbl->main_fb,
- g_data->overscan_pixels + rect->xmin,
- g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 1,
- rp->rect);
-
- float viewinv[4][4];
- DRW_view_viewmat_get(NULL, viewinv, true);
-
- /* Convert Eevee encoded normals to Blender normals. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) {
- if (rp->rect[i] == 0.0f && rp->rect[i + 1] == 0.0f) {
- /* If normal is not correct then do not produce NANs. */
- continue;
- }
-
- float fenc[2];
- fenc[0] = rp->rect[i + 0] * 4.0f - 2.0f;
- fenc[1] = rp->rect[i + 1] * 4.0f - 2.0f;
-
- float f = dot_v2v2(fenc, fenc);
- float g = sqrtf(1.0f - f / 4.0f);
-
- rp->rect[i + 0] = fenc[0] * g;
- rp->rect[i + 1] = fenc[1] * g;
- rp->rect[i + 2] = 1.0f - f / 2.0f;
-
- mul_mat3_m4_v3(viewinv, &rp->rect[i]);
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_NORMAL);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -341,49 +289,17 @@ static void eevee_render_result_z(RenderLayer *rl,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
- EEVEE_StorageList *stl = vedata->stl;
- EEVEE_PrivateData *g_data = stl->g_data;
+ const int current_sample = vedata->stl->effects->taa_current_sample;
/* Only read the center texel. */
- if (stl->effects->taa_current_sample > 1) {
+ if (current_sample > 1) {
return;
}
- if ((view_layer->passflag & SCE_PASS_Z) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->main_fb);
- GPU_framebuffer_read_depth(vedata->fbl->main_fb,
- g_data->overscan_pixels + rect->xmin,
- g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- rp->rect);
-
- bool is_persp = DRW_view_is_persp_get(NULL);
-
- float winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
-
- /* Convert ogl depth [0..1] to view Z [near..far] */
- for (int i = 0; i < rp->rectx * rp->recty; i++) {
- if (rp->rect[i] == 1.0f) {
- rp->rect[i] = 1e10f; /* Background */
- }
- else {
- if (is_persp) {
- rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
- rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]);
- }
- else {
- rp->rect[i] = -common_data->view_vecs[0][2] +
- rp->rect[i] * -common_data->view_vecs[1][2];
- }
- }
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_Z) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_Z);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -391,29 +307,12 @@ static void eevee_render_result_mist(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata),
- int render_samples)
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
-
- if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->mist_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->mist_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 1,
- 0,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty; i++) {
- rp->rect[i] /= (float)render_samples;
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_MIST) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_MIST);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -421,35 +320,17 @@ static void eevee_render_result_occlusion(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata),
- int render_samples)
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
-
if (vedata->fbl->ao_accum_fb == NULL) {
/* AO is not enabled. */
return;
}
- if ((view_layer->passflag & SCE_PASS_AO) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->ao_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->ao_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 0,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) {
- rp->rect[i] = rp->rect[i + 1] = rp->rect[i + 2] = min_ff(
- 1.0f, rp->rect[i] / (float)render_samples);
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_AO) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_AO);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -488,7 +369,6 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- ViewLayer *view_layer = draw_ctx->view_layer;
const char *viewname = RE_GetActiveRenderView(engine->re);
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
@@ -517,31 +397,20 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
GPU_framebuffer_bind(fbl->main_fb);
DRW_hair_update();
- if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT |
- SCE_PASS_SUBSURFACE_INDIRECT)) != 0) {
- EEVEE_subsurface_output_init(sldata, vedata);
- }
-
- if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
- EEVEE_mist_output_init(sldata, vedata);
- }
-
- if ((view_layer->passflag & SCE_PASS_AO) != 0) {
- EEVEE_occlusion_output_init(sldata, vedata);
- }
-
uint tot_sample = scene_eval->eevee.taa_render_samples;
uint render_samples = 0;
- if (RE_engine_test_break(engine)) {
- return;
- }
-
/* SSR needs one iteration to start properly. */
if (stl->effects->enabled_effects & EFFECT_SSR) {
tot_sample += 1;
}
+ EEVEE_renderpasses_output_init(sldata, vedata, tot_sample);
+
+ if (RE_engine_test_break(engine)) {
+ return;
+ }
+
while (render_samples < tot_sample && !RE_engine_test_break(engine)) {
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float clear_depth = 1.0f;
@@ -616,16 +485,12 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
DRW_draw_pass(psl->refract_depth_pass);
DRW_draw_pass(psl->refract_depth_pass_cull);
DRW_draw_pass(psl->refract_pass);
- /* Subsurface output */
- EEVEE_subsurface_output_accumulate(sldata, vedata);
- /* Occlusion output */
- EEVEE_occlusion_output_accumulate(sldata, vedata);
/* Result NORMAL */
eevee_render_result_normal(rl, viewname, rect, vedata, sldata);
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
- /* Mist output */
- EEVEE_mist_output_accumulate(sldata, vedata);
+ /* Subsurface output, Occlusion output, Mist output */
+ EEVEE_renderpasses_output_accumulate(sldata, vedata);
/* Transparent */
GPU_framebuffer_texture_attach(fbl->main_color_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(fbl->main_color_fb);
@@ -644,9 +509,9 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
}
eevee_render_result_combined(rl, viewname, rect, vedata, sldata);
- eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata, render_samples);
- eevee_render_result_mist(rl, viewname, rect, vedata, sldata, render_samples);
- eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata, render_samples);
+ eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_mist(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata);
/* Restore original viewport size. */
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
new file mode 100644
index 00000000000..927ff70a52b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -0,0 +1,278 @@
+/*
+ * 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
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "BLI_string_utils.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "eevee_private.h"
+
+extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_renderpass_postprocess_frag_glsl[];
+
+static struct {
+ struct GPUShader *postprocess_sh;
+} e_data = {NULL}; /* Engine data */
+
+/* bitmask containing all renderpasses that need post-processing */
+#define EEVEE_RENDERPASSES_WITH_POST_PROCESSING \
+ (SCE_PASS_Z | SCE_PASS_MIST | SCE_PASS_NORMAL | SCE_PASS_AO | SCE_PASS_SUBSURFACE_COLOR | \
+ SCE_PASS_SUBSURFACE_DIRECT)
+
+#define EEVEE_RENDERPASSES_SUBSURFACE \
+ (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_INDIRECT)
+
+#define EEVEE_RENDERPASSES_ALL (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | SCE_PASS_COMBINED)
+
+#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE (SCE_PASS_Z | SCE_PASS_NORMAL)
+
+#define EEVEE_RENDERPASSES_COLOR_PASS (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)
+
+bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ return (g_data->render_passes & ~EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) == 0;
+}
+
+void EEVEE_renderpasses_init(EEVEE_Data *vedata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ View3D *v3d = draw_ctx->v3d;
+
+ if (v3d) {
+ g_data->render_passes = v3d->shading.render_pass;
+ }
+ else {
+ g_data->render_passes = (view_layer->passflag & EEVEE_RENDERPASSES_ALL) | SCE_PASS_COMBINED;
+ }
+}
+
+void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ const bool needs_post_processing = (g_data->render_passes &
+ EEVEE_RENDERPASSES_WITH_POST_PROCESSING) > 0;
+ if (needs_post_processing) {
+ if (e_data.postprocess_sh == NULL) {
+ char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_renderpass_postprocess_frag_glsl);
+ e_data.postprocess_sh = DRW_shader_create_fullscreen(frag_str, NULL);
+ MEM_freeN(frag_str);
+ }
+
+ /* Create FrameBuffer. */
+
+ /* Should be enough to store the data needs for a single pass.
+ * Some passes will use less, but it is only relevant for final renderings and
+ * when renderpasses other than `SCE_PASS_COMBINED` are requested */
+ DRW_texture_ensure_fullscreen_2d(&txl->renderpass, GPU_RGBA16F, 0);
+ GPU_framebuffer_ensure_config(&fbl->renderpass_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->renderpass)});
+
+ if ((g_data->render_passes & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
+ EEVEE_subsurface_output_init(sldata, vedata, tot_samples);
+ }
+
+ if ((g_data->render_passes & SCE_PASS_MIST) != 0) {
+ EEVEE_mist_output_init(sldata, vedata);
+ }
+
+ if ((g_data->render_passes & SCE_PASS_AO) != 0) {
+ EEVEE_occlusion_output_init(sldata, vedata, tot_samples);
+ }
+
+ /* Create Pass. */
+ DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
+ }
+ else {
+ /* Free unneeded memory */
+ DRW_TEXTURE_FREE_SAFE(txl->renderpass);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->renderpass_fb);
+ psl->renderpass_pass = NULL;
+ }
+}
+
+/* Postprocess data to construct a specific renderpass
+ *
+ * This method will create a shading group to perform the post-processing for the given
+ * `renderpass_type`. The post-processing will be done and the result will be stored in the
+ * `vedata->txl->renderpass` texture.
+ *
+ * Only invoke this function for passes that need post-processing.
+ *
+ * After invoking this function the active framebuffer is set to `vedata->fbl->renderpass_fb`. */
+void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ eScenePassType renderpass_type)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ const int current_sample = effects->taa_current_sample;
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.postprocess_sh, psl->renderpass_pass);
+ DRW_shgroup_uniform_int_copy(shgrp, "renderpassType", renderpass_type);
+
+ switch (renderpass_type) {
+ case SCE_PASS_Z: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture_ref(shgrp, "depthBuffer", &dtxl->depth);
+ break;
+ }
+
+ case SCE_PASS_AO: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->ao_accum);
+ DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
+ break;
+ }
+
+ case SCE_PASS_NORMAL: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &effects->ssr_normal_input);
+ DRW_shgroup_uniform_texture_ref(shgrp, "depthBuffer", &dtxl->depth);
+ break;
+ }
+
+ case SCE_PASS_MIST: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->mist_accum);
+ DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
+ break;
+ }
+
+ case SCE_PASS_SUBSURFACE_DIRECT: {
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->sss_dir_accum);
+ DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
+ break;
+ }
+
+ case SCE_PASS_SUBSURFACE_COLOR: {
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->sss_col_accum);
+ DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ DRW_shgroup_call(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
+
+ /* only draw the shading group that has been added. This function can be called multiple times
+ * and the pass still hold the previous shading groups.*/
+ GPU_framebuffer_bind(fbl->renderpass_fb);
+ DRW_draw_pass_subset(psl->renderpass_pass, shgrp, shgrp);
+}
+
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ eScenePassType render_pass = stl->g_data->render_passes;
+
+ if ((render_pass & SCE_PASS_MIST) != 0) {
+ EEVEE_mist_output_accumulate(sldata, vedata);
+ }
+ if ((effects->enabled_effects & EFFECT_SSS) &&
+ (render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
+ EEVEE_subsurface_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & SCE_PASS_AO) != 0) {
+ EEVEE_occlusion_output_accumulate(sldata, vedata);
+ }
+}
+
+void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ eScenePassType render_pass = stl->g_data->render_passes;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+
+ bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0;
+ bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 &&
+ DRW_state_is_opengl_render();
+
+ /* When SSS isn't available, but the pass is requested, we mark it as invalid */
+ if ((render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0 &&
+ (effects->enabled_effects & EFFECT_SSS) == 0) {
+ is_valid = false;
+ }
+
+ /* When SSS isn't available, but the pass is requested, we mark it as invalid */
+ if ((render_pass & SCE_PASS_AO) != 0 && (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
+ is_valid = false;
+ }
+
+ const int current_sample = stl->effects->taa_current_sample;
+ const int total_samples = stl->effects->taa_total_sample;
+ if ((render_pass & EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) &&
+ (current_sample > 1 && total_samples != 1)) {
+ return;
+ }
+
+ if (is_valid) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, render_pass);
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_transform_to_display(txl->renderpass, needs_color_transfer, false);
+ }
+ else {
+ /* Draw state is not valid for this pass, clear the buffer */
+ static float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_bind(dfbl->default_fb);
+ GPU_framebuffer_clear_color(dfbl->default_fb, clear_color);
+ }
+ GPU_framebuffer_bind(fbl->main_fb);
+}
+
+void EEVEE_renderpasses_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.postprocess_sh);
+}
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index 8376b8c67b8..e94fc903694 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -156,7 +156,9 @@ static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
DRW_shgroup_stencil_mask(shgrp, 255);
}
-void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ uint tot_samples)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
@@ -164,8 +166,10 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
EEVEE_EffectsInfo *effects = stl->effects;
if (effects->enabled_effects & EFFECT_SSS) {
- DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, GPU_RGBA16F, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, GPU_RGBA16F, 0);
+ const eGPUTextureFormat texture_format_light = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
+ const eGPUTextureFormat texture_format_color = (tot_samples > 512) ? GPU_RGBA32F : GPU_RGBA16F;
+ DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, texture_format_light, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, texture_format_color, 0);
GPUTexture *stencil_tex = effects->sss_stencil;
@@ -183,9 +187,11 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
GPU_ATTACHMENT_TEXTURE(txl->sss_col_accum)});
/* Clear texture. */
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPU_framebuffer_bind(fbl->sss_accum_fb);
- GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_bind(fbl->sss_accum_fb);
+ GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
+ }
/* Make the opaque refraction pass mask the sss. */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
@@ -253,7 +259,8 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
- if (DRW_state_is_image_render()) {
+ if ((stl->g_data->render_passes & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)) !=
+ 0) {
grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_accum_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index e5f89aab4d1..0f0b4a3e0a9 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -234,7 +234,9 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL);
}
- effects->taa_total_sample = scene_eval->eevee.taa_samples;
+ effects->taa_total_sample = EEVEE_renderpasses_only_first_sample_pass_active(vedata) ?
+ 1 :
+ scene_eval->eevee.taa_samples;
MAX2(effects->taa_total_sample, 0);
DRW_view_persmat_get(NULL, persmat, false);
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
new file mode 100644
index 00000000000..5a738d0f130
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -0,0 +1,64 @@
+#define SCE_PASS_Z (1 << 1)
+#define SCE_PASS_AO (1 << 6)
+#define SCE_PASS_NORMAL (1 << 8)
+#define SCE_PASS_MIST (1 << 14)
+#define SCE_PASS_SUBSURFACE_DIRECT (1 << 28)
+#define SCE_PASS_SUBSURFACE_COLOR (1 << 30)
+
+#define ACCUMULATED_COLOR_PASSES (SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_COLOR)
+#define ACCUMULATED_VALUE_PASSES (SCE_PASS_MIST)
+uniform int renderpassType;
+uniform int currentSample;
+uniform sampler2D inputBuffer;
+
+out vec4 fragColor;
+
+void main()
+{
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+
+ if (renderpassType == SCE_PASS_Z) {
+ float depth = texelFetch(depthBuffer, texel, 0).r;
+ if (depth == 1.0f) {
+ depth = 1e10;
+ }
+ else {
+ depth = -get_view_z_from_depth(depth);
+ }
+ fragColor.r = depth;
+ }
+
+ else if (renderpassType == SCE_PASS_AO) {
+ float ao_accum = texelFetch(inputBuffer, texel, 0).r;
+ fragColor = vec4(vec3(min(1.0, ao_accum / currentSample)), 1.0);
+ }
+
+ else if (renderpassType == SCE_PASS_NORMAL) {
+ float depth = texelFetch(depthBuffer, texel, 0).r;
+ vec2 encoded_normal = texelFetch(inputBuffer, texel, 0).rg;
+ /* decode the normals only when they are valid. otherwise the result buffer will be filled with
+ * NaN's */
+ if (depth != 1.0 && any(notEqual(encoded_normal, vec2(0.0)))) {
+ vec3 decoded_normal = normal_decode(texelFetch(inputBuffer, texel, 0).rg, vec3(0.0));
+ vec3 world_normal = mat3(ViewMatrixInverse) * decoded_normal;
+ fragColor = vec4(world_normal, 1.0);
+ }
+ else {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ }
+
+ else if ((renderpassType & ACCUMULATED_VALUE_PASSES) != 0) {
+ float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
+ fragColor = vec4(vec3(accumulated_value / currentSample), 1.0);
+ }
+
+ else if ((renderpassType & ACCUMULATED_COLOR_PASSES) != 0) {
+ vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
+ fragColor = vec4(accumulated_color / currentSample, 1.0);
+ }
+
+ else {
+ fragColor = vec4(1.0, 0.0, 1.0, 1.0);
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 48912a914dc..cd96b21280f 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -1816,7 +1816,6 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
for (int i = 0; i < cache->grp_used; i++) {
elm = &cache->grp_cache[i];
array_elm = &cache_ob->shgrp_array[idx];
- const float scale = cache_ob->scale;
/* Limit stencil id */
if (stencil_id > 255) {
@@ -1858,6 +1857,8 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
break;
}
+ const float scale = (!cache_ob->is_dup_ob) ? mat4_to_scale(gpf->runtime.parent_obmat) :
+ cache_ob->scale;
float(*obmat)[4] = (!cache_ob->is_dup_ob) ? gpf->runtime.parent_obmat : cache_ob->obmat;
switch (elm->type) {
case eGpencilBatchGroupType_Stroke: {
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
index 0c290260b20..8285541e0b4 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
@@ -51,6 +51,7 @@ uniform float fade_ob_factor;
#define V3D_SHADING_MATERIAL_COLOR 0
#define V3D_SHADING_TEXTURE_COLOR 3
+#define V3D_SHADING_VERTEX_COLOR 5
in vec4 finalColor;
in vec2 texCoord_interp;
@@ -210,7 +211,8 @@ void main()
/* for solid override color */
if (shading_type[0] == OB_SOLID) {
if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) &&
- (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
+ (shading_type[1] != V3D_SHADING_TEXTURE_COLOR) &&
+ (shading_type[1] != V3D_SHADING_VERTEX_COLOR)) {
fragColor = wire_color;
}
if (viewport_xray == 1) {
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
index 87963c66858..33d7d714231 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
@@ -26,6 +26,7 @@ out vec4 finalprev_pos;
#define V3D_SHADING_MATERIAL_COLOR 0
#define V3D_SHADING_TEXTURE_COLOR 3
+#define V3D_SHADING_VERTEX_COLOR 5
float defaultpixsize = pixsize * (1000.0 / pixfactor);
@@ -52,7 +53,8 @@ void main()
/* for solid override color */
if (shading_type[0] == OB_SOLID) {
if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) &&
- (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
+ (shading_type[1] != V3D_SHADING_TEXTURE_COLOR) &&
+ (shading_type[1] != V3D_SHADING_VERTEX_COLOR)) {
finalColor = wire_color;
}
if (viewport_xray == 1) {
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
index 582b9a7f249..8df08f0bf68 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
@@ -24,6 +24,7 @@ out vec2 finaluvdata;
#define V3D_SHADING_MATERIAL_COLOR 0
#define V3D_SHADING_TEXTURE_COLOR 3
+#define V3D_SHADING_VERTEX_COLOR 5
float defaultpixsize = pixsize * (1000.0 / pixfactor);
@@ -49,7 +50,8 @@ void main(void)
/* for solid override color */
if (shading_type[0] == OB_SOLID) {
if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) &&
- (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
+ (shading_type[1] != V3D_SHADING_TEXTURE_COLOR) &&
+ (shading_type[1] != V3D_SHADING_VERTEX_COLOR)) {
finalColor = wire_color;
}
if (viewport_xray == 1) {
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 3e63f05ca64..42375f29d4d 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -30,6 +30,77 @@
#include "GPU_batch.h"
+/* -------------------------------------------------------------------- */
+/** \name World Data
+ * \{ */
+
+static void workbench_world_data_free(DrawData *dd)
+{
+ WORKBENCH_WorldData *data = (WORKBENCH_WorldData *)dd;
+ DRW_UBO_FREE_SAFE(data->world_ubo);
+}
+
+/* Ensure the availability of the world_ubo in the given WORKBENCH_PrivateData
+ *
+ * See T70167: Some platforms create threads to upload ubo's.
+ *
+ * Reuses the last previous created `world_ubo`. Due to limitations of
+ * DrawData it will only be reused when there is a world attached to the Scene.
+ * Future development: The best location would be to store it in the View3D.
+ *
+ * We don't cache the data itself as there was no indication that that lead to
+ * an improvement.
+ *
+ * This functions also sets the `WORKBENCH_PrivateData.is_world_ubo_owner` that must
+ * be respected.
+ */
+static void workbench_world_data_ubo_ensure(const Scene *scene, WORKBENCH_PrivateData *wpd)
+{
+ World *world = scene->world;
+ if (world) {
+ WORKBENCH_WorldData *engine_world_data = (WORKBENCH_WorldData *)DRW_drawdata_ensure(
+ &world->id,
+ &draw_engine_workbench_solid,
+ sizeof(WORKBENCH_WorldData),
+ NULL,
+ &workbench_world_data_free);
+
+ if (engine_world_data->world_ubo == NULL) {
+ engine_world_data->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World),
+ &wpd->world_data);
+ }
+ else {
+ DRW_uniformbuffer_update(engine_world_data->world_ubo, &wpd->world_data);
+ }
+
+ /* Borrow world data ubo */
+ wpd->is_world_ubo_owner = false;
+ wpd->world_ubo = engine_world_data->world_ubo;
+ }
+ else {
+ /* there is no world so we cannot cache the UBO. */
+ BLI_assert(!wpd->world_ubo || wpd->is_world_ubo_owner);
+ if (!wpd->world_ubo) {
+ wpd->is_world_ubo_owner = true;
+ wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
+ }
+ }
+}
+
+static void workbench_world_data_update_shadow_direction_vs(WORKBENCH_PrivateData *wpd)
+{
+ WORKBENCH_UBO_World *wd = &wpd->world_data;
+ float light_direction[3];
+ float view_matrix[4][4];
+ DRW_view_viewmat_get(NULL, view_matrix, false);
+
+ workbench_private_data_get_light_direction(light_direction);
+
+ /* Shadow direction. */
+ mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, light_direction);
+}
+/* \} */
+
void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info)
{
effect_info->jitter_index = 0;
@@ -139,7 +210,8 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
}
}
- wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
+ workbench_world_data_update_shadow_direction_vs(wpd);
+ workbench_world_data_ubo_ensure(scene, wpd);
/* Cavity settings */
{
@@ -203,31 +275,29 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
BLI_listbase_clear(&wpd->smoke_domains);
}
-void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd,
- float r_light_direction[3])
+void workbench_private_data_get_light_direction(float r_light_direction[3])
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
- WORKBENCH_UBO_World *wd = &wpd->world_data;
- float view_matrix[4][4];
- DRW_view_viewmat_get(NULL, view_matrix, false);
copy_v3_v3(r_light_direction, scene->display.light_direction);
SWAP(float, r_light_direction[2], r_light_direction[1]);
r_light_direction[2] = -r_light_direction[2];
r_light_direction[0] = -r_light_direction[0];
-
- /* Shadow direction. */
- mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, r_light_direction);
-
- DRW_uniformbuffer_update(wpd->world_ubo, wd);
}
void workbench_private_data_free(WORKBENCH_PrivateData *wpd)
{
BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
BLI_ghash_free(wpd->material_transp_hash, NULL, MEM_freeN);
- DRW_UBO_FREE_SAFE(wpd->world_ubo);
+
+ if (wpd->is_world_ubo_owner) {
+ DRW_UBO_FREE_SAFE(wpd->world_ubo);
+ }
+ else {
+ wpd->world_ubo = NULL;
+ }
+
DRW_UBO_FREE_SAFE(wpd->dof_ubo);
GPU_BATCH_DISCARD_SAFE(wpd->world_clip_planes_batch);
}
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 9a7e1a5a782..e5872dbac50 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -728,7 +728,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
/* Deferred Mix Pass */
{
- workbench_private_data_get_light_direction(wpd, e_data.display.light_direction);
+ workbench_private_data_get_light_direction(e_data.display.light_direction);
studiolight_update_light(wpd, e_data.display.light_direction);
if (SHADOW_ENABLED(wpd)) {
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index d731b167c06..80b274e9b76 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -22,8 +22,6 @@
#include "workbench_private.h"
-#include "BIF_gl.h"
-
#include "BLI_alloca.h"
#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
@@ -337,8 +335,6 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
}
WORKBENCH_PrivateData *wpd = stl->g_data;
workbench_private_data_init(wpd);
- float light_direction[3];
- workbench_private_data_get_light_direction(wpd, light_direction);
if (!e_data.checker_depth_sh) {
e_data.checker_depth_sh = DRW_shader_create_fullscreen(
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 0f9551a8cc9..45d49448490 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -22,8 +22,6 @@
#include "workbench_private.h"
-#include "BIF_gl.h"
-
#include "BKE_image.h"
#include "BKE_node.h"
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 595b92d19d0..9fcd9651f94 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -217,6 +217,11 @@ typedef struct WORKBENCH_PrivateData {
View3DShading shading;
StudioLight *studio_light;
const UserDef *preferences;
+ /* Does this instance owns the `world_ubo` field.
+ * Normally the field is borrowed from `WORKBENCH_WorldData`. In case that
+ * there is no World attached to the scene the UBO cannot be cached and should
+ * be freed after using. */
+ bool is_world_ubo_owner;
struct GPUUniformBuffer *world_ubo;
struct DRWShadingGroup *shadow_shgrp;
struct DRWShadingGroup *depth_shgrp;
@@ -307,6 +312,12 @@ typedef struct WORKBENCH_ObjectData {
bool shadow_bbox_dirty;
} WORKBENCH_ObjectData;
+typedef struct WORKBENCH_WorldData {
+ DrawData dd;
+ /* The cached `GPUUniformBuffer`, that is reused between draw calls. */
+ struct GPUUniformBuffer *world_ubo;
+} WORKBENCH_WorldData;
+
/* inline helper functions */
BLI_INLINE bool workbench_is_specular_highlight_enabled(WORKBENCH_PrivateData *wpd)
{
@@ -526,8 +537,7 @@ bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd,
void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info);
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
void workbench_private_data_free(WORKBENCH_PrivateData *wpd);
-void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd,
- float r_light_direction[3]);
+void workbench_private_data_get_light_direction(float r_light_direction[3]);
/* workbench_volume.c */
void workbench_volume_engine_init(void);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 98a9ea965de..4bfae75848b 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2576,6 +2576,9 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
RegionView3D *rv3d = ar->regiondata;
DRW_opengl_context_enable();
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
+ GPU_matrix_mul(object->obmat);
/* Setup framebuffer */
DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
@@ -2583,7 +2586,6 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
GPU_framebuffer_bind(fbl->depth_only_fb);
GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
GPU_depth_test(true);
- GPU_matrix_mul(object->obmat);
const float(*world_clip_planes)[4] = NULL;
if (rv3d->rflag & RV3D_CLIPPING) {
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 36583ecf060..13358808a23 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -228,6 +228,47 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
*last = max;
}
+/**
+ * Function used in operator polls, checks whether the markers region is currently drawn in the
+ * editor in which the operator is called.
+ */
+static bool ED_operator_markers_region_active(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+
+ switch (sa->spacetype) {
+ case SPACE_ACTION: {
+ SpaceAction *saction = sa->spacedata.first;
+ if (saction->flag & SACTION_SHOW_MARKERS) {
+ return true;
+ }
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = sa->spacedata.first;
+ if (sipo->mode != SIPO_MODE_DRIVERS && sipo->flag & SIPO_SHOW_MARKERS) {
+ return true;
+ }
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = sa->spacedata.first;
+ if (snla->flag & SNLA_SHOW_MARKERS) {
+ return true;
+ }
+ break;
+ }
+ case SPACE_SEQ: {
+ SpaceSeq *seq = sa->spacedata.first;
+ if (seq->flag & SEQ_SHOW_MARKERS) {
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
static bool region_position_is_over_marker(View2D *v2d, ListBase *markers, float region_x)
{
if (markers == NULL || BLI_listbase_is_empty(markers)) {
@@ -409,7 +450,7 @@ static void draw_marker_name(const uiFontStyle *fstyle,
UI_fontstyle_draw_simple(fstyle, name_x, text_y, name, text_color);
}
-static void draw_marker_line(const float color[4], float x, float ymin, float ymax)
+static void draw_marker_line(const float color[4], int xpos, int ymin, int ymax)
{
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -426,8 +467,8 @@ static void draw_marker_line(const float color[4], float x, float ymin, float ym
immUniform1f("dash_factor", 0.5f);
immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, x, ymin);
- immVertex2f(pos, x, ymax);
+ immVertex2f(pos, xpos, ymin);
+ immVertex2f(pos, xpos, ymax);
immEnd();
immUnbindProgram();
@@ -449,26 +490,6 @@ static int marker_get_icon_id(TimeMarker *marker, int flag)
}
}
-static void draw_marker_line_if_necessary(TimeMarker *marker, int flag, int xpos, int height)
-{
-#ifdef DURIAN_CAMERA_SWITCH
- if ((marker->camera) || (flag & DRAW_MARKERS_LINES))
-#else
- if (flag & DRAW_MARKERS_LINES)
-#endif
- {
- float color[4];
- if (marker->flag & SELECT) {
- copy_v4_fl4(color, 1.0f, 1.0f, 1.0f, 0.38f);
- }
- else {
- copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 0.38f);
- }
-
- draw_marker_line(color, xpos, UI_DPI_FAC * 20, height);
- }
-}
-
static void draw_marker(
const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height)
{
@@ -476,7 +497,15 @@ static void draw_marker(
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- draw_marker_line_if_necessary(marker, flag, xpos, region_height);
+ float color[4];
+ if (marker->flag & SELECT) {
+ copy_v4_fl4(color, 1.0f, 1.0f, 1.0f, 0.38f);
+ }
+ else {
+ copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 0.38f);
+ }
+
+ draw_marker_line(color, xpos, UI_DPI_FAC * 20, region_height);
int icon_id = marker_get_icon_id(marker, flag);
UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id);
@@ -599,8 +628,7 @@ static bool ed_markers_poll_selected_markers(bContext *C)
{
ListBase *markers = ED_context_get_markers(C);
- /* first things first: markers can only exist in timeline views */
- if (ED_operator_animview_active(C) == 0) {
+ if (!ED_operator_markers_region_active(C)) {
return 0;
}
@@ -613,12 +641,7 @@ static bool ed_markers_poll_selected_no_locked_markers(bContext *C)
ListBase *markers = ED_context_get_markers(C);
ToolSettings *ts = CTX_data_tool_settings(C);
- if (ts->lock_markers) {
- return 0;
- }
-
- /* first things first: markers can only exist in timeline views */
- if (ED_operator_animview_active(C) == 0) {
+ if (ts->lock_markers || !ED_operator_markers_region_active(C)) {
return 0;
}
@@ -632,12 +655,7 @@ static bool ed_markers_poll_markers_exist(bContext *C)
ListBase *markers = ED_context_get_markers(C);
ToolSettings *ts = CTX_data_tool_settings(C);
- if (ts->lock_markers) {
- return 0;
- }
-
- /* first things first: markers can only exist in timeline views */
- if (ED_operator_animview_active(C) == 0) {
+ if (ts->lock_markers || !ED_operator_markers_region_active(C)) {
return 0;
}
@@ -692,7 +710,7 @@ static void MARKER_OT_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = ed_marker_add_exec;
- ot->poll = ED_operator_animview_active;
+ ot->poll = ED_operator_markers_region_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1661,7 +1679,7 @@ static void MARKER_OT_camera_bind(wmOperatorType *ot)
/* api callbacks */
ot->exec = ed_marker_camera_bind_exec;
- ot->poll = ED_operator_animview_active;
+ ot->poll = ED_operator_markers_region_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 92957c51c08..c9206e8df4a 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1320,20 +1320,36 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
int kern, delta = RNA_int_get(op->ptr, "delta");
+ int selstart, selend;
+ bool changed = false;
- kern = ef->textbufinfo[ef->pos - 1].kern;
- kern += delta;
- CLAMP(kern, -20, 20);
-
- if (ef->textbufinfo[ef->pos - 1].kern == kern) {
- return OPERATOR_CANCELLED;
+ const bool has_select = BKE_vfont_select_get(obedit, &selstart, &selend);
+ if (has_select) {
+ selstart -= 1;
+ }
+ else {
+ selstart = selend = ef->pos - 1;
}
+ selstart = max_ii(0, selstart);
- ef->textbufinfo[ef->pos - 1].kern = kern;
+ for (int i = selstart; i <= selend; i++) {
+ kern = ef->textbufinfo[i].kern + delta;
+ CLAMP(kern, -20, 20);
- text_update_edited(C, obedit, FO_EDIT);
+ if (ef->textbufinfo[i].kern != kern) {
+ ef->textbufinfo[i].kern = kern;
+ changed = true;
+ }
+ }
- return OPERATOR_FINISHED;
+ if (changed) {
+ text_update_edited(C, obedit, FO_EDIT);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void FONT_OT_change_spacing(wmOperatorType *ot)
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 680fe3a00e5..fd8fe103a2d 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -529,10 +529,6 @@ set(ICON_NAMES
axis_side
axis_front
axis_top
- ndof_dom
- ndof_turn
- ndof_fly
- ndof_trans
layer_used
layer_active
sortalpha
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 80795b825b0..06e5f36637b 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -51,6 +51,7 @@
#include "BKE_context.h"
#include "BKE_brush.h"
#include "BKE_global.h"
+#include "BKE_material.h"
#include "BKE_paint.h"
#include "BKE_gpencil.h"
#include "BKE_image.h"
@@ -427,7 +428,9 @@ static void gp_draw_stroke_fill(bGPdata *gpd,
const float color[4])
{
BLI_assert(gps->totpoints >= 3);
- Material *ma = gpd->mat[gps->mat_nr];
+ const bool use_mat = (gpd->mat != NULL);
+
+ Material *ma = (use_mat) ? gpd->mat[gps->mat_nr] : BKE_material_gpencil_default_get();
MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL;
/* Calculate triangles cache for filling area (must be done only after changes) */
@@ -869,6 +872,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
short sthickness;
float ink[4];
const bool is_unique = (tgpw->gps != NULL);
+ const bool use_mat = (tgpw->gpd->mat != NULL);
GPU_program_point_size(true);
@@ -880,7 +884,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
continue;
}
/* check if the color is visible */
- Material *ma = tgpw->gpd->mat[gps->mat_nr];
+ Material *ma = (use_mat) ? tgpw->gpd->mat[gps->mat_nr] : BKE_material_gpencil_default_get();
MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL;
if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE) ||
@@ -1159,6 +1163,9 @@ void ED_gp_draw_interpolation(const bContext *C, tGPDinterpolate *tgpi, const in
copy_v4_v4(tgpw.tintcolor, color);
tgpw.onion = true;
tgpw.custonion = true;
+ if (obact->totcol == 0) {
+ tgpw.gpd->mat = NULL;
+ }
gp_draw_strokes(&tgpw);
}
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 3c4d43b5f53..ec26006eb06 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -1052,8 +1052,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
/* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */
if (gps_from->totpoints > gps_to->totpoints) {
/* free weights of removed points */
- if (gps_from->dvert != NULL) {
- BKE_defvert_array_free_elems(gps_from->dvert + gps_to->totpoints,
+ if (new_stroke->dvert != NULL) {
+ BKE_defvert_array_free_elems(new_stroke->dvert + gps_to->totpoints,
gps_from->totpoints - gps_to->totpoints);
}
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index fc7b0d8be8f..4bf43a2034a 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -83,6 +83,7 @@ void EDBM_mesh_clear(struct BMEditMesh *em);
void EDBM_selectmode_to_scene(struct bContext *C);
void EDBM_mesh_make(struct Object *ob, const int select_mode, const bool add_key_index);
void EDBM_mesh_free(struct BMEditMesh *em);
+void EDBM_mesh_load_ex(struct Main *bmain, struct Object *ob, bool free_data);
void EDBM_mesh_load(struct Main *bmain, struct Object *ob);
/* flushes based on the current select mode. if in vertex select mode,
@@ -236,6 +237,14 @@ void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* rename
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
bool EDBM_mesh_deselect_all_multi(struct bContext *C);
+bool EDBM_selectmode_disable_multi_ex(struct Scene *scene,
+ struct Base **bases,
+ const uint bases_len,
+ const short selectmode_disable,
+ const short selectmode_fallback);
+bool EDBM_selectmode_disable_multi(struct bContext *C,
+ const short selectmode_disable,
+ const short selectmode_fallback);
/* editmesh_preselect_edgering.c */
struct EditMesh_PreSelEdgeRing;
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index c15f299bca8..2bf50d3b4b8 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -739,10 +739,10 @@ DEF_ICON_BLANK(251)
DEF_ICON(AXIS_SIDE)
DEF_ICON(AXIS_FRONT)
DEF_ICON(AXIS_TOP)
-DEF_ICON(NDOF_DOM)
-DEF_ICON(NDOF_TURN)
-DEF_ICON(NDOF_FLY)
-DEF_ICON(NDOF_TRANS)
+DEF_ICON_BLANK(252)
+DEF_ICON_BLANK(252a)
+DEF_ICON_BLANK(252b)
+DEF_ICON_BLANK(252c)
DEF_ICON(LAYER_USED)
DEF_ICON(LAYER_ACTIVE)
/* available */
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 499842a570b..31cbd2a3831 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -2019,7 +2019,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const uiWidgetColors *wcol, cons
rctf line_range;
/* First curve point. */
- if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
line_range.xmin = rect->xmin;
line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
}
@@ -2028,7 +2028,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const uiWidgetColors *wcol, cons
line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
}
/* Last curve point. */
- if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
line_range.xmax = rect->xmax;
line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
}
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index 0cf357c508b..2b5cf2ed6b9 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -39,7 +39,7 @@
#include "RNA_access.h"
-#include "BIF_gl.h"
+#include "GPU_glew.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 11106dd403f..b34188684e6 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -294,6 +294,7 @@ typedef struct uiHandleButtonMulti {
typedef struct uiHandleButtonData {
wmWindowManager *wm;
wmWindow *window;
+ ScrArea *area;
ARegion *region;
bool interactive;
@@ -7721,7 +7722,8 @@ static void button_tooltip_timer_reset(bContext *C, uiBut *but)
if (!wm->drags.first) {
bool is_label = UI_but_has_tooltip_label(but);
double delay = is_label ? UI_TOOLTIP_DELAY_LABEL : UI_TOOLTIP_DELAY;
- WM_tooltip_timer_init_ex(C, data->window, data->region, ui_but_tooltip_init, delay);
+ WM_tooltip_timer_init_ex(
+ C, data->window, data->area, data->region, ui_but_tooltip_init, delay);
if (is_label) {
bScreen *sc = WM_window_get_active_screen(data->window);
if (sc->tool_tip) {
@@ -7927,6 +7929,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
data->wm = CTX_wm_manager(C);
data->window = CTX_wm_window(C);
+ data->area = CTX_wm_area(C);
BLI_assert(ar != NULL);
data->region = ar;
@@ -8009,7 +8012,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
/* Show a label for this button. */
bScreen *sc = WM_window_get_active_screen(data->window);
if ((PIL_check_seconds_timer() - WM_tooltip_time_closed()) < 0.1) {
- WM_tooltip_immediate_init(C, CTX_wm_window(C), ar, ui_but_tooltip_init);
+ WM_tooltip_immediate_init(C, CTX_wm_window(C), data->area, ar, ui_but_tooltip_init);
if (sc->tool_tip) {
sc->tool_tip->pass = 1;
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 956fd4514af..17247736d3b 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -3992,11 +3992,11 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
BKE_curvemapping_changed(cumap, false);
break;
case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
- cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemapping_changed(cumap, false);
break;
case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
- cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
+ cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemapping_changed(cumap, false);
break;
}
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 573dfcde88a..7582ef3f41d 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -127,7 +127,7 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
.apply_subdiv = RNA_boolean_get(op->ptr, "apply_subdiv"),
.curves_as_mesh = RNA_boolean_get(op->ptr, "curves_as_mesh"),
.flatten_hierarchy = RNA_boolean_get(op->ptr, "flatten"),
- .visible_layers_only = RNA_boolean_get(op->ptr, "visible_layers_only"),
+ .visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only"),
.renderable_only = RNA_boolean_get(op->ptr, "renderable_only"),
.face_sets = RNA_boolean_get(op->ptr, "face_sets"),
.use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"),
@@ -209,7 +209,7 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "renderable_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "visible_layers_only", 0, NULL, ICON_NONE);
+ uiItemR(row, imfptr, "visible_objects_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "flatten", 0, NULL, ICON_NONE);
@@ -392,10 +392,10 @@ void WM_OT_alembic_export(wmOperatorType *ot)
"Export only objects marked renderable in the outliner");
RNA_def_boolean(ot->srna,
- "visible_layers_only",
+ "visible_objects_only",
0,
- "Visible Layers Only",
- "Export only objects in visible layers");
+ "Visible Objects Only",
+ "Export only objects that are visible");
RNA_def_boolean(ot->srna,
"flatten",
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index b7f506a8a41..5c9fb866df7 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -36,8 +36,6 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
-#include "BIF_gl.h"
-
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index a709bd010aa..ebd1e62e596 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -22,7 +22,6 @@
*/
#include "DNA_curve_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BLI_math.h"
@@ -143,21 +142,7 @@ static int knifeproject_exec(bContext *C, wmOperator *op)
/* select only tagged faces */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
- if (ob->type == OB_MESH) {
- Mesh *me = (Mesh *)ob->data;
- BMEditMesh *embm = me->edit_mesh;
- if (embm) {
- /* not essential, but switch out of vertex mode since the
- * selected regions wont be nicely isolated after flushing.
- * note: call after de-select to avoid selection flushing.
- * note: do this on all participating meshes so this is in sync
- * e.g. for later selection picking, see T68852.*/
- EDBM_selectmode_disable(scene, embm, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
- }
- }
- }
- CTX_DATA_END;
+ EDBM_selectmode_disable_multi(C, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 7955ccc0977..40d57af97aa 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2653,6 +2653,41 @@ bool EDBM_mesh_deselect_all_multi(struct bContext *C)
return changed_multi;
}
+bool EDBM_selectmode_disable_multi_ex(Scene *scene,
+ struct Base **bases,
+ const uint bases_len,
+ const short selectmode_disable,
+ const short selectmode_fallback)
+{
+ bool changed_multi = false;
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ Object *ob_iter = base_iter->object;
+ BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
+
+ EDBM_selectmode_disable(scene, em_iter, selectmode_disable, selectmode_fallback);
+ changed_multi = true;
+ }
+ return changed_multi;
+}
+
+bool EDBM_selectmode_disable_multi(struct bContext *C,
+ const short selectmode_disable,
+ const short selectmode_fallback)
+{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewContext vc;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ vc.view_layer, NULL, &bases_len);
+ bool changed_multi = EDBM_selectmode_disable_multi_ex(
+ scene, bases, bases_len, selectmode_disable, selectmode_fallback);
+ MEM_freeN(bases);
+ return changed_multi;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 8df392fb04b..59090acf433 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4197,7 +4197,12 @@ static bool mesh_separate_loose(
BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
if (clear_object_data) {
- BM_mesh_bm_to_me(NULL, bm_old, me_old, (&(struct BMeshToMeshParams){0}));
+ BM_mesh_bm_to_me(NULL,
+ bm_old,
+ me_old,
+ (&(struct BMeshToMeshParams){
+ .update_shapekey_indices = true,
+ }));
}
finally:
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 44984251243..d07ba05de20 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -521,6 +521,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
(&(struct BMeshToMeshParams){
/* Undo code should not be manipulating 'G_MAIN->object' hooks/vertex-parent. */
.calc_object_remap = false,
+ .update_shapekey_indices = false,
.cd_mask_extra = {.vmask = CD_MASK_SHAPE_KEYINDEX},
}));
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 522c2f32d27..42404554ed8 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -325,7 +325,7 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
* \warning This can invalidate the #Mesh runtime cache of other objects (for linked duplicates).
* Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913
*/
-void EDBM_mesh_load(Main *bmain, Object *ob)
+void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
{
Mesh *me = ob->data;
BMesh *bm = me->edit_mesh->bm;
@@ -341,6 +341,7 @@ void EDBM_mesh_load(Main *bmain, Object *ob)
me,
(&(struct BMeshToMeshParams){
.calc_object_remap = true,
+ .update_shapekey_indices = !free_data,
}));
/* Free derived mesh. usually this would happen through depsgraph but there
@@ -380,6 +381,11 @@ void EDBM_mesh_clear(BMEditMesh *em)
}
}
+void EDBM_mesh_load(Main *bmain, Object *ob)
+{
+ EDBM_mesh_load_ex(bmain, ob, true);
+}
+
/**
* Should only be called on the active editmesh, otherwise call #BKE_editmesh_free
*/
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index be815fb0d10..b7c9579e277 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -445,7 +445,7 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
return false;
}
- EDBM_mesh_load(bmain, obedit);
+ EDBM_mesh_load_ex(bmain, obedit, freedata);
if (freedata) {
EDBM_mesh_free(me->edit_mesh);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 7106af25a82..5740dacd05f 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1173,7 +1173,7 @@ static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op)
CurveMap *cm = mblur_shutter_curve->cm;
int preset = RNA_enum_get(op->ptr, "shape");
- cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ mblur_shutter_curve->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
mblur_shutter_curve->preset = preset;
BKE_curvemap_reset(
cm, &mblur_shutter_curve->clipr, mblur_shutter_curve->preset, CURVEMAP_SLOPE_POS_NEG);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index f419d30a17e..0d0e183e480 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -18,7 +18,7 @@
*/
/** \file
- * \ingroup edrend
+ * \ingroup render
*/
#include <math.h>
@@ -77,7 +77,7 @@
#include "render_intern.h"
/* Define this to get timing information. */
-// #undef DEBUG_TIME
+// #define DEBUG_TIME
#ifdef DEBUG_TIME
# include "PIL_time.h"
@@ -138,6 +138,8 @@ typedef struct OGLRender {
TaskPool *task_pool;
bool pool_ok;
bool is_animation;
+
+ eImageFormatDepth color_depth;
SpinLock reports_lock;
unsigned int num_scheduled_frames;
ThreadMutex task_mutex;
@@ -356,6 +358,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
char err_out[256] = "unknown";
ImBuf *ibuf_view;
const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
+ int output_flags = oglrender->color_depth <= R_IMF_CHAN_DEPTH_8 ? IB_rect : IB_rectfloat;
if (view_context) {
ibuf_view = ED_view3d_draw_offscreen_imbuf(depsgraph,
@@ -365,7 +368,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
ar,
sizex,
sizey,
- IB_rectfloat,
+ output_flags,
alpha_mode,
oglrender->ofs_samples,
viewname,
@@ -385,7 +388,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
scene->camera,
oglrender->sizex,
oglrender->sizey,
- IB_rectfloat,
+ output_flags,
V3D_OFSDRAW_SHOW_ANNOTATION,
alpha_mode,
oglrender->ofs_samples,
@@ -528,6 +531,8 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
const bool is_animation = RNA_boolean_get(op->ptr, "animation");
const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
+ const eImageFormatDepth color_depth = (is_animation) ? scene->r.im_format.depth :
+ R_IMF_CHAN_DEPTH_32;
const int samples = U.ogl_multisamples;
char err_out[256] = "unknown";
@@ -600,6 +605,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->write_still = is_write_still && !is_animation;
oglrender->is_animation = is_animation;
+ oglrender->color_depth = color_depth;
oglrender->views_len = BKE_scene_multiview_num_views_get(&scene->r);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 6dc3a1ec1ac..1fe299e58a9 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -80,10 +80,10 @@
#include "IMB_imbuf_types.h"
#include "IMB_thumbs.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "GPU_shader.h"
+#include "GPU_glew.h"
#include "RE_pipeline.h"
#include "RE_engine.h"
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 78c9980134f..856072ec47a 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -648,7 +648,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
GPU_matrix_translate_2f(-x, -y);
/* scale based on tablet pressure */
- if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
+ if (primary && ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
const float scale = ups->size_pressure_value;
GPU_matrix_translate_2f(x, y);
GPU_matrix_scale_2f(scale, scale);
@@ -778,7 +778,7 @@ static bool paint_draw_cursor_overlay(
}
/* scale based on tablet pressure */
- if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
+ if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
do_pop = true;
GPU_matrix_push();
GPU_matrix_translate_2fv(center);
@@ -1075,7 +1075,7 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups,
unprojected_radius = paint_calc_object_space_radius(vc, location, projected_radius);
/* scale 3D brush radius by pressure */
- if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
+ if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
unprojected_radius *= ups->size_pressure_value;
}
@@ -1362,7 +1362,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
immUniformColor3fvAlpha(outline_col, outline_alpha);
/* draw brush outline */
- if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
+ if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
imm_draw_circle_wire_2d(
pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
/* outer at half alpha */
@@ -1407,8 +1407,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
immUniformColor3fvAlpha(outline_col, outline_alpha);
- if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush) &&
- mode != PAINT_MODE_SCULPT) {
+ if (ups->stroke_active && BKE_brush_use_size_pressure(brush) && mode != PAINT_MODE_SCULPT) {
imm_draw_circle_wire_3d(
pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
/* outer at half alpha */
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 9acc189ae95..0b770f17314 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -548,7 +548,7 @@ static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke, Po
return;
}
- if (BKE_brush_use_alpha_pressure(scene, brush)) {
+ if (BKE_brush_use_alpha_pressure(brush)) {
BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure * alphafac));
}
else {
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index ee359def68c..fc0c6d748cb 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -336,7 +336,7 @@ static bool paint_brush_update(bContext *C,
ups->pixel_radius = BKE_brush_size_get(scene, brush);
- if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, mode)) {
+ if (BKE_brush_use_size_pressure(brush) && paint_supports_dynamic_size(brush, mode)) {
ups->pixel_radius *= stroke->cached_size_pressure;
}
@@ -527,8 +527,8 @@ static void paint_brush_stroke_add_step(bContext *C,
* windows for some tablets, then we just skip first touch .. */
if (tablet && (pressure >= 0.99f) &&
((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) ||
- BKE_brush_use_alpha_pressure(scene, pop->s.brush) ||
- BKE_brush_use_size_pressure(scene, pop->s.brush))) {
+ BKE_brush_use_alpha_pressure(pop->s.brush) ||
+ BKE_brush_use_size_pressure(pop->s.brush))) {
return;
}
@@ -540,8 +540,8 @@ static void paint_brush_stroke_add_step(bContext *C,
* which is the sensitivity of the most sensitive pen tablet available */
if (tablet && (pressure < 0.0002f) &&
((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) ||
- BKE_brush_use_alpha_pressure(scene, pop->s.brush) ||
- BKE_brush_use_size_pressure(scene, pop->s.brush))) {
+ BKE_brush_use_alpha_pressure(pop->s.brush) ||
+ BKE_brush_use_size_pressure(pop->s.brush))) {
return;
}
#endif
@@ -756,7 +756,7 @@ static float paint_space_stroke_spacing_variable(bContext *C,
float dpressure,
float length)
{
- if (BKE_brush_use_size_pressure(scene, stroke->brush)) {
+ if (BKE_brush_use_size_pressure(stroke->brush)) {
/* use pressure to modify size. set spacing so that at 100%, the circles
* are aligned nicely with no overlap. for this the spacing needs to be
* the average of the previous and next size. */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index ac7cf310099..536d93cac29 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1522,7 +1522,7 @@ static void vwpaint_update_cache_variants(bContext *C, VPaint *vp, Object *ob, P
}
}
- if (BKE_brush_use_size_pressure(scene, brush) &&
+ if (BKE_brush_use_size_pressure(brush) &&
paint_supports_dynamic_size(brush, PAINT_MODE_SCULPT)) {
cache->radius = cache->initial_radius * cache->pressure;
}
@@ -1684,11 +1684,9 @@ static void get_brush_alpha_data(const Scene *scene,
float *r_brush_alpha_pressure)
{
*r_brush_size_pressure = BKE_brush_size_get(scene, brush) *
- (BKE_brush_use_size_pressure(scene, brush) ? ss->cache->pressure :
- 1.0f);
+ (BKE_brush_use_size_pressure(brush) ? ss->cache->pressure : 1.0f);
*r_brush_alpha_value = BKE_brush_alpha_get(scene, brush);
- *r_brush_alpha_pressure = (BKE_brush_use_alpha_pressure(scene, brush) ? ss->cache->pressure :
- 1.0f);
+ *r_brush_alpha_pressure = (BKE_brush_use_alpha_pressure(brush) ? ss->cache->pressure : 1.0f);
}
static float wpaint_get_active_weight(const MDeformVert *dv, const WeightPaintInfo *wpi)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 2e98d463945..9eb32a9f731 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -48,6 +48,7 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
+#include "BKE_kelvinlet.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -1723,7 +1724,7 @@ static float brush_strength(const Sculpt *sd,
const float root_alpha = BKE_brush_alpha_get(scene, brush);
float alpha = root_alpha * root_alpha;
float dir = (brush->flag & BRUSH_DIR_IN) ? -1 : 1;
- float pressure = BKE_brush_use_alpha_pressure(scene, brush) ? cache->pressure : 1;
+ float pressure = BKE_brush_use_alpha_pressure(brush) ? cache->pressure : 1;
float pen_flip = cache->pen_flip ? -1 : 1;
float invert = cache->invert ? -1 : 1;
float overlap = ups->overlap_factor;
@@ -1740,8 +1741,9 @@ static float brush_strength(const Sculpt *sd,
switch (brush->sculpt_tool) {
case SCULPT_TOOL_CLAY:
+ final_pressure = pow4f(pressure);
overlap = (1.0f + overlap) / 2.0f;
- return 0.25f * alpha * flip * pressure * overlap * feather;
+ return 0.25f * alpha * flip * final_pressure * overlap * feather;
case SCULPT_TOOL_DRAW:
case SCULPT_TOOL_DRAW_SHARP:
case SCULPT_TOOL_LAYER:
@@ -2631,152 +2633,48 @@ static void do_smooth_brush_multires_task_cb_ex(void *__restrict userdata,
const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
- SculptDoBrushSmoothGridDataChunk *data_chunk = tls->userdata_chunk;
SculptSession *ss = data->ob->sculpt;
Sculpt *sd = data->sd;
const Brush *brush = data->brush;
const bool smooth_mask = data->smooth_mask;
float bstrength = data->strength;
- CCGElem **griddata, *gddata;
-
- float(*tmpgrid_co)[3] = NULL;
- float tmprow_co[2][3];
- float *tmpgrid_mask = NULL;
- float tmprow_mask[2];
+ PBVHVertexIter vd;
- BLI_bitmap *const *grid_hidden;
- int *grid_indices, totgrid, gridsize;
- int i, x, y;
+ CLAMP(bstrength, 0.0f, 1.0f);
SculptBrushTest test;
SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(
ss, &test, data->brush->falloff_shape);
- CLAMP(bstrength, 0.0f, 1.0f);
-
- BKE_pbvh_node_get_grids(
- ss->pbvh, data->nodes[n], &grid_indices, &totgrid, NULL, &gridsize, &griddata);
- CCGKey key = *BKE_pbvh_get_grid_key(ss->pbvh);
-
- grid_hidden = BKE_pbvh_grid_hidden(ss->pbvh);
-
- if (smooth_mask) {
- tmpgrid_mask = (void *)(data_chunk + 1);
- }
- else {
- tmpgrid_co = (void *)(data_chunk + 1);
- }
-
- for (i = 0; i < totgrid; i++) {
- int gi = grid_indices[i];
- const BLI_bitmap *gh = grid_hidden[gi];
- gddata = griddata[gi];
-
- if (smooth_mask) {
- memset(tmpgrid_mask, 0, data_chunk->tmpgrid_size);
- }
- else {
- memset(tmpgrid_co, 0, data_chunk->tmpgrid_size);
- }
-
- for (y = 0; y < gridsize - 1; y++) {
- const int v = y * gridsize;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade = bstrength * tex_strength(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
+ vd.index,
+ tls->thread_id);
if (smooth_mask) {
- tmprow_mask[0] = (*CCG_elem_offset_mask(&key, gddata, v) +
- *CCG_elem_offset_mask(&key, gddata, v + gridsize));
+ float val = grids_neighbor_average_mask(ss, vd.index) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
}
else {
- add_v3_v3v3(tmprow_co[0],
- CCG_elem_offset_co(&key, gddata, v),
- CCG_elem_offset_co(&key, gddata, v + gridsize));
- }
-
- for (x = 0; x < gridsize - 1; x++) {
- const int v1 = x + y * gridsize;
- const int v2 = v1 + 1;
- const int v3 = v1 + gridsize;
- const int v4 = v3 + 1;
-
- if (smooth_mask) {
- float tmp;
-
- tmprow_mask[(x + 1) % 2] = (*CCG_elem_offset_mask(&key, gddata, v2) +
- *CCG_elem_offset_mask(&key, gddata, v4));
- tmp = tmprow_mask[(x + 1) % 2] + tmprow_mask[x % 2];
-
- tmpgrid_mask[v1] += tmp;
- tmpgrid_mask[v2] += tmp;
- tmpgrid_mask[v3] += tmp;
- tmpgrid_mask[v4] += tmp;
- }
- else {
- float tmp[3];
-
- add_v3_v3v3(tmprow_co[(x + 1) % 2],
- CCG_elem_offset_co(&key, gddata, v2),
- CCG_elem_offset_co(&key, gddata, v4));
- add_v3_v3v3(tmp, tmprow_co[(x + 1) % 2], tmprow_co[x % 2]);
-
- add_v3_v3(tmpgrid_co[v1], tmp);
- add_v3_v3(tmpgrid_co[v2], tmp);
- add_v3_v3(tmpgrid_co[v3], tmp);
- add_v3_v3(tmpgrid_co[v4], tmp);
- }
- }
- }
-
- /* blend with existing coordinates */
- for (y = 0; y < gridsize; y++) {
- for (x = 0; x < gridsize; x++) {
- float *co;
- const float *fno;
- float *mask;
- const int index = y * gridsize + x;
-
- if (gh) {
- if (BLI_BITMAP_TEST(gh, index)) {
- continue;
- }
- }
-
- co = CCG_elem_offset_co(&key, gddata, index);
- fno = CCG_elem_offset_no(&key, gddata, index);
- mask = CCG_elem_offset_mask(&key, gddata, index);
-
- if (sculpt_brush_test_sq_fn(&test, co)) {
- const float strength_mask = (smooth_mask ? 0.0f : *mask);
- const float fade =
- bstrength *
- tex_strength(
- ss, brush, co, sqrtf(test.dist), NULL, fno, strength_mask, 0, tls->thread_id);
- float f = 1.0f / 16.0f;
-
- if (x == 0 || x == gridsize - 1) {
- f *= 2.0f;
- }
-
- if (y == 0 || y == gridsize - 1) {
- f *= 2.0f;
- }
-
- if (smooth_mask) {
- *mask += ((tmpgrid_mask[index] * f) - *mask) * fade;
- }
- else {
- float *avg = tmpgrid_co[index];
- float val[3];
-
- mul_v3_fl(avg, f);
- sub_v3_v3v3(val, avg, co);
- madd_v3_v3v3fl(val, co, val, fade);
-
- sculpt_clip(sd, ss, co, val);
- }
- }
+ float avg[3], val[3];
+ grids_neighbor_average(ss, avg, vd.index);
+ sub_v3_v3v3(val, avg, vd.co);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
+ sculpt_clip(sd, ss, vd.co, val);
}
}
}
+ BKE_pbvh_vertex_iter_end;
}
static void smooth(Sculpt *sd,
@@ -2821,25 +2719,9 @@ static void smooth(Sculpt *sd,
BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
switch (type) {
- case PBVH_GRIDS: {
- int gridsize;
- size_t size;
- SculptDoBrushSmoothGridDataChunk *data_chunk;
-
- BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL, &gridsize, NULL);
- size = (size_t)gridsize;
- size = sizeof(float) * size * size * (smooth_mask ? 1 : 3);
- data_chunk = MEM_mallocN(sizeof(*data_chunk) + size, __func__);
- data_chunk->tmpgrid_size = size;
- size += sizeof(*data_chunk);
-
- settings.userdata_chunk = data_chunk;
- settings.userdata_chunk_size = size;
+ case PBVH_GRIDS:
BKE_pbvh_parallel_range(0, totnode, &data, do_smooth_brush_multires_task_cb_ex, &settings);
-
- MEM_freeN(data_chunk);
break;
- }
case PBVH_FACES:
BKE_pbvh_parallel_range(0, totnode, &data, do_smooth_brush_mesh_task_cb_ex, &settings);
break;
@@ -2847,10 +2729,6 @@ static void smooth(Sculpt *sd,
BKE_pbvh_parallel_range(0, totnode, &data, do_smooth_brush_bmesh_task_cb_ex, &settings);
break;
}
-
- if (ss->multires) {
- multires_stitch_grids(ob);
- }
}
}
@@ -3528,98 +3406,6 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
BKE_pbvh_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings);
}
-/* Regularized Kelvinlets: Sculpting Brushes based on Fundamental Solutions of Elasticity
- * Pixar Technical Memo #17-03 */
-
-typedef struct KelvinletParams {
- float f;
- float a;
- float b;
- float c;
- float radius_scaled;
-} KelvinletParams;
-
-static int sculpt_kelvinlet_get_scale_iteration_count(eBrushElasticDeformType type)
-{
- if (type == BRUSH_ELASTIC_DEFORM_GRAB) {
- return 1;
- }
- if (type == BRUSH_ELASTIC_DEFORM_GRAB_BISCALE) {
- return 2;
- }
- if (type == BRUSH_ELASTIC_DEFORM_GRAB_TRISCALE) {
- return 3;
- }
- return 0;
-}
-
-static void sculpt_kelvinet_integrate(void (*kelvinlet)(float disp[3],
- const float vertex_co[3],
- const float location[3],
- float normal[3],
- KelvinletParams *p),
- float r_disp[3],
- const float vertex_co[3],
- const float location[3],
- float normal[3],
- KelvinletParams *p)
-{
- float k[4][3], k_it[4][3];
- kelvinlet(k[0], vertex_co, location, normal, p);
- copy_v3_v3(k_it[0], k[0]);
- mul_v3_fl(k_it[0], 0.5f);
- add_v3_v3v3(k_it[0], vertex_co, k_it[0]);
- kelvinlet(k[1], k_it[0], location, normal, p);
- copy_v3_v3(k_it[1], k[1]);
- mul_v3_fl(k_it[1], 0.5f);
- add_v3_v3v3(k_it[1], vertex_co, k_it[1]);
- kelvinlet(k[2], k_it[1], location, normal, p);
- copy_v3_v3(k_it[2], k[2]);
- add_v3_v3v3(k_it[2], vertex_co, k_it[2]);
- sub_v3_v3v3(k_it[2], k_it[2], location);
- kelvinlet(k[3], k_it[2], location, normal, p);
- copy_v3_v3(r_disp, k[0]);
- madd_v3_v3fl(r_disp, k[1], 2);
- madd_v3_v3fl(r_disp, k[2], 2);
- add_v3_v3(r_disp, k[3]);
- mul_v3_fl(r_disp, 1.0f / 6.0f);
-}
-
-/* Regularized Kelvinlets: Formula (16) */
-static void sculpt_kelvinlet_scale(float disp[3],
- const float vertex_co[3],
- const float location[3],
- float UNUSED(normal[3]),
- KelvinletParams *p)
-{
- float r_v[3];
- sub_v3_v3v3(r_v, vertex_co, location);
- float r = len_v3(r_v);
- float r_e = sqrtf(r * r + p->radius_scaled * p->radius_scaled);
- float u = (2.0f * p->b - p->a) * ((1.0f / (r_e * r_e * r_e))) +
- ((3.0f * p->radius_scaled * p->radius_scaled) / (2.0f * r_e * r_e * r_e * r_e * r_e));
- float fade = u * p->c;
- mul_v3_v3fl(disp, r_v, fade * p->f);
-}
-
-/* Regularized Kelvinlets: Formula (15) */
-static void sculpt_kelvinlet_twist(float disp[3],
- const float vertex_co[3],
- const float location[3],
- float normal[3],
- KelvinletParams *p)
-{
- float r_v[3], q_r[3];
- sub_v3_v3v3(r_v, vertex_co, location);
- float r = len_v3(r_v);
- float r_e = sqrtf(r * r + p->radius_scaled * p->radius_scaled);
- float u = -p->a * ((1.0f / (r_e * r_e * r_e))) +
- ((3.0f * p->radius_scaled * p->radius_scaled) / (2.0f * r_e * r_e * r_e * r_e * r_e));
- float fade = u * p->c;
- cross_v3_v3v3(q_r, normal, r_v);
- mul_v3_v3fl(disp, q_r, fade * p->f);
-}
-
static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict UNUSED(tls))
@@ -3640,23 +3426,6 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
- /* Maybe this can be exposed to the user */
- float radius_e[3] = {1.0f, 2.0f, 2.0f};
- float r_e[3];
- float kvl[3];
- float radius_scaled[3];
-
- radius_scaled[0] = ss->cache->radius * radius_e[0];
- radius_scaled[1] = radius_scaled[0] * radius_e[1];
- radius_scaled[2] = radius_scaled[1] * radius_e[2];
-
- float shear_modulus = 1.0f;
- float poisson_ratio = brush->elastic_deform_volume_preservation;
-
- float a = 1.0f / (4.0f * (float)M_PI * shear_modulus);
- float b = a / (4.0f * (1.0f - poisson_ratio));
- float c = 2 * (3.0f * a - 2.0f * b);
-
float dir;
if (ss->cache->mouse[0] > ss->cache->initial_mouse[0]) {
dir = 1.0f;
@@ -3671,73 +3440,38 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
dir = -dir;
}
}
+
+ KelvinletParams params;
+ float force = len_v3(grab_delta) * dir * bstrength;
+ BKE_kelvinlet_init_params(
+ &params, ss->cache->radius, force, 1.0f, brush->elastic_deform_volume_preservation);
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
sculpt_orig_vert_data_update(&orig_data, &vd);
- float fade, final_disp[3], weights[3];
- float r = len_v3v3(location, orig_data.co);
- KelvinletParams params;
- params.a = a;
- params.b = b;
- params.c = c;
- params.radius_scaled = radius_scaled[0];
-
- int multi_scale_it = sculpt_kelvinlet_get_scale_iteration_count(brush->elastic_deform_type);
- for (int it = 0; it < max_ii(1, multi_scale_it); it++) {
- r_e[it] = sqrtf(r * r + radius_scaled[it] * radius_scaled[it]);
- }
-
- /* Regularized Kelvinlets: Formula (6) */
- for (int s_it = 0; s_it < multi_scale_it; s_it++) {
- kvl[s_it] = ((a - b) / r_e[s_it]) + ((b * r * r) / (r_e[s_it] * r_e[s_it] * r_e[s_it])) +
- ((a * radius_scaled[s_it] * radius_scaled[s_it]) /
- (2.0f * r_e[s_it] * r_e[s_it] * r_e[s_it]));
- }
-
+ float final_disp[3];
switch (brush->elastic_deform_type) {
- /* Regularized Kelvinlets: Multi-scale extrapolation. Formula (11) */
case BRUSH_ELASTIC_DEFORM_GRAB:
- fade = kvl[0] * c;
- mul_v3_v3fl(final_disp, grab_delta, fade * bstrength * 20.f);
+ BKE_kelvinlet_grab(final_disp, &params, orig_data.co, location, grab_delta);
+ mul_v3_fl(final_disp, bstrength * 20.0f);
break;
case BRUSH_ELASTIC_DEFORM_GRAB_BISCALE: {
- const float u = kvl[0] - kvl[1];
- fade = u * c / ((1.0f / radius_scaled[0]) - (1.0f / radius_scaled[1]));
- mul_v3_v3fl(final_disp, grab_delta, fade * bstrength * 20.0f);
+ BKE_kelvinlet_grab_biscale(final_disp, &params, orig_data.co, location, grab_delta);
+ mul_v3_fl(final_disp, bstrength * 20.0f);
break;
}
case BRUSH_ELASTIC_DEFORM_GRAB_TRISCALE: {
- weights[0] = 1.0f;
- weights[1] = -(
- (radius_scaled[2] * radius_scaled[2] - radius_scaled[0] * radius_scaled[0]) /
- (radius_scaled[2] * radius_scaled[2] - radius_scaled[1] * radius_scaled[1]));
- weights[2] = ((radius_scaled[1] * radius_scaled[1] - radius_scaled[0] * radius_scaled[0]) /
- (radius_scaled[2] * radius_scaled[2] - radius_scaled[1] * radius_scaled[1]));
-
- const float u = weights[0] * kvl[0] + weights[1] * kvl[1] + weights[2] * kvl[2];
- fade = u * c /
- (weights[0] / radius_scaled[0] + weights[1] / radius_scaled[1] +
- weights[2] / radius_scaled[2]);
- mul_v3_v3fl(final_disp, grab_delta, fade * bstrength * 20.0f);
+ BKE_kelvinlet_grab_triscale(final_disp, &params, orig_data.co, location, grab_delta);
+ mul_v3_fl(final_disp, bstrength * 20.0f);
break;
}
case BRUSH_ELASTIC_DEFORM_SCALE:
- params.f = len_v3(grab_delta) * dir * bstrength;
- sculpt_kelvinet_integrate(sculpt_kelvinlet_scale,
- final_disp,
- orig_data.co,
- location,
- ss->cache->sculpt_normal_symm,
- &params);
+ BKE_kelvinlet_scale(
+ final_disp, &params, orig_data.co, location, ss->cache->sculpt_normal_symm);
break;
case BRUSH_ELASTIC_DEFORM_TWIST:
- params.f = len_v3(grab_delta) * dir * bstrength;
- sculpt_kelvinet_integrate(sculpt_kelvinlet_twist,
- final_disp,
- orig_data.co,
- location,
- ss->cache->sculpt_normal_symm,
- &params);
+ BKE_kelvinlet_twist(
+ final_disp, &params, orig_data.co, location, ss->cache->sculpt_normal_symm);
break;
}
@@ -4926,7 +4660,6 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
float intr[3];
float val[3];
-
closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
sub_v3_v3v3(val, intr, vd.co);
@@ -4962,6 +4695,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
Brush *brush = BKE_paint_brush(&sd->paint);
const float radius = fabsf(ss->cache->radius);
+ const float initial_radius = fabsf(ss->cache->initial_radius);
bool flip = ss->cache->bstrength < 0.0f;
float offset = get_offset(sd, ss);
@@ -4997,7 +4731,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
d_offset = min_ff(radius, d_offset);
d_offset = d_offset / radius;
d_offset = 1.0f - d_offset;
- displace = fabsf(radius * (0.25f + offset + (d_offset * 0.15f)));
+ displace = fabsf(initial_radius * (0.25f + offset + (d_offset * 0.15f)));
if (flip) {
displace = -displace;
}
@@ -6781,8 +6515,10 @@ static void sculpt_update_cache_invariants(
static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, float initial_size)
{
switch (brush->sculpt_tool) {
+ case SCULPT_TOOL_CLAY:
+ return max_ff(initial_size * 0.20f, initial_size * pow3f(cache->pressure));
case SCULPT_TOOL_CLAY_STRIPS:
- return max_ff(initial_size * 0.35f, initial_size * cache->pressure * cache->pressure);
+ return max_ff(initial_size * 0.35f, initial_size * pow2f(cache->pressure));
default:
return initial_size * cache->pressure;
}
@@ -6986,12 +6722,14 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
}
}
- if (BKE_brush_use_size_pressure(scene, brush) &&
+ if (BKE_brush_use_size_pressure(brush) &&
paint_supports_dynamic_size(brush, PAINT_MODE_SCULPT)) {
cache->radius = sculpt_brush_dynamic_size_get(brush, cache, cache->initial_radius);
+ cache->dyntopo_radius = cache->initial_radius * cache->pressure;
}
else {
cache->radius = cache->initial_radius;
+ cache->dyntopo_radius = cache->initial_radius;
}
cache->radius_squared = cache->radius * cache->radius;
@@ -7402,14 +7140,13 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
{
- SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
/* Restore the mesh before continuing with anchored stroke */
if ((brush->flag & BRUSH_ANCHORED) ||
((brush->sculpt_tool == SCULPT_TOOL_GRAB ||
brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) &&
- BKE_brush_use_size_pressure(ss->cache->vc->scene, brush)) ||
+ BKE_brush_use_size_pressure(brush)) ||
(brush->flag & BRUSH_DRAG_DOT)) {
paint_mesh_restore_co(sd, ob);
}
@@ -7603,11 +7340,12 @@ static void sculpt_stroke_update_step(bContext *C,
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
}
else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
- BKE_pbvh_bmesh_detail_size_set(ss->pbvh, ss->cache->radius * sd->detail_percent / 100.0f);
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
+ ss->cache->dyntopo_radius * sd->detail_percent / 100.0f);
}
else {
BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
- (ss->cache->radius / (float)ups->pixel_radius) *
+ (ss->cache->dyntopo_radius / (float)ups->pixel_radius) *
(float)(sd->detail_size * U.pixelsize) / 0.4f);
}
@@ -8710,36 +8448,60 @@ static void SCULPT_OT_detail_flood_fill(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void sample_detail(bContext *C, int mx, int my)
+typedef enum eSculptSampleDetailModeTypes {
+ SAMPLE_DETAIL_DYNTOPO = 0,
+ SAMPLE_DETAIL_VOXEL = 1,
+} eSculptSampleDetailModeTypes;
+
+static EnumPropertyItem prop_sculpt_sample_detail_mode_types[] = {
+ {SAMPLE_DETAIL_DYNTOPO, "DYNTOPO", 0, "Dyntopo", "Sample dyntopo detail"},
+ {SAMPLE_DETAIL_VOXEL, "VOXEL", 0, "Voxel", "Sample mesh voxel size"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my)
{
- /* Find 3D view to pick from. */
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, mx, my);
- ARegion *ar = (sa) ? BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my) : NULL;
- if (ar == NULL) {
- return;
- }
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = vc->obact;
+ Mesh *mesh = ob->data;
- /* Set context to 3D view. */
- ScrArea *prev_sa = CTX_wm_area(C);
- ARegion *prev_ar = CTX_wm_region(C);
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
+ SculptSession *ss = ob->sculpt;
+ SculptCursorGeometryInfo sgi;
+ sculpt_vertex_random_access_init(ss);
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ /* Update the active vertex */
+ float mouse[2] = {mx, my};
+ sculpt_cursor_geometry_info_update(C, &sgi, mouse, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
- /* Pick sample detail. */
+ /* Average the edge length of the connected edges to the active vertex */
+ int active_vertex = sculpt_active_vertex_get(ss);
+ const float *active_vertex_co = sculpt_active_vertex_co_get(ss);
+ float edge_length = 0.0f;
+ int tot = 0;
+ SculptVertexNeighborIter ni;
+ sculpt_vertex_neighbors_iter_begin(ss, active_vertex, ni)
+ {
+ edge_length += len_v3v3(active_vertex_co, sculpt_vertex_co_get(ss, ni.index));
+ tot += 1;
+ }
+ sculpt_vertex_neighbors_iter_end(ni);
+ if (tot > 0) {
+ mesh->remesh_voxel_size = edge_length / (float)tot;
+ }
+}
+
+static void sample_detail_dyntopo(bContext *C, ViewContext *vc, ARegion *ar, int mx, int my)
+{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- Object *ob = vc.obact;
+ Object *ob = vc->obact;
Brush *brush = BKE_paint_brush(&sd->paint);
sculpt_stroke_modifiers_check(C, ob, brush);
float mouse[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
float ray_start[3], ray_end[3], ray_normal[3];
- float depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
+ float depth = sculpt_raycast_init(vc, mouse, ray_start, ray_end, ray_normal, false);
SculptDetailRaycastData srd;
srd.hit = 0;
@@ -8754,6 +8516,37 @@ static void sample_detail(bContext *C, int mx, int my)
/* Convert edge length to world space detail resolution. */
sd->constant_detail = 1 / (srd.edge_length * mat4_to_scale(ob->obmat));
}
+}
+
+static void sample_detail(bContext *C, int mx, int my, int mode)
+{
+ /* Find 3D view to pick from. */
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, mx, my);
+ ARegion *ar = (sa) ? BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my) : NULL;
+ if (ar == NULL) {
+ return;
+ }
+
+ /* Set context to 3D view. */
+ ScrArea *prev_sa = CTX_wm_area(C);
+ ARegion *prev_ar = CTX_wm_region(C);
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ViewContext vc;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+
+ /* Pick sample detail. */
+ switch (mode) {
+ case SAMPLE_DETAIL_DYNTOPO:
+ sample_detail_dyntopo(C, &vc, ar, mx, my);
+ break;
+ case SAMPLE_DETAIL_VOXEL:
+ sample_detail_voxel(C, &vc, mx, my);
+ break;
+ }
/* Restore context. */
CTX_wm_area_set(C, prev_sa);
@@ -8764,7 +8557,8 @@ static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op)
{
int ss_co[2];
RNA_int_get_array(op->ptr, "location", ss_co);
- sample_detail(C, ss_co[0], ss_co[1]);
+ int mode = RNA_enum_get(op->ptr, "mode");
+ sample_detail(C, ss_co[0], ss_co[1], mode);
return OPERATOR_FINISHED;
}
@@ -8783,7 +8577,8 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm
if (event->val == KM_PRESS) {
int ss_co[2] = {event->x, event->y};
- sample_detail(C, ss_co[0], ss_co[1]);
+ int mode = RNA_enum_get(op->ptr, "mode");
+ sample_detail(C, ss_co[0], ss_co[1], mode);
RNA_int_set_array(op->ptr, "location", ss_co);
WM_cursor_modal_restore(CTX_wm_window(C));
@@ -8816,7 +8611,7 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
ot->invoke = sculpt_sample_detail_size_invoke;
ot->exec = sculpt_sample_detail_size_exec;
ot->modal = sculpt_sample_detail_size_modal;
- ot->poll = sculpt_and_constant_or_manual_detail_poll;
+ ot->poll = sculpt_mode_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8830,6 +8625,12 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
"Screen Coordinates of sampling",
0,
SHRT_MAX);
+ RNA_def_enum(ot->srna,
+ "mode",
+ prop_sculpt_sample_detail_mode_types,
+ SAMPLE_DETAIL_DYNTOPO,
+ "Detail Mode",
+ "Target sculpting workflow that is going to use the sampled size");
}
/* Dynamic-topology detail size
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 0b25ab31ce0..324ca250c86 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -318,6 +318,10 @@ typedef struct StrokeCache {
float true_last_location[3];
float location[3];
float last_location[3];
+
+ /* This radius variable is not affected by pressure curves */
+ float dyntopo_radius;
+
bool is_last_valid;
bool pen_flip;
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 1685852dd02..901efbdf0ff 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -71,7 +71,7 @@ static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
saction->autosnap = SACTSNAP_FRAME;
saction->mode = SACTCONT_DOPESHEET;
saction->mode_prev = SACTCONT_DOPESHEET;
- saction->flag = SACTION_SHOW_INTERPOLATION | SACTION_SHOW_MARKER_LINES;
+ saction->flag = SACTION_SHOW_INTERPOLATION | SACTION_SHOW_MARKERS;
saction->ads.filterflag |= ADS_FILTER_SUMMARY;
@@ -215,10 +215,10 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
marker_flag = ((ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0) |
DRAW_MARKERS_MARGIN;
- if (saction->flag & SACTION_SHOW_MARKER_LINES) {
- marker_flag |= DRAW_MARKERS_LINES;
+
+ if (saction->flag & SACTION_SHOW_MARKERS) {
+ ED_markers_draw(C, marker_flag);
}
- ED_markers_draw(C, marker_flag);
/* caches */
if (saction->mode == SACTCONT_TIMELINE) {
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index b8d9d3b791f..eb7ba480296 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -81,7 +81,7 @@ static SpaceLink *graph_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* settings for making it easier by default to just see what you're interested in tweaking */
sipo->ads->filterflag |= ADS_FILTER_ONLYSEL;
- sipo->flag |= SIPO_SELVHANDLESONLY | SIPO_MARKER_LINES;
+ sipo->flag |= SIPO_SELVHANDLESONLY | SIPO_SHOW_MARKERS;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for graphedit");
@@ -296,10 +296,9 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
if (sipo->mode != SIPO_MODE_DRIVERS) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
int marker_draw_flag = DRAW_MARKERS_MARGIN;
- if (sipo->flag & SIPO_MARKER_LINES) {
- marker_draw_flag |= DRAW_MARKERS_LINES;
+ if (sipo->flag & SIPO_SHOW_MARKERS) {
+ ED_markers_draw(C, marker_draw_flag);
}
- ED_markers_draw(C, marker_draw_flag);
}
/* preview range */
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index b51aec90e4f..225ca72a7d0 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -123,6 +123,10 @@ static bool stats_mesheval(Mesh *me_eval, bool is_selected, SceneStats *stats)
static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
{
+ if ((ob->base_flag & BASE_VISIBLE_VIEWLAYER) == 0) {
+ return;
+ }
+
const bool is_selected = (ob->base_flag & BASE_SELECTED) != 0;
stats->totobj++;
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index f274f3c93ec..5cd2a86adf8 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -71,7 +71,7 @@ static SpaceLink *nla_new(const ScrArea *sa, const Scene *scene)
/* set auto-snapping settings */
snla->autosnap = SACTSNAP_FRAME;
- snla->flag = SNLA_SHOW_MARKER_LINES;
+ snla->flag = SNLA_SHOW_MARKERS;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for nla");
@@ -274,10 +274,9 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
int marker_draw_flag = DRAW_MARKERS_MARGIN;
- if (snla->flag & SNLA_SHOW_MARKER_LINES) {
- marker_draw_flag |= DRAW_MARKERS_LINES;
+ if (snla->flag & SNLA_SHOW_MARKERS) {
+ ED_markers_draw(C, marker_draw_flag);
}
- ED_markers_draw(C, marker_draw_flag);
/* preview range */
UI_view2d_view_ortho(v2d);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 5ca4ae7b666..70cb28fa937 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -2067,10 +2067,9 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
int marker_draw_flag = DRAW_MARKERS_MARGIN;
- if (sseq->flag & SEQ_SHOW_MARKER_LINES) {
- marker_draw_flag |= DRAW_MARKERS_LINES;
+ if (sseq->flag & SEQ_SHOW_MARKERS) {
+ ED_markers_draw(C, marker_draw_flag);
}
- ED_markers_draw(C, marker_draw_flag);
UI_view2d_view_ortho(v2d);
/* draw cache on top of markers area */
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index e1cf6d00b90..6e1b9d62f0e 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -93,7 +93,7 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(sa), const Scene *scene)
sseq->chanshown = 0;
sseq->view = SEQ_VIEW_SEQUENCE;
sseq->mainb = SEQ_DRAW_IMG_IMBUF;
- sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKER_LINES;
+ sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKERS;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for sequencer");
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 3ee9755cb06..5f029e840d3 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1121,13 +1121,6 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
immEnd();
immUnbindProgram();
-# if 0
- /* find screen coordinates for rotation center, then draw pretty icon */
- mul_m4_v3(rv3d->persinv, rot_center);
- UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
- /* ^^ just playing around, does not work */
-# endif
-
GPU_blend(false);
glDepthMask(GL_TRUE);
}
@@ -1866,9 +1859,11 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
if (drawtype == OB_MATERIAL) {
v3d.shading.flag = V3D_SHADING_SCENE_WORLD | V3D_SHADING_SCENE_LIGHTS;
+ v3d.shading.render_pass = SCE_PASS_COMBINED;
}
else if (drawtype == OB_RENDER) {
v3d.shading.flag = V3D_SHADING_SCENE_WORLD_RENDER | V3D_SHADING_SCENE_LIGHTS_RENDER;
+ v3d.shading.render_pass = SCE_PASS_COMBINED;
}
v3d.flag2 = V3D_HIDE_OVERLAYS;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 3ad194a5d2b..d40f79cea3f 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -992,8 +992,17 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
* \{ */
#ifdef WITH_INPUT_NDOF
-# define NDOF_HAS_TRANSLATE ((!ED_view3d_offset_lock_check(v3d, rv3d)) && !is_zero_v3(ndof->tvec))
-# define NDOF_HAS_ROTATE (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
+static bool ndof_has_translate(const wmNDOFMotionData *ndof,
+ const View3D *v3d,
+ const RegionView3D *rv3d)
+{
+ return !is_zero_v3(ndof->tvec) && (!ED_view3d_offset_lock_check(v3d, rv3d));
+}
+
+static bool ndof_has_rotate(const wmNDOFMotionData *ndof, const RegionView3D *rv3d)
+{
+ return !is_zero_v3(ndof->rvec) && ((rv3d->viewlock & RV3D_LOCKED) == 0);
+}
/**
* \param depth_pt: A point to calculate the depth (in perspective mode)
@@ -1189,8 +1198,8 @@ void view3d_ndof_fly(const wmNDOFMotionData *ndof,
bool *r_has_translate,
bool *r_has_rotate)
{
- bool has_translate = NDOF_HAS_TRANSLATE;
- bool has_rotate = NDOF_HAS_ROTATE;
+ bool has_translate = ndof_has_translate(ndof, v3d, rv3d);
+ bool has_rotate = ndof_has_rotate(ndof, rv3d);
float view_inv[4];
invert_qt_qt_normalized(view_inv, rv3d->viewquat);
@@ -1338,9 +1347,10 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
if (ndof->progress != P_FINISHING) {
- const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_rotation = ndof_has_rotate(ndof, rv3d);
/* if we can't rotate, fallback to translate (locked axis views) */
- const bool has_translate = NDOF_HAS_TRANSLATE && (rv3d->viewlock & RV3D_LOCKED);
+ const bool has_translate = ndof_has_translate(ndof, v3d, rv3d) &&
+ (rv3d->viewlock & RV3D_LOCKED);
const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
if (has_translate || has_zoom) {
@@ -1423,7 +1433,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
}
else if ((rv3d->persp == RV3D_ORTHO) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
/* if we can't rotate, fallback to translate (locked axis views) */
- const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_translate = ndof_has_translate(ndof, v3d, rv3d);
const bool has_zoom = (ndof->tvec[2] != 0.0f) && ED_view3d_offset_lock_check(v3d, rv3d);
if (has_translate || has_zoom) {
@@ -1431,41 +1441,33 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
xform_flag |= HAS_TRANSLATE;
}
}
- else if ((U.ndof_flag & NDOF_MODE_ORBIT) || ED_view3d_offset_lock_check(v3d, rv3d)) {
- const bool has_rotation = NDOF_HAS_ROTATE;
+ else {
+ /* Note: based on feedback from T67579, users want to have pan and orbit enabled at once.
+ * It's arguable that orbit shouldn't pan (since we have a pan only operator),
+ * so if there are users who like to separate orbit/pan operations - it can be a preference. */
+ const bool is_orbit_around_pivot = (U.ndof_flag & NDOF_MODE_ORBIT) ||
+ ED_view3d_offset_lock_check(v3d, rv3d);
+ const bool has_rotation = ndof_has_rotate(ndof, rv3d);
+ const bool has_translate = !is_zero_v2(ndof->tvec) && ndof_has_translate(ndof, v3d, rv3d);
const bool has_zoom = (ndof->tvec[2] != 0.0f);
- if (has_zoom) {
- view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, false, has_zoom);
- xform_flag |= HAS_TRANSLATE;
- }
-
+ /* Rotation first because dynamic offset resets offset otherwise (and disasbles panning). */
if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
+ const float dist_backup = rv3d->dist;
+ if (!is_orbit_around_pivot) {
+ ED_view3d_distance_set(rv3d, 0.0f);
+ }
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, is_orbit_around_pivot);
xform_flag |= HAS_ROTATE;
+ if (!is_orbit_around_pivot) {
+ ED_view3d_distance_set(rv3d, dist_backup);
+ }
}
- }
- else { /* free/explore (like fly mode) */
- const bool has_rotation = NDOF_HAS_ROTATE;
- const bool has_translate = NDOF_HAS_TRANSLATE;
- const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
-
- float dist_backup;
if (has_translate || has_zoom) {
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
xform_flag |= HAS_TRANSLATE;
}
-
- dist_backup = rv3d->dist;
- ED_view3d_distance_set(rv3d, 0.0f);
-
- if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, false);
- xform_flag |= HAS_ROTATE;
- }
-
- ED_view3d_distance_set(rv3d, dist_backup);
}
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
@@ -1514,7 +1516,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e
const wmNDOFMotionData *ndof = event->customdata;
char xform_flag = 0;
- const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_translate = ndof_has_translate(ndof, v3d, rv3d);
const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
/* we're panning here! so erase any leftover rotation from other operators */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index f3d26f85471..74fc1406795 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -5262,12 +5262,12 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
copy_v3_v3(tvec, vec);
}
+ mul_m3_v3(td->smtx, tvec);
+
if (use_rotate_offset) {
add_v3_v3(tvec, rotate_offset);
}
- mul_m3_v3(td->smtx, tvec);
-
if (t->options & CTX_GPENCIL_STROKES) {
/* grease pencil multiframe falloff */
bGPDstroke *gps = (bGPDstroke *)td->extra;
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 0c52dd15092..987327eefc1 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -44,7 +44,6 @@ set(SRC
select_utils.c
# general includes
- ../include/BIF_gl.h
../include/BIF_glutil.h
../include/ED_anim_api.h
../include/ED_armature.h
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 367ad556d02..a6512a64776 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -266,8 +266,8 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
cumap = (CurveMapping *)py_srna->ptr.data;
BKE_curvemapping_initialize(cumap);
/* disable extrapolation if enabled */
- if ((cumap->cm[cur].flag & CUMA_EXTEND_EXTRAPOLATE)) {
- cumap->cm[cur].flag &= ~(CUMA_EXTEND_EXTRAPOLATE);
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE)) {
+ cumap->flag &= ~(CUMA_EXTEND_EXTRAPOLATE);
BKE_curvemapping_changed(cumap, 0);
}
return PyFloat_FromDouble(BKE_curvemapping_evaluateF(cumap, cur, value));
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
index 01bb0ae2b93..e3ad5a64ac3 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
@@ -71,8 +71,14 @@ static int remapTime(struct GpencilModifierData *md,
const bool invpass = mmd->flag & GP_TIME_INVERT_LAYERPASS;
int sfra = custom ? mmd->sfra : scene->r.sfra;
int efra = custom ? mmd->efra : scene->r.efra;
- CLAMP_MIN(sfra, 1);
- CLAMP_MIN(efra, 1);
+ CLAMP_MIN(sfra, 0);
+ CLAMP_MIN(efra, 0);
+
+ /* Avoid inverse ranges. */
+ if (efra < sfra) {
+ return cfra;
+ }
+
const int time_range = efra - sfra + 1;
int offset = mmd->offset;
int segments = 0;
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 4bbcb6a4335..e692262358b 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -32,6 +32,7 @@
#include "GPU_texture.h"
#define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT */
+#define GLA_PIXEL_OFS 0.375f
typedef struct GPUViewport GPUViewport;
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 8b372c0b110..717983f94d8 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -696,11 +696,24 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
// BLI_assert(v_first + v_count <=
// (batch->elem ? batch->elem->index_len : batch->verts[0]->vertex_len));
+#ifdef __APPLE__
+ GLuint vao = 0;
+#endif
+
if (!GPU_arb_base_instance_is_supported()) {
if (i_first > 0) {
+#ifdef __APPLE__
+ /**
+ * There seems to be a nasty bug when drawing using the same VAO reconfiguring. (see T71147)
+ * We just use a throwaway VAO for that. Note that this is likely to degrade performance.
+ **/
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+#else
/* If using offset drawing with instancing, we must
* use the default VAO and redo bindings. */
glBindVertexArray(GPU_vao_default());
+#endif
batch_update_program_bindings(batch, i_first);
}
else {
@@ -739,6 +752,12 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
glEnable(GL_PRIMITIVE_RESTART);
#endif
}
+
+#ifdef __APPLE__
+ if (vao != 0) {
+ glDeleteVertexArrays(1, &vao);
+ }
+#endif
}
/* just draw some vertices and let shader place them where we want. */
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 1a7b999514c..972ff87ebcf 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -29,8 +29,6 @@
#include "BLI_rect.h"
#include "BLI_memblock.h"
-#include "BIF_gl.h"
-
#include "DNA_vec_types.h"
#include "DNA_userdef_types.h"
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 1b911226c6f..71e9da70c35 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1029,11 +1029,11 @@ void IMB_colormanagement_init_default_view_settings(
static void curve_mapping_apply_pixel(CurveMapping *curve_mapping, float *pixel, int channels)
{
if (channels == 1) {
- pixel[0] = BKE_curvemap_evaluateF(curve_mapping->cm, pixel[0]);
+ pixel[0] = BKE_curvemap_evaluateF(curve_mapping, curve_mapping->cm, pixel[0]);
}
else if (channels == 2) {
- pixel[0] = BKE_curvemap_evaluateF(curve_mapping->cm, pixel[0]);
- pixel[1] = BKE_curvemap_evaluateF(curve_mapping->cm, pixel[1]);
+ pixel[0] = BKE_curvemap_evaluateF(curve_mapping, curve_mapping->cm, pixel[0]);
+ pixel[1] = BKE_curvemap_evaluateF(curve_mapping, curve_mapping->cm, pixel[1]);
}
else {
BKE_curvemapping_evaluate_premulRGBF(curve_mapping, pixel, pixel);
@@ -3904,10 +3904,11 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
BKE_curvemapping_table_RGBA(
curve_mapping, &curve_mapping_settings->lut, &curve_mapping_settings->lut_size);
+ curve_mapping_settings->use_extend_extrapolate = (curve_mapping->flag &
+ CUMA_EXTEND_EXTRAPOLATE) != 0;
+
for (i = 0; i < 4; i++) {
CurveMap *cuma = curve_mapping->cm + i;
- curve_mapping_settings->use_extend_extrapolate[i] = (cuma->flag & CUMA_EXTEND_EXTRAPOLATE) !=
- 0;
curve_mapping_settings->range[i] = cuma->range;
curve_mapping_settings->mintable[i] = cuma->mintable;
curve_mapping_settings->ext_in_x[i] = cuma->ext_in[0];
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index b7834e2c7e0..b95a4ca3d96 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -28,6 +28,10 @@
#ifndef __DNA_ACTION_TYPES_H__
#define __DNA_ACTION_TYPES_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "DNA_listBase.h"
#include "DNA_ID.h"
#include "DNA_view2d_types.h"
@@ -856,8 +860,8 @@ typedef enum eSAction_Flag {
SACTION_SHOW_INTERPOLATION = (1 << 12),
/* show extremes */
SACTION_SHOW_EXTREMES = (1 << 13),
- /* show vertical line markers */
- SACTION_SHOW_MARKER_LINES = (1 << 14),
+ /* show markers region */
+ SACTION_SHOW_MARKERS = (1 << 14),
} eSAction_Flag;
/* SpaceAction_Runtime.flag */
@@ -955,4 +959,8 @@ typedef enum eActionChannelFlag {
ACHAN_MOVED = (1u << 31),
} eActionChannelFlag;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __DNA_ACTION_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index 219fc96554a..66adc547cf2 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -24,6 +24,7 @@
#ifndef __DNA_COLOR_TYPES_H__
#define __DNA_COLOR_TYPES_H__
+#include "DNA_defs.h"
#include "DNA_vec_types.h"
/* general defines for kernel functions */
@@ -47,7 +48,8 @@ enum {
};
typedef struct CurveMap {
- short totpoint, flag;
+ short totpoint;
+ short flag DNA_DEPRECATED;
/** Quick multiply value for reading table. */
float range;
@@ -67,9 +69,6 @@ typedef struct CurveMap {
float premul_ext_out[2];
} CurveMap;
-/* cuma->flag */
-#define CUMA_EXTEND_EXTRAPOLATE 1
-
typedef struct CurveMapping {
/** Cur; for buttons, to show active curve. */
int flag, cur;
@@ -93,11 +92,17 @@ typedef struct CurveMapping {
char _pad[6];
} CurveMapping;
-/* cumapping->flag */
-#define CUMA_DO_CLIP (1 << 0)
-#define CUMA_PREMULLED (1 << 1)
-#define CUMA_DRAW_CFRA (1 << 2)
-#define CUMA_DRAW_SAMPLE (1 << 3)
+/* CurveMapping.flag */
+typedef enum eCurveMappingFlags {
+ CUMA_DO_CLIP = (1 << 0),
+ CUMA_PREMULLED = (1 << 1),
+ CUMA_DRAW_CFRA = (1 << 2),
+ CUMA_DRAW_SAMPLE = (1 << 3),
+
+ /* The curve is extended by extrapolation. When not set the curve is extended
+ * Horizontally */
+ CUMA_EXTEND_EXTRAPOLATE = (1 << 4),
+} eCurveMappingFlags;
/* cumapping->preset */
typedef enum eCurveMappingPreset {
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index fb9e522dfa9..60e0eb2976e 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -28,6 +28,10 @@
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct AnimData;
struct Ipo;
struct Key;
@@ -277,4 +281,8 @@ enum {
#define MESH_MAX_VERTS 2000000000L
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h
index 8de79d9ea2b..2e0c43bdb51 100644
--- a/source/blender/makesdna/DNA_movieclip_types.h
+++ b/source/blender/makesdna/DNA_movieclip_types.h
@@ -24,6 +24,10 @@
#ifndef __DNA_MOVIECLIP_TYPES_H__
#define __DNA_MOVIECLIP_TYPES_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "DNA_ID.h"
#include "DNA_tracking_types.h"
#include "DNA_color_types.h" /* for color management */
@@ -207,4 +211,8 @@ enum {
MCLIP_PROXY_RENDER_USE_FALLBACK_RENDER = 2,
};
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 0de43c1632f..54ae38f608c 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -483,13 +483,23 @@ typedef struct ImageFormatData {
#define R_IMF_FLAG_PREVIEW_JPG (1 << 1) /* was R_PREVIEW_JPG */
/* return values from BKE_imtype_valid_depths, note this is depts per channel */
-#define R_IMF_CHAN_DEPTH_1 (1 << 0) /* 1bits (unused) */
-#define R_IMF_CHAN_DEPTH_8 (1 << 1) /* 8bits (default) */
-#define R_IMF_CHAN_DEPTH_10 (1 << 2) /* 10bits (uncommon, Cineon/DPX support) */
-#define R_IMF_CHAN_DEPTH_12 (1 << 3) /* 12bits (uncommon, jp2/DPX support) */
-#define R_IMF_CHAN_DEPTH_16 (1 << 4) /* 16bits (tiff, halff float exr) */
-#define R_IMF_CHAN_DEPTH_24 (1 << 5) /* 24bits (unused) */
-#define R_IMF_CHAN_DEPTH_32 (1 << 6) /* 32bits (full float exr) */
+/* ImageFormatData.depth */
+typedef enum eImageFormatDepth {
+ /* 1bits (unused) */
+ R_IMF_CHAN_DEPTH_1 = (1 << 0),
+ /* 8bits (default) */
+ R_IMF_CHAN_DEPTH_8 = (1 << 1),
+ /* 10bits (uncommon, Cineon/DPX support) */
+ R_IMF_CHAN_DEPTH_10 = (1 << 2),
+ /* 12bits (uncommon, jp2/DPX support) */
+ R_IMF_CHAN_DEPTH_12 = (1 << 3),
+ /* 16bits (tiff, half float exr) */
+ R_IMF_CHAN_DEPTH_16 = (1 << 4),
+ /* 24bits (unused) */
+ R_IMF_CHAN_DEPTH_24 = (1 << 5),
+ /* 32bits (full float exr) */
+ R_IMF_CHAN_DEPTH_32 = (1 << 6),
+} eImageFormatDepth;
/* ImageFormatData.planes */
#define R_IMF_PLANES_RGB 24
@@ -1288,14 +1298,11 @@ typedef enum {
UNIFIED_PAINT_WEIGHT = (1 << 5),
UNIFIED_PAINT_COLOR = (1 << 6),
- /* only used if unified size is enabled, mirrors the brush flags
- * BRUSH_LOCK_SIZE and BRUSH_SIZE_PRESSURE */
+ /* only used if unified size is enabled, mirrors the brush flag BRUSH_LOCK_SIZE */
UNIFIED_PAINT_BRUSH_LOCK_SIZE = (1 << 2),
- UNIFIED_PAINT_BRUSH_SIZE_PRESSURE = (1 << 3),
+ UNIFIED_PAINT_FLAG_UNUSED_0 = (1 << 3),
- /* only used if unified alpha is enabled, mirrors the brush flag
- * BRUSH_ALPHA_PRESSURE */
- UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE = (1 << 4),
+ UNIFIED_PAINT_FLAG_UNUSED_1 = (1 << 4),
} eUnifiedPaintSettingsFlags;
typedef struct CurvePaintSettings {
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 8d9dc77c49b..fb941a61ae8 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -37,6 +37,10 @@
#include "DNA_vec_types.h"
#include "DNA_vfont_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct Ipo;
struct MovieClip;
struct Scene;
@@ -680,4 +684,8 @@ enum {
SEQ_CACHE_PREFETCH_ENABLE = (1 << 10),
};
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __DNA_SEQUENCE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 1ce282a5a91..7692a4b17bb 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -466,8 +466,8 @@ typedef enum eGraphEdit_Flag {
/* normalize curves on display */
SIPO_NORMALIZE = (1 << 14),
SIPO_NORMALIZE_FREEZE = (1 << 15),
- /* show vertical line for every marker */
- SIPO_MARKER_LINES = (1 << 16),
+ /* show markers region */
+ SIPO_SHOW_MARKERS = (1 << 16),
} eGraphEdit_Flag;
/* SpaceGraph.mode (Graph Editor Mode) */
@@ -532,8 +532,8 @@ typedef enum eSpaceNla_Flag {
SNLA_NOREALTIMEUPDATES = (1 << 6),
/* don't show local strip marker indications */
SNLA_NOLOCALMARKERS = (1 << 7),
- /* show vertical line for every marker */
- SNLA_SHOW_MARKER_LINES = (1 << 8),
+ /* show markers region */
+ SNLA_SHOW_MARKERS = (1 << 8),
} eSpaceNla_Flag;
/** \} */
@@ -615,7 +615,7 @@ typedef enum eSpaceSeq_Flag {
SEQ_NO_WAVEFORMS = (1 << 8), /* draw no waveforms */
SEQ_SHOW_SAFE_CENTER = (1 << 9),
SEQ_SHOW_METADATA = (1 << 10),
- SEQ_SHOW_MARKER_LINES = (1 << 11),
+ SEQ_SHOW_MARKERS = (1 << 11), /* show markers region */
} eSpaceSeq_Flag;
/* SpaceSeq.view */
diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h
index 365b1993d80..f6c8c0b1f6d 100644
--- a/source/blender/makesdna/DNA_view3d_defaults.h
+++ b/source/blender/makesdna/DNA_view3d_defaults.h
@@ -46,6 +46,7 @@
.single_color = {0.8f, 0.8f, 0.8f}, \
.background_color = {0.05f, 0.05f, 0.05f}, \
.studiolight_intensity = 1.0f, \
+ .render_pass = SCE_PASS_COMBINED, \
}
#define _DNA_DEFAULT_View3DOverlay \
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 7b832f1b646..a9a20980677 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -179,6 +179,10 @@ typedef struct View3DShading {
float curvature_ridge_factor;
float curvature_valley_factor;
+ /* Render pass displayed in the viewport. Is an `eScenePassType` where one bit is set */
+ int render_pass;
+ char _pad2[4];
+
struct IDProperty *prop;
} View3DShading;
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 011e373cc61..679ccc9725b 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -123,6 +123,14 @@ static void rna_CurveMapping_tone_update(Main *UNUSED(bmain),
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
}
+static void rna_CurveMapping_extend_update(Main *UNUSED(bmain),
+ Scene *UNUSED(scene),
+ PointerRNA *UNUSED(ptr))
+{
+ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
+}
+
static void rna_CurveMapping_clipminx_range(
PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax))
{
@@ -670,8 +678,17 @@ static void rna_ColorManagement_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
}
/* this function only exists because #BKE_curvemap_evaluateF uses a 'const' qualifier */
-static float rna_CurveMap_evaluateF(struct CurveMap *cuma, ReportList *reports, float value)
+static float rna_CurveMapping_evaluateF(struct CurveMapping *cumap,
+ ReportList *reports,
+ struct CurveMap *cuma,
+ float value)
{
+ if (&cumap->cm[0] != cuma && &cumap->cm[1] != cuma && &cumap->cm[2] != cuma &&
+ &cumap->cm[3] != cuma) {
+ BKE_report(reports, RPT_ERROR, "CurveMapping does not own CurveMap");
+ return 0.0f;
+ }
+
if (!cuma->table) {
BKE_report(
reports,
@@ -679,7 +696,7 @@ static float rna_CurveMap_evaluateF(struct CurveMap *cuma, ReportList *reports,
"CurveMap table not initialized, call initialize() on CurveMapping owner of the CurveMap");
return 0.0f;
}
- return BKE_curvemap_evaluateF(cuma, value);
+ return BKE_curvemap_evaluateF(cumap, cuma, value);
}
static void rna_CurveMap_initialize(struct CurveMapping *cumap)
@@ -758,58 +775,22 @@ static void rna_def_curvemap_points_api(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_curvemap(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop, *parm;
- FunctionRNA *func;
-
- static const EnumPropertyItem prop_extend_items[] = {
- {0, "HORIZONTAL", 0, "Horizontal", ""},
- {CUMA_EXTEND_EXTRAPOLATE, "EXTRAPOLATED", 0, "Extrapolated", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ PropertyRNA *prop;
srna = RNA_def_struct(brna, "CurveMap", NULL);
RNA_def_struct_ui_text(srna, "CurveMap", "Curve in a curve mapping");
- prop = RNA_def_property(srna, "extend", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
- RNA_def_property_enum_items(prop, prop_extend_items);
- RNA_def_property_ui_text(prop, "Extend", "Extrapolate the curve or extend it horizontally");
-
prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "curve", "totpoint");
RNA_def_property_struct_type(prop, "CurveMapPoint");
RNA_def_property_ui_text(prop, "Points", "");
rna_def_curvemap_points_api(brna, prop);
-
- func = RNA_def_function(srna, "evaluate", "rna_CurveMap_evaluateF");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- RNA_def_function_ui_description(func, "Evaluate curve at given location");
- parm = RNA_def_float(func,
- "position",
- 0.0f,
- -FLT_MAX,
- FLT_MAX,
- "Position",
- "Position to evaluate curve at",
- -FLT_MAX,
- FLT_MAX);
- RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- parm = RNA_def_float(func,
- "value",
- 0.0f,
- -FLT_MAX,
- FLT_MAX,
- "Value",
- "Value of curve at given location",
- -FLT_MAX,
- FLT_MAX);
- RNA_def_function_return(func, parm);
}
static void rna_def_curvemapping(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+ PropertyRNA *prop, *parm;
FunctionRNA *func;
static const EnumPropertyItem tone_items[] = {
@@ -818,6 +799,12 @@ static void rna_def_curvemapping(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem prop_extend_items[] = {
+ {0, "HORIZONTAL", 0, "Horizontal", ""},
+ {CUMA_EXTEND_EXTRAPOLATE, "EXTRAPOLATED", 0, "Extrapolated", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "CurveMapping", NULL);
RNA_def_struct_ui_text(
srna,
@@ -860,6 +847,12 @@ static void rna_def_curvemapping(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clip Max Y", "");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_CurveMapping_clipmaxy_range");
+ prop = RNA_def_property(srna, "extend", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, prop_extend_items);
+ RNA_def_property_ui_text(prop, "Extend", "Extrapolate the curve or extend it horizontally");
+ RNA_def_property_update(prop, 0, "rna_CurveMapping_extend_update");
+
prop = RNA_def_property(srna, "curves", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop,
"rna_CurveMapping_curves_begin",
@@ -894,6 +887,32 @@ static void rna_def_curvemapping(BlenderRNA *brna)
func = RNA_def_function(srna, "initialize", "rna_CurveMap_initialize");
RNA_def_function_ui_description(func, "Initialize curve");
+
+ func = RNA_def_function(srna, "evaluate", "rna_CurveMapping_evaluateF");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Evaluate curve at given location");
+ parm = RNA_def_pointer(func, "curve", "CurveMap", "curve", "Curve to evaluate");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_float(func,
+ "position",
+ 0.0f,
+ -FLT_MAX,
+ FLT_MAX,
+ "Position",
+ "Position to evaluate curve at",
+ -FLT_MAX,
+ FLT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_float(func,
+ "value",
+ 0.0f,
+ -FLT_MAX,
+ FLT_MAX,
+ "Value",
+ "Value of curve at given location",
+ -FLT_MAX,
+ FLT_MAX);
+ RNA_def_function_return(func, parm);
}
static void rna_def_color_ramp_element(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index d167c650683..997a5f5ca45 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -31,8 +31,6 @@
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
-#include "BIF_gl.h"
-
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -52,6 +50,8 @@
# include "DNA_image_types.h"
# include "DNA_scene_types.h"
+# include "GPU_glew.h"
+
# include "MEM_guardedalloc.h"
static void rna_ImagePackedFile_save(ImagePackedFile *imapf, Main *bmain, ReportList *reports)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 2b47b1664d7..cca82abc9da 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -3411,17 +3411,6 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Secondary Color", "");
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
- prop = RNA_def_property(srna, "use_pressure_size", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_SIZE_PRESSURE);
- RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
- RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size");
-
- prop = RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE);
- RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
- RNA_def_property_ui_text(
- prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength");
-
prop = RNA_def_property(srna, "use_locked_size", PROP_ENUM, PROP_NONE); /* as an enum */
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, brush_size_unit_items);
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 8a06d594c1f..3562569acec 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -216,7 +216,7 @@ static void rna_Scene_alembic_export(Scene *scene,
bool vcolors,
bool apply_subdiv,
bool flatten_hierarchy,
- bool visible_layers_only,
+ bool visible_objects_only,
bool renderable_only,
bool face_sets,
bool use_subdiv_schema,
@@ -251,7 +251,7 @@ static void rna_Scene_alembic_export(Scene *scene,
.vcolors = vcolors,
.apply_subdiv = apply_subdiv,
.flatten_hierarchy = flatten_hierarchy,
- .visible_layers_only = visible_layers_only,
+ .visible_objects_only = visible_objects_only,
.renderable_only = renderable_only,
.face_sets = face_sets,
.use_subdiv_schema = use_subdiv_schema,
@@ -391,7 +391,7 @@ void RNA_api_scene(StructRNA *srna)
func, "apply_subdiv", 1, "Subsurfs as meshes", "Export subdivision surfaces as meshes");
RNA_def_boolean(func, "flatten", 0, "Flatten hierarchy", "Flatten hierarchy");
RNA_def_boolean(func,
- "visible_layers_only",
+ "visible_objects_only",
0,
"Visible layers only",
"Export only objects in visible layers");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index e14fff0220e..c97d19f47e5 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -374,6 +374,18 @@ static const EnumPropertyItem rna_enum_studio_light_items[] = {
{0, NULL, 0, NULL, NULL},
};
+const EnumPropertyItem rna_enum_view3dshading_render_pass_type_items[] = {
+ {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
+ /* {SCE_PASS_Z, "Z", 0, "Z", ""},*/
+ {SCE_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
+ {SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
+ {SCE_PASS_MIST, "MIST", 0, "Mist", ""},
+ {SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
+ /* {SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""}, */
+ {SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
const EnumPropertyItem rna_enum_clip_editor_mode_items[] = {
{SC_MODE_TRACKING, "TRACKING", ICON_ANIM_DATA, "Tracking", "Show tracking and solving tools"},
{SC_MODE_MASKEDIT, "MASK", ICON_MOD_MASK, "Mask", "Show mask editing tools"},
@@ -3280,6 +3292,12 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.00f, 1.0f, 1, 3);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "render_pass", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "render_pass");
+ RNA_def_property_enum_items(prop, rna_enum_view3dshading_render_pass_type_items);
+ RNA_def_property_ui_text(prop, "Render Pass", "Render Pass to show in the viewport");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
static void rna_def_space_view3d_overlay(BlenderRNA *brna)
@@ -4542,9 +4560,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
- prop = RNA_def_property(srna, "show_marker_lines", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_MARKER_LINES);
- RNA_def_property_ui_text(prop, "Show Marker Lines", "Show a vertical line for every marker");
+ prop = RNA_def_property(srna, "show_markers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_MARKERS);
+ RNA_def_property_ui_text(
+ prop,
+ "Show Markers",
+ "If any exists, show markers in a separate row at the bottom of the editor");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE);
@@ -4800,7 +4821,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_pose_markers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_POSEMARKERS_SHOW);
RNA_def_property_ui_text(prop,
- "Show Pose Markers",
+ "Toggle Pose Markers",
"Show markers belonging to the active action instead of Scene markers "
"(Action and Shape Key Editors only)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
@@ -4829,10 +4850,13 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
"comparison with adjacent keys");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
- prop = RNA_def_property(srna, "show_marker_lines", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_SHOW_MARKER_LINES);
- RNA_def_property_ui_text(prop, "Show Marker Lines", "Show a vertical line for every marker");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
+ prop = RNA_def_property(srna, "show_markers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_SHOW_MARKERS);
+ RNA_def_property_ui_text(
+ prop,
+ "Show Markers",
+ "If any exists, show markers in a separate row at the bottom of the editor");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
/* editing */
prop = RNA_def_property(srna, "use_auto_merge_keyframes", PROP_BOOLEAN, PROP_NONE);
@@ -4986,9 +5010,12 @@ static void rna_def_space_graph(BlenderRNA *brna)
"Display groups and channels with colors matching their corresponding groups");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
- prop = RNA_def_property(srna, "show_marker_lines", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_MARKER_LINES);
- RNA_def_property_ui_text(prop, "Show Marker Lines", "Show a vertical line for every marker");
+ prop = RNA_def_property(srna, "show_markers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SHOW_MARKERS);
+ RNA_def_property_ui_text(
+ prop,
+ "Show Markers",
+ "If any exists, show markers in a separate row at the bottom of the editor");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
/* editing */
@@ -5097,10 +5124,13 @@ static void rna_def_space_nla(BlenderRNA *brna)
"Show action-local markers on the strips, useful when synchronizing timing across strips");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NLA, NULL);
- prop = RNA_def_property(srna, "show_marker_lines", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SNLA_SHOW_MARKER_LINES);
- RNA_def_property_ui_text(prop, "Show Marker Lines", "Show a vertical line for every marker");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
+ prop = RNA_def_property(srna, "show_markers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SNLA_SHOW_MARKERS);
+ RNA_def_property_ui_text(
+ prop,
+ "Show Markers",
+ "If any exists, show markers in a separate row at the bottom of the editor");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NLA, NULL);
/* editing */
prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index f5c89e6ba41..6292d7b5062 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -147,7 +147,7 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
ext_rgba[a][2] = cm->maxtable;
range_rgba[a] = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
/* Compute extrapolation gradients. */
- if ((cm->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
ext_rgba[a][1] = (cm->ext_in[0] != 0.0f) ?
(cm->ext_in[1] / (cm->ext_in[0] * range_rgba[a])) :
1e8f;
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index af595de2ee4..b601a35f7f2 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1091,7 +1091,9 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
bm = self->bm;
struct Main *bmain = NULL;
- struct BMeshToMeshParams params = {0};
+ struct BMeshToMeshParams params = {
+ .update_shapekey_indices = true,
+ };
if (me->id.tag & LIB_TAG_NO_MAIN) {
/* Mesh might be coming from a self-contained source like object.to_mesh(). No need to remap
* anything in this case. */
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 6fb2b2fd7ee..d49e782c317 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -7818,7 +7818,7 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
}
}
- {
+ if (ret == 0) {
/* This block can be removed once 2.8x is released and annotations are in use. */
bool has_warning = false;
while (PyDict_Next(class_dict, &pos, &key, &item)) {
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 44fd9158934..72ccbb0fb55 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -821,15 +821,18 @@ typedef struct ARegion *(*wmTooltipInitFn)(struct bContext *C,
void WM_tooltip_immediate_init(struct bContext *C,
struct wmWindow *win,
+ struct ScrArea *sa,
struct ARegion *ar,
wmTooltipInitFn init);
void WM_tooltip_timer_init_ex(struct bContext *C,
struct wmWindow *win,
+ struct ScrArea *sa,
struct ARegion *ar,
wmTooltipInitFn init,
double delay);
void WM_tooltip_timer_init(struct bContext *C,
struct wmWindow *win,
+ struct ScrArea *sa,
struct ARegion *ar,
wmTooltipInitFn init);
void WM_tooltip_timer_clear(struct bContext *C, struct wmWindow *win);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 15ad8cbedc4..0c3a5f92113 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -894,6 +894,8 @@ typedef struct wmDropBox {
typedef struct wmTooltipState {
/** Create tooltip on this event. */
struct wmTimer *timer;
+ /** The area the tooltip is created in. */
+ struct ScrArea *area_from;
/** The region the tooltip is created in. */
struct ARegion *region_from;
/** The tooltip region. */
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 901594850dd..e2462bb59b1 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -34,14 +34,15 @@
#include "BLI_blenlib.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BKE_context.h"
#include "BKE_idcode.h"
+#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_state.h"
+#include "GPU_viewport.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 2f538a19ba2..09b7d89fc2b 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -39,8 +39,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BIF_gl.h"
-
#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_main.h"
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index c63bc24d58e..180a518de2b 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2850,7 +2850,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
if (wm_gizmomap_highlight_set(gzmap, C, gz, part)) {
if (gz != NULL) {
if (U.flag & USER_TOOLTIPS) {
- WM_tooltip_timer_init(C, CTX_wm_window(C), region, WM_gizmomap_tooltip_init);
+ WM_tooltip_timer_init(C, CTX_wm_window(C), area, region, WM_gizmomap_tooltip_init);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 9b62e532132..54953c097eb 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -32,8 +32,6 @@
#include "BLI_utildefines.h"
-#include "BIF_gl.h"
-
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_report.h"
@@ -44,6 +42,7 @@
#include "GPU_immediate.h"
#include "GPU_texture.h"
+#include "GPU_viewport.h"
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 2f40947b395..6a5de84ac31 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -29,9 +29,9 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-#include "BIF_gl.h"
-
+#include "GPU_glew.h"
#include "GPU_matrix.h"
+#include "GPU_viewport.h"
#include "WM_api.h"
diff --git a/source/blender/windowmanager/intern/wm_tooltip.c b/source/blender/windowmanager/intern/wm_tooltip.c
index 3a219d7a573..b192ea94010 100644
--- a/source/blender/windowmanager/intern/wm_tooltip.c
+++ b/source/blender/windowmanager/intern/wm_tooltip.c
@@ -42,7 +42,8 @@ double WM_tooltip_time_closed(void)
return g_tooltip_time_closed;
}
-void WM_tooltip_immediate_init(bContext *C, wmWindow *win, ARegion *ar, wmTooltipInitFn init)
+void WM_tooltip_immediate_init(
+ bContext *C, wmWindow *win, ScrArea *sa, ARegion *ar, wmTooltipInitFn init)
{
WM_tooltip_timer_clear(C, win);
@@ -50,13 +51,14 @@ void WM_tooltip_immediate_init(bContext *C, wmWindow *win, ARegion *ar, wmToolti
if (screen->tool_tip == NULL) {
screen->tool_tip = MEM_callocN(sizeof(*screen->tool_tip), __func__);
}
+ screen->tool_tip->area_from = sa;
screen->tool_tip->region_from = ar;
screen->tool_tip->init = init;
WM_tooltip_init(C, win);
}
void WM_tooltip_timer_init_ex(
- bContext *C, wmWindow *win, ARegion *ar, wmTooltipInitFn init, double delay)
+ bContext *C, wmWindow *win, ScrArea *sa, ARegion *ar, wmTooltipInitFn init, double delay)
{
WM_tooltip_timer_clear(C, win);
@@ -65,14 +67,16 @@ void WM_tooltip_timer_init_ex(
if (screen->tool_tip == NULL) {
screen->tool_tip = MEM_callocN(sizeof(*screen->tool_tip), __func__);
}
+ screen->tool_tip->area_from = sa;
screen->tool_tip->region_from = ar;
screen->tool_tip->timer = WM_event_add_timer(wm, win, TIMER, delay);
screen->tool_tip->init = init;
}
-void WM_tooltip_timer_init(bContext *C, wmWindow *win, ARegion *ar, wmTooltipInitFn init)
+void WM_tooltip_timer_init(
+ bContext *C, wmWindow *win, ScrArea *sa, ARegion *ar, wmTooltipInitFn init)
{
- WM_tooltip_timer_init_ex(C, win, ar, init, UI_TOOLTIP_DELAY);
+ WM_tooltip_timer_init_ex(C, win, sa, ar, init, UI_TOOLTIP_DELAY);
}
void WM_tooltip_timer_clear(bContext *C, wmWindow *win)
@@ -112,11 +116,21 @@ void WM_tooltip_init(bContext *C, wmWindow *win)
}
const int pass_prev = screen->tool_tip->pass;
double pass_delay = 0.0;
- screen->tool_tip->region = screen->tool_tip->init(C,
- screen->tool_tip->region_from,
- &screen->tool_tip->pass,
- &pass_delay,
- &screen->tool_tip->exit_on_event);
+
+ {
+ ScrArea *area_prev = CTX_wm_area(C);
+ ARegion *ar_prev = CTX_wm_region(C);
+ CTX_wm_area_set(C, screen->tool_tip->area_from);
+ CTX_wm_region_set(C, screen->tool_tip->region_from);
+ screen->tool_tip->region = screen->tool_tip->init(C,
+ screen->tool_tip->region_from,
+ &screen->tool_tip->pass,
+ &pass_delay,
+ &screen->tool_tip->exit_on_event);
+ CTX_wm_area_set(C, area_prev);
+ CTX_wm_region_set(C, ar_prev);
+ }
+
copy_v2_v2_int(screen->tool_tip->event_xy, &win->eventstate->x);
if (pass_prev != screen->tool_tip->pass) {
/* The pass changed, add timer for next pass. */
diff --git a/tests/gtests/CMakeLists.txt b/tests/gtests/CMakeLists.txt
index 285b414e997..54a1ee41198 100644
--- a/tests/gtests/CMakeLists.txt
+++ b/tests/gtests/CMakeLists.txt
@@ -13,6 +13,7 @@ if(WITH_GTESTS)
add_subdirectory(testing)
add_subdirectory(blenlib)
+ add_subdirectory(blenloader)
add_subdirectory(guardedalloc)
add_subdirectory(bmesh)
if(WITH_ALEMBIC)
diff --git a/tests/gtests/blenloader/CMakeLists.txt b/tests/gtests/blenloader/CMakeLists.txt
new file mode 100644
index 00000000000..f8457e0164b
--- /dev/null
+++ b/tests/gtests/blenloader/CMakeLists.txt
@@ -0,0 +1,90 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2019 by Blender Foundation.
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ ..
+ ../../../source/blender/blenkernel
+ ../../../source/blender/blenlib
+ ../../../source/blender/blenloader
+ ../../../source/blender/depsgraph
+ ../../../source/blender/imbuf
+ ../../../source/blender/makesdna
+ ../../../source/blender/makesrna
+ ../../../source/blender/windowmanager
+ ../../../intern/guardedalloc
+ ${GLOG_INCLUDE_DIRS}
+ ${GFLAGS_INCLUDE_DIRS}
+ ../../../extern/gtest/include
+)
+
+set(SRC
+ blendfile_loading_base_test.cc
+ blendfile_loading_base_test.h
+)
+
+set(LIB
+)
+
+blender_add_lib(bf_blenloader_test "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+
+set(INC
+ .
+ ..
+ ../../../source/blender/blenlib
+ ../../../source/blender/blenloader
+ ../../../source/blender/blenkernel
+ ../../../source/blender/makesdna
+ ../../../source/blender/makesrna
+ ../../../source/blender/depsgraph
+ ../../../intern/guardedalloc
+)
+
+set(LIB
+ bf_blenloader_test
+ bf_blenloader
+
+ # Should not be needed but gives windows linker errors if the ocio libs are linked before this:
+ bf_intern_opencolorio
+ bf_gpu
+)
+
+include_directories(${INC})
+
+setup_libdirs()
+get_property(BLENDER_SORTED_LIBS GLOBAL PROPERTY BLENDER_SORTED_LIBS_PROP)
+
+
+set(SRC
+ blendfile_load_test.cc
+)
+if(WITH_BUILDINFO)
+ list(APPEND SRC "$<TARGET_OBJECTS:buildinfoobj>")
+endif()
+
+BLENDER_SRC_GTEST_EX(
+ NAME blenloader
+ SRC "${SRC}"
+ EXTRA_LIBS "${LIB}"
+ COMMAND_ARGS --test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests")
+
+unset(_buildinfo_src)
+
+setup_liblinks(blenloader_test)
diff --git a/tests/gtests/blenloader/blendfile_load_test.cc b/tests/gtests/blenloader/blendfile_load_test.cc
new file mode 100644
index 00000000000..2ba3e3fcd88
--- /dev/null
+++ b/tests/gtests/blenloader/blendfile_load_test.cc
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 by Blender Foundation.
+ */
+#include "blendfile_loading_base_test.h"
+
+class BlendfileLoadingTest : public BlendfileLoadingBaseTest {
+};
+
+TEST_F(BlendfileLoadingTest, CanaryTest)
+{
+ /* Load the smallest blend file we have in the SVN lib/tests directory. */
+ if (!blendfile_load("modifier_stack/array_test.blend")) {
+ return;
+ }
+ depsgraph_create(DAG_EVAL_RENDER);
+ EXPECT_NE(nullptr, this->depsgraph);
+}
diff --git a/tests/gtests/blenloader/blendfile_loading_base_test.cc b/tests/gtests/blenloader/blendfile_loading_base_test.cc
new file mode 100644
index 00000000000..5a1a7f9aae5
--- /dev/null
+++ b/tests/gtests/blenloader/blendfile_loading_base_test.cc
@@ -0,0 +1,172 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 by Blender Foundation.
+ */
+#include "blendfile_loading_base_test.h"
+
+extern "C" {
+#include "BKE_appdir.h"
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+
+#include "BLI_threads.h"
+#include "BLI_path_util.h"
+
+#include "BLO_readfile.h"
+
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph.h"
+
+#include "DNA_genfile.h" /* for DNA_sdna_current_init() */
+#include "DNA_windowmanager_types.h"
+
+#include "IMB_imbuf.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "wm.h"
+}
+
+DEFINE_string(test_assets_dir, "", "lib/tests directory from SVN containing the test assets.");
+
+BlendfileLoadingBaseTest::~BlendfileLoadingBaseTest()
+{
+}
+
+void BlendfileLoadingBaseTest::SetUpTestCase()
+{
+ testing::Test::SetUpTestCase();
+
+ /* Minimal code to make loading a blendfile and constructing a depsgraph not crash, copied from
+ * main() in creator.c. */
+ BLI_threadapi_init();
+
+ DNA_sdna_current_init();
+ BKE_blender_globals_init();
+ IMB_init();
+ BKE_images_init();
+ BKE_modifier_init();
+ DEG_register_node_types();
+ RNA_init();
+ init_nodesystem();
+
+ G.background = true;
+ G.factory_startup = true;
+
+ /* Allocate a dummy window manager. The real window manager will try and load Python scripts from
+ * the release directory, which it won't be able to find. */
+ ASSERT_EQ(G.main->wm.first, nullptr);
+ G.main->wm.first = MEM_callocN(sizeof(wmWindowManager), __func__);
+}
+
+void BlendfileLoadingBaseTest::TearDownTestCase()
+{
+ if (G.main->wm.first != nullptr) {
+ MEM_freeN(G.main->wm.first);
+ G.main->wm.first = nullptr;
+ }
+
+ /* Copied from WM_exit_ex() in wm_init_exit.c, and cherry-picked those lines that match the
+ * allocation/initialisation done in SetUpTestCase(). */
+ BKE_blender_free();
+ RNA_exit();
+
+ DEG_free_node_types();
+ DNA_sdna_current_free();
+ BLI_threadapi_exit();
+
+ BKE_blender_atexit();
+
+ if (MEM_get_memory_blocks_in_use() != 0) {
+ size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use();
+ printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n",
+ MEM_get_memory_blocks_in_use(),
+ (double)mem_in_use / 1024 / 1024);
+ MEM_printmemlist();
+ }
+
+ BKE_tempdir_session_purge();
+
+ testing::Test::TearDownTestCase();
+}
+
+void BlendfileLoadingBaseTest::TearDown()
+{
+ depsgraph_free();
+ blendfile_free();
+
+ testing::Test::TearDown();
+}
+
+bool BlendfileLoadingBaseTest::blendfile_load(const char *filepath)
+{
+ if (FLAGS_test_assets_dir.empty()) {
+ ADD_FAILURE()
+ << "Pass the flag --test-assets-dir and point to the lib/tests directory from SVN.";
+ return false;
+ }
+
+ char abspath[FILENAME_MAX];
+ BLI_path_join(abspath, sizeof(abspath), FLAGS_test_assets_dir.c_str(), filepath, NULL);
+
+ bfile = BLO_read_from_file(abspath, BLO_READ_SKIP_NONE, NULL /* reports */);
+ if (bfile == nullptr) {
+ ADD_FAILURE() << "Unable to load file '" << filepath << "' from test assets dir '"
+ << FLAGS_test_assets_dir << "'";
+ return false;
+ }
+ return true;
+}
+
+void BlendfileLoadingBaseTest::blendfile_free()
+{
+ if (bfile == nullptr) {
+ return;
+ }
+
+ wmWindowManager *wm = static_cast<wmWindowManager *>(bfile->main->wm.first);
+ if (wm != nullptr) {
+ wm_close_and_free(NULL, wm);
+ }
+ BLO_blendfiledata_free(bfile);
+ bfile = nullptr;
+}
+
+void BlendfileLoadingBaseTest::depsgraph_create(eEvaluationMode depsgraph_evaluation_mode)
+{
+ depsgraph = DEG_graph_new(
+ bfile->main, bfile->curscene, bfile->cur_view_layer, depsgraph_evaluation_mode);
+ DEG_graph_build_from_view_layer(depsgraph, bfile->main, bfile->curscene, bfile->cur_view_layer);
+ BKE_scene_graph_update_tagged(depsgraph, bfile->main);
+}
+
+void BlendfileLoadingBaseTest::depsgraph_free()
+{
+ if (depsgraph == nullptr) {
+ return;
+ }
+ DEG_graph_free(depsgraph);
+ depsgraph = nullptr;
+}
diff --git a/tests/gtests/blenloader/blendfile_loading_base_test.h b/tests/gtests/blenloader/blendfile_loading_base_test.h
new file mode 100644
index 00000000000..466bbcd2392
--- /dev/null
+++ b/tests/gtests/blenloader/blendfile_loading_base_test.h
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 by Blender Foundation.
+ */
+#ifndef __BLENDFILE_LOADING_BASE_TEST_H__
+#define __BLENDFILE_LOADING_BASE_TEST_H__
+
+#include "testing/testing.h"
+#include "DEG_depsgraph.h"
+
+struct BlendFileData;
+struct Depsgraph;
+
+class BlendfileLoadingBaseTest : public testing::Test {
+ protected:
+ struct BlendFileData *bfile = nullptr;
+ struct Depsgraph *depsgraph = nullptr;
+
+ public:
+ virtual ~BlendfileLoadingBaseTest();
+
+ /* Sets up Blender just enough to not crash on loading
+ * a blendfile and constructing a depsgraph. */
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+
+ protected:
+ /* Frees the depsgraph & blendfile. */
+ virtual void TearDown();
+
+ /* Loads a blend file from the lib/tests directory from SVN.
+ * Returns 'ok' flag (true=good, false=bad) and sets this->bfile.
+ * Fails the test if the file cannot be loaded (still returns though).
+ * Requires the CLI argument --test-asset-dir to point to ../../lib/tests.
+ *
+ * WARNING: only files saved with Blender 2.80+ can be loaded. Since Blender
+ * is only partially initialised (most importantly, without window manager),
+ * the space types are not registered, so any versioning code that handles
+ * those will SEGFAULT.
+ */
+ bool blendfile_load(const char *filepath);
+ /* Free bfile if it is not nullptr. */
+ void blendfile_free();
+
+ /* Create a depsgraph. Assumes a blend file has been loaded to this->bfile. */
+ void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode);
+ /* Free the depsgraph if it's not nullptr. */
+ void depsgraph_free();
+};
+
+#endif /* __BLENDFILE_LOADING_BASE_TEST_H__ */
diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py
index 09e9b8981e3..9de1bc06d84 100755
--- a/tests/python/alembic_tests.py
+++ b/tests/python/alembic_tests.py
@@ -170,7 +170,7 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest):
def test_hierarchical_export(self, tempdir: pathlib.Path):
abc = tempdir / 'cubes_hierarchical.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=True, visible_layers_only=True, flatten=False)" % abc.as_posix()
+ "renderable_only=True, visible_objects_only=True, flatten=False)" % abc.as_posix()
self.run_blender('cubes-hierarchy.blend', script)
# Now check the resulting Alembic file.
@@ -188,7 +188,7 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest):
def test_flat_export(self, tempdir: pathlib.Path):
abc = tempdir / 'cubes_flat.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=True, visible_layers_only=True, flatten=True)" % abc.as_posix()
+ "renderable_only=True, visible_objects_only=True, flatten=True)" % abc.as_posix()
self.run_blender('cubes-hierarchy.blend', script)
# Now check the resulting Alembic file.
@@ -209,7 +209,7 @@ class DupliGroupExportTest(AbstractAlembicTest):
def test_hierarchical_export(self, tempdir: pathlib.Path):
abc = tempdir / 'dupligroup_hierarchical.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=True, visible_layers_only=True, flatten=False)" % abc.as_posix()
+ "renderable_only=True, visible_objects_only=True, flatten=False)" % abc.as_posix()
self.run_blender('dupligroup-scene.blend', script)
# Now check the resulting Alembic file.
@@ -227,7 +227,7 @@ class DupliGroupExportTest(AbstractAlembicTest):
def test_flat_export(self, tempdir: pathlib.Path):
abc = tempdir / 'dupligroup_hierarchical.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=True, visible_layers_only=True, flatten=True)" % abc.as_posix()
+ "renderable_only=True, visible_objects_only=True, flatten=True)" % abc.as_posix()
self.run_blender('dupligroup-scene.blend', script)
# Now check the resulting Alembic file.
@@ -248,7 +248,7 @@ class CurveExportTest(AbstractAlembicTest):
def test_export_single_curve(self, tempdir: pathlib.Path):
abc = tempdir / 'single-curve.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=True, visible_layers_only=True, flatten=False)" % abc.as_posix()
+ "renderable_only=True, visible_objects_only=True, flatten=False)" % abc.as_posix()
self.run_blender('single-curve.blend', script)
# Now check the resulting Alembic file.
@@ -269,7 +269,7 @@ class HairParticlesExportTest(AbstractAlembicTest):
def _do_test(self, tempdir: pathlib.Path, export_hair: bool, export_particles: bool) -> pathlib.Path:
abc = tempdir / 'hair-particles.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=True, visible_layers_only=True, flatten=False, " \
+ "renderable_only=True, visible_objects_only=True, flatten=False, " \
"export_hair=%r, export_particles=%r, as_background_job=False)" \
% (abc.as_posix(), export_hair, export_particles)
self.run_blender('hair-particles.blend', script)
@@ -330,7 +330,7 @@ class LongNamesExportTest(AbstractAlembicTest):
def test_export_long_names(self, tempdir: pathlib.Path):
abc = tempdir / 'long-names.abc'
script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
- "renderable_only=False, visible_layers_only=False, flatten=False)" % abc.as_posix()
+ "renderable_only=False, visible_objects_only=False, flatten=False)" % abc.as_posix()
self.run_blender('long-names.blend', script)
name_parts = [