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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doxygen/Doxyfile2
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h2
-rw-r--r--intern/guardedalloc/CMakeLists.txt6
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h6
-rw-r--r--intern/guardedalloc/intern/mmap_win.c294
-rw-r--r--intern/guardedalloc/mmap_win.h50
-rw-r--r--release/datafiles/splash.pngbin887863 -> 737984 bytes
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py10
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py6
-rw-r--r--release/scripts/startup/bl_ui/space_node.py10
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h3
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh94
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h10
-rw-r--r--source/blender/blenkernel/BKE_node.h26
-rw-r--r--source/blender/blenkernel/BKE_screen.h43
-rw-r--r--source/blender/blenkernel/BKE_tracking.h33
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c528
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc17
-rw-r--r--source/blender/blenkernel/intern/bpath.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/context.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c2
-rw-r--r--source/blender/blenkernel/intern/curve_deform.c2
-rw-r--r--source/blender/blenkernel/intern/displist.c5
-rw-r--r--source/blender/blenkernel/intern/gpencil.c115
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c9
-rw-r--r--source/blender/blenkernel/intern/lib_override.c4
-rw-r--r--source/blender/blenkernel/intern/node.c38
-rw-r--r--source/blender/blenkernel/intern/object_update.c2
-rw-r--r--source/blender/blenkernel/intern/ocean.c2
-rw-r--r--source/blender/blenkernel/intern/screen.c3
-rw-r--r--source/blender/blenkernel/intern/tracking.c317
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c6
-rw-r--r--source/blender/blenkernel/intern/tracking_test.cc170
-rw-r--r--source/blender/blenkernel/intern/unit.c3
-rw-r--r--source/blender/blenkernel/nla_private.h4
-rw-r--r--source/blender/blenlib/BLI_fileops.h2
-rw-r--r--source/blender/blenlib/BLI_float2.hh13
-rw-r--r--source/blender/blenlib/BLI_math.h3
-rw-r--r--source/blender/blenlib/BLI_math_base.h3
-rw-r--r--source/blender/blenlib/BLI_math_bits.h3
-rw-r--r--source/blender/blenlib/BLI_math_color.h3
-rw-r--r--source/blender/blenlib/BLI_math_color_blend.h3
-rw-r--r--source/blender/blenlib/BLI_math_geom.h8
-rw-r--r--source/blender/blenlib/BLI_math_inline.h3
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h2
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h3
-rw-r--r--source/blender/blenlib/BLI_math_solvers.h2
-rw-r--r--source/blender/blenlib/BLI_math_statistics.h2
-rw-r--r--source/blender/blenlib/BLI_math_vector.h3
-rw-r--r--source/blender/blenlib/BLI_mmap.h56
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/intern/BLI_mmap.c233
-rw-r--r--source/blender/blenlib/intern/bitmap_draw_2d.c3
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c3
-rw-r--r--source/blender/blenlib/intern/math_base.c3
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_bits_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_color.c3
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_geom.c58
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_solvers.c2
-rw-r--r--source/blender/blenlib/intern/math_statistics.c2
-rw-r--r--source/blender/blenlib/intern/math_vector.c3
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c3
-rw-r--r--source/blender/blenlib/intern/path_util.c2
-rw-r--r--source/blender/blenlib/intern/threads.cc5
-rw-r--r--source/blender/blenlib/intern/voxel.c8
-rw-r--r--source/blender/blenloader/intern/readfile.c68
-rw-r--r--source/blender/blenloader/intern/readfile.h4
-rw-r--r--source/blender/blenloader/intern/versioning_290.c30
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c3
-rw-r--r--source/blender/compositor/operations/COM_BokehImageOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_DotproductOperation.cpp2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h4
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c4
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h2
-rw-r--r--source/blender/draw/engines/overlay/overlay_gpencil.c15
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c8
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c4
-rw-r--r--source/blender/editors/animation/keyframing.c2
-rw-r--r--source/blender/editors/armature/armature_add.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c8
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c24
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c22
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h16
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c19
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c22
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_undo.c20
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c67
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c25
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c25
-rw-r--r--source/blender/editors/include/ED_gpencil.h10
-rw-r--r--source/blender/editors/include/ED_node.h4
-rw-r--r--source/blender/editors/include/ED_screen.h44
-rw-r--r--source/blender/editors/include/ED_transform.h3
-rw-r--r--source/blender/editors/include/UI_interface.h3
-rw-r--r--source/blender/editors/include/UI_view2d.h2
-rw-r--r--source/blender/editors/interface/interface.c6
-rw-r--r--source/blender/editors/interface/interface_region_popup.c9
-rw-r--r--source/blender/editors/interface/view2d.c2
-rw-r--r--source/blender/editors/object/object_add.c3
-rw-r--r--source/blender/editors/object/object_transform.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c3
-rw-r--r--source/blender/editors/screen/area.c72
-rw-r--r--source/blender/editors/screen/area_utils.c13
-rw-r--r--source/blender/editors/screen/glutil.c20
-rw-r--r--source/blender/editors/screen/screen_context.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c5
-rw-r--r--source/blender/editors/space_action/space_action.c72
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c40
-rw-r--r--source/blender/editors/space_clip/clip_intern.h1
-rw-r--r--source/blender/editors/space_clip/space_clip.c60
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c91
-rw-r--r--source/blender/editors/space_console/space_console.c10
-rw-r--r--source/blender/editors/space_file/space_file.c74
-rw-r--r--source/blender/editors/space_graph/space_graph.c30
-rw-r--r--source/blender/editors/space_image/space_image.c42
-rw-r--r--source/blender/editors/space_info/space_info.c29
-rw-r--r--source/blender/editors/space_nla/space_nla.c62
-rw-r--r--source/blender/editors/space_node/drawnode.c37
-rw-r--r--source/blender/editors/space_node/node_add.c16
-rw-r--r--source/blender/editors/space_node/node_draw.c72
-rw-r--r--source/blender/editors/space_node/node_edit.c4
-rw-r--r--source/blender/editors/space_node/node_intern.h45
-rw-r--r--source/blender/editors/space_node/node_relationships.c16
-rw-r--r--source/blender/editors/space_node/node_select.c5
-rw-r--r--source/blender/editors/space_node/space_node.c61
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c30
-rw-r--r--source/blender/editors/space_script/space_script.c7
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c47
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c20
-rw-r--r--source/blender/editors/space_text/space_text.c7
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c30
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c34
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c56
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c3
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c12
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c221
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_skin.c4
-rw-r--r--source/blender/editors/transform/transform_convert_tracking.c246
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c2
-rw-r--r--source/blender/editors/transform/transform_snap.c118
-rw-r--r--source/blender/editors/undo/ed_undo.c64
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c36
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc2
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp2
-rw-r--r--source/blender/imbuf/intern/IMB_allocimbuf.h2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c2
-rw-r--r--source/blender/imbuf/intern/filter.c2
-rw-r--r--source/blender/imbuf/intern/readimage.c24
-rw-r--r--source/blender/io/alembic/exporter/abc_archive.cc2
-rw-r--r--source/blender/makesdna/DNA_ID.h2
-rw-r--r--source/blender/makesdna/DNA_brush_types.h9
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h6
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h2
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h11
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h6
-rw-r--r--source/blender/makesdna/DNA_space_types.h35
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h11
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt6
-rw-r--r--source/blender/makesdna/intern/makesdna.c17
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt1
-rw-r--r--source/blender/makesrna/intern/makesrna.c11
-rw-r--r--source/blender/makesrna/intern/rna_brush.c10
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c49
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c9
-rw-r--r--source/blender/makesrna/intern/rna_rna.c16
-rw-r--r--source/blender/makesrna/intern/rna_space.c30
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c16
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc12
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c4
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc190
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc57
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c52
-rw-r--r--source/blender/python/intern/bpy_rna.c10
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_api.h2
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c2
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c24
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c5
196 files changed, 3283 insertions, 2025 deletions
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 772fac56f63..f9055f02bcf 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = "V2.92"
+PROJECT_NUMBER = "V2.93"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index caca3c28c8d..f1789f0d7eb 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -43,7 +43,7 @@ class ColorSpaceProcessor;
*
* Data needed by OSL render services, that is global to a rendering session.
* This includes all OSL shaders, name to attribute mapping and texture handles.
- * */
+ */
struct OSLGlobals {
OSLGlobals()
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 0d46e81cd87..b47565b8ef9 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -49,12 +49,6 @@ set(LIB
)
if(WIN32 AND NOT UNIX)
- list(APPEND SRC
- intern/mmap_win.c
-
- mmap_win.h
- )
-
list(APPEND INC_SYS
${PTHREADS_INC}
)
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index a0174e30aff..62f28c9e97e 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -122,7 +122,7 @@ extern void *(*MEM_calloc_arrayN)(size_t len,
/**
* Allocate a block of memory of size len, with tag name str. The
* name must be a static, because only a pointer to it is stored !
- * */
+ */
extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
@@ -130,7 +130,7 @@ extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_
* Allocate a block of memory of size (len * size), with tag name str,
* aborting in case of integer overflow to prevent vulnerabilities. The
* name must be a static, because only a pointer to it is stored !
- * */
+ */
extern void *(*MEM_malloc_arrayN)(size_t len,
size_t size,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
@@ -139,7 +139,7 @@ extern void *(*MEM_malloc_arrayN)(size_t len,
/**
* Allocate an aligned block of memory of size len, with tag name str. The
* name must be a static, because only a pointer to it is stored !
- * */
+ */
extern void *(*MEM_mallocN_aligned)(size_t len,
size_t alignment,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c
deleted file mode 100644
index a02a0f88fa9..00000000000
--- a/intern/guardedalloc/intern/mmap_win.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * 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) 2008 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup MEM
- */
-
-#ifdef WIN32
-
-# include <errno.h>
-# include <io.h>
-# include <stdio.h>
-# include <sys/types.h>
-# include <windows.h>
-
-# include "mmap_win.h"
-
-# ifndef FILE_MAP_EXECUTE
-// not defined in earlier versions of the Platform SDK (before February 2003)
-# define FILE_MAP_EXECUTE 0x0020
-# endif
-
-/* copied from BLI_utildefines.h, ugh */
-# ifdef __GNUC__
-# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
-# else
-# define UNUSED(x) x
-# endif
-
-/* --------------------------------------------------------------------- */
-/* local storage definitions */
-/* --------------------------------------------------------------------- */
-/* all memory mapped chunks are put in linked lists */
-typedef struct mmapLink {
- struct mmapLink *next, *prev;
-} mmapLink;
-
-typedef struct mmapListBase {
- void *first, *last;
-} mmapListBase;
-
-typedef struct MemMap {
- struct MemMap *next, *prev;
- void *mmap;
- HANDLE fhandle;
- HANDLE maphandle;
-} MemMap;
-
-/* --------------------------------------------------------------------- */
-/* local functions */
-/* --------------------------------------------------------------------- */
-
-static void mmap_addtail(volatile mmapListBase *listbase, void *vlink);
-static void mmap_remlink(volatile mmapListBase *listbase, void *vlink);
-static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr);
-
-static int mmap_get_prot_flags(int flags);
-static int mmap_get_access_flags(int flags);
-
-/* --------------------------------------------------------------------- */
-/* vars */
-/* --------------------------------------------------------------------- */
-volatile static struct mmapListBase _mmapbase;
-volatile static struct mmapListBase *mmapbase = &_mmapbase;
-
-/* --------------------------------------------------------------------- */
-/* implementation */
-/* --------------------------------------------------------------------- */
-
-/* mmap for windows */
-void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset)
-{
- HANDLE fhandle = INVALID_HANDLE_VALUE;
- HANDLE maphandle;
- int prot_flags = mmap_get_prot_flags(prot);
- int access_flags = mmap_get_access_flags(prot);
- MemMap *mm = NULL;
- void *ptr = NULL;
-
- if (flags & MAP_FIXED) {
- return MAP_FAILED;
- }
-
-# if 0
- if (fd == -1) {
- _set_errno(EBADF);
- return MAP_FAILED;
- }
-# endif
-
- if (fd != -1) {
- fhandle = (HANDLE)_get_osfhandle(fd);
- }
- if (fhandle == INVALID_HANDLE_VALUE) {
- if (!(flags & MAP_ANONYMOUS)) {
- errno = EBADF;
- return MAP_FAILED;
- }
- }
- else {
- if (!DuplicateHandle(GetCurrentProcess(),
- fhandle,
- GetCurrentProcess(),
- &fhandle,
- 0,
- FALSE,
- DUPLICATE_SAME_ACCESS)) {
- return MAP_FAILED;
- }
- }
-
- /* Split 64 bit size into low and high bits. */
- DWORD len_bits_high = len >> 32;
- DWORD len_bits_low = len & 0xFFFFFFFF;
-
- maphandle = CreateFileMapping(fhandle, NULL, prot_flags, len_bits_high, len_bits_low, NULL);
- if (maphandle == 0) {
- errno = EBADF;
- return MAP_FAILED;
- }
-
- ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
- if (ptr == NULL) {
- DWORD dwLastErr = GetLastError();
- if (dwLastErr == ERROR_MAPPED_ALIGNMENT) {
- errno = EINVAL;
- }
- else {
- errno = EACCES;
- }
- CloseHandle(maphandle);
- return MAP_FAILED;
- }
-
- mm = (MemMap *)malloc(sizeof(MemMap));
- if (!mm) {
- errno = ENOMEM;
- }
- mm->fhandle = fhandle;
- mm->maphandle = maphandle;
- mm->mmap = ptr;
- mmap_addtail(mmapbase, mm);
-
- return ptr;
-}
-
-/* munmap for windows */
-intptr_t munmap(void *ptr, size_t UNUSED(size))
-{
- MemMap *mm = mmap_findlink(mmapbase, ptr);
- if (!mm) {
- errno = EINVAL;
- return -1;
- }
- UnmapViewOfFile(mm->mmap);
- CloseHandle(mm->maphandle);
- CloseHandle(mm->fhandle);
- mmap_remlink(mmapbase, mm);
- free(mm);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* local functions */
-/* --------------------------------------------------------------------- */
-
-static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
-{
- struct mmapLink *link = vlink;
-
- if (link == NULL) {
- return;
- }
- if (listbase == NULL) {
- return;
- }
-
- link->next = 0;
- link->prev = listbase->last;
-
- if (listbase->last) {
- ((struct mmapLink *)listbase->last)->next = link;
- }
- if (listbase->first == NULL) {
- listbase->first = link;
- }
- listbase->last = link;
-}
-
-static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
-{
- struct mmapLink *link = vlink;
-
- if (link == NULL) {
- return;
- }
- if (listbase == NULL) {
- return;
- }
- if (link->next) {
- link->next->prev = link->prev;
- }
- if (link->prev) {
- link->prev->next = link->next;
- }
-
- if (listbase->last == link) {
- listbase->last = link->prev;
- }
- if (listbase->first == link) {
- listbase->first = link->next;
- }
-}
-
-static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
-{
- MemMap *mm;
-
- if (ptr == NULL) {
- return NULL;
- }
- if (listbase == NULL) {
- return NULL;
- }
-
- mm = (MemMap *)listbase->first;
- while (mm) {
- if (mm->mmap == ptr) {
- return mm;
- }
- mm = mm->next;
- }
- return NULL;
-}
-
-static int mmap_get_prot_flags(int flags)
-{
- int prot = PAGE_NOACCESS;
-
- if ((flags & PROT_READ) == PROT_READ) {
- if ((flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
- }
- else {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
- }
- }
- else if ((flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
- }
- else if ((flags & PROT_EXEC) == PROT_EXEC) {
- prot = PAGE_EXECUTE_READ;
- }
- return prot;
-}
-
-static int mmap_get_access_flags(int flags)
-{
- int access = 0;
-
- if ((flags & PROT_READ) == PROT_READ) {
- if ((flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_WRITE;
- }
- else {
- access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
- }
- }
- else if ((flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_COPY;
- }
- else if ((flags & PROT_EXEC) == PROT_EXEC) {
- access = FILE_MAP_EXECUTE;
- }
- return access;
-}
-
-#endif // WIN32
diff --git a/intern/guardedalloc/mmap_win.h b/intern/guardedalloc/mmap_win.h
deleted file mode 100644
index c0cbaa0e512..00000000000
--- a/intern/guardedalloc/mmap_win.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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) 2008 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup MEM
- */
-
-#ifndef __MMAP_WIN_H__
-#define __MMAP_WIN_H__
-
-#define PROT_NONE 0
-#define PROT_READ 1
-#define PROT_WRITE 2
-#define PROT_EXEC 4
-
-#define MAP_FILE 0
-#define MAP_SHARED 1
-#define MAP_PRIVATE 2
-#define MAP_TYPE 0xF
-#define MAP_FIXED 0x10
-#define MAP_ANONYMOUS 0x20
-#define MAP_ANON MAP_ANONYMOUS
-
-#define MAP_FAILED ((void *)-1)
-
-/* needed for uintptr_t, exception, dont use BLI anywhere else in MEM_* */
-#include "../../source/blender/blenlib/BLI_sys_types.h"
-
-#include <sys/types.h>
-
-void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset);
-intptr_t munmap(void *ptr, size_t size);
-
-#endif
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 858709833fb..babb3e30c6d 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 8b404c4a306..fecc09da539 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -759,6 +759,16 @@ class GreasePencilLayerAdjustmentsPanel:
col = layout.row(align=True)
col.prop(gpl, "lock_material")
+ # Transforms
+ row = layout.row(align=True)
+ row.prop(gpl, "location")
+
+ row = layout.row(align=True)
+ row.prop(gpl, "rotation")
+
+ row = layout.row(align=True)
+ row.prop(gpl, "scale")
+
class GPENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 495bf77b0e7..7fe1c3b29f4 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -502,7 +502,9 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
col = layout.column(align=True)
row = col.row(align=True)
row.label(text="Merge:")
- row.operator("clip.join_tracks", text="Join Tracks")
+ sub = row.column()
+ sub.operator("clip.join_tracks", text="Join Tracks")
+ sub.operator("clip.average_tracks", text="Average Tracks")
class CLIP_PT_tools_plane_tracking(CLIP_PT_tracking_panel, Panel):
@@ -1482,6 +1484,7 @@ class CLIP_MT_track(Menu):
layout.separator()
layout.operator("clip.join_tracks")
+ layout.operator("clip.average_tracks")
layout.separator()
@@ -1608,6 +1611,7 @@ class CLIP_MT_tracking_context_menu(Menu):
layout.separator()
layout.operator("clip.join_tracks")
+ layout.operator("clip.average_tracks")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index e6af83b61f4..a9934850acd 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -678,16 +678,8 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
- # inputs get icon on the left
- if not socket.is_output:
- row.template_node_socket(color=color)
-
+ row.template_node_socket(color=color)
row.prop(socket, "name", text="", emboss=False, icon_value=icon)
-
- # outputs get icon on the right
- if socket.is_output:
- row.template_node_socket(color=color)
-
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.template_node_socket(color=color)
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 577f9678a62..60982421318 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1435,7 +1435,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
row.prop(gp_settings, "fill_layer_mode", text="Layers")
col.separator()
- col.prop(gp_settings, "fill_factor", text="Resolution")
+ col.prop(gp_settings, "fill_factor")
if gp_settings.fill_draw_mode != 'STROKE':
col = layout.column(align=False, heading="Ignore Transparent")
col.use_property_decorate = False
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 8d904bd6019..2fce4bfc5b8 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -212,8 +212,7 @@ struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
struct ListBase *cache,
struct PointerRNA *ptr,
struct AnimData *adt,
- const struct AnimationEvalContext *anim_eval_context,
- const bool flush_to_original);
+ const struct AnimationEvalContext *anim_eval_context);
bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
struct PointerRNA *prop_ptr,
struct PropertyRNA *prop,
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
new file mode 100644
index 00000000000..b8bb2048d9d
--- /dev/null
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#include "BLI_color.hh"
+#include "BLI_float2.hh"
+#include "BLI_float3.hh"
+#include "DNA_customdata_types.h"
+
+namespace blender::attribute_math {
+
+/**
+ * Utility function that simplifies calling a templated function based on a custom data type.
+ */
+template<typename Func>
+void convert_to_static_type(const CustomDataType data_type, const Func &func)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ func(float());
+ break;
+ case CD_PROP_FLOAT2:
+ func(float2());
+ break;
+ case CD_PROP_FLOAT3:
+ func(float3());
+ break;
+ case CD_PROP_INT32:
+ func(int());
+ break;
+ case CD_PROP_BOOL:
+ func(bool());
+ break;
+ case CD_PROP_COLOR:
+ func(Color4f());
+ break;
+ default:
+ BLI_assert(false);
+ break;
+ }
+}
+
+/* Interpolate between three values. */
+template<typename T> T mix3(const float3 &weights, const T &v0, const T &v1, const T &v2);
+
+template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v1, const bool &v2)
+{
+ return (weights.x * v0 + weights.y * v1 + weights.z * v2) >= 0.5f;
+}
+
+template<> inline int mix3(const float3 &weights, const int &v0, const int &v1, const int &v2)
+{
+ return static_cast<int>(weights.x * v0 + weights.y * v1 + weights.z * v2);
+}
+
+template<>
+inline float mix3(const float3 &weights, const float &v0, const float &v1, const float &v2)
+{
+ return weights.x * v0 + weights.y * v1 + weights.z * v2;
+}
+
+template<>
+inline float2 mix3(const float3 &weights, const float2 &v0, const float2 &v1, const float2 &v2)
+{
+ return weights.x * v0 + weights.y * v1 + weights.z * v2;
+}
+
+template<>
+inline float3 mix3(const float3 &weights, const float3 &v0, const float3 &v1, const float3 &v2)
+{
+ return weights.x * v0 + weights.y * v1 + weights.z * v2;
+}
+
+template<>
+inline Color4f mix3(const float3 &weights, const Color4f &v0, const Color4f &v1, const Color4f &v2)
+{
+ Color4f result;
+ interp_v4_v4v4v4(result, v0, v1, v2, weights);
+ return result;
+}
+
+} // namespace blender::attribute_math
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 4ee96d1ab8d..8752fd9c8cd 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -31,15 +31,15 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 292
+#define BLENDER_VERSION 293
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
-#define BLENDER_VERSION_CYCLE beta
+#define BLENDER_VERSION_CYCLE alpha
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 14
+#define BLENDER_FILE_SUBVERSION 1
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index df5711f5120..8903abee432 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -280,12 +280,12 @@ void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig
const struct bGPDframe *gpf_eval);
void BKE_gpencil_update_orig_pointers(const struct Object *ob_orig, const struct Object *ob_eval);
-void BKE_gpencil_parent_matrix_get(const struct Depsgraph *depsgraph,
- struct Object *obact,
- struct bGPDlayer *gpl,
- float diff_mat[4][4]);
+void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph,
+ struct Object *obact,
+ struct bGPDlayer *gpl,
+ float diff_mat[4][4]);
-void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct Object *ob);
+void BKE_gpencil_update_layer_transforms(const struct Depsgraph *depsgraph, struct Object *ob);
int BKE_gpencil_material_find_index_by_name_prefix(struct Object *ob, const char *name_prefix);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 79bc00766fd..6ab401a2d41 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -463,8 +463,8 @@ void ntreeSetOutput(struct bNodeTree *ntree);
void ntreeFreeCache(struct bNodeTree *ntree);
-bool ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode);
-bool ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock);
+bool ntreeNodeExists(const struct bNodeTree *ntree, const struct bNode *testnode);
+bool ntreeOutputExists(const struct bNode *node, const struct bNodeSocket *testsock);
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable);
struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
@@ -501,7 +501,7 @@ struct bNodeSocket *ntreeInsertSocketInterfaceFromSocket(struct bNodeTree *ntree
struct bNodeSocket *from_sock);
void ntreeRemoveSocketInterface(struct bNodeTree *ntree, struct bNodeSocket *sock);
-struct StructRNA *ntreeInterfaceTypeGet(struct bNodeTree *ntree, int create);
+struct StructRNA *ntreeInterfaceTypeGet(struct bNodeTree *ntree, bool create);
void ntreeInterfaceTypeFree(struct bNodeTree *ntree);
void ntreeInterfaceTypeUpdate(struct bNodeTree *ntree);
@@ -624,12 +624,12 @@ struct bNodeLink *nodeAddLink(struct bNodeTree *ntree,
struct bNodeSocket *tosock);
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
-bool nodeLinkIsHidden(struct bNodeLink *link);
+bool nodeLinkIsHidden(const struct bNodeLink *link);
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
-void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry);
-void nodeFromView(struct bNode *node, float x, float y, float *rx, float *ry);
-bool nodeAttachNodeCheck(struct bNode *node, struct bNode *parent);
+void nodeToView(const struct bNode *node, float x, float y, float *rx, float *ry);
+void nodeFromView(const struct bNode *node, float x, float y, float *rx, float *ry);
+bool nodeAttachNodeCheck(const struct bNode *node, const struct bNode *parent);
void nodeAttachNode(struct bNode *node, struct bNode *parent);
void nodeDetachNode(struct bNode *node);
@@ -661,9 +661,9 @@ void nodeChainIterBackwards(const bNodeTree *ntree,
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree,
- struct bNodeSocket *from,
- struct bNodeSocket *to);
-int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
+ const struct bNodeSocket *from,
+ const struct bNodeSocket *to);
+int nodeCountSocketLinks(const struct bNodeTree *ntree, const struct bNodeSocket *sock);
void nodeSetSelected(struct bNode *node, bool select);
void nodeSetActive(struct bNodeTree *ntree, struct bNode *node);
@@ -678,11 +678,11 @@ void nodeUpdate(struct bNodeTree *ntree, struct bNode *node);
bool nodeUpdateID(struct bNodeTree *ntree, struct ID *id);
void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node);
-int nodeSocketIsHidden(struct bNodeSocket *sock);
+int nodeSocketIsHidden(const struct bNodeSocket *sock);
void ntreeTagUsedSockets(struct bNodeTree *ntree);
void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available);
-int nodeSocketLinkLimit(struct bNodeSocket *sock);
+int nodeSocketLinkLimit(const struct bNodeSocket *sock);
/* Node Clipboard */
void BKE_node_clipboard_init(struct bNodeTree *ntree);
@@ -767,7 +767,7 @@ BLI_INLINE bool BKE_node_instance_hash_iterator_done(bNodeInstanceHashIterator *
/* Node Previews */
-int BKE_node_preview_used(struct bNode *node);
+bool BKE_node_preview_used(const struct bNode *node);
bNodePreview *BKE_node_preview_verify(
struct bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create);
bNodePreview *BKE_node_preview_copy(struct bNodePreview *preview);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 7b5df98d148..e9a141709b5 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -67,6 +67,13 @@ struct wmWindowManager;
#define BKE_ST_MAXNAME 64
+typedef struct wmSpaceTypeListenerParams {
+ struct wmWindow *window;
+ struct ScrArea *area;
+ struct wmNotifier *notifier;
+ const struct Scene *scene;
+} wmSpaceTypeListenerParams;
+
typedef struct SpaceType {
struct SpaceType *next, *prev;
@@ -85,10 +92,7 @@ typedef struct SpaceType {
/* exit is called when the area is hidden or removed */
void (*exit)(struct wmWindowManager *wm, struct ScrArea *area);
/* Listeners can react to bContext changes */
- void (*listener)(struct wmWindow *win,
- struct ScrArea *area,
- struct wmNotifier *wmn,
- struct Scene *scene);
+ void (*listener)(const wmSpaceTypeListenerParams *params);
/* called when the mouse moves out of the area */
void (*deactivate)(struct ScrArea *area);
@@ -134,6 +138,23 @@ typedef struct SpaceType {
/* region types are also defined using spacetypes_init, via a callback */
+typedef struct wmRegionListenerParams {
+ struct ScrArea *area; /* Can be NULL when the region is not part of an area. */
+ struct ARegion *region;
+ struct wmNotifier *notifier;
+ const struct Scene *scene;
+} wmRegionListenerParams;
+
+typedef struct wmRegionMessageSubscribeParams {
+ const struct bContext *context;
+ struct wmMsgBus *message_bus;
+ struct WorkSpace *workspace;
+ struct Scene *scene;
+ struct bScreen *screen;
+ struct ScrArea *area;
+ struct ARegion *region;
+} wmRegionMessageSubscribeParams;
+
typedef struct ARegionType {
struct ARegionType *next, *prev;
@@ -158,19 +179,9 @@ typedef struct ARegionType {
/* snap the size of the region (can be NULL for no snapping). */
int (*snap_size)(const struct ARegion *region, int size, int axis);
/* contextual changes should be handled here */
- void (*listener)(struct wmWindow *win,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmNotifier *wmn,
- const struct Scene *scene);
+ void (*listener)(const wmRegionListenerParams *params);
/* Optional callback to generate subscriptions. */
- void (*message_subscribe)(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+ void (*message_subscribe)(const wmRegionMessageSubscribeParams *params);
void (*free)(struct ARegion *);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 4dbc22ae18f..c2544c06514 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -89,6 +89,23 @@ struct MovieTrackingTrack *BKE_tracking_track_duplicate(struct MovieTrackingTrac
void BKE_tracking_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
void BKE_tracking_track_free(struct MovieTrackingTrack *track);
+void BKE_tracking_track_first_last_frame_get(const struct MovieTrackingTrack *track,
+ int *r_first_frame,
+ int *r_last_frame);
+
+void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ struct MovieTrackingTrack **tracks,
+ const int num_tracks,
+ int *r_first_frame,
+ int *r_last_frame);
+
+int BKE_tracking_count_selected_tracks_in_list(const struct ListBase *tracks_list);
+int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ struct MovieTracking *tracking);
+
+/* Get array of selected tracks from the current active object in the tracking structure.
+ * If nothing is selected then the result is nullptr and `r_num_tracks` is set to 0. */
+struct MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(
+ struct MovieTracking *tracking, int *r_num_tracks);
+
void BKE_tracking_track_flag_set(struct MovieTrackingTrack *track, int area, int flag);
void BKE_tracking_track_flag_clear(struct MovieTrackingTrack *track, int area, int flag);
@@ -96,10 +113,15 @@ bool BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, in
bool BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action);
+
void BKE_tracking_tracks_join(struct MovieTracking *tracking,
struct MovieTrackingTrack *dst_track,
struct MovieTrackingTrack *src_track);
+void BKE_tracking_tracks_average(struct MovieTrackingTrack *dst_track,
+ /*const*/ struct MovieTrackingTrack **src_tracks,
+ const int num_src_tracks);
+
struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking,
struct MovieTrackingObject *object,
const char *name);
@@ -139,6 +161,17 @@ struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTr
struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track,
int framenr);
+/* Get marker position, possibly interpolating interpolating gap between keyframed/tracked markers.
+ *
+ * The result marker frame number is set to the requested frame number. Its flags are 0 if the
+ * marker is interpolated, and is set to original marker flag if there were no interpolation
+ * involved.
+ *
+ * Returns truth if the result is usable. */
+bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
+ const int framenr,
+ struct MovieTrackingMarker *r_marker);
+
void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker,
float min[2],
float max[2]);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 9aa2baef53c..20c57f4e15a 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -275,6 +275,7 @@ set(SRC
BKE_asset.h
BKE_attribute.h
BKE_attribute_access.hh
+ BKE_attribute_math.hh
BKE_autoexec.h
BKE_blender.h
BKE_blender_copybuffer.h
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 20956d6eb18..da874539232 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -362,6 +362,20 @@ void BKE_keyingsets_blend_read_expand(BlendExpander *expander, ListBase *list)
/* ***************************************** */
/* Evaluation Data-Setting Backend */
+static bool is_fcurve_evaluatable(FCurve *fcu)
+{
+ if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
+ return false;
+ }
+ if (fcu->grp != NULL && (fcu->grp->flag & AGRP_MUTED)) {
+ return false;
+ }
+ if (BKE_fcurve_is_empty(fcu)) {
+ return false;
+ }
+ return true;
+}
+
bool BKE_animsys_store_rna_setting(PointerRNA *ptr,
/* typically 'fcu->rna_path', 'fcu->array_index' */
const char *rna_path,
@@ -594,18 +608,11 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
{
/* Calculate then execute each curve. */
LISTBASE_FOREACH (FCurve *, fcu, list) {
- /* Check if this F-Curve doesn't belong to a muted group. */
- if ((fcu->grp != NULL) && (fcu->grp->flag & AGRP_MUTED)) {
- continue;
- }
- /* Check if this curve should be skipped. */
- if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) {
- continue;
- }
- /* Skip empty curves, as if muted. */
- if (BKE_fcurve_is_empty(fcu)) {
+
+ if (!is_fcurve_evaluatable(fcu)) {
continue;
}
+
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
@@ -979,6 +986,19 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
return nes;
}
+static NlaEvalStrip *nlastrips_ctime_get_strip_single(
+ ListBase *dst_list,
+ NlaStrip *single_strip,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
+{
+ ListBase single_tracks_list;
+ single_tracks_list.first = single_tracks_list.last = single_strip;
+
+ return nlastrips_ctime_get_strip(
+ dst_list, &single_tracks_list, -1, anim_eval_context, flush_to_original);
+}
+
/* ---------------------- */
/* Initialize a valid mask, allocating memory if necessary. */
@@ -1152,7 +1172,7 @@ static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot)
/* Free memory owned by this evaluation channel. */
static void nlaevalchan_free_data(NlaEvalChannel *nec)
{
- nlavalidmask_free(&nec->valid);
+ nlavalidmask_free(&nec->domain);
if (nec->blend_snapshot != NULL) {
nlaevalchan_snapshot_free(nec->blend_snapshot);
@@ -1353,7 +1373,7 @@ static NlaEvalChannel *nlaevalchan_verify_key(NlaEvalData *nlaeval,
nec->mix_mode = nlaevalchan_detect_mix_mode(key, length);
- nlavalidmask_init(&nec->valid, length);
+ nlavalidmask_init(&nec->domain, length);
nec->base_snapshot.channel = nec;
nec->base_snapshot.length = length;
@@ -1682,14 +1702,6 @@ static bool nlaeval_blend_value(NlaBlendData *blend,
return false;
}
- if (nec->mix_mode == NEC_MIX_QUATERNION) {
- /* For quaternion properties, always output all sub-channels. */
- BLI_bitmap_set_all(nec->valid.ptr, true, 4);
- }
- else {
- BLI_BITMAP_ENABLE(nec->valid.ptr, array_index);
- }
-
NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
float *p_value = &nec_snapshot->values[array_index];
@@ -1889,16 +1901,8 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
/* Evaluate all the F-Curves in the action,
* saving the relevant pointers to data that will need to be used. */
for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
- float value = 0.0f;
- /* check if this curve should be skipped */
- if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
- continue;
- }
- if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
- continue;
- }
- if (BKE_fcurve_is_empty(fcu)) {
+ if (!is_fcurve_evaluatable(fcu)) {
continue;
}
@@ -1906,7 +1910,7 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
* NOTE: we use the modified time here, since strip's F-Curve Modifiers
* are applied on top of this.
*/
- value = evaluate_fcurve(fcu, evaltime);
+ float value = evaluate_fcurve(fcu, evaltime);
/* apply strip's F-Curve Modifiers on this value
* NOTE: we apply the strip's original evaluation time not the modified one
@@ -2099,12 +2103,21 @@ void nladata_flush_channels(PointerRNA *ptr,
/* for each channel with accumulated values, write its value on the property it affects */
LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) {
+ /**
+ * The bitmask is set for all channels touched by NLA due to the domain() function.
+ * Channels touched by current set of evaluated strips will have a snapshot channel directly
+ * from the evaluation snapshot.
+ *
+ * This function falls back to the default value if the snapshot channel doesn't exist.
+ * Thus channels, touched by NLA but not by the current set of evaluated strips, will be
+ * reset to default. If channel not touched by NLA then it's value is unchanged.
+ */
NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec);
PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1};
for (int i = 0; i < nec_snapshot->length; i++) {
- if (BLI_BITMAP_TEST(nec->valid.ptr, i)) {
+ if (BLI_BITMAP_TEST(nec->domain.ptr, i)) {
float value = nec_snapshot->values[i];
if (nec->is_array) {
rna.prop_index = i;
@@ -2131,13 +2144,7 @@ static void nla_eval_domain_action(PointerRNA *ptr,
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
/* check if this curve should be skipped */
- if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
- continue;
- }
- if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
- continue;
- }
- if (BKE_fcurve_is_empty(fcu)) {
+ if (!is_fcurve_evaluatable(fcu)) {
continue;
}
@@ -2146,14 +2153,14 @@ static void nla_eval_domain_action(PointerRNA *ptr,
if (nec != NULL) {
/* For quaternion properties, enable all sub-channels. */
if (nec->mix_mode == NEC_MIX_QUATERNION) {
- BLI_bitmap_set_all(nec->valid.ptr, true, 4);
+ BLI_bitmap_set_all(nec->domain.ptr, true, 4);
continue;
}
int idx = nlaevalchan_validate_index(nec, fcu->array_index);
if (idx >= 0) {
- BLI_BITMAP_ENABLE(nec->valid.ptr, idx);
+ BLI_BITMAP_ENABLE(nec->domain.ptr, idx);
}
}
}
@@ -2212,190 +2219,345 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
/* ---------------------- */
+/** Tweaked strip is evaluated differently from other strips. Adjacent strips are ignored
+ * and includes a workaround for when user is not editing in place. */
+static void animsys_create_tweak_strip(const AnimData *adt,
+ const bool keyframing_to_strip,
+ NlaStrip *r_tweak_strip)
+
+{
+ /* Copy active strip so we can modify how it evaluates without affecting user data. */
+ memcpy(r_tweak_strip, adt->actstrip, sizeof(NlaStrip));
+ r_tweak_strip->next = r_tweak_strip->prev = NULL;
+
+ /* If tweaked strip is syncing action length, then evaluate using action length. */
+ if (r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
+ BKE_nlastrip_recalculate_bounds_sync_action(r_tweak_strip);
+ }
+
+ /* Strips with a user-defined time curve don't get properly remapped for editing
+ * at the moment, so mapping them just for display may be confusing. */
+ const bool is_inplace_tweak = !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
+ !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
+
+ if (!is_inplace_tweak) {
+ /* Use Hold due to no proper remapping yet (the note above). */
+ r_tweak_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+
+ /* Disable range. */
+ r_tweak_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+ }
+
+ /** Controls whether able to keyframe outside range of tweaked strip. */
+ if (keyframing_to_strip) {
+ r_tweak_strip->extendmode = (is_inplace_tweak &&
+ !(r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
+ NLASTRIP_EXTEND_NOTHING :
+ NLASTRIP_EXTEND_HOLD;
+ }
+}
+
+/** Action track and strip are associated with the non-pushed action. */
+static void animsys_create_action_track_strip(const AnimData *adt,
+ const bool keyframing_to_strip,
+ NlaStrip *r_action_strip)
+{
+ memset(r_action_strip, 0, sizeof(NlaStrip));
+
+ bAction *action = adt->action;
+
+ if ((adt->flag & ADT_NLA_EDIT_ON)) {
+ action = adt->tmpact;
+ }
+
+ /* Set settings of dummy NLA strip from AnimData settings. */
+ r_action_strip->act = action;
+
+ /* Action range is calculated taking F-Modifiers into account
+ * (which making new strips doesn't do due to the troublesome nature of that). */
+ calc_action_range(r_action_strip->act, &r_action_strip->actstart, &r_action_strip->actend, 1);
+ r_action_strip->start = r_action_strip->actstart;
+ r_action_strip->end = (IS_EQF(r_action_strip->actstart, r_action_strip->actend)) ?
+ (r_action_strip->actstart + 1.0f) :
+ (r_action_strip->actend);
+
+ r_action_strip->blendmode = adt->act_blendmode;
+ r_action_strip->extendmode = adt->act_extendmode;
+ r_action_strip->influence = adt->act_influence;
+
+ /* NOTE: must set this, or else the default setting overrides,
+ * and this setting doesn't work. */
+ r_action_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+
+ /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range.
+ * Extendmode Nothing and Hold will behave as normal. Hold Forward will behave just like Hold.
+ */
+ if (r_action_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+ r_action_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+ }
+
+ const bool tweaking = (adt->flag & ADT_NLA_EDIT_ON) != 0;
+ const bool soloing = (adt->flag & ADT_NLA_SOLO_TRACK) != 0;
+ const bool actionstrip_evaluated = r_action_strip->act && !soloing && !tweaking;
+ if (!actionstrip_evaluated) {
+ r_action_strip->flag |= NLASTRIP_FLAG_MUTED;
+ }
+
+ /** If we're keyframing, then we must allow keyframing outside fcurve bounds. */
+ if (keyframing_to_strip) {
+ r_action_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+ }
+}
+
+static bool is_nlatrack_evaluatable(const AnimData *adt, const NlaTrack *nlt)
+{
+ /* Skip disabled tracks unless it contains the tweaked strip. */
+ const bool contains_tweak_strip = (adt->flag & ADT_NLA_EDIT_ON) &&
+ (nlt->index == adt->act_track->index);
+ if ((nlt->flag & NLATRACK_DISABLED) && !contains_tweak_strip) {
+ return false;
+ }
+
+ /* Solo and muting are mutually exclusive. */
+ if (adt->flag & ADT_NLA_SOLO_TRACK) {
+ /* Skip if there is a solo track, but this isn't it. */
+ if ((nlt->flag & NLATRACK_SOLO) == 0) {
+ return false;
+ }
+ }
+ else {
+ /* Skip track if muted. */
+ if (nlt->flag & NLATRACK_MUTED) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/** Check for special case of non-pushed action being evaluated with no NLA influence (off and no
+ * strips evaluated) nor NLA interference (ensure NLA not soloing). */
+static bool is_action_track_evaluated_without_nla(const AnimData *adt,
+ const bool any_strip_evaluated)
+{
+ if (adt->action == NULL) {
+ return false;
+ }
+
+ if (any_strip_evaluated) {
+ return false;
+ }
+
+ /** NLA settings interference. */
+ if ((adt->flag & (ADT_NLA_SOLO_TRACK | ADT_NLA_EDIT_ON)) == 0) {
+ return false;
+ }
+
+ /** Allow action track to evaluate as if there isn't any NLA data. */
+ return true;
+}
+
/**
- * NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels"
+ * XXX(Wayde Moss): #BKE_nlatrack_find_tweaked() exists within nla.c, but it doesn't appear to
+ * work as expected. From #animsys_evaluate_nla_for_flush(), it returns NULL in tweak mode. I'm not
+ * sure why. Preferably, it would be as simple as checking for `(adt->act_Track == nlt)` but that
+ * doesn't work either, neither does comparing indices.
*
+ * This function is a temporary work around. The first disabled track is always the tweaked track.
+ */
+static NlaTrack *nlatrack_find_tweaked(const AnimData *adt)
+{
+ NlaTrack *nlt;
+
+ if (adt == NULL) {
+ return NULL;
+ }
+
+ /* Since the track itself gets disabled, we want the first disabled. */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ if (nlt->flag & NLATRACK_DISABLED) {
+ return nlt;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels"
* \param[out] echannels: Evaluation channels with calculated values
- * \param[out] r_context: If not NULL,
- * data about the currently edited strip is stored here and excluded from value calculation.
- * \return false if NLA evaluation isn't actually applicable.
*/
-static bool animsys_evaluate_nla(NlaEvalData *echannels,
- PointerRNA *ptr,
- AnimData *adt,
- const AnimationEvalContext *anim_eval_context,
- const bool flush_to_original,
- NlaKeyframingContext *r_context)
+static bool animsys_evaluate_nla_for_flush(NlaEvalData *echannels,
+ PointerRNA *ptr,
+ const AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
NlaTrack *nlt;
short track_index = 0;
bool has_strips = false;
-
ListBase estrips = {NULL, NULL};
NlaEvalStrip *nes;
- NlaStrip dummy_strip_buf;
- /* dummy strip for active action */
- NlaStrip *dummy_strip = r_context ? &r_context->strip : &dummy_strip_buf;
+ NlaStrip tweak_strip;
- memset(dummy_strip, 0, sizeof(*dummy_strip));
+ NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
- /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
+ /* Get the stack of strips to evaluate at current time (influence calculated here). */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
- /* stop here if tweaking is on and this strip is the tweaking track
- * (it will be the first one that's 'disabled')... */
- if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED)) {
- break;
+
+ if (!is_nlatrack_evaluatable(adt, nlt)) {
+ continue;
}
- /* solo and muting are mutually exclusive... */
- if (adt->flag & ADT_NLA_SOLO_TRACK) {
- /* skip if there is a solo track, but this isn't it */
- if ((nlt->flag & NLATRACK_SOLO) == 0) {
- continue;
- }
- /* else - mute doesn't matter */
+ if (nlt->strips.first) {
+ has_strips = true;
+ }
+
+ /** Append strip to evaluate for this track. */
+ if (nlt == tweaked_track) {
+ /** Tweaked strip is evaluated differently. */
+ animsys_create_tweak_strip(adt, false, &tweak_strip);
+ nes = nlastrips_ctime_get_strip_single(
+ &estrips, &tweak_strip, anim_eval_context, flush_to_original);
}
else {
- /* no solo tracks - skip track if muted */
- if (nlt->flag & NLATRACK_MUTED) {
- continue;
- }
+ nes = nlastrips_ctime_get_strip(
+ &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
+ }
+ if (nes) {
+ nes->track = nlt;
+ }
+ }
+
+ if (is_action_track_evaluated_without_nla(adt, has_strips)) {
+ BLI_freelistN(&estrips);
+ return false;
+ }
+
+ NlaStrip action_strip = {0};
+ animsys_create_action_track_strip(adt, false, &action_strip);
+ nlastrips_ctime_get_strip_single(&estrips, &action_strip, anim_eval_context, flush_to_original);
+
+ /* Per strip, evaluate and accumulate on top of existing channels. */
+ for (nes = estrips.first; nes; nes = nes->next) {
+ nlastrip_evaluate(ptr,
+ echannels,
+ NULL,
+ nes,
+ &echannels->eval_snapshot,
+ anim_eval_context,
+ flush_to_original);
+ }
+
+ /* Free temporary evaluation data that's not used elsewhere. */
+ BLI_freelistN(&estrips);
+ return true;
+}
+
+/** Lower blended values are calculated and accumulated into r_context->lower_eval_data. */
+static void animsys_evaluate_nla_for_keyframing(PointerRNA *ptr,
+ const AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ NlaKeyframingContext *r_context)
+{
+ if (!r_context) {
+ return;
+ }
+
+ /* Early out. If NLA track is soloing and tweaked action isn't it, then don't allow keyframe
+ * insertion. */
+ if (adt->flag & ADT_NLA_SOLO_TRACK) {
+ if (!(adt->act_track && (adt->act_track->flag & NLATRACK_SOLO))) {
+ r_context->eval_strip = NULL;
+ return;
+ }
+ }
+
+ NlaTrack *nlt;
+ short track_index = 0;
+ bool has_strips = false;
+
+ ListBase lower_estrips = {NULL, NULL};
+ NlaEvalStrip *nes;
+
+ NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
+
+ /* Get the lower stack of strips to evaluate at current time (influence calculated here). */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
+
+ if (!is_nlatrack_evaluatable(adt, nlt)) {
+ continue;
+ }
+
+ /* Tweaked strip effect should not be stored in any snapshot. */
+ if (nlt == tweaked_track) {
+ break;
}
- /* if this track has strips (but maybe they won't be suitable), set has_strips
- * - used for mainly for still allowing normal action evaluation...
- */
if (nlt->strips.first) {
has_strips = true;
}
- /* otherwise, get strip to evaluate for this channel */
+ /* Get strip to evaluate for this channel. */
nes = nlastrips_ctime_get_strip(
- &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
+ &lower_estrips, &nlt->strips, track_index, anim_eval_context, false);
if (nes) {
nes->track = nlt;
}
}
- /* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack
- * - only do this if we're not exclusively evaluating the 'solo' NLA-track
- * - however, if the 'solo' track houses the current 'tweaking' strip,
- * then we should allow this to play, otherwise nothing happens
+ /** Note: Although we early out, we can still keyframe to the non-pushed action since the
+ * keyframe remap function detects (r_context->strip.act == NULL) and will keyframe without
+ * remapping.
*/
- if ((adt->action) && ((adt->flag & ADT_NLA_SOLO_TRACK) == 0 || (adt->flag & ADT_NLA_EDIT_ON))) {
- /* if there are strips, evaluate action as per NLA rules */
- if ((has_strips) || (adt->actstrip)) {
- /* make dummy NLA strip, and add that to the stack */
- ListBase dummy_trackslist;
-
- dummy_trackslist.first = dummy_trackslist.last = dummy_strip;
-
- /* Strips with a user-defined time curve don't get properly remapped for editing
- * at the moment, so mapping them just for display may be confusing. */
- bool is_inplace_tweak = (nlt) && !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
- !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
-
- if (is_inplace_tweak) {
- /* edit active action in-place according to its active strip, so copy the data */
- memcpy(dummy_strip, adt->actstrip, sizeof(NlaStrip));
- /* Prevents nla eval from considering active strip's adj strips.
- * For user, this means entering tweak mode on a strip ignores evaluating adjacent strips
- * in the same track. */
- dummy_strip->next = dummy_strip->prev = NULL;
-
- /* If tweaked strip is syncing action length, then evaluate using action length. */
- if (dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
- BKE_nlastrip_recalculate_bounds_sync_action(dummy_strip);
- }
- }
- else {
- /* set settings of dummy NLA strip from AnimData settings */
- dummy_strip->act = adt->action;
-
- /* action range is calculated taking F-Modifiers into account
- * (which making new strips doesn't do due to the troublesome nature of that) */
- calc_action_range(dummy_strip->act, &dummy_strip->actstart, &dummy_strip->actend, 1);
- dummy_strip->start = dummy_strip->actstart;
- dummy_strip->end = (IS_EQF(dummy_strip->actstart, dummy_strip->actend)) ?
- (dummy_strip->actstart + 1.0f) :
- (dummy_strip->actend);
-
- /* Always use the blend mode of the strip in tweak mode, even if not in-place. */
- if (nlt && adt->actstrip) {
- dummy_strip->blendmode = adt->actstrip->blendmode;
- dummy_strip->extendmode = NLASTRIP_EXTEND_HOLD;
- }
- else {
- dummy_strip->blendmode = adt->act_blendmode;
- dummy_strip->extendmode = adt->act_extendmode;
- }
+ if (is_action_track_evaluated_without_nla(adt, has_strips)) {
+ BLI_freelistN(&lower_estrips);
+ return;
+ }
- /* Unless extend-mode is Nothing (might be useful for flattening NLA evaluation),
- * disable range. */
- if (dummy_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
- dummy_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
- }
+ /* Write r_context->eval_strip. */
+ if (adt->flag & ADT_NLA_EDIT_ON) {
- dummy_strip->influence = adt->act_influence;
+ NlaStrip *tweak_strip = &r_context->strip;
+ animsys_create_tweak_strip(adt, true, tweak_strip);
+ r_context->eval_strip = nlastrips_ctime_get_strip_single(
+ NULL, tweak_strip, anim_eval_context, false);
+ }
+ else {
- /* NOTE: must set this, or else the default setting overrides,
- * and this setting doesn't work. */
- dummy_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
- }
+ NlaStrip *action_strip = &r_context->strip;
+ animsys_create_action_track_strip(adt, true, action_strip);
+ r_context->eval_strip = nlastrips_ctime_get_strip_single(
+ NULL, action_strip, anim_eval_context, false);
+ }
- /* add this to our list of evaluation strips */
- if (r_context == NULL) {
- nlastrips_ctime_get_strip(
- &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
- }
- /* If computing the context for keyframing, store data there instead of the list. */
- else {
- /* The extend mode here effectively controls
- * whether it is possible to key-frame beyond the ends.*/
- dummy_strip->extendmode = (is_inplace_tweak &&
- !(dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
- NLASTRIP_EXTEND_NOTHING :
- NLASTRIP_EXTEND_HOLD;
-
- r_context->eval_strip = nes = nlastrips_ctime_get_strip(
- NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
-
- /* These setting combinations require no data from strips below, so exit immediately. */
- if ((nes == NULL) ||
- (dummy_strip->blendmode == NLASTRIP_MODE_REPLACE && dummy_strip->influence == 1.0f)) {
- BLI_freelistN(&estrips);
- return true;
- }
- }
- }
- else {
- /* special case - evaluate as if there isn't any NLA data */
- BLI_freelistN(&estrips);
- return false;
- }
+ /* If NULL, then keyframing will fail. No need to do any more processing. */
+ if (!r_context->eval_strip) {
+ BLI_freelistN(&lower_estrips);
+ return;
}
- /* only continue if there are strips to evaluate */
- if (BLI_listbase_is_empty(&estrips)) {
- return true;
+ /* If tweak strip is full REPLACE, then lower strips not needed. */
+ if (r_context->strip.blendmode == NLASTRIP_MODE_REPLACE &&
+ IS_EQF(r_context->strip.influence, 1.0f)) {
+ BLI_freelistN(&lower_estrips);
+ return;
}
- /* 2. for each strip, evaluate then accumulate on top of existing channels,
- * but don't set values yet. */
- for (nes = estrips.first; nes; nes = nes->next) {
+ /* For each strip, evaluate then accumulate on top of existing channels. */
+ for (nes = lower_estrips.first; nes; nes = nes->next) {
nlastrip_evaluate(ptr,
- echannels,
+ &r_context->lower_eval_data,
NULL,
nes,
- &echannels->eval_snapshot,
+ &r_context->lower_eval_data.eval_snapshot,
anim_eval_context,
- flush_to_original);
+ false);
}
- /* 3. free temporary evaluation data that's not used elsewhere */
- BLI_freelistN(&estrips);
- return true;
+ /* Free temporary evaluation data that's not used elsewhere. */
+ BLI_freelistN(&lower_estrips);
}
/* NLA Evaluation function (mostly for use through do_animdata)
@@ -2412,7 +2574,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
nlaeval_init(&echannels);
/* evaluate the NLA stack, obtaining a set of values to flush */
- if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) {
+ if (animsys_evaluate_nla_for_flush(&echannels, ptr, adt, anim_eval_context, flush_to_original)) {
/* reset any channels touched by currently inactive actions to default value */
animsys_evaluate_nla_domain(ptr, &echannels, adt);
@@ -2448,8 +2610,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
struct ListBase *cache,
struct PointerRNA *ptr,
struct AnimData *adt,
- const AnimationEvalContext *anim_eval_context,
- const bool flush_to_original)
+ const AnimationEvalContext *anim_eval_context)
{
/* No remapping needed if NLA is off or no action. */
if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
@@ -2472,8 +2633,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
ctx->adt = adt;
nlaeval_init(&ctx->lower_eval_data);
- animsys_evaluate_nla(
- &ctx->lower_eval_data, ptr, adt, anim_eval_context, flush_to_original, ctx);
+ animsys_evaluate_nla_for_keyframing(ptr, adt, anim_eval_context, ctx);
BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
BLI_addtail(cache, ctx);
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 2e1094364fd..21ab7f61447 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -526,6 +526,10 @@ static ReadAttributePtr read_attribute_from_custom_data(const CustomData &custom
case CD_PROP_BOOL:
return std::make_unique<ArrayReadAttribute<bool>>(
domain, Span(static_cast<bool *>(layer.data), size));
+ case CD_MLOOPUV:
+ auto get_uv = [](const MLoopUV &uv) { return float2(uv.uv); };
+ return std::make_unique<DerivedArrayReadAttribute<MLoopUV, float2, decltype(get_uv)>>(
+ domain, Span(static_cast<MLoopUV *>(layer.data), size), get_uv);
}
}
}
@@ -570,6 +574,12 @@ static WriteAttributePtr write_attribute_from_custom_data(
case CD_PROP_BOOL:
return std::make_unique<ArrayWriteAttribute<bool>>(
domain, MutableSpan(static_cast<bool *>(layer.data), size));
+ case CD_MLOOPUV:
+ auto get_uv = [](const MLoopUV &uv) { return float2(uv.uv); };
+ auto set_uv = [](MLoopUV &uv, const float2 value) { copy_v2_v2(uv.uv, value); };
+ return std::make_unique<
+ DerivedArrayWriteAttribute<MLoopUV, float2, decltype(get_uv), decltype(set_uv)>>(
+ domain, MutableSpan(static_cast<MLoopUV *>(layer.data), size), get_uv, set_uv);
}
}
}
@@ -597,8 +607,9 @@ static void get_custom_data_layer_attribute_names(const CustomData &custom_data,
Set<std::string> &r_names)
{
for (const CustomDataLayer &layer : blender::Span(custom_data.layers, custom_data.totlayer)) {
- if (component.attribute_domain_with_type_supported(domain,
- static_cast<CustomDataType>(layer.type))) {
+ const CustomDataType data_type = static_cast<CustomDataType>(layer.type);
+ if (component.attribute_domain_with_type_supported(domain, data_type) ||
+ ELEM(data_type, CD_MLOOPUV)) {
r_names.add(layer.name);
}
}
@@ -1318,7 +1329,7 @@ Set<std::string> MeshComponent::attribute_names() const
for (StringRef name : vertex_group_names_.keys()) {
names.add(name);
}
- get_custom_data_layer_attribute_names(mesh_->pdata, *this, ATTR_DOMAIN_CORNER, names);
+ get_custom_data_layer_attribute_names(mesh_->ldata, *this, ATTR_DOMAIN_CORNER, names);
get_custom_data_layer_attribute_names(mesh_->vdata, *this, ATTR_DOMAIN_POINT, names);
get_custom_data_layer_attribute_names(mesh_->edata, *this, ATTR_DOMAIN_EDGE, names);
get_custom_data_layer_attribute_names(mesh_->pdata, *this, ATTR_DOMAIN_POLYGON, names);
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 762ced7dc5f..2ad0ac950d0 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -23,7 +23,7 @@
* - passing output paths to the visitor?, like render out.
* - passing sequence strips with many images.
* - passing directory paths - visitors don't know which path is a dir or a file.
- * */
+ */
#include <sys/stat.h>
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 9a954a89cad..ea1b0f8c1cc 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -978,7 +978,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->fill_leak = 3;
brush->gpencil_settings->fill_threshold = 0.1f;
brush->gpencil_settings->fill_simplylvl = 1;
- brush->gpencil_settings->fill_factor = 1;
+ brush->gpencil_settings->fill_factor = 1.0f;
brush->gpencil_settings->draw_strength = 1.0f;
brush->gpencil_settings->hardeness = 1.0f;
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 65accc66084..6bc385ecd31 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -318,7 +318,7 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData
*
* Values in order of importance
* (0, -1, 1) - Where 1 is highest priority
- * */
+ */
if (done != 1 && recursion < 1 && C->wm.store) {
C->data.recursion = 1;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index ebce28c4e23..e896a0eb517 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2373,7 +2373,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
* 0,1,2,3,4 --> 1,2,3,4,0
*
* this is why we compare last with second last
- * */
+ */
float vec_1[3] = {0, 1, 0}, vec_2[3] = {0, 1, 0}, angle, ang_fac, cross_tmp[3];
BevPoint *bevp_first;
diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c
index 4725be6d302..63da7c1dd11 100644
--- a/source/blender/blenkernel/intern/curve_deform.c
+++ b/source/blender/blenkernel/intern/curve_deform.c
@@ -233,7 +233,7 @@ static bool calc_curve_deform(
* Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
*
* note: moved functions into quat_apply_track/vec_apply_track
- * */
+ */
copy_qt_qt(quat, new_quat);
copy_v3_v3(cent, co);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 375792a02c2..58c050493c9 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -488,6 +488,7 @@ void BKE_displist_fill(ListBase *dispbase,
while (cont) {
int dl_flag_accum = 0;
+ int dl_rt_accum = 0;
cont = 0;
totvert = 0;
nextcol = 0;
@@ -535,6 +536,7 @@ void BKE_displist_fill(ListBase *dispbase,
}
}
dl_flag_accum |= dl->flag;
+ dl_rt_accum |= dl->rt;
}
}
@@ -544,6 +546,7 @@ void BKE_displist_fill(ListBase *dispbase,
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
dlnew->flag = (dl_flag_accum & (DL_BACK_CURVE | DL_FRONT_CURVE));
+ dlnew->rt = (dl_rt_accum & CU_SMOOTH);
dlnew->col = colnr;
dlnew->nr = totvert;
dlnew->parts = tot;
@@ -1129,7 +1132,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
*
* The right solution would be to COW the Curve data block at the input of the modifier
* stack just like what the mesh modifier does.
- * */
+ */
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index f68a390db64..453960fbd61 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -95,6 +95,32 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
/* TODO here too could add unused flags... */
bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
+ /* Apply local layer transform to all frames. Calc the active frame is not enough
+ * because onion skin can use more frames. This is more slow but required here. */
+ if (gpl_dst->actframe != NULL) {
+ bool transfomed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
+ (!is_one_v3(gpl_dst->scale)));
+ if (transfomed) {
+ loc_eul_size_to_mat4(
+ gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
+ bool do_onion = ((gpl_dst->onion_flag & GP_LAYER_ONIONSKIN) != 0);
+ bGPDframe *init_gpf = (do_onion) ? gpl_dst->frames.first : gpl_dst->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ mul_m4_v3(gpl_dst->layer_mat, &pt->x);
+ }
+ }
+ /* if not onion, exit loop. */
+ if (!do_onion) {
+ break;
+ }
+ }
+ }
+ }
+
BLI_addtail(&gpd_dst->layers, gpl_dst);
}
}
@@ -686,6 +712,14 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
/* Enable always affected by scene lights. */
gpl->flag |= GP_LAYER_USE_LIGHTS;
+
+ /* Init transform. */
+ zero_v3(gpl->location);
+ zero_v3(gpl->rotation);
+ copy_v3_fl(gpl->scale, 1.0f);
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* make this one the active one */
if (setactive) {
BKE_gpencil_layer_active_set(gpd, gpl);
@@ -2519,7 +2553,7 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
int cfra)
{
bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_multiedit = GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const bool is_multiedit = ((GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) && (!GPENCIL_PLAY_ON(gpd)));
const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
@@ -2541,6 +2575,11 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
continue;
}
+ /* If scale to 0 the layer must be invisible. */
+ if (is_zero_v3(gpl->scale)) {
+ continue;
+ }
+
/* Hide the layer if it's defined a view layer filter. This is used to
* generate renders, putting only selected GP layers for each View Layer.
* This is used only in final render and never in Viewport. */
@@ -2759,10 +2798,10 @@ void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_ev
* \param gpl: Grease pencil layer
* \param diff_mat: Result parent matrix
*/
-void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
- Object *obact,
- bGPDlayer *gpl,
- float diff_mat[4][4])
+void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
+ Object *obact,
+ bGPDlayer *gpl,
+ float diff_mat[4][4])
{
Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
Object *obparent = gpl->parent;
@@ -2771,11 +2810,10 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
/* if not layer parented, try with object parented */
if (obparent_eval == NULL) {
- if (ob_eval != NULL) {
- if (ob_eval->type == OB_GPENCIL) {
- copy_m4_m4(diff_mat, ob_eval->obmat);
- return;
- }
+ if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
+ copy_m4_m4(diff_mat, ob_eval->obmat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
+ return;
}
/* not gpencil object */
unit_m4(diff_mat);
@@ -2785,6 +2823,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
return;
}
if (gpl->partype == PARBONE) {
@@ -2800,6 +2839,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
}
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
return;
}
@@ -2807,11 +2847,11 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
}
/**
- * Update parent matrix.
+ * Update parent matrix and local transforms.
* \param depsgraph: Depsgraph
* \param ob: Grease pencil object
*/
-void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
+void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
{
if (ob->type != OB_GPENCIL) {
return;
@@ -2820,31 +2860,50 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
bGPdata *gpd = (bGPdata *)ob->data;
float cur_mat[4][4];
+ bool changed = false;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if ((gpl->parent != NULL) && (gpl->actframe != NULL)) {
- Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
- /* calculate new matrix */
- if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
- copy_m4_m4(cur_mat, ob_parent->obmat);
- }
- else if (gpl->partype == PARBONE) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
- if (pchan != NULL) {
- copy_m4_m4(cur_mat, ob->imat);
- mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
+ unit_m4(cur_mat);
+ if (gpl->actframe != NULL) {
+ if (gpl->parent != NULL) {
+ Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
+ /* calculate new matrix */
+ if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
+ copy_m4_m4(cur_mat, ob_parent->obmat);
}
- else {
- unit_m4(cur_mat);
+ else if (gpl->partype == PARBONE) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
+ if (pchan != NULL) {
+ copy_m4_m4(cur_mat, ob->imat);
+ mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
+ }
+ else {
+ unit_m4(cur_mat);
+ }
}
+ changed = !equals_m4m4(gpl->inverse, cur_mat);
}
+
+ /* Calc local layer transform. */
+ bool transfomed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
+ (!is_one_v3(gpl->scale)));
+ if (transfomed) {
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ }
+
/* only redo if any change */
- if (!equals_m4m4(gpl->inverse, cur_mat)) {
+ if (changed || transfomed) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
bGPDspoint *pt;
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- mul_m4_v3(gpl->inverse, &pt->x);
- mul_m4_v3(cur_mat, &pt->x);
+ if (changed) {
+ mul_m4_v3(gpl->inverse, &pt->x);
+ mul_m4_v3(cur_mat, &pt->x);
+ }
+
+ if (transfomed) {
+ mul_m4_v3(gpl->layer_mat, &pt->x);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 1be2cba31b5..8b12e1b5fca 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -701,13 +701,18 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
- /* Need check if some layer is parented. */
+ /* Need check if some layer is parented or transformed. */
bool do_parent = false;
+ bool do_transform = false;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
if (gpl->parent != NULL) {
do_parent = true;
break;
}
+ if ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) || (!is_one_v3(gpl->scale))) {
+ do_transform = true;
+ break;
+ }
}
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_eval);
@@ -715,7 +720,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
(ob->greasepencil_modifiers.first != NULL) &&
(!GPENCIL_SIMPLIFY_MODIF(scene)));
- if ((!do_modifiers) && (!do_parent)) {
+ if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
return;
}
DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index e4094c48368..a7e2394e7ad 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1922,7 +1922,9 @@ ID *BKE_lib_override_library_operations_store_start(Main *bmain,
ID *local)
{
if (ID_IS_OVERRIDE_LIBRARY_TEMPLATE(local) || ID_IS_OVERRIDE_LIBRARY_VIRTUAL(local)) {
- /* This is actually purely local data with an override template, nothing to do here! */
+ /* This is actually purely local data with an override template, or one of those embedded IDs
+ * (root node trees, master collections or shapekeys) that cannot have their own override.
+ * Nothing to do here! */
return NULL;
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 76885eadaae..52de4b108b9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2149,7 +2149,7 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
ntree->update |= NTREE_UPDATE_LINKS;
}
-bool nodeLinkIsHidden(bNodeLink *link)
+bool nodeLinkIsHidden(const bNodeLink *link)
{
return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock);
}
@@ -2200,7 +2200,7 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
}
}
-void nodeToView(bNode *node, float x, float y, float *rx, float *ry)
+void nodeToView(const bNode *node, float x, float y, float *rx, float *ry)
{
if (node->parent) {
nodeToView(node->parent, x + node->locx, y + node->locy, rx, ry);
@@ -2211,7 +2211,7 @@ void nodeToView(bNode *node, float x, float y, float *rx, float *ry)
}
}
-void nodeFromView(bNode *node, float x, float y, float *rx, float *ry)
+void nodeFromView(const bNode *node, float x, float y, float *rx, float *ry)
{
if (node->parent) {
nodeFromView(node->parent, x, y, rx, ry);
@@ -2224,10 +2224,10 @@ void nodeFromView(bNode *node, float x, float y, float *rx, float *ry)
}
}
-bool nodeAttachNodeCheck(bNode *node, bNode *parent)
+bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
{
- for (bNode *parent_recurse = node; parent_recurse; parent_recurse = parent_recurse->parent) {
- if (parent_recurse == parent) {
+ for (const bNode *parent_iter = node; parent_iter; parent_iter = parent_iter->parent) {
+ if (parent_iter == parent) {
return true;
}
}
@@ -2317,8 +2317,6 @@ void nodePositionPropagate(bNode *node)
bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
{
- bNodeTree *ntree;
-
/* trees are created as local trees for compositor, material or texture nodes,
* node groups and other tree types are created as library data.
*/
@@ -2327,7 +2325,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
if (is_embedded) {
flag |= LIB_ID_CREATE_NO_MAIN;
}
- ntree = BKE_libblock_alloc(bmain, ID_NT, name, flag);
+ bNodeTree *ntree = BKE_libblock_alloc(bmain, ID_NT, name, flag);
if (is_embedded) {
ntree->id.flag |= LIB_EMBEDDED_DATA;
}
@@ -2362,7 +2360,7 @@ bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
* using BKE_node_preview_init_tree to set up previews for a whole node tree in advance.
* This should be left more to the individual node tree implementations.
*/
-int BKE_node_preview_used(bNode *node)
+bool BKE_node_preview_used(const bNode *node)
{
/* XXX check for closed nodes? */
return (node->typeinfo->flag & NODE_PREVIEW) != 0;
@@ -2959,9 +2957,9 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
return NULL;
}
-bool ntreeNodeExists(bNodeTree *ntree, bNode *testnode)
+bool ntreeNodeExists(const bNodeTree *ntree, const bNode *testnode)
{
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (const bNode *, node, &ntree->nodes) {
if (node == testnode) {
return true;
}
@@ -2969,9 +2967,9 @@ bool ntreeNodeExists(bNodeTree *ntree, bNode *testnode)
return false;
}
-bool ntreeOutputExists(bNode *node, bNodeSocket *testsock)
+bool ntreeOutputExists(const bNode *node, const bNodeSocket *testsock)
{
- LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
+ LISTBASE_FOREACH (const bNodeSocket *, sock, &node->outputs) {
if (sock == testsock) {
return true;
}
@@ -3246,7 +3244,7 @@ static void ntree_interface_type_create(bNodeTree *ntree)
}
}
-StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, int create)
+StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, bool create)
{
if (ntree->interface_type) {
/* strings are generated from base string + ID name, sizes are sufficient */
@@ -3333,7 +3331,7 @@ bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
return false;
}
-bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
+bNodeLink *nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to)
{
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (link->fromsock == from && link->tosock == to) {
@@ -3346,10 +3344,10 @@ bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
return NULL;
}
-int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
+int nodeCountSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
{
int tot = 0;
- LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ LISTBASE_FOREACH (const bNodeLink *, link, &ntree->links) {
if (link->fromsock == sock || link->tosock == sock) {
tot++;
}
@@ -3515,7 +3513,7 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
}
}
-int nodeSocketIsHidden(bNodeSocket *sock)
+int nodeSocketIsHidden(const bNodeSocket *sock)
{
return ((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0);
}
@@ -3530,7 +3528,7 @@ void nodeSetSocketAvailability(bNodeSocket *sock, bool is_available)
}
}
-int nodeSocketLinkLimit(struct bNodeSocket *sock)
+int nodeSocketLinkLimit(const bNodeSocket *sock)
{
bNodeSocketType *stype = sock->typeinfo;
if (stype != NULL && stype->use_link_limits_of_type) {
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 1d79f871fa2..69442b7646c 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -225,7 +225,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
case OB_GPENCIL: {
BKE_gpencil_prepare_eval_data(depsgraph, scene, ob);
BKE_gpencil_modifiers_calc(depsgraph, scene, ob);
- BKE_gpencil_update_layer_parent(depsgraph, ob);
+ BKE_gpencil_update_layer_transforms(depsgraph, ob);
break;
}
case OB_HAIR:
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 1d62a1cce2a..d2f4d0702ed 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -140,7 +140,7 @@ static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, fl
* instead of Complex.h
* in fftw.h "fftw_complex" typedefed as double[2]
* below you can see functions are needed to work with such complex numbers.
- * */
+ */
static void init_complex(fftw_complex cmpl, float real, float image)
{
cmpl[0] = real;
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 52c41c9fd05..64f08e10c98 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -1599,8 +1599,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
BLO_read_list(reader, &snode->treepath);
snode->edittree = NULL;
- snode->iofsd = NULL;
- BLI_listbase_clear(&snode->linkdrag);
+ snode->runtime = NULL;
}
else if (sl->spacetype == SPACE_TEXT) {
SpaceText *st = (SpaceText *)sl;
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index e5f9d59270e..5353d0b9628 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -587,15 +587,15 @@ MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking,
{
const MovieTrackingSettings *settings = &tracking->settings;
+ MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
+ MovieTrackingMarker marker;
+
const float half_pattern_px = settings->default_pattern_size / 2.0f;
const float half_search_px = settings->default_search_size / 2.0f;
const float pattern_size[2] = {half_pattern_px / width, half_pattern_px / height};
const float search_size[2] = {half_search_px / width, half_search_px / height};
- MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
-
- MovieTrackingMarker marker;
memset(&marker, 0, sizeof(marker));
marker.pos[0] = x;
marker.pos[1] = y;
@@ -665,6 +665,86 @@ void BKE_tracking_track_free(MovieTrackingTrack *track)
}
}
+/* Get frame numbers of the very first and last markers.
+ * There is no check on whether the marker is enabled or not. */
+void BKE_tracking_track_first_last_frame_get(const MovieTrackingTrack *track,
+ int *r_first_frame,
+ int *r_last_frame)
+{
+ BLI_assert(track->markersnr > 0);
+ const int last_marker_index = track->markersnr - 1;
+ *r_first_frame = track->markers[0].framenr;
+ *r_last_frame = track->markers[last_marker_index].framenr;
+}
+
+/* Find the minimum starting frame and maximum ending frame within given set of
+ * tracks.
+ */
+void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ MovieTrackingTrack **tracks,
+ const int num_tracks,
+ int *r_first_frame,
+ int *r_last_frame)
+{
+ *r_first_frame = INT_MAX;
+ *r_last_frame = INT_MIN;
+ for (int i = 0; i < num_tracks; ++i) {
+ const struct MovieTrackingTrack *track = tracks[i];
+ int track_first_frame, track_last_frame;
+ BKE_tracking_track_first_last_frame_get(track, &track_first_frame, &track_last_frame);
+ *r_first_frame = min_ii(*r_first_frame, track_first_frame);
+ *r_last_frame = max_ii(*r_last_frame, track_last_frame);
+ }
+}
+
+int BKE_tracking_count_selected_tracks_in_list(const ListBase *tracks_list)
+{
+ int num_selected_tracks = 0;
+ LISTBASE_FOREACH (const MovieTrackingTrack *, track, tracks_list) {
+ if (TRACK_SELECTED(track)) {
+ ++num_selected_tracks;
+ }
+ }
+ return num_selected_tracks;
+}
+
+int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ MovieTracking *tracking)
+{
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ return BKE_tracking_count_selected_tracks_in_list(tracks_list);
+}
+
+MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(MovieTracking *tracking,
+ int *r_num_tracks)
+{
+ *r_num_tracks = 0;
+
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ if (tracks_list == NULL) {
+ return NULL;
+ }
+
+ /* Initialize input. */
+ const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
+ if (num_selected_tracks == 0) {
+ return NULL;
+ }
+
+ MovieTrackingTrack **source_tracks = MEM_malloc_arrayN(
+ num_selected_tracks, sizeof(MovieTrackingTrack *), "selected tracks array");
+ int source_track_index = 0;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks_list) {
+ if (!TRACK_SELECTED(track)) {
+ continue;
+ }
+ source_tracks[source_track_index] = track;
+ ++source_track_index;
+ }
+
+ *r_num_tracks = num_selected_tracks;
+
+ return source_tracks;
+}
+
/* Set flag for all specified track's areas.
*
* area - which part of marker should be selected. see TRACK_AREA_* constants.
@@ -918,6 +998,96 @@ void BKE_tracking_tracks_join(MovieTracking *tracking,
BKE_tracking_dopesheet_tag_update(tracking);
}
+static void accumulate_marker(MovieTrackingMarker *dst_marker,
+ const MovieTrackingMarker *src_marker)
+{
+ BLI_assert(dst_marker->framenr == src_marker->framenr);
+
+ if (src_marker->flag & MARKER_DISABLED) {
+ return;
+ }
+
+ add_v2_v2(dst_marker->pos, src_marker->pos);
+ for (int corner = 0; corner < 4; ++corner) {
+ add_v2_v2(dst_marker->pattern_corners[corner], src_marker->pattern_corners[corner]);
+ }
+ add_v2_v2(dst_marker->search_min, src_marker->search_min);
+ add_v2_v2(dst_marker->search_max, src_marker->search_max);
+
+ BLI_assert(is_finite_v2(src_marker->search_min));
+ BLI_assert(is_finite_v2(src_marker->search_max));
+
+ dst_marker->flag &= ~MARKER_DISABLED;
+ if ((src_marker->flag & MARKER_TRACKED) == 0) {
+ dst_marker->flag &= ~MARKER_TRACKED;
+ }
+}
+
+static void multiply_marker(MovieTrackingMarker *marker, const float multiplier)
+{
+ mul_v2_fl(marker->pos, multiplier);
+ for (int corner = 0; corner < 4; ++corner) {
+ mul_v2_fl(marker->pattern_corners[corner], multiplier);
+ }
+ mul_v2_fl(marker->search_min, multiplier);
+ mul_v2_fl(marker->search_max, multiplier);
+}
+
+void BKE_tracking_tracks_average(MovieTrackingTrack *dst_track,
+ /*const*/ MovieTrackingTrack **src_tracks,
+ const int num_src_tracks)
+{
+ /* Get global range of frames within which averaging would happen. */
+ int first_frame, last_frame;
+ BKE_tracking_tracks_first_last_frame_minmax(
+ src_tracks, num_src_tracks, &first_frame, &last_frame);
+ if (last_frame < first_frame) {
+ return;
+ }
+ const int num_frames = last_frame - first_frame + 1;
+
+ /* Allocate temporary array where averaging will happen into. */
+ MovieTrackingMarker *accumulator = MEM_calloc_arrayN(
+ num_frames, sizeof(MovieTrackingMarker), "tracks average accumulator");
+ int *counters = MEM_calloc_arrayN(num_frames, sizeof(int), "tracks accumulator counters");
+ for (int frame = first_frame; frame <= last_frame; ++frame) {
+ const int frame_index = frame - first_frame;
+ accumulator[frame_index].framenr = frame;
+ accumulator[frame_index].flag |= (MARKER_DISABLED | MARKER_TRACKED);
+ }
+
+ /* Accumulate track markers. */
+ for (int track_index = 0; track_index < num_src_tracks; ++track_index) {
+ /*const*/ MovieTrackingTrack *track = src_tracks[track_index];
+ for (int frame = first_frame; frame <= last_frame; ++frame) {
+ MovieTrackingMarker interpolated_marker;
+ if (!BKE_tracking_marker_get_interpolated(track, frame, &interpolated_marker)) {
+ continue;
+ }
+ const int frame_index = frame - first_frame;
+ accumulate_marker(&accumulator[frame_index], &interpolated_marker);
+ ++counters[frame_index];
+ }
+ }
+
+ /* Average and store the result. */
+ for (int frame = first_frame; frame <= last_frame; ++frame) {
+ /* Average. */
+ const int frame_index = frame - first_frame;
+ if (!counters[frame_index]) {
+ continue;
+ }
+ const float multiplier = 1.0f / (float)counters[frame_index];
+ multiply_marker(&accumulator[frame_index], multiplier);
+ /* Store the result. */
+ BKE_tracking_marker_insert(dst_track, &accumulator[frame_index]);
+ }
+
+ /* Free memory. */
+ MEM_freeN(accumulator);
+ MEM_freeN(counters);
+}
+
MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking,
MovieTrackingObject *object,
const char *name)
@@ -1224,8 +1394,6 @@ MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track,
/* put new marker */
track->markers[a + 1] = *marker;
- track->last_marker = a + 1;
-
return &track->markers[a + 1];
}
@@ -1314,51 +1482,47 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
}
}
+/**
+ * Get marker closest to the given frame number.
+ *
+ * If there is maker with exact frame number it returned.
+ * Otherwise, marker with highest frame number but lower than the requested
+ * frame is returned if such marker exists. Otherwise, the marker with lowest
+ * frame number greater than the requested frame number is returned.
+ *
+ * This function has complexity of `O(log number_of_markers)`.
+ */
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
{
- int a = track->markersnr - 1;
+ const int num_markers = track->markersnr;
- if (!track->markersnr) {
+ if (num_markers == 0) {
+ BLI_assert(!"Detected degenerated track, should never happen.");
return NULL;
}
- /* approximate pre-first framenr marker with first marker */
- if (framenr < track->markers[0].framenr) {
- return &track->markers[0];
- }
-
- if (track->last_marker < track->markersnr) {
- a = track->last_marker;
- }
-
- if (track->markers[a].framenr <= framenr) {
- while (a < track->markersnr && track->markers[a].framenr <= framenr) {
- if (track->markers[a].framenr == framenr) {
- track->last_marker = a;
+ int left_boundary = 0;
+ int right_boundary = num_markers;
+ while (left_boundary < right_boundary) {
+ const int median_index = (left_boundary + right_boundary) / 2;
+ MovieTrackingMarker *marker = &track->markers[median_index];
- return &track->markers[a];
- }
- a++;
+ if (marker->framenr == framenr) {
+ return marker;
}
- /* if there's no marker for exact position, use nearest marker from left side */
- return &track->markers[a - 1];
- }
-
- while (a >= 0 && track->markers[a].framenr >= framenr) {
- if (track->markers[a].framenr == framenr) {
- track->last_marker = a;
-
- return &track->markers[a];
+ if (marker->framenr < framenr) {
+ left_boundary = median_index + 1;
+ }
+ else {
+ BLI_assert(marker->framenr > framenr);
+ right_boundary = median_index - 1;
}
-
- a--;
}
- /* if there's no marker for exact position, use nearest marker from left side */
- return &track->markers[a];
+ const int closest_index = clamp_i(right_boundary, 0, num_markers - 1);
- return NULL;
+ return &track->markers[closest_index];
}
MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
@@ -1389,6 +1553,84 @@ MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int f
return marker;
}
+static const MovieTrackingMarker *get_usable_marker_for_interpolation(
+ struct MovieTrackingTrack *track,
+ const MovieTrackingMarker *anchor_marker,
+ const int direction)
+{
+ BLI_assert(direction == -1 || direction == 1);
+
+ const MovieTrackingMarker *last_marker = track->markers + track->markersnr - 1;
+ const MovieTrackingMarker *current_marker = anchor_marker;
+
+ while (current_marker >= track->markers && current_marker <= last_marker) {
+ if ((current_marker->flag & MARKER_DISABLED) == 0) {
+ return current_marker;
+ }
+ current_marker += direction;
+ }
+
+ return NULL;
+}
+
+bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
+ const int framenr,
+ struct MovieTrackingMarker *r_marker)
+{
+ const MovieTrackingMarker *closest_marker = BKE_tracking_marker_get(track, framenr);
+ if (closest_marker == NULL) {
+ return false;
+ }
+ if (closest_marker->framenr == framenr && (closest_marker->flag & MARKER_DISABLED) == 0) {
+ *r_marker = *closest_marker;
+ return true;
+ }
+
+ const MovieTrackingMarker *left_marker = get_usable_marker_for_interpolation(
+ track, closest_marker, -1);
+ if (left_marker == NULL) {
+ return false;
+ }
+
+ const MovieTrackingMarker *right_marker = get_usable_marker_for_interpolation(
+ track, closest_marker + 1, 1);
+ if (right_marker == NULL) {
+ return false;
+ }
+
+ if (left_marker == right_marker) {
+ *r_marker = *left_marker;
+ return true;
+ }
+
+ const float factor = (float)(framenr - left_marker->framenr) /
+ (right_marker->framenr - left_marker->framenr);
+
+ interp_v2_v2v2(r_marker->pos, left_marker->pos, right_marker->pos, factor);
+
+ for (int i = 0; i < 4; i++) {
+ interp_v2_v2v2(r_marker->pattern_corners[i],
+ left_marker->pattern_corners[i],
+ right_marker->pattern_corners[i],
+ factor);
+ }
+
+ interp_v2_v2v2(r_marker->search_min, left_marker->search_min, right_marker->search_min, factor);
+ interp_v2_v2v2(r_marker->search_max, left_marker->search_max, right_marker->search_max, factor);
+
+ r_marker->framenr = framenr;
+ r_marker->flag = 0;
+
+ if (framenr == left_marker->framenr) {
+ r_marker->flag = left_marker->flag;
+ }
+ else if (framenr == right_marker->framenr) {
+ r_marker->flag = right_marker->flag;
+ }
+
+ return true;
+}
+
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker,
float min[2],
float max[2])
@@ -1683,7 +1925,6 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTra
/* Put new marker to an array. */
plane_track->markers[a + 1] = *plane_marker;
- plane_track->last_marker = a + 1;
return &plane_track->markers[a + 1];
}
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index 6f58416924f..46589a578a8 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -311,11 +311,7 @@ static void retrieve_next_lower_usable_frame(
* translation stabilization, which has an enabled tracking marker at this very
* frame. We search both for the next lower and next higher position, to allow
* the caller to interpolate gaps and to extrapolate at the ends of the
- * definition range.
- *
- * NOTE: Regarding performance note that the individual tracks will cache the
- * last search position.
- */
+ * definition range. */
static void find_next_working_frames(StabContext *ctx,
int framenr,
int *next_lower,
diff --git a/source/blender/blenkernel/intern/tracking_test.cc b/source/blender/blenkernel/intern/tracking_test.cc
index 6afcf6872eb..2877d8db358 100644
--- a/source/blender/blenkernel/intern/tracking_test.cc
+++ b/source/blender/blenkernel/intern/tracking_test.cc
@@ -5,15 +5,23 @@
#include "DNA_tracking_types.h"
#include "BKE_tracking.h"
+#include "BLI_float2.hh"
+
+namespace blender {
namespace {
class TrackingTest : public ::testing::Test {
protected:
- MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track, int frame_number)
+ MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track,
+ int frame_number,
+ const float2 &position = float2(0.0f, 0.0f),
+ int flag = 0)
{
MovieTrackingMarker marker = {{0.0f}};
+ copy_v2_v2(marker.pos, position);
marker.framenr = frame_number;
+ marker.flag = flag;
return BKE_tracking_marker_insert(track, &marker);
}
};
@@ -22,24 +30,58 @@ class TrackingTest : public ::testing::Test {
TEST_F(TrackingTest, BKE_tracking_marker_get)
{
- MovieTrackingTrack track = {nullptr};
+ {
+ MovieTrackingTrack track = {nullptr};
- addMarkerToTrack(&track, 1);
- addMarkerToTrack(&track, 10);
+ addMarkerToTrack(&track, 10);
- {
- const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 1);
- EXPECT_NE(marker, nullptr);
- EXPECT_EQ(marker->framenr, 1);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 0), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 10), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 20), &track.markers[0]);
+
+ BKE_tracking_track_free(&track);
}
{
- const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 5);
- EXPECT_NE(marker, nullptr);
- EXPECT_EQ(marker->framenr, 1);
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1);
+ addMarkerToTrack(&track, 10);
+
+ {
+ const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 1);
+ EXPECT_NE(marker, nullptr);
+ EXPECT_EQ(marker->framenr, 1);
+ }
+
+ {
+ const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 5);
+ EXPECT_NE(marker, nullptr);
+ EXPECT_EQ(marker->framenr, 1);
+ }
+
+ BKE_tracking_track_free(&track);
}
- BKE_tracking_track_free(&track);
+ {
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1);
+ addMarkerToTrack(&track, 2);
+ addMarkerToTrack(&track, 10);
+
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 0), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 1), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 2), &track.markers[1]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 3), &track.markers[1]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 9), &track.markers[1]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 10), &track.markers[2]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 11), &track.markers[2]);
+
+ BKE_tracking_track_free(&track);
+ }
+ }
}
TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
@@ -62,3 +104,107 @@ TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
BKE_tracking_track_free(&track);
}
+
+TEST_F(TrackingTest, BKE_tracking_marker_get_interpolated)
+{
+ /* Simple case, no disabled markers in a way. */
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
+ addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 1);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 10);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 4);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 1e-6f);
+ }
+
+ BKE_tracking_track_free(&track);
+ }
+
+ /* More comprehensive test, which resembles real life trackign scenario better. */
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
+ addMarkerToTrack(&track, 2, float2(0.0f, 0.0f), MARKER_DISABLED);
+ addMarkerToTrack(&track, 9, float2(0.0f, 0.0f), MARKER_DISABLED);
+ addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 1);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 10);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 4);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 9, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 9);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.888888f, 1.4444444f), 1e-6f);
+ }
+
+ BKE_tracking_track_free(&track);
+ }
+
+ /* Tracked/keyframed flag check. */
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1, float2(1.0f, 5.0f), MARKER_TRACKED);
+ addMarkerToTrack(&track, 10, float2(2.0f, 1.0f), MARKER_TRACKED);
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.flag, 0);
+ }
+
+ BKE_tracking_track_free(&track);
+ }
+}
+
+} // namespace blender
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index b55f80c6473..e98fae9d92a 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -1167,8 +1167,7 @@ bool BKE_unit_replace_string(
/* Replace # with add sign when there is no operator between it and the next number.
*
* "1*1# 3*100# * 3" -> "1*1+ 3*100 * 3"
- *
- * */
+ */
{
char *str_found = str;
const char *ch = str;
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index 7257be66b79..034f3f39fd3 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -112,8 +112,8 @@ typedef struct NlaEvalChannel {
struct NlaEvalChannel *next_blend;
NlaEvalChannelSnapshot *blend_snapshot;
- /* Mask of array items controlled by NLA. */
- NlaValidMask valid;
+ /* Associated with the RNA property's value(s), marks which elements are affected by NLA. */
+ NlaValidMask domain;
/* Base set of values. */
NlaEvalChannelSnapshot base_snapshot;
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 74a491898b6..9f144a0ddaa 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -20,7 +20,7 @@
/** \file
* \ingroup bli
* \brief File and directory operations.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_float2.hh b/source/blender/blenlib/BLI_float2.hh
index 2a5320e4c35..84dd0e358a2 100644
--- a/source/blender/blenlib/BLI_float2.hh
+++ b/source/blender/blenlib/BLI_float2.hh
@@ -29,6 +29,14 @@ struct float2 {
{
}
+ explicit float2(float value) : x(value), y(value)
+ {
+ }
+
+ explicit float2(int value) : x(value), y(value)
+ {
+ }
+
float2(float x, float y) : x(x), y(y)
{
}
@@ -52,6 +60,11 @@ struct float2 {
return len_v2(*this);
}
+ float length_squared() const
+ {
+ return len_squared_v2(*this);
+ }
+
float2 &operator+=(const float2 &other)
{
x += other.x;
diff --git a/source/blender/blenlib/BLI_math.h b/source/blender/blenlib/BLI_math.h
index 51833d081d0..f6075367ac5 100644
--- a/source/blender/blenlib/BLI_math.h
+++ b/source/blender/blenlib/BLI_math.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 0ec65999006..c862290b262 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_bits.h b/source/blender/blenlib/BLI_math_bits.h
index b007dd7cfed..e881f1a0e4e 100644
--- a/source/blender/blenlib/BLI_math_bits.h
+++ b/source/blender/blenlib/BLI_math_bits.h
@@ -12,8 +12,7 @@
* 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.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 9e613270538..26d2f1fcb29 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h
index d5e4eedb1a6..2aff629def8 100644
--- a/source/blender/blenlib/BLI_math_color_blend.h
+++ b/source/blender/blenlib/BLI_math_color_blend.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index c0a9ea91e75..d767c2924d1 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
@@ -826,6 +825,11 @@ MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[
float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]);
+/********************************** Geodesics *********************************/
+
+float geodesic_distance_propagate_across_triangle(
+ const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2);
+
/**************************** Inline Definitions ******************************/
#if BLI_MATH_DO_INLINE
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index 506386f8d25..70f56d15164 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index d971f48c4cf..eac7f25f11a 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -17,7 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index 15d4dc21f8d..f45a4d6fdef 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_solvers.h b/source/blender/blenlib/BLI_math_solvers.h
index 9b2d1eedec7..13481e27e2a 100644
--- a/source/blender/blenlib/BLI_math_solvers.h
+++ b/source/blender/blenlib/BLI_math_solvers.h
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation
* All rights reserved.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_statistics.h b/source/blender/blenlib/BLI_math_statistics.h
index ad6cb1a3c1e..6e818f5c8df 100644
--- a/source/blender/blenlib/BLI_math_statistics.h
+++ b/source/blender/blenlib/BLI_math_statistics.h
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation
* All rights reserved.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 0bddff9101e..1df22f7c2c9 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_mmap.h b/source/blender/blenlib/BLI_mmap.h
new file mode 100644
index 00000000000..4920152c9d1
--- /dev/null
+++ b/source/blender/blenlib/BLI_mmap.h
@@ -0,0 +1,56 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ */
+
+#include "BLI_compiler_attrs.h"
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Memory-mapped file IO that implements all the OS-specific details and error handling. */
+
+struct BLI_mmap_file;
+
+typedef struct BLI_mmap_file BLI_mmap_file;
+
+/* Prepares an opened file for memory-mapped IO.
+ * May return NULL if the operation fails.
+ * Note that this seeks to the end of the file to determine its length. */
+BLI_mmap_file *BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+
+/* Reads length bytes from file at the given offset into dest.
+ * Returns whether the operation was successful (may fail when reading beyond the file
+ * end or when IO errors occur). */
+bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+
+void *BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT;
+
+void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 45a1054fb53..363d3003b3c 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -54,6 +54,7 @@ set(SRC
intern/BLI_memblock.c
intern/BLI_memiter.c
intern/BLI_mempool.c
+ intern/BLI_mmap.c
intern/BLI_timer.c
intern/DLRB_tree.c
intern/array_store.c
@@ -243,6 +244,7 @@ set(SRC
BLI_mempool.h
BLI_mesh_boolean.hh
BLI_mesh_intersect.hh
+ BLI_mmap.h
BLI_mpq2.hh
BLI_mpq3.hh
BLI_multi_value_map.hh
diff --git a/source/blender/blenlib/intern/BLI_mmap.c b/source/blender/blenlib/intern/BLI_mmap.c
new file mode 100644
index 00000000000..f0b13183c68
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_mmap.c
@@ -0,0 +1,233 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include "BLI_mmap.h"
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "MEM_guardedalloc.h"
+
+#include <string.h>
+
+#ifndef WIN32
+# include <stdlib.h>
+# include <signal.h>
+# include <sys/mman.h> // for mmap
+# include <unistd.h> // for read close
+#else
+# include "BLI_winstuff.h"
+# include <io.h> // for open close read
+#endif
+
+struct BLI_mmap_file {
+ /* The address to which the file was mapped. */
+ char *memory;
+
+ /* The length of the file (and therefore the mapped region). */
+ size_t length;
+
+ /* Platform-specific handle for the mapping. */
+ void *handle;
+
+ /* Flag to indicate IO errors. Needs to be volatile since it's being set from
+ * within the signal handler, which is not part of the normal execution flow. */
+ volatile bool io_error;
+};
+
+#ifndef WIN32
+/* When using memory-mapped files, any IO errors will result in a SIGBUS signal.
+ * Therefore, we need to catch that signal and stop reading the file in question.
+ * To do so, we keep a list of all current FileDatas that use memory-mapped files,
+ * and if a SIGBUS is caught, we check if the failed address is inside one of the
+ * mapped regions.
+ * If it is, we set a flag to indicate a failed read and remap the memory in
+ * question to a zero-backed region in order to avoid additional signals.
+ * The code that actually reads the memory area has to check whether the flag was
+ * set after it's done reading.
+ * If the error occurred outside of a memory-mapped region, we call the previous
+ * handler if one was configured and abort the process otherwise.
+ */
+
+struct error_handler_data {
+ ListBase open_mmaps;
+ char configured;
+ void (*next_handler)(int, siginfo_t *, void *);
+} error_handler = {0};
+
+static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr)
+{
+ /* We only handle SIGBUS here for now. */
+ BLI_assert(sig == SIGBUS);
+
+ char *error_addr = (char *)siginfo->si_addr;
+ /* Find the file that this error belongs to. */
+ LISTBASE_FOREACH (LinkData *, link, &error_handler.open_mmaps) {
+ BLI_mmap_file *file = link->data;
+
+ /* Is the address where the error occurred in this file's mapped range? */
+ if (error_addr >= file->memory && error_addr < file->memory + file->length) {
+ file->io_error = true;
+
+ /* Replace the mapped memory with zeroes. */
+ mmap(file->memory, file->length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+
+ return;
+ }
+ }
+
+ /* Fall back to other handler if there was one. */
+ if (error_handler.next_handler) {
+ error_handler.next_handler(sig, siginfo, ptr);
+ }
+ else {
+ fprintf(stderr, "Unhandled SIGBUS caught\n");
+ abort();
+ }
+}
+
+/* Ensures that the error handler is set up and ready. */
+static bool sigbus_handler_setup(void)
+{
+ if (!error_handler.configured) {
+ struct sigaction newact = {0}, oldact = {0};
+
+ newact.sa_sigaction = sigbus_handler;
+ newact.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGBUS, &newact, &oldact)) {
+ return false;
+ }
+
+ /* Remember the previously configured handler to fall back to it if the error
+ * does not belong to any of the mapped files. */
+ error_handler.next_handler = oldact.sa_sigaction;
+ error_handler.configured = 1;
+ }
+
+ return true;
+}
+
+/* Adds a file to the list that the error handler checks. */
+static void sigbus_handler_add(BLI_mmap_file *file)
+{
+ BLI_addtail(&error_handler.open_mmaps, BLI_genericNodeN(file));
+}
+
+/* Removes a file from the list that the error handler checks. */
+static void sigbus_handler_remove(BLI_mmap_file *file)
+{
+ LinkData *link = BLI_findptr(&error_handler.open_mmaps, file, offsetof(LinkData, data));
+ BLI_freelinkN(&error_handler.open_mmaps, link);
+}
+#endif
+
+BLI_mmap_file *BLI_mmap_open(int fd)
+{
+ void *memory, *handle = NULL;
+ size_t length = BLI_lseek(fd, 0, SEEK_END);
+
+#ifndef WIN32
+ /* Ensure that the SIGBUS handler is configured. */
+ if (!sigbus_handler_setup()) {
+ return NULL;
+ }
+
+ /* Map the given file to memory. */
+ memory = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (memory == MAP_FAILED) {
+ return NULL;
+ }
+#else
+ /* Convert the POSIX-style file descriptor to a Windows handle. */
+ void *file_handle = (void *)_get_osfhandle(fd);
+ /* Memory mapping on Windows is a two-step process - first we create a mapping,
+ * then we create a view into that mapping.
+ * In our case, one view that spans the entire file is enough. */
+ handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (handle == NULL) {
+ return NULL;
+ }
+ memory = MapViewOfFile(handle, FILE_MAP_READ, 0, 0, 0);
+ if (memory == NULL) {
+ CloseHandle(handle);
+ return NULL;
+ }
+#endif
+
+ /* Now that the mapping was successful, allocate memory and set up the BLI_mmap_file. */
+ BLI_mmap_file *file = MEM_callocN(sizeof(BLI_mmap_file), __func__);
+ file->memory = memory;
+ file->handle = handle;
+ file->length = length;
+
+#ifndef WIN32
+ /* Register the file with the error handler. */
+ sigbus_handler_add(file);
+#endif
+
+ return file;
+}
+
+bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length)
+{
+ /* If a previous read has already failed or we try to read past the end,
+ * don't even attempt to read any further. */
+ if (file->io_error || (offset + length > file->length)) {
+ return false;
+ }
+
+#ifndef WIN32
+ /* If an error occurs in this call, sigbus_handler will be called and will set
+ * file->io_error to true. */
+ memcpy(dest, file->memory + offset, length);
+#else
+ /* On Windows, we use exception handling to be notified of errors. */
+ __try {
+ memcpy(dest, file->memory + offset, length);
+ }
+ __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH) {
+ file->io_error = true;
+ return false;
+ }
+#endif
+
+ return !file->io_error;
+}
+
+void *BLI_mmap_get_pointer(BLI_mmap_file *file)
+{
+ return file->memory;
+}
+
+void BLI_mmap_free(BLI_mmap_file *file)
+{
+#ifndef WIN32
+ munmap((void *)file->memory, file->length);
+ sigbus_handler_remove(file);
+#else
+ UnmapViewOfFile(file->memory);
+ CloseHandle(file->handle);
+#endif
+
+ MEM_freeN(file);
+}
diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c
index 33250105c79..9d3b66d72d7 100644
--- a/source/blender/blenlib/intern/bitmap_draw_2d.c
+++ b/source/blender/blenlib/intern/bitmap_draw_2d.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index 9840dc77148..3d010011a79 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -414,8 +414,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
/* This vert has a free quadrant
* Test if we can place the box here
- * vert->free & quad_flags[j] - Checks
- * */
+ * `vert->free & quad_flags[j]` - Checks. */
for (j = 0; (j < 4) && isect; j++) {
if (vert->free & quad_flag(j)) {
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index 2bf06371740..1137c4114a5 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 1dc7c21f1d4..b332a0b2cb9 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_bits_inline.c b/source/blender/blenlib/intern/math_bits_inline.c
index ba18bb73850..1b381dccbfd 100644
--- a/source/blender/blenlib/intern/math_bits_inline.c
+++ b/source/blender/blenlib/intern/math_bits_inline.c
@@ -12,8 +12,7 @@
* 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.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 31ee81de40e..8fd2802a547 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c
index 7ad4f0d9585..53257cc9285 100644
--- a/source/blender/blenlib/intern/math_color_blend_inline.c
+++ b/source/blender/blenlib/intern/math_color_blend_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 1264620cf36..a1caf2fe02d 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 3cc4d03d547..07fabcd775e 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
@@ -3887,7 +3886,7 @@ void interp_weights_quad_v3(float w[4],
* - 0 if the point is outside of triangle.
* - 1 if the point is inside triangle.
* - 2 if it's on the edge.
- * */
+ */
int barycentric_inside_triangle_v2(const float w[3])
{
if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) {
@@ -6246,3 +6245,56 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
const float angle_cos = cosf(angle);
return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
}
+
+/**
+ * Utility for computing approximate geodesic distances on triangle meshes.
+ *
+ * Given triangle with vertex coordinates v0, v1, v2, and known geodesic distances
+ * dist1 and dist2 at v1 and v2, estimate a geodesic distance at vertex v0.
+ *
+ * From "Dart Throwing on Surfaces", EGSR 2009. Section 7, Geodesic Dart Throwing.
+ */
+float geodesic_distance_propagate_across_triangle(
+ const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2)
+{
+ /* Vectors along triangle edges. */
+ float v10[3], v12[3];
+ sub_v3_v3v3(v10, v0, v1);
+ sub_v3_v3v3(v12, v2, v1);
+
+ if (dist1 != 0.0f && dist2 != 0.0f) {
+ /* Local coordinate system in the triangle plane. */
+ float u[3], v[3], n[3];
+ const float d12 = normalize_v3_v3(u, v12);
+
+ if (d12 * d12 > 0.0f) {
+ cross_v3_v3v3(n, v12, v10);
+ normalize_v3(n);
+ cross_v3_v3v3(v, n, u);
+
+ /* v0 in local coordinates */
+ const float v0_[2] = {dot_v3v3(v10, u), fabsf(dot_v3v3(v10, v))};
+
+ /* Compute virtual source point in local coordinates, that we estimate the geodesic
+ * distance is being computed from. See figure 9 in the paper for the derivation. */
+ const float a = 0.5f * (1.0f + (dist1 * dist1 - dist2 * dist2) / (d12 * d12));
+ const float hh = dist1 * dist1 - a * a * d12 * d12;
+
+ if (hh > 0.0f) {
+ const float h = sqrtf(hh);
+ const float S_[2] = {a * d12, -h};
+
+ /* Only valid if the line between the source point and v0 crosses
+ * the edge between v1 and v2. */
+ const float x_intercept = S_[0] + h * (v0_[0] - S_[0]) / (v0_[1] + h);
+ if (x_intercept >= 0.0f && x_intercept <= d12) {
+ return len_v2v2(S_, v0_);
+ }
+ }
+ }
+ }
+
+ /* Fall back to Dijsktra approximation in trivial case, or if no valid source
+ * point found that connects to v0 across the triangle. */
+ return min_ff(dist1 + len_v3(v10), dist2 + len_v3v3(v0, v2));
+}
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index db317f5e81d..23c351026f2 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c
index e366d834fc4..85900dc32a6 100644
--- a/source/blender/blenlib/intern/math_solvers.c
+++ b/source/blender/blenlib/intern/math_solvers.c
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation.
* All rights reserved.
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c
index 18affbed708..b90ac99dbfe 100644
--- a/source/blender/blenlib/intern/math_statistics.c
+++ b/source/blender/blenlib/intern/math_statistics.c
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation.
* All rights reserved.
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 5f3297134c6..000468b3715 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index f17b7535258..ead354c2d87 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 5636ffafb6a..7cd7991b8d8 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1650,7 +1650,7 @@ bool BLI_path_filename_ensure(char *filepath, size_t maxlen, const char *filenam
* - Wont create any directories.
* - Doesn't use CWD, or deal with relative paths.
* - Only fill's in \a dir and \a file when they are non NULL.
- * */
+ */
void BLI_split_dirfile(
const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
{
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index 0b88cf53442..b42c50803e0 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -289,9 +289,8 @@ void BLI_threadpool_clear(ListBase *threadbase)
void BLI_threadpool_end(ListBase *threadbase)
{
- /* only needed if there's actually some stuff to end
- * this way we don't end up decrementing thread_levels on an empty threadbase
- * */
+ /* Only needed if there's actually some stuff to end
+ * this way we don't end up decrementing thread_levels on an empty `threadbase`. */
if (threadbase == nullptr || BLI_listbase_is_empty(threadbase)) {
return;
}
diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c
index eac01a0e2aa..c0c895654e3 100644
--- a/source/blender/blenlib/intern/voxel.c
+++ b/source/blender/blenlib/intern/voxel.c
@@ -54,12 +54,14 @@ BLI_INLINE int FLOORI(float x)
return ((x >= 0.0f) || (float)r == x) ? r : (r - 1);
}
-/* clamp function, cannot use the CLAMPIS macro,
+/**
+ * clamp function, cannot use the CLAMPIS macro,
* it sometimes returns unwanted results apparently related to
- * gcc optimization flag -fstrict-overflow which is enabled at -O2
+ * gcc optimization flag `-fstrict-overflow` which is enabled at `-O2`
*
* this causes the test (x + 2) < 0 with int x == 2147483647 to return false (x being an integer,
- * x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't) */
+ * x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't).
+ */
BLI_INLINE int64_t _clamp(int a, int b, int c)
{
return (a < b) ? b : ((a > c) ? c : a);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b61abd4ed06..2192e9a378f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -68,6 +68,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_mempool.h"
+#include "BLI_mmap.h"
#include "BLI_threads.h"
#include "BLT_translation.h"
@@ -1179,6 +1180,53 @@ static ssize_t fd_read_from_memory(FileData *filedata,
return readsize;
}
+/* Memory-mapped file reading.
+ * By using mmap(), we can map a file so that it can be treated like normal memory,
+ * meaning that we can just read from it with memcpy() etc.
+ * This avoids system call overhead and can significantly speed up file loading.
+ */
+
+static ssize_t fd_read_from_mmap(FileData *filedata,
+ void *buffer,
+ size_t size,
+ bool *UNUSED(r_is_memchunck_identical))
+{
+ /* don't read more bytes than there are available in the buffer */
+ size_t readsize = MIN2(size, (size_t)(filedata->buffersize - filedata->file_offset));
+
+ if (!BLI_mmap_read(filedata->mmap_file, buffer, filedata->file_offset, readsize)) {
+ return 0;
+ }
+
+ filedata->file_offset += readsize;
+
+ return readsize;
+}
+
+static off64_t fd_seek_from_mmap(FileData *filedata, off64_t offset, int whence)
+{
+ off64_t new_pos;
+ if (whence == SEEK_CUR) {
+ new_pos = filedata->file_offset + offset;
+ }
+ else if (whence == SEEK_SET) {
+ new_pos = offset;
+ }
+ else if (whence == SEEK_END) {
+ new_pos = filedata->buffersize + offset;
+ }
+ else {
+ return -1;
+ }
+
+ if (new_pos < 0 || new_pos > filedata->buffersize) {
+ return -1;
+ }
+
+ filedata->file_offset = new_pos;
+ return filedata->file_offset;
+}
+
/* MemFile reading. */
static ssize_t fd_read_from_memfile(FileData *filedata,
@@ -1306,6 +1354,8 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
{
FileDataReadFn *read_fn = NULL;
FileDataSeekFn *seek_fn = NULL; /* Optional. */
+ size_t buffersize = 0;
+ BLI_mmap_file *mmap_file = NULL;
gzFile gzfile = (gzFile)Z_NULL;
@@ -1322,14 +1372,21 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
return NULL;
}
- BLI_lseek(file, 0, SEEK_SET);
-
/* Regular file. */
if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
read_fn = fd_read_data_from_file;
seek_fn = fd_seek_data_from_file;
+
+ mmap_file = BLI_mmap_open(file);
+ if (mmap_file != NULL) {
+ read_fn = fd_read_from_mmap;
+ seek_fn = fd_seek_from_mmap;
+ buffersize = BLI_lseek(file, 0, SEEK_END);
+ }
}
+ BLI_lseek(file, 0, SEEK_SET);
+
/* Gzip file. */
errno = 0;
if ((read_fn == NULL) &&
@@ -1363,6 +1420,8 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
fd->read = read_fn;
fd->seek = seek_fn;
+ fd->mmap_file = mmap_file;
+ fd->buffersize = buffersize;
return fd;
}
@@ -1531,6 +1590,11 @@ void blo_filedata_free(FileData *fd)
fd->buffer = NULL;
}
+ if (fd->mmap_file) {
+ BLI_mmap_free(fd->mmap_file);
+ fd->mmap_file = NULL;
+ }
+
/* Free all BHeadN data blocks */
#ifndef NDEBUG
BLI_freelistN(&fd->bhead_list);
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index c724cc32051..86f05eda7b7 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -41,6 +41,7 @@ struct Object;
struct OldNewMap;
struct ReportList;
struct UserDef;
+struct BLI_mmap_file;
typedef struct IDNameLib_Map IDNameLib_Map;
@@ -83,8 +84,9 @@ typedef struct FileData {
/** Regular file reading. */
int filedes;
- /** Variables needed for reading from memory / stream. */
+ /** Variables needed for reading from memory / stream / memory-mapped files. */
const char *buffer;
+ struct BLI_mmap_file *mmap_file;
/** Variables needed for reading from memfile (undo). */
struct MemFile *memfile;
/** Whether we are undoing (< 0) or redoing (> 0), used to choose which 'unchanged' flag to use
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index ec537e6f3d8..ff82dab3405 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -499,7 +499,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
/**
* Make sure Emission Alpha fcurve and drivers is properly mapped after the Emission Strength
* got introduced.
- * */
+ */
/**
* Effectively we are replacing the (animation of) node socket input 18 with 19.
@@ -510,7 +510,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
*
* The for loop for the input ids is at the top level otherwise we lose the animation
* keyframe data.
- * */
+ */
for (int input_id = 21; input_id >= 18; input_id--) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
@@ -1547,7 +1547,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
- if (!MAIN_VERSION_ATLEAST(bmain, 292, 13)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 1)) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_GEOMETRY) {
version_node_socket_name(ntree, GEO_NODE_BOOLEAN, "Geometry A", "Geometry 1");
@@ -1572,7 +1572,8 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- if (!MAIN_VERSION_ATLEAST(bmain, 292, 14)) {
+ if ((!MAIN_VERSION_ATLEAST(bmain, 292, 14)) ||
+ ((bmain->versionfile == 293) && (!MAIN_VERSION_ATLEAST(bmain, 293, 1)))) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type != NTREE_GEOMETRY) {
continue;
@@ -1589,6 +1590,27 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 1)) {
+ /* Grease pencil layer transform matrix. */
+ if (!DNA_struct_elem_find(fd->filesdna, "bGPDlayer", "float", "location[0]")) {
+ LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ zero_v3(gpl->location);
+ zero_v3(gpl->rotation);
+ copy_v3_fl(gpl->scale, 1.0f);
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+ }
+ }
+ }
+ /* Fix Fill factor for grease pencil fill brushes. */
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ if ((brush->gpencil_settings) && (brush->gpencil_settings->fill_factor == 0.0f)) {
+ brush->gpencil_settings->fill_factor = 1.0f;
+ }
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 60c49587387..6ae889fcee5 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -294,8 +294,7 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
/* subtract existing cost to further differentiate edges from one another
*
* keep topology cost below 0.0 so their values don't interfere with quadric cost,
- * (and they get handled first).
- * */
+ * (and they get handled first). */
if (vweights == NULL) {
cost = bm_decim_build_edge_cost_single_squared__topology(e) - cost;
}
diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h
index 01ffa026152..2d775bdf738 100644
--- a/source/blender/compositor/operations/COM_BokehImageOperation.h
+++ b/source/blender/compositor/operations/COM_BokehImageOperation.h
@@ -55,7 +55,7 @@ class BokehImageOperation : public NodeOperation {
NodeBokehImage *m_data;
/**
- * \brief precalced center of the image
+ * \brief precalculate center of the image
*/
float m_center[2];
@@ -87,7 +87,7 @@ class BokehImageOperation : public NodeOperation {
/**
* \brief determine the coordinate of a flap corner.
*
- * \param r: result in bokehimage space are stored [x,y]
+ * \param r: result in bokeh-image space are stored [x,y]
* \param flapNumber: the flap number to calculate
* \param distance: the lens distance is used to simulate lens shifts
*/
diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cpp b/source/blender/compositor/operations/COM_DotproductOperation.cpp
index 750e4308d11..5914be21453 100644
--- a/source/blender/compositor/operations/COM_DotproductOperation.cpp
+++ b/source/blender/compositor/operations/COM_DotproductOperation.cpp
@@ -39,7 +39,7 @@ void DotproductOperation::deinitExecution()
this->m_input2Operation = nullptr;
}
-/** \todo: current implementation is the inverse of a dotproduct. not 'logically' correct
+/** \todo current implementation is the inverse of a dot-product. not 'logically' correct
*/
void DotproductOperation::executePixelSampled(float output[4],
float x,
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index c4d36685bb8..e2d3b3fc36f 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -88,7 +88,7 @@ struct IDNode : public Node {
* which could be "stale" pointer. */
uint id_orig_session_uuid;
- /* Evaluated datablock.
+ /* Evaluated data-block.
* Will be covered by the copy-on-write system if the ID Type needs it. */
ID *id_cow;
@@ -107,7 +107,7 @@ struct IDNode : public Node {
eDepsNode_LinkedState_Type linked_state;
- /* Indicates the datablock is visible in the evaluated scene. */
+ /* Indicates the data-block is visible in the evaluated scene. */
bool is_directly_visible;
/* For the collection type of ID, denotes whether collection was fully
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 20044fbe3ce..b6f0817adb3 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -214,6 +214,7 @@ void GPENCIL_cache_init(void *ved)
NULL :
false;
pd->do_onion = show_onion && !hide_overlay && !playing;
+ pd->playing = playing;
/* Save simplify flags (can change while drawing, so it's better to save). */
Scene *scene = draw_ctx->scene;
pd->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, playing);
@@ -241,6 +242,7 @@ void GPENCIL_cache_init(void *ved)
pd->simplify_fill = false;
pd->simplify_fx = false;
pd->fade_layer_opacity = -1.0f;
+ pd->playing = false;
}
{
@@ -617,7 +619,7 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
/* Special case for rendering onion skin. */
bGPdata *gpd = (bGPdata *)ob->data;
bool do_onion = (!pd->is_render) ? pd->do_onion : (gpd->onion_flag & GP_ONION_GHOST_ALWAYS);
-
+ gpd->runtime.playing = (short)pd->playing;
BKE_gpencil_visible_stroke_iter(is_final_render ? pd->view_layer : NULL,
ob,
gpencil_layer_cache_populate,
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index d0bd56b42dd..2b07ea53187 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -342,6 +342,8 @@ typedef struct GPENCIL_PrivateData {
/* Display onion skinning */
bool do_onion;
+ /* Playing animation */
+ bool playing;
/* simplify settings */
bool simplify_fill;
bool simplify_fx;
diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.c
index 7f9290a6c3a..19af3ae7e5d 100644
--- a/source/blender/draw/engines/overlay/overlay_gpencil.c
+++ b/source/blender/draw/engines/overlay/overlay_gpencil.c
@@ -258,6 +258,16 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
copy_m4_m4(mat, ob->obmat);
+ /* Rotate and scale except align to cursor. */
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+ if (gpl != NULL) {
+ if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
+ float matrot[3][3];
+ copy_m3_m4(matrot, gpl->layer_mat);
+ mul_m4_m4m3(mat, mat, matrot);
+ }
+ }
+
float viewinv[4][4];
/* Set the grid in the selected axis */
switch (ts->gp_sculpt.lock_axis) {
@@ -294,6 +304,11 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
mul_v2_v2fl(size, gpd->grid.scale, 2.0f * ED_scene_grid_scale(scene, &grid_unit));
rescale_m4(mat, (float[3]){size[0], size[1], 0.0f});
+ /* Apply layer loc transform, except cursor mode. */
+ if ((gpl != NULL) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ add_v3_v3(mat[3], gpl->layer_mat[3]);
+ }
+
const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
int line_ct = gridlines * 4 + 2;
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index e1523db36c7..8feacf8b026 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -800,20 +800,20 @@ static void gpencil_edit_curve_stroke_iter_cb(bGPDlayer *gpl,
};
/* First segment. */
- copy_v3_v3(vert_ptr->pos, bezt->vec[0]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[0]);
vert_ptr->data = vflag[0];
vert_ptr++;
- copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
vert_ptr->data = vflag[1];
vert_ptr++;
/* Second segment. */
- copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
vert_ptr->data = vflag[1];
vert_ptr++;
- copy_v3_v3(vert_ptr->pos, bezt->vec[2]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[2]);
vert_ptr->data = vflag[2];
vert_ptr++;
}
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 05cbb3ef48f..8f6d0045c9c 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -4710,7 +4710,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
(float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, adt, &anim_eval_context, false);
+ &nla_cache, &id_ptr, adt, &anim_eval_context);
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
@@ -4766,7 +4766,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
(float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, key->adt, &anim_eval_context, false);
+ &nla_cache, &id_ptr, key->adt, &anim_eval_context);
/* get current frame and apply NLA-mapping to it (if applicable) */
const float remapped_frame = BKE_nla_tweakedit_remap(
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index e8146ca960a..db3a1b99135 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1384,7 +1384,7 @@ static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval
if (adt && adt->action == act) {
/* Get NLA context for value remapping. */
*r_nla_context = BKE_animsys_get_nla_keyframing_context(
- nla_cache, id_ptr, adt, anim_eval_context, false);
+ nla_cache, id_ptr, adt, anim_eval_context);
/* Apply NLA-mapping to frame. */
const float remapped_frame = BKE_nla_tweakedit_remap(
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index f32d28c4a15..aa048912a76 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -306,8 +306,7 @@ static EditBone *get_named_editbone(ListBase *edbo, const char *name)
return NULL;
}
-/* Call this before doing any duplications
- * */
+/* Call this before doing any duplications. */
void preEditBoneDuplicate(ListBase *editbones)
{
/* clear temp */
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 09b57029350..22a628de8b1 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -178,7 +178,7 @@ static void gpencil_strokepoint_convertcoords(bContext *C,
/* apply parent transform */
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
copy_v3_v3(&pt->x, fpt);
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index ad9b72b713e..8f24ce0ddd8 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -1560,7 +1560,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* some stroke is already at front*/
@@ -1725,7 +1725,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2854,7 +2854,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
float inverse_diff_mat[4][4];
/* recalculate all stroke points */
- BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat);
Material *ma_src = NULL;
@@ -3388,7 +3388,7 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index d1c8eca1be0..b5269bbfacf 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1867,7 +1867,7 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2610,7 +2610,7 @@ static int gpencil_delete_selected_points(bContext *C)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2800,7 +2800,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
float diff_mat[4][4];
/* calculate difference matrix object */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* skip strokes that are invalid for current view */
@@ -2808,7 +2808,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
@@ -2935,7 +2935,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
float diff_mat[4][4];
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
bGPDspoint *pt;
@@ -2946,7 +2946,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
@@ -3039,7 +3039,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
float diff_mat[4][4];
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
bGPDspoint *pt;
@@ -3050,7 +3050,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
@@ -3565,7 +3565,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
elem = &strokes_list[tot_strokes];
@@ -3697,7 +3697,7 @@ static int gpencil_stroke_flip_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -4516,7 +4516,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Separate selected strokes. */
@@ -4717,7 +4717,7 @@ static int gpencil_stroke_split_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Split selected strokes. */
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 622556943c9..84447059884 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -81,6 +81,7 @@
#define LEAK_HORZ 0
#define LEAK_VERT 1
+#define MIN_WINDOW_SIZE 128
/* Temporary fill operation data (op->customdata) */
typedef struct tGPDfill {
@@ -137,7 +138,7 @@ typedef struct tGPDfill {
/** boundary limits drawing mode */
int fill_draw_mode;
/* scaling factor */
- short fill_factor;
+ float fill_factor;
/* Frame to use. */
int active_cfra;
@@ -262,14 +263,14 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
BLI_assert(gpl_active_index >= 0);
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* calculate parent position */
- BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
-
/* do not draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE) {
continue;
}
+ /* calculate parent position */
+ BKE_gpencil_layer_transform_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
+
/* Decide if the strokes of layers are included or not depending on the layer mode.
* Cannot skip the layer because it can use boundary strokes and must be used. */
bool skip = false;
@@ -398,8 +399,8 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
/* resize region */
tgpf->region->winrct.xmin = 0;
tgpf->region->winrct.ymin = 0;
- tgpf->region->winrct.xmax = (int)tgpf->region->winx * tgpf->fill_factor;
- tgpf->region->winrct.ymax = (int)tgpf->region->winy * tgpf->fill_factor;
+ tgpf->region->winrct.xmax = max_ii((int)tgpf->region->winx * tgpf->fill_factor, MIN_WINDOW_SIZE);
+ tgpf->region->winrct.ymax = max_ii((int)tgpf->region->winy * tgpf->fill_factor, MIN_WINDOW_SIZE);
tgpf->region->winx = (short)abs(tgpf->region->winrct.xmax - tgpf->region->winrct.xmin);
tgpf->region->winy = (short)abs(tgpf->region->winrct.ymax - tgpf->region->winrct.ymin);
@@ -456,7 +457,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
GPU_matrix_push_projection();
- GPU_matrix_identity_set();
+ GPU_matrix_identity_projection_set();
GPU_matrix_push();
GPU_matrix_identity_set();
@@ -1274,7 +1275,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
float origin[3];
ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
ED_gpencil_project_stroke_to_plane(
- tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
+ tgpf->scene, tgpf->ob, tgpf->rv3d, tgpf->gpl, gps, origin, tgpf->lock_axis - 1);
}
/* if parented change position relative to parent object */
@@ -1394,11 +1395,12 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
tgpf->brush = brush;
tgpf->flag = brush->gpencil_settings->flag;
- tgpf->fill_leak = brush->gpencil_settings->fill_leak;
tgpf->fill_threshold = brush->gpencil_settings->fill_threshold;
tgpf->fill_simplylvl = brush->gpencil_settings->fill_simplylvl;
tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode;
- tgpf->fill_factor = (short)max_ii(1, min_ii((int)brush->gpencil_settings->fill_factor, 8));
+ tgpf->fill_factor = max_ff(GPENCIL_MIN_FILL_FAC,
+ min_ff(brush->gpencil_settings->fill_factor, 8.0f));
+ tgpf->fill_leak = (int)ceil((float)brush->gpencil_settings->fill_leak * tgpf->fill_factor);
int totcol = tgpf->ob->totcol;
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 4a908eff92e..5fea46626d5 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -667,7 +667,8 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
bGPDstroke *gpsn_; \
@@ -678,7 +679,7 @@ struct GP_EditableStrokes_Iter {
continue; \
} \
/* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
+ if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
/* ... Do Stuff With Strokes ... */
@@ -718,7 +719,8 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
bGPDstroke *gpsn_; \
@@ -767,8 +769,10 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
- invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ /* Undo layer transform. */ \
+ mul_m4_m4m4(gpstroke_iter.diff_mat, gpstroke_iter.diff_mat, gpl->layer_invmat); \
/* loop over strokes */ \
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_->strokes) { \
/* skip strokes that are invalid for current view */ \
@@ -776,7 +780,7 @@ struct GP_EditableStrokes_Iter {
continue; \
} \
/* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
+ if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
/* ... Do Stuff With Strokes ... */
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 1c967110198..9a952e1a54b 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -229,7 +229,7 @@ static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
continue;
}
@@ -315,7 +315,7 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, tgpil->gpl, gps_from) == false) {
valid = false;
}
@@ -1038,7 +1038,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 14313a50118..7571f7cded8 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -426,7 +426,7 @@ static void gpencil_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
/* get drawing origin */
gpencil_get_3d_reference(p, origin);
- ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
+ ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, p->gpl, gps, origin, p->lock_axis - 1);
}
/* convert screen-coordinates to buffer-coordinates */
@@ -887,11 +887,13 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
gpencil_get_3d_reference(p, origin);
/* reproject current */
ED_gpencil_tpoint_to_point(p->region, origin, pt, &spt);
- ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
+ ED_gpencil_project_point_to_plane(
+ p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(p->region, origin, ptb, &spt2);
- ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
+ ED_gpencil_project_point_to_plane(
+ p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt2);
p->totpixlen += len_v3v3(&spt.x, &spt2.x);
pt->uv_fac = p->totpixlen;
}
@@ -1349,7 +1351,7 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
float diff_mat[4][4];
/* calculate difference matrix if parent object */
- BKE_gpencil_parent_matrix_get(p->depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(p->depsgraph, obact, gpl, diff_mat);
if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
@@ -1731,12 +1733,12 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
continue;
}
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
/* loop over strokes, checking segments for intersections */
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(p->ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(p->ob, gpl, gps) == false) {
continue;
}
@@ -2103,6 +2105,11 @@ static void gpencil_paint_initstroke(tGPsdata *p,
copy_v3_v3(p->gpl->color, p->custom_color);
}
}
+
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(p->gpl->layer_mat, p->gpl->location, p->gpl->rotation, p->gpl->scale);
+ invert_m4_m4(p->gpl->layer_invmat, p->gpl->layer_mat);
+
if ((paintmode != GP_PAINTMODE_ERASER) && (p->gpl->flag & GP_LAYER_LOCKED)) {
p->status = GP_STATUS_ERROR;
if (G.debug & G_DEBUG) {
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index b457cd819d2..99242e48cc1 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -317,6 +317,10 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
}
tgpi->gpl = gpl;
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* create a new temporary frame */
tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
tgpi->gpf->framenum = tgpi->cframe = cfra;
@@ -1004,12 +1008,12 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
/* reproject current */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
ED_gpencil_project_point_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
+ tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tptb, &spt2);
ED_gpencil_project_point_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
+ tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
tgpi->totpixlen += len_v3v3(&spt.x, &spt2.x);
tpt->uv_fac = tgpi->totpixlen;
}
@@ -1067,7 +1071,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
float origin[3];
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
ED_gpencil_project_stroke_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
+ tgpi->scene, tgpi->ob, tgpi->rv3d, tgpi->gpl, gps, origin, ts->gp_sculpt.lock_axis - 1);
}
/* if parented change position relative to parent object */
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index bb9dd8cac5d..0d3ab9011d6 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1441,11 +1441,6 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
bool changed = false;
float rot_eval = 0.0f;
- /* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
- return false;
- }
-
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
@@ -1577,6 +1572,13 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
Object *ob = gso->object;
bGPdata *gpd = ob->data;
char tool = gso->brush->gpencil_sculpt_tool;
+ GP_SpaceConversion *gsc = &gso->gsc;
+ Brush *brush = gso->brush;
+ const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
+ gso->brush->size;
+ /* Calc bound box matrix. */
+ float bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* skip strokes that are invalid for current view */
@@ -1584,7 +1586,12 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
+ continue;
+ }
+
+ /* Check if the stroke collide with brush. */
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
continue;
}
@@ -1742,7 +1749,8 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
/* calculate difference matrix */
float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 281ab8c5adc..a00d21bf88a 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -2473,7 +2473,7 @@ static void gpencil_selected_hue_table(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
if ((gps->flag & GP_STROKE_SELECT) == 0) {
diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c
index c2504ce329e..d9bc77c8715 100644
--- a/source/blender/editors/gpencil/gpencil_undo.c
+++ b/source/blender/editors/gpencil/gpencil_undo.c
@@ -61,28 +61,22 @@ int ED_gpencil_session_active(void)
return (BLI_listbase_is_empty(&undo_nodes) == false);
}
-int ED_undo_gpencil_step(bContext *C, int step, const char *name)
+int ED_undo_gpencil_step(bContext *C, const int step)
{
bGPdata **gpd_ptr = NULL, *new_gpd = NULL;
gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
- if (step == 1) { /* undo */
- // printf("\t\tGP - undo step\n");
+ if (step == -1) { /* undo */
if (cur_node->prev) {
- if (!name || STREQ(cur_node->name, name)) {
- cur_node = cur_node->prev;
- new_gpd = cur_node->gpd;
- }
+ cur_node = cur_node->prev;
+ new_gpd = cur_node->gpd;
}
}
- else if (step == -1) {
- // printf("\t\tGP - redo step\n");
+ else if (step == 1) {
if (cur_node->next) {
- if (!name || STREQ(cur_node->name, name)) {
- cur_node = cur_node->next;
- new_gpd = cur_node->gpd;
- }
+ cur_node = cur_node->next;
+ new_gpd = cur_node->gpd;
}
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 7c796f7b7a1..42e3055ef65 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -579,7 +579,7 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
}
/* Check whether given stroke can be edited for the current color */
-bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
+bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
{
/* check if the color is editable */
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
@@ -674,7 +674,7 @@ void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, b
float inverse_diff_mat[4][4];
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
for (i = 0; i < gps->totpoints; i++) {
@@ -697,10 +697,11 @@ void gpencil_apply_parent_point(Depsgraph *depsgraph,
float inverse_diff_mat[4][4];
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
+
copy_v3_v3(&pt->x, fpt);
}
@@ -997,6 +998,12 @@ void ED_gpencil_drawing_reference_get(const Scene *scene,
else {
/* use object location */
copy_v3_v3(r_vec, ob->obmat[3]);
+ /* Apply layer offset. */
+ bGPdata *gpd = ob->data;
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+ if (gpl != NULL) {
+ add_v3_v3(r_vec, gpl->layer_mat[3]);
+ }
}
}
}
@@ -1021,7 +1028,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
/* init space conversion stuff */
gpencil_point_conversion_init(C, &gsc);
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
/* Adjust each point */
@@ -1046,6 +1053,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
void ED_gpencil_project_stroke_to_plane(const Scene *scene,
const Object *ob,
const RegionView3D *rv3d,
+ bGPDlayer *gpl,
bGPDstroke *gps,
const float origin[3],
const int axis)
@@ -1058,6 +1066,10 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
float ray[3];
float rpoint[3];
+ /* Recalculate layer transform matrix. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* normal vector for a plane locked to axis */
zero_v3(plane_normal);
if (axis < 0) {
@@ -1074,24 +1086,27 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
copy_m4_m4(mat, ob->obmat);
/* move origin to cursor */
+ if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if (gpl != NULL) {
+ add_v3_v3(mat[3], gpl->location);
+ }
+ }
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
copy_v3_v3(mat[3], cursor->location);
}
mul_mat3_m4_v3(mat, plane_normal);
}
+
+ if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
+ mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
+ }
}
else {
const float scale[3] = {1.0f, 1.0f, 1.0f};
plane_normal[2] = 1.0f;
float mat[4][4];
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
-
- /* move origin to object */
- if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
- copy_v3_v3(mat[3], ob->obmat[3]);
- }
-
mul_mat3_m4_v3(mat, plane_normal);
}
@@ -1127,8 +1142,12 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
ARegion *region = gsc->region;
RegionView3D *rv3d = region->regiondata;
+ /* Recalculate layer transform matrix. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
float diff_mat[4][4], inverse_diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
float origin[3];
@@ -1194,7 +1213,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
}
}
- ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
+ ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, gpl, rv3d, origin, axis, &pt2);
copy_v3_v3(&pt->x, &pt2.x);
@@ -1250,6 +1269,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
*/
void ED_gpencil_project_point_to_plane(const Scene *scene,
const Object *ob,
+ bGPDlayer *gpl,
const RegionView3D *rv3d,
const float origin[3],
const int axis,
@@ -1277,6 +1297,11 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
if (ob && (ob->type == OB_GPENCIL)) {
float mat[4][4];
copy_m4_m4(mat, ob->obmat);
+ if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if (gpl != NULL) {
+ add_v3_v3(mat[3], gpl->location);
+ }
+ }
/* move origin to cursor */
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
@@ -1284,6 +1309,10 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
}
mul_mat3_m4_v3(mat, plane_normal);
+ /* Apply layer rotation (local transform). */
+ if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
+ mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
+ }
}
}
else {
@@ -1449,7 +1478,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
/* only redo if any change */
if (!equals_m4m4(gpl->inverse, cur_mat)) {
/* first apply current transformation to all strokes */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* undo local object */
sub_v3_v3(diff_mat[3], gpl_loc);
@@ -2144,7 +2173,7 @@ void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* check if it is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
gps_ma = BKE_gpencil_material(ob, gps->mat_nr + 1);
@@ -3126,7 +3155,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
/* calculate difference matrix object */
float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
/* Calculate the extremes of the stroke in 2D. */
bGPDspoint pt_parent;
@@ -3144,15 +3173,13 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
float dist_min = FLT_MAX;
LISTBASE_FOREACH (bGPDstroke *, gps_target, &gpf->strokes) {
/* Check if the color is editable. */
- if ((gps_target == gps) || (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)) {
+ if ((gps_target == gps) || (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false)) {
continue;
}
/* Check if one of the ends is inside target stroke bounding box. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_start, radius, diff_mat)) {
- continue;
- }
- if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_end, radius, diff_mat)) {
+ if ((!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_start, radius, diff_mat)) &&
+ (!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_end, radius, diff_mat))) {
continue;
}
/* Check the distance of the ends with the ends of target stroke to avoid middle contact.
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index b212872b607..49f45acdb11 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -674,7 +674,7 @@ static bool gpencil_extract_palette_from_vertex(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
@@ -859,7 +859,7 @@ static int gpencil_material_to_vertex_exec(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 62ddfaab012..7fb57534638 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -825,7 +825,8 @@ static void gpencil_save_selected_point(tGP_BrushVertexpaintData *gso,
static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
bGPDstroke *gps,
const char tool,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -846,7 +847,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
bool saved = false;
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
return false;
}
@@ -991,7 +992,8 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
tGP_BrushVertexpaintData *gso,
bGPDlayer *gpl,
bGPDframe *gpf,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
@@ -1013,12 +1015,12 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Check points below the brush. */
- bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
+ bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat, bound_mat);
/* If stroke was hit and has an editcurve the curve needs an update. */
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
@@ -1123,9 +1125,11 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
continue;
}
- /* calculate difference matrix */
- float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* Calculate transform matrix. */
+ float diff_mat[4][4], bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ copy_m4_m4(bound_mat, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
@@ -1152,7 +1156,7 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
}
/* affect strokes in this frame */
- changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
}
}
}
@@ -1160,7 +1164,8 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
/* Apply to active frame's strokes */
if (gpl->actframe != NULL) {
gso->mf_falloff = 1.0f;
- changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(
+ C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
}
}
}
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 7fa71fcce3c..a3e5ece5862 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -383,7 +383,8 @@ static void gpencil_save_selected_point(tGP_BrushWeightpaintData *gso,
/* Select points in this stroke and add to an array to be used later. */
static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
bGPDstroke *gps,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -402,7 +403,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
bool include_last = false;
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
return;
}
@@ -505,7 +506,8 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
tGP_BrushWeightpaintData *gso,
bGPDlayer *gpl,
bGPDframe *gpf,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
char tool = gso->brush->gpencil_weight_tool;
@@ -526,12 +528,12 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Check points below the brush. */
- gpencil_weightpaint_select_stroke(gso, gps, diff_mat);
+ gpencil_weightpaint_select_stroke(gso, gps, diff_mat, bound_mat);
}
/*---------------------------------------------------------------------
@@ -578,9 +580,11 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
continue;
}
- /* calculate difference matrix */
- float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* Calculate transform matrix. */
+ float diff_mat[4][4], bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ copy_m4_m4(bound_mat, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
@@ -608,7 +612,7 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
}
/* affect strokes in this frame */
- changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
}
}
}
@@ -616,7 +620,8 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
if (gpl->actframe != NULL) {
/* Apply to active frame's strokes */
gso->mf_falloff = 1.0f;
- changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(
+ C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
}
}
}
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 1b7caf27ecf..acaa6495ba9 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -147,9 +147,9 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *area, const struct bGPDstroke *gps);
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
-bool ED_gpencil_stroke_color_use(struct Object *ob,
- const struct bGPDlayer *gpl,
- const struct bGPDstroke *gps);
+bool ED_gpencil_stroke_material_editable(struct Object *ob,
+ const struct bGPDlayer *gpl,
+ const struct bGPDstroke *gps);
/* ----------- Grease Pencil Operators ----------------- */
@@ -213,7 +213,7 @@ bool ED_gpencil_anim_copybuf_paste(struct bAnimContext *ac, const short copy_mod
/* ------------ Grease-Pencil Undo System ------------------ */
int ED_gpencil_session_active(void);
-int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
+int ED_undo_gpencil_step(struct bContext *C, const int step);
/* ------------ Grease-Pencil Armature ------------------ */
bool ED_gpencil_add_armature(const struct bContext *C,
@@ -263,11 +263,13 @@ bool ED_object_gpencil_exit(struct Main *bmain, struct Object *ob);
void ED_gpencil_project_stroke_to_plane(const struct Scene *scene,
const struct Object *ob,
const struct RegionView3D *rv3d,
+ struct bGPDlayer *gpl,
struct bGPDstroke *gps,
const float origin[3],
const int axis);
void ED_gpencil_project_point_to_plane(const struct Scene *scene,
const struct Object *ob,
+ struct bGPDlayer *gpl,
const struct RegionView3D *rv3d,
const float origin[3],
const int axis,
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 417cae800ea..78f354a300d 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -51,6 +51,10 @@ typedef enum {
#define NODE_GRID_STEPS 5
/* space_node.c */
+
+void ED_node_cursor_location_get(const struct SpaceNode *snode, float value[2]);
+void ED_node_cursor_location_set(struct SpaceNode *snode, const float value[2]);
+
int ED_node_tree_path_length(struct SpaceNode *snode);
void ED_node_tree_path_get(struct SpaceNode *snode, char *value);
void ED_node_tree_path_get_fixedbuf(struct SpaceNode *snode, char *value, int max_length);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 20417634020..deb6b7502c7 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -57,15 +57,14 @@ struct wmMsgSubscribeKey;
struct wmMsgSubscribeValue;
struct wmNotifier;
struct wmOperatorType;
+struct wmRegionListenerParams;
+struct wmRegionMessageSubscribeParams;
+struct wmSpaceTypeListenerParams;
struct wmWindow;
struct wmWindowManager;
/* regions */
-void ED_region_do_listen(struct wmWindow *win,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmNotifier *note,
- const Scene *scene);
+void ED_region_do_listen(struct wmRegionListenerParams *params);
void ED_region_do_layout(struct bContext *C, struct ARegion *region);
void ED_region_do_draw(struct bContext *C, struct ARegion *region);
void ED_region_exit(struct bContext *C, struct ARegion *region);
@@ -144,29 +143,11 @@ void ED_area_do_msg_notify_tag_refresh(struct bContext *C,
struct wmMsgSubscribeKey *msg_key,
struct wmMsgSubscribeValue *msg_val);
-void ED_area_do_mgs_subscribe_for_tool_header(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
-void ED_area_do_mgs_subscribe_for_tool_ui(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_area_do_mgs_subscribe_for_tool_header(const struct wmRegionMessageSubscribeParams *params);
+void ED_area_do_mgs_subscribe_for_tool_ui(const struct wmRegionMessageSubscribeParams *params);
/* message bus */
-void ED_region_message_subscribe(struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_region_message_subscribe(struct wmRegionMessageSubscribeParams *params);
/* spaces */
void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
@@ -178,7 +159,7 @@ void ED_area_exit(struct bContext *C, struct ScrArea *area);
int ED_screen_area_active(const struct bContext *C);
void ED_screen_global_areas_refresh(struct wmWindow *win);
void ED_screen_global_areas_sync(struct wmWindow *win);
-void ED_area_do_listen(struct wmWindow *win, ScrArea *area, struct wmNotifier *note, Scene *scene);
+void ED_area_do_listen(struct wmSpaceTypeListenerParams *params);
void ED_area_tag_redraw(ScrArea *area);
void ED_area_tag_redraw_no_rebuild(ScrArea *area);
void ED_area_tag_redraw_regiontype(ScrArea *area, int type);
@@ -427,13 +408,8 @@ void ED_region_cache_draw_cached_segments(struct ARegion *region,
const int efra);
/* area_utils.c */
-void ED_region_generic_tools_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_region_generic_tools_region_message_subscribe(
+ const struct wmRegionMessageSubscribeParams *params);
int ED_region_generic_tools_region_snap_size(const struct ARegion *region, int size, int axis);
/* area_query.c */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index ca3e351a052..2ab062a718c 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -98,8 +98,7 @@ enum TfmMode {
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
- * (if 0 is returns, *vec is unmodified)
- * */
+ * (if false is returns, `cent3d` is unmodified). */
bool calculateTransformCenter(struct bContext *C,
int centerMode,
float cent3d[3],
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7bbb7225f14..ec2cb93a89f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -664,8 +664,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name);
* Begin/Define Buttons/End/Draw is the typical order in which these
* function should be called, though for popup blocks Draw is left out.
* Freeing blocks is done by the screen/ module automatically.
- *
- * */
+ */
uiBlock *UI_block_begin(const struct bContext *C,
struct ARegion *region,
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 8df29e5b520..64f881052a1 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -231,7 +231,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
void UI_view2d_scroller_size_get(const struct View2D *v2d, float *r_x, float *r_y);
-void UI_view2d_scale_get(struct View2D *v2d, float *r_x, float *r_y);
+void UI_view2d_scale_get(const struct View2D *v2d, float *r_x, float *r_y);
float UI_view2d_scale_get_x(const struct View2D *v2d);
float UI_view2d_scale_get_y(const struct View2D *v2d);
void UI_view2d_scale_get_inverse(const struct View2D *v2d, float *r_x, float *r_y);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index e53dfa83867..af8c6255656 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1279,12 +1279,10 @@ static bool ui_but_event_property_operator_string(const bContext *C,
char *buf,
const size_t buf_len)
{
- /* context toggle operator names to check... */
+ /* Context toggle operator names to check. */
/* This function could use a refactor to generalize button type to operator relationship
- * as well as which operators use properties.
- * - Campbell
- * */
+ * as well as which operators use properties. - Campbell */
const char *ctx_toggle_opnames[] = {
"WM_OT_context_toggle",
"WM_OT_context_toggle_enum",
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 93e3dbb2cc8..62b8ce9d3eb 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -413,12 +413,11 @@ static void ui_block_region_draw(const bContext *C, ARegion *region)
/**
* Use to refresh centered popups on screen resizing (for splash).
*/
-static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void ui_block_region_popup_window_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
switch (wmn->category) {
case NC_WINDOW: {
switch (wmn->action) {
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f115618c13b..59aee0fde29 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1895,7 +1895,7 @@ void UI_view2d_scroller_size_get(const View2D *v2d, float *r_x, float *r_y)
*
* \param r_x, r_y: scale on each axis
*/
-void UI_view2d_scale_get(View2D *v2d, float *r_x, float *r_y)
+void UI_view2d_scale_get(const View2D *v2d, float *r_x, float *r_y)
{
if (r_x) {
*r_x = UI_view2d_scale_get_x(v2d);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index c6d6b8b16b9..4e8936357eb 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -3364,6 +3364,9 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
}
+ /* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
+ * BKE_view_layer_base_deselect_all(). */
+ ED_object_base_deselect_all(view_layer, NULL, BA_DESELECT);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 0528d64dca9..13c0740bce6 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1394,7 +1394,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
* (all layers are considered without evaluating lock attributes) */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* undo matrix */
invert_m4_m4(inverse_diff_mat, diff_mat);
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 8ab25fa74b8..05b523af5f9 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -3750,8 +3750,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
}
}
else {
- /* compute position as if hair was standing up straight.
- * */
+ /* Compute position as if hair was standing up straight. */
float length;
copy_v3_v3(co_prev, co);
copy_v3_v3(co, key->co);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 581169d823e..a11dab0291a 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -141,13 +141,15 @@ void ED_region_pixelspace(ARegion *region)
}
/* only exported for WM */
-void ED_region_do_listen(
- wmWindow *win, ScrArea *area, ARegion *region, wmNotifier *note, const Scene *scene)
+void ED_region_do_listen(wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *notifier = params->notifier;
+
/* generic notes first */
- switch (note->category) {
+ switch (notifier->category) {
case NC_WM:
- if (note->data == ND_FILEREAD) {
+ if (notifier->data == ND_FILEREAD) {
ED_region_tag_redraw(region);
}
break;
@@ -157,16 +159,16 @@ void ED_region_do_listen(
}
if (region->type && region->type->listener) {
- region->type->listener(win, area, region, note, scene);
+ region->type->listener(params);
}
}
/* only exported for WM */
-void ED_area_do_listen(wmWindow *win, ScrArea *area, wmNotifier *note, Scene *scene)
+void ED_area_do_listen(wmSpaceTypeListenerParams *params)
{
/* no generic notes? */
- if (area->type && area->type->listener) {
- area->type->listener(win, area, note, scene);
+ if (params->area->type && params->area->type->listener) {
+ params->area->type->listener(params);
}
}
@@ -418,16 +420,13 @@ void ED_area_do_msg_notify_tag_refresh(
ED_area_tag_refresh(area);
}
-void ED_area_do_mgs_subscribe_for_tool_header(
- /* Follow ARegionType.message_subscribe */
- const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+/* Follow ARegionType.message_subscribe */
+void ED_area_do_mgs_subscribe_for_tool_header(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
BLI_assert(region->regiontype == RGN_TYPE_TOOL_HEADER);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
@@ -438,16 +437,12 @@ void ED_area_do_mgs_subscribe_for_tool_header(
mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
}
-void ED_area_do_mgs_subscribe_for_tool_ui(
- /* Follow ARegionType.message_subscribe */
- const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_area_do_mgs_subscribe_for_tool_ui(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
BLI_assert(region->regiontype == RGN_TYPE_UI);
const char *panel_category_tool = "Tool";
const char *category = UI_panel_category_active_get(region, false);
@@ -634,7 +629,16 @@ void ED_region_do_draw(bContext *C, ARegion *region)
WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__);
}
- ED_region_message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ wmRegionMessageSubscribeParams message_subscribe_params = {
+ .context = C,
+ .message_bus = mbus,
+ .workspace = workspace,
+ .scene = scene,
+ .screen = screen,
+ .area = area,
+ .region = region,
+ };
+ ED_region_message_subscribe(&message_subscribe_params);
}
}
@@ -4027,14 +4031,12 @@ void ED_region_cache_draw_cached_segments(
/**
* Generate subscriptions for this region.
*/
-void ED_region_message_subscribe(bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_region_message_subscribe(wmRegionMessageSubscribeParams *params)
{
+ ARegion *region = params->region;
+ const bContext *C = params->context;
+ struct wmMsgBus *mbus = params->message_bus;
+
if (region->gizmo_map != NULL) {
WM_gizmomap_message_subscribe(C, region->gizmo_map, region, mbus);
}
@@ -4044,7 +4046,7 @@ void ED_region_message_subscribe(bContext *C,
}
if (region->type->message_subscribe != NULL) {
- region->type->message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ region->type->message_subscribe(params);
}
}
diff --git a/source/blender/editors/screen/area_utils.c b/source/blender/editors/screen/area_utils.c
index 075759f1120..b784a4b0056 100644
--- a/source/blender/editors/screen/area_utils.c
+++ b/source/blender/editors/screen/area_utils.c
@@ -22,6 +22,8 @@
#include "DNA_userdef_types.h"
+#include "BKE_screen.h"
+
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -42,14 +44,11 @@
/**
* Callback for #ARegionType.message_subscribe
*/
-void ED_region_generic_tools_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_region_generic_tools_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 33b918e6d4d..a88afecd064 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -57,11 +57,12 @@ static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
-/* To be used before calling immDrawPixelsTex
- * Default shader is GPU_SHADER_2D_IMAGE_COLOR
- * You can still set uniforms with :
- * GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);
- * */
+/**
+ * To be used before calling #immDrawPixelsTex
+ * Default shader is #GPU_SHADER_2D_IMAGE_COLOR
+ * You can still set uniforms with:
+ * `GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);`
+ */
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
{
IMMDrawPixelsTexState state;
@@ -77,10 +78,11 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
return state;
}
-/* Use the currently bound shader.
+/**
+ * Use the currently bound shader.
*
- * Use immDrawPixelsTexSetup to bind the shader you
- * want before calling immDrawPixelsTex.
+ * Use #immDrawPixelsTexSetup to bind the shader you
+ * want before calling #immDrawPixelsTex.
*
* If using a special shader double check it uses the same
* attributes "pos" "texCoord" and uniform "image".
@@ -89,7 +91,7 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
*
* Be also aware that this function unbinds the shader when
* it's finished.
- * */
+ */
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x,
float y,
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 1dfe606be78..627a67358f2 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -866,7 +866,7 @@ static eContextResult screen_ctx_editable_gpencil_strokes(const bContext *C,
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if (ED_gpencil_stroke_can_use_direct(area, gps)) {
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 6e6386b24aa..27726b8370e 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -2415,9 +2415,10 @@ static bool IsectPT2Df_limit(
(area_tri_v2(v1, v2, v3))) < limit;
}
-/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
+/**
+ * Clip the face by a bucket and set the uv-space bucket_bounds_uv
* so we have the clipped UV's to do pixel intersection tests with
- * */
+ */
static int float_z_sort_flip(const void *p1, const void *p2)
{
return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index ff0201f9702..691287a543f 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -305,12 +305,11 @@ static void action_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void action_channel_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_channel_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -356,14 +355,13 @@ static void action_channel_region_listener(wmWindow *UNUSED(win),
}
}
-static void saction_channel_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void saction_channel_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, area->spacedata.first, &ptr);
@@ -401,12 +399,11 @@ static void saction_channel_region_message_subscribe(const struct bContext *UNUS
}
}
-static void action_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -460,14 +457,14 @@ static void action_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void saction_main_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void saction_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, area->spacedata.first, &ptr);
@@ -502,15 +499,14 @@ static void saction_main_region_message_subscribe(const struct bContext *C,
}
/* Now run the general "channels region" one - since channels and main should be in sync */
- saction_channel_region_message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ saction_channel_region_message_subscribe(params);
}
/* editor level listener */
-static void action_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void action_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceAction *saction = (SpaceAction *)area->spacedata.first;
/* context changes */
@@ -660,12 +656,11 @@ static void action_listener(wmWindow *UNUSED(win),
}
}
-static void action_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_header_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
SpaceAction *saction = (SpaceAction *)area->spacedata.first;
/* context changes */
@@ -737,12 +732,11 @@ static void action_buttons_area_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void action_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index e50ca2ec92b..07bc1d42c3f 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -514,12 +514,11 @@ static void buttons_main_region_layout(const bContext *C, ARegion *region)
sbuts->mainbo = sbuts->mainb;
}
-static void buttons_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void buttons_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -567,15 +566,13 @@ static void buttons_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void buttons_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *area,
- ARegion *region,
- struct wmMsgBus *mbus)
+static void buttons_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceProperties *sbuts = area->spacedata.first;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -621,14 +618,12 @@ static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *regio
ED_region_panels_draw(C, region);
}
-static void buttons_navigation_bar_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void buttons_navigation_bar_region_message_subscribe(
+ const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -657,11 +652,10 @@ static void buttons_area_redraw(ScrArea *area, short buttons)
* \{ */
/* reused! */
-static void buttons_area_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceProperties *sbuts = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 4848ec72f79..81df8cc8ecd 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -191,6 +191,7 @@ void CLIP_OT_clear_solution(struct wmOperatorType *ot);
void CLIP_OT_clear_track_path(struct wmOperatorType *ot);
void CLIP_OT_join_tracks(struct wmOperatorType *ot);
+void CLIP_OT_average_tracks(struct wmOperatorType *ot);
void CLIP_OT_disable_markers(struct wmOperatorType *ot);
void CLIP_OT_hide_tracks(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 3bdf016b64c..d4391fc3ff4 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -229,7 +229,7 @@ static void clip_scopes_check_gpencil_change(ScrArea *area)
}
}
-static void clip_area_sync_frame_from_scene(ScrArea *area, Scene *scene)
+static void clip_area_sync_frame_from_scene(ScrArea *area, const Scene *scene)
{
SpaceClip *space_clip = (SpaceClip *)area->spacedata.first;
BKE_movieclip_user_set_frame(&space_clip->user, scene->r.cfra);
@@ -334,8 +334,12 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
return (SpaceLink *)scn;
}
-static void clip_listener(wmWindow *UNUSED(win), ScrArea *area, wmNotifier *wmn, Scene *scene)
+static void clip_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+ const Scene *scene = params->scene;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -514,6 +518,7 @@ static void clip_operatortypes(void)
/* clean-up */
WM_operatortype_append(CLIP_OT_clear_track_path);
WM_operatortype_append(CLIP_OT_join_tracks);
+ WM_operatortype_append(CLIP_OT_average_tracks);
WM_operatortype_append(CLIP_OT_track_copy_color);
WM_operatortype_append(CLIP_OT_clean_tracks);
@@ -988,7 +993,10 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
}
/* callback */
+ GPU_matrix_push_projection();
+ wmOrtho2(region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin, region->v2d.cur.ymax);
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
+ GPU_matrix_pop_projection();
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -1001,12 +1009,11 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
WM_gizmomap_draw(region->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
}
-static void clip_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -1137,11 +1144,7 @@ static void clip_preview_region_draw(const bContext *C, ARegion *region)
}
}
-static void clip_preview_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void clip_preview_region_listener(const wmRegionListenerParams *UNUSED(params))
{
}
@@ -1182,11 +1185,7 @@ static void clip_channels_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
}
-static void clip_channels_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void clip_channels_region_listener(const wmRegionListenerParams *UNUSED(params))
{
}
@@ -1203,12 +1202,11 @@ static void clip_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void clip_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -1246,12 +1244,11 @@ static void clip_tools_region_draw(const bContext *C, ARegion *region)
/****************** tool properties region ******************/
-static void clip_props_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_props_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -1299,12 +1296,11 @@ static void clip_properties_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void clip_properties_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_properties_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 49313005c43..10574063ebd 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1490,6 +1490,97 @@ void CLIP_OT_join_tracks(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/********************** Average tracks operator *********************/
+
+static int average_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ MovieTracking *tracking = &clip->tracking;
+
+ /* Collect source tracks. */
+ int num_source_tracks;
+ MovieTrackingTrack **source_tracks = BKE_tracking_selected_tracks_in_active_object(
+ tracking, &num_source_tracks);
+ if (num_source_tracks == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Create new empty track, which will be the averaged result.
+ * Makes it simple to average all selection to it. */
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ MovieTrackingTrack *result_track = BKE_tracking_track_add_empty(tracking, tracks_list);
+
+ /* Perform averaging. */
+ BKE_tracking_tracks_average(result_track, source_tracks, num_source_tracks);
+
+ const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ if (!keep_original) {
+ for (int i = 0; i < num_source_tracks; i++) {
+ clip_delete_track(C, clip, source_tracks[i]);
+ }
+ }
+
+ /* Update selection, making the result track active and selected. */
+ /* TODO(sergey): Should become some sort of utility function available for all operators. */
+
+ BKE_tracking_track_select(tracks_list, result_track, TRACK_AREA_ALL, 0);
+ ListBase *plane_tracks_list = BKE_tracking_get_active_plane_tracks(tracking);
+ BKE_tracking_plane_tracks_deselect_all(plane_tracks_list);
+
+ clip->tracking.act_track = result_track;
+ clip->tracking.act_plane_track = NULL;
+
+ /* Inform the dependency graph and interface about changes. */
+ DEG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+
+ /* Free memory. */
+ MEM_freeN(source_tracks);
+
+ return OPERATOR_FINISHED;
+}
+
+static int average_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ PropertyRNA *prop_keep_original = RNA_struct_find_property(op->ptr, "keep_original");
+ if (!RNA_property_is_set(op->ptr, prop_keep_original)) {
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ MovieTracking *tracking = &clip->tracking;
+
+ const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
+
+ if (num_selected_tracks == 1) {
+ RNA_property_boolean_set(op->ptr, prop_keep_original, false);
+ }
+ }
+
+ return average_tracks_exec(C, op);
+}
+
+void CLIP_OT_average_tracks(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Average Tracks";
+ ot->description = "Average selected tracks into active";
+ ot->idname = "CLIP_OT_average_tracks";
+
+ /* API callbacks. */
+ ot->exec = average_tracks_exec;
+ ot->invoke = average_tracks_invoke;
+ ot->poll = ED_space_clip_tracking_poll;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties. */
+ PropertyRNA *prop;
+
+ prop = RNA_def_boolean(ot->srna, "keep_original", 1, "Keep Original", "Keep original tracks");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
/********************** lock tracks operator *********************/
enum {
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 9b8e9e0e871..6265cbdd920 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -273,13 +273,11 @@ static void console_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void console_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void console_main_region_listener(const wmRegionListenerParams *params)
{
- // SpaceInfo *sinfo = area->spacedata.first;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index aedc6228355..193b141d528 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -104,6 +104,7 @@ static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_pre
BLI_insertlinkafter(&area->regionbase, region_prev, region);
region->regiontype = RGN_TYPE_TOOL_PROPS;
region->alignment = RGN_ALIGN_RIGHT;
+ region->flag = RGN_FLAG_HIDDEN;
return region;
}
@@ -246,13 +247,13 @@ static void file_ensure_valid_region_state(bContext *C,
BLI_assert(region_tools);
if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) {
- ARegion *region_execute = file_execute_region_ensure(area, region_tools);
- ARegion *region_props = file_tool_props_region_ensure(area, region_execute);
-
- /* Hide specific regions by default. */
- region_props->flag |= RGN_FLAG_HIDDEN;
- region_execute->flag |= RGN_FLAG_HIDDEN;
+ file_tool_props_region_ensure(area, region_tools);
+ ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
+ if (region_execute) {
+ ED_region_remove(C, area, region_execute);
+ needs_init = true;
+ }
ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI);
if (region_ui) {
ED_region_remove(C, area, region_ui);
@@ -281,11 +282,12 @@ static void file_ensure_valid_region_state(bContext *C,
ARegion *region_ui = file_ui_region_ensure(area, region_tools);
UNUSED_VARS(region_ui);
+ if (region_execute) {
+ ED_region_remove(C, area, region_execute);
+ needs_init = true;
+ }
if (region_props) {
- BLI_assert(region_execute);
-
ED_region_remove(C, area, region_props);
- ED_region_remove(C, area, region_execute);
needs_init = true;
}
}
@@ -390,11 +392,10 @@ static void file_refresh(const bContext *C, ScrArea *area)
ED_area_tag_redraw(area);
}
-static void file_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void file_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
/* context changes */
@@ -445,12 +446,11 @@ static void file_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
}
-static void file_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void file_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
@@ -466,16 +466,15 @@ static void file_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void file_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceFile *sfile = area->spacedata.first;
- FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
+
+ FileSelectParams *file_params = ED_fileselect_ensure_active_params(sfile);
/* This is a bit odd that a region owns the subscriber for an area,
* keep for now since all subscribers for WM are regions.
* May be worth re-visiting later. */
@@ -497,7 +496,7 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
/* FileSelectParams */
{
PointerRNA ptr;
- RNA_pointer_create(&screen->id, &RNA_FileSelectParams, params, &ptr);
+ RNA_pointer_create(&screen->id, &RNA_FileSelectParams, file_params, &ptr);
/* All properties for this space type. */
WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_area_tag_refresh, __func__);
@@ -647,18 +646,8 @@ static void file_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_tools_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void file_tools_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-#if 0
- /* context changes */
- switch (wmn->category) {
- /* pass */
- }
-#endif
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -715,12 +704,11 @@ static void file_execution_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_ui_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void file_ui_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 791039498e8..9f01773eadf 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -403,12 +403,11 @@ static void graph_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void graph_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void graph_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -470,14 +469,14 @@ static void graph_region_listener(wmWindow *UNUSED(win),
}
}
-static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void graph_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceGraphEditor, area->spacedata.first, &ptr);
@@ -546,11 +545,10 @@ static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
}
/* editor level listener */
-static void graph_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void graph_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceGraph *sipo = (SpaceGraph *)area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index d504bfbe276..5e1a6882d56 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -320,8 +320,11 @@ static void image_refresh(const bContext *C, ScrArea *area)
}
}
-static void image_listener(wmWindow *win, ScrArea *area, wmNotifier *wmn, Scene *UNUSED(scene))
+static void image_listener(const wmSpaceTypeListenerParams *params)
{
+ wmWindow *win = params->window;
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceImage *sima = (SpaceImage *)area->spacedata.first;
/* context changes */
@@ -723,12 +726,12 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
draw_image_cache(C, region);
}
-static void image_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GEOM:
@@ -838,12 +841,11 @@ static void image_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels_draw(C, region);
}
-static void image_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_TEXTURE:
@@ -901,12 +903,11 @@ static void image_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void image_tools_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_tools_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -958,12 +959,11 @@ static void image_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void image_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 8d3f21aefeb..5e44db4c791 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -204,13 +204,10 @@ static void info_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void info_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void info_main_region_listener(const wmRegionListenerParams *params)
{
- // SpaceInfo *sinfo = area->spacedata.first;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
@@ -223,12 +220,11 @@ static void info_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void info_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void info_header_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -259,14 +255,11 @@ static void info_header_listener(wmWindow *UNUSED(win),
}
}
-static void info_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void info_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index c6fe1b8539e..efe851c64ed 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -324,12 +324,11 @@ static void nla_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void nla_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -364,12 +363,11 @@ static void nla_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -423,14 +421,14 @@ static void nla_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void nla_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
@@ -465,12 +463,11 @@ static void nla_main_region_message_subscribe(const struct bContext *UNUSED(C),
}
}
-static void nla_channel_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_channel_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -508,14 +505,13 @@ static void nla_channel_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_channel_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void nla_channel_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
@@ -543,11 +539,11 @@ static void nla_channel_region_message_subscribe(const struct bContext *UNUSED(C
}
/* editor level listener */
-static void nla_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void nla_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index df29950bc59..7b09f681dfa 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -455,7 +455,7 @@ static void node_draw_frame(const bContext *C,
}
/* label */
- node_draw_frame_label(ntree, node, snode->aspect);
+ node_draw_frame_label(ntree, node, snode->runtime->aspect);
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
@@ -3825,18 +3825,18 @@ void draw_nodespace_back_pix(const bContext *C,
}
/* return quadratic beziers points for a given nodelink and clip if v2d is not NULL. */
-static bool node_link_bezier_handles(View2D *v2d,
- SpaceNode *snode,
- bNodeLink *link,
+static bool node_link_bezier_handles(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
float vec[4][2])
{
float cursor[2] = {0.0f, 0.0f};
/* this function can be called with snode null (via cut_links_intersect) */
- /* XXX map snode->cursor back to view space */
+ /* XXX map snode->runtime->cursor back to view space */
if (snode) {
- cursor[0] = snode->cursor[0] * UI_DPI_FAC;
- cursor[1] = snode->cursor[1] * UI_DPI_FAC;
+ cursor[0] = snode->runtime->cursor[0] * UI_DPI_FAC;
+ cursor[1] = snode->runtime->cursor[1] * UI_DPI_FAC;
}
/* in v0 and v3 we put begin/end points */
@@ -3920,8 +3920,11 @@ static bool node_link_bezier_handles(View2D *v2d,
}
/* if v2d not NULL, it clips and returns 0 if not visible */
-bool node_link_bezier_points(
- View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+bool node_link_bezier_points(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ float coord_array[][2],
+ const int resol)
{
float vec[4][2];
@@ -4084,7 +4087,7 @@ static char nodelink_get_color_id(int th_col)
return 0;
}
-static void nodelink_batch_draw(SpaceNode *snode)
+static void nodelink_batch_draw(const SpaceNode *snode)
{
if (g_batch_link.count == 0) {
return;
@@ -4104,7 +4107,7 @@ static void nodelink_batch_draw(SpaceNode *snode)
GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, colors);
- GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->runtime->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
GPU_batch_draw(g_batch_link.batch);
@@ -4124,7 +4127,7 @@ void nodelink_batch_end(SpaceNode *snode)
g_batch_link.enabled = false;
}
-static void nodelink_batch_add_link(SpaceNode *snode,
+static void nodelink_batch_add_link(const SpaceNode *snode,
const float p0[2],
const float p1[2],
const float p2[2],
@@ -4156,8 +4159,12 @@ static void nodelink_batch_add_link(SpaceNode *snode,
}
/* don't do shadows if th_col3 is -1. */
-void node_draw_link_bezier(
- View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int th_col3)
+void node_draw_link_bezier(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ int th_col1,
+ int th_col2,
+ int th_col3)
{
float vec[4][2];
@@ -4187,7 +4194,7 @@ void node_draw_link_bezier(
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, vec);
GPU_batch_uniform_4fv_array(batch, "colors", 3, colors);
- GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(batch, "expandSize", snode->runtime->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
GPU_batch_uniform_1i(batch, "doArrow", drawarrow);
GPU_batch_draw(batch);
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 508c0a47e21..a3e47404c80 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -341,7 +341,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(C, NULL, type, snode->cursor[0], snode->cursor[1]);
+ node = node_add_node(C, NULL, type, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
@@ -370,11 +370,14 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even
SpaceNode *snode = CTX_wm_space_node(C);
/* convert mouse coordinates to v2d space */
- UI_view2d_region_to_view(
- &region->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
+ UI_view2d_region_to_view(&region->v2d,
+ event->mval[0],
+ event->mval[1],
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
if (RNA_struct_property_is_set(op->ptr, "filepath") ||
RNA_struct_property_is_set(op->ptr, "name")) {
@@ -435,7 +438,8 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]);
+ node = node_add_node(
+ C, NULL, CMP_NODE_MASK, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add a mask node");
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index d3fec7257f5..6ce65cd35cb 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -317,14 +317,14 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
}
}
-void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry)
+void node_to_view(const bNode *node, float x, float y, float *rx, float *ry)
{
nodeToView(node, x, y, rx, ry);
*rx *= UI_DPI_FAC;
*ry *= UI_DPI_FAC;
}
-void node_to_updated_rect(struct bNode *node, rctf *r_rect)
+void node_to_updated_rect(const bNode *node, rctf *r_rect)
{
node_to_view(node, node->offsetx, node->offsety, &r_rect->xmin, &r_rect->ymax);
node_to_view(node,
@@ -334,7 +334,7 @@ void node_to_updated_rect(struct bNode *node, rctf *r_rect)
&r_rect->ymin);
}
-void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry)
+void node_from_view(const bNode *node, float x, float y, float *rx, float *ry)
{
x /= UI_DPI_FAC;
y /= UI_DPI_FAC;
@@ -689,11 +689,11 @@ int node_get_colorid(bNode *node)
/* note: in cmp_util.c is similar code, for node_compo_pass_on()
* the same goes for shader and texture nodes. */
/* note: in node_edit.c is similar code, for untangle node */
-static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
+static void node_draw_mute_line(const View2D *v2d, const SpaceNode *snode, const bNode *node)
{
GPU_blend(GPU_BLEND_ALPHA);
- LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
+ LISTBASE_FOREACH (const bNodeLink *, link, &node->internal_links) {
node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1);
}
@@ -947,14 +947,14 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_
WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
}
-void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
+void node_draw_shadow(const SpaceNode *snode, const bNode *node, float radius, float alpha)
{
- rctf *rct = &node->totr;
+ const rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
+ ui_draw_dropshadow(rct, radius, snode->runtime->aspect, alpha, node->flag & SELECT);
}
-void node_draw_sockets(View2D *v2d,
+void node_draw_sockets(const View2D *v2d,
const bContext *C,
bNodeTree *ntree,
bNode *node,
@@ -1118,8 +1118,8 @@ void node_draw_sockets(View2D *v2d,
}
static void node_draw_basis(const bContext *C,
- ARegion *region,
- SpaceNode *snode,
+ const View2D *v2d,
+ const SpaceNode *snode,
bNodeTree *ntree,
bNode *node,
bNodeInstanceKey key)
@@ -1127,8 +1127,6 @@ static void node_draw_basis(const bContext *C,
/* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */
float iconbutw = 0.8f * UI_UNIT_X;
- View2D *v2d = &region->v2d;
-
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) {
UI_block_end(C, node->block);
@@ -1343,8 +1341,8 @@ static void node_draw_basis(const bContext *C,
}
static void node_draw_hidden(const bContext *C,
- ARegion *region,
- SpaceNode *snode,
+ const View2D *v2d,
+ const SpaceNode *snode,
bNodeTree *ntree,
bNode *node,
bNodeInstanceKey UNUSED(key))
@@ -1353,8 +1351,6 @@ static void node_draw_hidden(const bContext *C,
float centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- View2D *v2d = &region->v2d;
-
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
@@ -1438,7 +1434,7 @@ static void node_draw_hidden(const bContext *C,
/* disable lines */
if (node->flag & NODE_MUTED) {
- node_draw_mute_line(&region->v2d, snode, node);
+ node_draw_mute_line(v2d, snode, node);
}
char showname[128]; /* 128 is used below */
@@ -1477,19 +1473,19 @@ static void node_draw_hidden(const bContext *C,
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
immUniformThemeColorShade(color_id, 30);
- dx -= snode->aspect;
+ dx -= snode->runtime->aspect;
immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
immUnbindProgram();
@@ -1550,11 +1546,12 @@ void node_draw_default(const bContext *C,
bNode *node,
bNodeInstanceKey key)
{
+ const View2D *v2d = &region->v2d;
if (node->flag & NODE_HIDDEN) {
- node_draw_hidden(C, region, snode, ntree, node, key);
+ node_draw_hidden(C, v2d, snode, ntree, node, key);
}
else {
- node_draw_basis(C, region, snode, ntree, node, key);
+ node_draw_basis(C, v2d, snode, ntree, node, key);
}
}
@@ -1607,8 +1604,7 @@ void node_draw_nodetree(const bContext *C,
#endif
/* draw background nodes, last nodes in front */
- int a = 0;
- LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, a) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
#ifdef USE_DRAW_TOT_UPDATE
/* unrelated to background nodes, update the v2d->tot,
* can be anywhere before we draw the scroll bars */
@@ -1635,8 +1631,7 @@ void node_draw_nodetree(const bContext *C,
GPU_blend(GPU_BLEND_NONE);
/* draw foreground nodes, last nodes in front */
- a = 0;
- LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, a) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_BACKGROUND) {
continue;
}
@@ -1666,7 +1661,7 @@ static void snode_setup_v2d(SpaceNode *snode, ARegion *region, const float cente
UI_view2d_view_ortho(v2d);
/* aspect+font, set each time */
- snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)region->winx;
+ snode->runtime->aspect = BLI_rctf_size_x(&v2d->cur) / (float)region->winx;
// XXX snode->curfont = uiSetCurFont_ext(snode->aspect);
}
@@ -1686,8 +1681,8 @@ static void draw_nodetree(const bContext *C,
/* shade the parent node group and add a uiBlock to clip mouse events */
static void draw_group_overlay(const bContext *C, ARegion *region)
{
- View2D *v2d = &region->v2d;
- rctf rect = v2d->cur;
+ const View2D *v2d = &region->v2d;
+ const rctf rect = v2d->cur;
float color[4];
/* shade node groups to separate them visually */
@@ -1722,14 +1717,15 @@ void node_draw_space(const bContext *C, ARegion *region)
GPU_depth_test(GPU_DEPTH_NONE);
GPU_scissor_test(true);
- /* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
+ /* XXX snode->runtime->cursor set in coordspace for placing new nodes, used for drawing noodles
+ * too */
UI_view2d_region_to_view(&region->v2d,
win->eventstate->x - region->winrct.xmin,
win->eventstate->y - region->winrct.ymin,
- &snode->cursor[0],
- &snode->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
int grid_levels = UI_GetThemeValueType(TH_NODE_GRID_LEVELS, SPACE_NODE);
@@ -1819,7 +1815,7 @@ void node_draw_space(const bContext *C, ARegion *region)
/* temporary links */
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->linkdrag) {
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
node_draw_link(v2d, snode, (bNodeLink *)linkdata->data);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 30eee416b12..ced81401874 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -880,8 +880,8 @@ static void node_resize_init(
NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
op->customdata = nsw;
- nsw->mxstart = snode->cursor[0] * UI_DPI_FAC;
- nsw->mystart = snode->cursor[1] * UI_DPI_FAC;
+ nsw->mxstart = snode->runtime->cursor[0] * UI_DPI_FAC;
+ nsw->mystart = snode->runtime->cursor[1] * UI_DPI_FAC;
/* store old */
nsw->oldlocx = node->locx;
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index aa59b7293a3..a2b04fa9665 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -37,6 +37,7 @@ struct bContext;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
+struct NodeInsertOfsData;
struct wmGizmoGroupType;
struct wmKeyConfig;
struct wmWindow;
@@ -53,6 +54,23 @@ typedef struct bNodeLinkDrag {
int in_out;
} bNodeLinkDrag;
+typedef struct SpaceNode_Runtime {
+ float aspect;
+
+ /** Mouse position for drawing socket-less links and adding nodes. */
+ float cursor[2];
+
+ /** For auto compositing. */
+ bool recalc;
+
+ /** Temporary data for modal linking operator. */
+ struct ListBase linkdrag;
+
+ /* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
+ /** Temporary data for node insert offset (in UI called Auto-offset). */
+ struct NodeInsertOfsData *iofsd;
+} SpaceNode_Runtime;
+
/* space_node.c */
/* transform between View2Ds in the tree path */
@@ -61,14 +79,17 @@ void space_node_group_offset(struct SpaceNode *snode, float *x, float *y);
/* node_draw.c */
int node_get_colorid(struct bNode *node);
int node_get_resize_cursor(int directions);
-void node_draw_shadow(struct SpaceNode *snode, struct bNode *node, float radius, float alpha);
+void node_draw_shadow(const struct SpaceNode *snode,
+ const struct bNode *node,
+ float radius,
+ float alpha);
void node_draw_default(const struct bContext *C,
struct ARegion *region,
struct SpaceNode *snode,
struct bNodeTree *ntree,
struct bNode *node,
bNodeInstanceKey key);
-void node_draw_sockets(struct View2D *v2d,
+void node_draw_sockets(const struct View2D *v2d,
const struct bContext *C,
struct bNodeTree *ntree,
struct bNode *node,
@@ -92,9 +113,9 @@ void node_draw_space(const bContext *C, ARegion *region);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode, float cursor[2]);
/* DPI scaled coords */
-void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
-void node_to_updated_rect(struct bNode *node, rctf *r_rect);
-void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
+void node_to_view(const struct bNode *node, float x, float y, float *rx, float *ry);
+void node_to_updated_rect(const struct bNode *node, rctf *r_rect);
+void node_from_view(const struct bNode *node, float x, float y, float *rx, float *ry);
/* node_buttons.c */
void node_buttons_register(struct ARegionType *art);
@@ -145,17 +166,17 @@ void nodelink_batch_start(struct SpaceNode *snode);
void nodelink_batch_end(struct SpaceNode *snode);
void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link);
-void node_draw_link_bezier(struct View2D *v2d,
- struct SpaceNode *snode,
- struct bNodeLink *link,
+void node_draw_link_bezier(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
int th_col1,
int th_col2,
int th_col3);
-bool node_link_bezier_points(struct View2D *v2d,
- struct SpaceNode *snode,
- struct bNodeLink *link,
+bool node_link_bezier_points(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
float coord_array[][2],
- int resol);
+ const int resol);
void draw_nodespace_back_pix(const struct bContext *C,
struct ARegion *region,
struct SpaceNode *snode,
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index ba1e752e276..ee7c8bca2f8 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -58,7 +58,7 @@
static bool ntree_has_drivers(bNodeTree *ntree)
{
- AnimData *adt = BKE_animdata_from_id(&ntree->id);
+ const AnimData *adt = BKE_animdata_from_id(&ntree->id);
if (adt == NULL) {
return false;
}
@@ -663,7 +663,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
snode_dag_update(C, snode);
}
- BLI_remlink(&snode->linkdrag, nldrag);
+ BLI_remlink(&snode->runtime->linkdrag, nldrag);
/* links->data pointers are either held by the tree or freed already */
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
@@ -903,7 +903,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (nldrag) {
op->customdata = nldrag;
- BLI_addtail(&snode->linkdrag, nldrag);
+ BLI_addtail(&snode->runtime->linkdrag, nldrag);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -918,7 +918,7 @@ static void node_link_cancel(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLinkDrag *nldrag = op->customdata;
- BLI_remlink(&snode->linkdrag, nldrag);
+ BLI_remlink(&snode->runtime->linkdrag, nldrag);
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
@@ -1798,7 +1798,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->iofsd;
+ NodeInsertOfsData *iofsd = snode->runtime->iofsd;
bool redraw = false;
if (!snode || event->type != TIMER || iofsd == NULL || iofsd->anim_timer != event->customdata) {
@@ -1837,7 +1837,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
node->anim_init_locx = node->anim_ofsx = 0.0f;
}
- snode->iofsd = NULL;
+ snode->runtime->iofsd = NULL;
MEM_freeN(iofsd);
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
@@ -1851,7 +1851,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
static int node_insert_offset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->iofsd;
+ NodeInsertOfsData *iofsd = snode->runtime->iofsd;
if (!iofsd || !iofsd->insert) {
return OPERATOR_CANCELLED;
@@ -1927,7 +1927,7 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
iofsd->prev = link->fromnode;
iofsd->next = node;
- snode->iofsd = iofsd;
+ snode->runtime->iofsd = iofsd;
}
ntreeUpdateTree(bmain, snode->edittree); /* needed for pointers */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 5060ac0db8a..a41f99afb4c 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -62,14 +62,15 @@
#include "node_intern.h" /* own include */
-/* Function to detect if there is a visible view3d that uses workbench in texture mode.
+/**
+ * Function to detect if there is a visible view3d that uses workbench in texture mode.
* This function is for fixing T76970 for Blender 2.83. The actual fix should add a mechanism in
* the depsgraph that can be used by the draw engines to check if they need to be redrawn.
*
* We don't want to add these risky changes this close before releasing 2.83 without good testing
* hence this workaround. There are still cases were too many updates happen. For example when you
* have both a Cycles and workbench with textures viewport.
- * */
+ */
static bool has_workbench_in_texture_color(const wmWindowManager *wm,
const Scene *scene,
const Object *ob)
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ad7632377a3..2722b2a8c17 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -321,18 +321,25 @@ static void node_free(SpaceLink *sl)
LISTBASE_FOREACH_MUTABLE (bNodeTreePath *, path, &snode->treepath) {
MEM_freeN(path);
}
+
+ MEM_SAFE_FREE(snode->runtime);
}
/* spacetype; init callback */
-static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
+static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
{
+ SpaceNode *snode = (SpaceNode *)area->spacedata.first;
+
+ if (snode->runtime == NULL) {
+ snode->runtime = MEM_callocN(sizeof(SpaceNode_Runtime), __func__);
+ }
}
-static void node_area_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void node_area_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* note, ED_area_tag_refresh will re-execute compositor */
SpaceNode *snode = area->spacedata.first;
/* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
@@ -362,7 +369,7 @@ static void node_area_listener(wmWindow *UNUSED(win),
case ND_TRANSFORM_DONE:
if (ED_node_is_compositor(snode)) {
if (snode->flag & SNODE_AUTO_RENDER) {
- snode->recalc = 1;
+ snode->runtime->recalc = true;
ED_area_tag_refresh(area);
}
}
@@ -521,8 +528,8 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area)
Scene *scene = (Scene *)snode->id;
if (scene->use_nodes) {
/* recalc is set on 3d view changes for auto compo */
- if (snode->recalc) {
- snode->recalc = 0;
+ if (snode->runtime->recalc) {
+ snode->runtime->recalc = false;
node_render_changed_exec((struct bContext *)C, NULL);
}
else {
@@ -546,8 +553,10 @@ static SpaceLink *node_duplicate(SpaceLink *sl)
BLI_duplicatelist(&snoden->treepath, &snode->treepath);
- /* clear or remove stuff from old */
- BLI_listbase_clear(&snoden->linkdrag);
+ if (snode->runtime != NULL) {
+ snoden->runtime = MEM_dupallocN(snode->runtime);
+ BLI_listbase_clear(&snoden->runtime->linkdrag);
+ }
/* Note: no need to set node tree user counts,
* the editor only keeps at least 1 (id_us_ensure_real),
@@ -589,6 +598,16 @@ static void node_toolbar_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
+void ED_node_cursor_location_get(const SpaceNode *snode, float value[2])
+{
+ copy_v2_v2(value, snode->runtime->cursor);
+}
+
+void ED_node_cursor_location_set(SpaceNode *snode, const float value[2])
+{
+ copy_v2_v2(snode->runtime->cursor, value);
+}
+
static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
{
SpaceNode *snode = area->spacedata.first;
@@ -597,15 +616,15 @@ static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
UI_view2d_region_to_view(&region->v2d,
win->eventstate->x - region->winrct.xmin,
win->eventstate->y - region->winrct.ymin,
- &snode->cursor[0],
- &snode->cursor[1]);
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
- /* here snode->cursor is used to detect the node edge for sizing */
- node_set_cursor(win, snode, snode->cursor);
+ /* here snode->runtime->cursor is used to detect the node edge for sizing */
+ node_set_cursor(win, snode, snode->runtime->cursor);
- /* XXX snode->cursor is in placing new nodes space */
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ /* XXX snode->runtime->cursor is in placing new nodes space */
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
}
/* Initialize main region, setting handlers. */
@@ -703,12 +722,10 @@ static void node_header_region_draw(const bContext *C, ARegion *region)
}
/* used for header + main region */
-static void node_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void node_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
wmGizmoMap *gzmap = region->gizmo_map;
/* context changes */
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 8104c1e0d58..d6658e59d8e 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -314,7 +314,7 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
/**
* Object properties.
- * */
+ */
static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Object *ob = poin;
@@ -324,7 +324,7 @@ static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void
/**
* Base properties.
- * */
+ */
static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Base *base = poin;
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index f8812ff5970..6125f40c022 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1547,7 +1547,7 @@ static bool outliner_is_co_within_active_mode_column(bContext *C,
* Action to run when clicking in the outliner,
*
* May expend/collapse branches or activate items.
- * */
+ */
static int outliner_item_do_activate_from_cursor(bContext *C,
const int mval[2],
const bool extend,
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 6c9d4433abd..88e88ab0c66 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -102,12 +102,11 @@ static void outliner_main_region_free(ARegion *UNUSED(region))
{
}
-static void outliner_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void outliner_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
SpaceOutliner *space_outliner = area->spacedata.first;
/* context changes */
@@ -264,15 +263,13 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void outliner_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void outliner_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceOutliner *space_outliner = area->spacedata.first;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -301,12 +298,11 @@ static void outliner_header_region_free(ARegion *UNUSED(region))
{
}
-static void outliner_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void outliner_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 3330ba14530..47de18e8faf 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -156,13 +156,8 @@ static void script_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void script_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void script_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-/* context changes */
/* XXX - Todo, need the ScriptSpace accessible to get the python script to run. */
#if 0
BPY_run_script_space_listener()
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index b11e2a32b87..51c2d3ebdf1 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -334,11 +334,11 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl)
return (SpaceLink *)sseqn;
}
-static void sequencer_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void sequencer_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_SCENE:
@@ -534,12 +534,11 @@ static void sequencer_main_region_draw_overlay(const bContext *C, ARegion *regio
draw_timeline_seq_display(C, region);
}
-static void sequencer_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_SCENE:
@@ -579,14 +578,12 @@ static void sequencer_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void sequencer_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void sequencer_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -746,12 +743,11 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region)
}
}
-static void sequencer_preview_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_preview_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_GPENCIL:
@@ -816,12 +812,11 @@ static void sequencer_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void sequencer_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_GPENCIL:
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index ae56b111360..e877cf8ffcf 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -95,12 +95,11 @@ static void statusbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
{
}
-static void statusbar_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void statusbar_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -131,14 +130,11 @@ static void statusbar_header_region_listener(wmWindow *UNUSED(win),
}
}
-static void statusbar_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void statusbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 0f5ac5abe1d..045305e0f5d 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -122,11 +122,10 @@ static SpaceLink *text_duplicate(SpaceLink *sl)
return (SpaceLink *)stextn;
}
-static void text_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void text_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceText *st = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index dc357cdd355..6a7439df6e3 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -129,12 +129,11 @@ static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *regi
ED_region_header_init(region);
}
-static void topbar_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void topbar_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -160,12 +159,11 @@ static void topbar_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void topbar_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void topbar_header_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -191,14 +189,12 @@ static void topbar_header_listener(wmWindow *UNUSED(win),
}
}
-static void topbar_header_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void topbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 3efdee9cec9..d4692f156d3 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -183,46 +183,20 @@ static void userpref_execute_region_init(wmWindowManager *wm, ARegion *region)
region->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
}
-static void userpref_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
-static void userpref_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_header_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
-#if 0
- switch (wmn->category) {
- default:
- break;
- }
-#endif
}
-static void userpref_navigation_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_navigation_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
-static void userpref_execute_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_execute_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
/* only called once, from space/spacetypes.c */
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 34d342ddd94..b5b7f0b22cd 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -783,9 +783,12 @@ static void *view3d_main_region_duplicate(void *poin)
return NULL;
}
-static void view3d_main_region_listener(
- wmWindow *UNUSED(win), ScrArea *area, ARegion *region, wmNotifier *wmn, const Scene *scene)
+static void view3d_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+ const Scene *scene = params->scene;
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
wmGizmoMap *gzmap = region->gizmo_map;
@@ -1041,14 +1044,13 @@ static void view3d_main_region_listener(
}
}
-static void view3d_main_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ const bContext *C = params->context;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
/* Developer note: there are many properties that impact 3D view drawing,
* so instead of subscribing to individual properties, just subscribe to types
* accepting some redundant redraws.
@@ -1163,12 +1165,11 @@ static void view3d_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void view3d_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void view3d_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -1233,14 +1234,11 @@ static void view3d_header_region_listener(wmWindow *UNUSED(win),
#endif
}
-static void view3d_header_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void view3d_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgParams_RNA msg_key_params = {{0}};
/* Only subscribe to types. */
@@ -1378,12 +1376,11 @@ static void view3d_buttons_region_layout(const bContext *C, ARegion *region)
ED_view3d_buttons_region_layout_ex(C, region, NULL);
}
-static void view3d_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void view3d_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -1502,11 +1499,10 @@ static void view3d_tools_region_draw(const bContext *C, ARegion *region)
}
/* area (not region) level listener */
-static void space_view3d_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- struct wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void space_view3d_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
View3D *v3d = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 35ec4de5077..9ee6e44f825 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -2494,8 +2494,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
}
/* Pass-through allows tweaks
- * FINISHED to signal one operator worked
- * */
+ * FINISHED to signal one operator worked. */
if (retval) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 0a742ec4470..17362ae65e5 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -135,7 +135,7 @@ static void createTransGPencil_curves(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* Check if stroke has an editcurve */
@@ -242,7 +242,7 @@ static void createTransGPencil_curves(bContext *C,
}
/* Calculate difference matrix. */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
copy_m3_m4(mtx, diff_mat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -263,7 +263,7 @@ static void createTransGPencil_curves(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* Check if stroke has an editcurve */
@@ -436,7 +436,7 @@ static void createTransGPencil_strokes(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
@@ -507,7 +507,7 @@ static void createTransGPencil_strokes(bContext *C,
}
/* Calculate difference matrix. */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* Undo matrix. */
invert_m4_m4(inverse_diff_mat, diff_mat);
@@ -551,7 +551,7 @@ static void createTransGPencil_strokes(bContext *C,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* What we need to include depends on proportional editing settings... */
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index b3bd6b31879..ce74c5f5a36 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -251,29 +251,55 @@ void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data)
*
* \{ */
-static bool bmesh_test_dist_add(BMVert *v,
- BMVert *v_other,
+/* Propagate distance from v1 and v2 to v0. */
+static bool bmesh_test_dist_add(BMVert *v0,
+ BMVert *v1,
+ BMVert *v2,
float *dists,
- const float *dists_prev,
/* optionally track original index */
int *index,
- const int *index_prev,
const float mtx[3][3])
{
- if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
- (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0)) {
- const int i = BM_elem_index_get(v);
- const int i_other = BM_elem_index_get(v_other);
- float vec[3];
- float dist_other;
- sub_v3_v3v3(vec, v->co, v_other->co);
- mul_m3_v3(mtx, vec);
-
- dist_other = dists_prev[i] + len_v3(vec);
- if (dist_other < dists[i_other]) {
- dists[i_other] = dist_other;
+ if ((BM_elem_flag_test(v0, BM_ELEM_SELECT) == 0) &&
+ (BM_elem_flag_test(v0, BM_ELEM_HIDDEN) == 0)) {
+ const int i0 = BM_elem_index_get(v0);
+ const int i1 = BM_elem_index_get(v1);
+
+ BLI_assert(dists[i1] != FLT_MAX);
+ if (dists[i0] <= dists[i1]) {
+ return false;
+ }
+
+ float dist0;
+
+ if (v2) {
+ /* Distance across triangle. */
+ const int i2 = BM_elem_index_get(v2);
+ BLI_assert(dists[i2] != FLT_MAX);
+ if (dists[i0] <= dists[i2]) {
+ return false;
+ }
+
+ float vm0[3], vm1[3], vm2[3];
+ mul_v3_m3v3(vm0, mtx, v0->co);
+ mul_v3_m3v3(vm1, mtx, v1->co);
+ mul_v3_m3v3(vm2, mtx, v2->co);
+
+ dist0 = geodesic_distance_propagate_across_triangle(vm0, vm1, vm2, dists[i1], dists[i2]);
+ }
+ else {
+ /* Distance along edge. */
+ float vec[3];
+ sub_v3_v3v3(vec, v1->co, v0->co);
+ mul_m3_v3(mtx, vec);
+
+ dist0 = dists[i1] + len_v3(vec);
+ }
+
+ if (dist0 < dists[i0]) {
+ dists[i0] = dist0;
if (index != NULL) {
- index[i_other] = index_prev[i];
+ index[i0] = index[i1];
}
return true;
}
@@ -292,15 +318,16 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
float *dists,
int *index)
{
- BLI_LINKSTACK_DECLARE(queue, BMVert *);
+ BLI_LINKSTACK_DECLARE(queue, BMEdge *);
- /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
- BLI_LINKSTACK_DECLARE(queue_next, BMVert *);
+ /* any BM_ELEM_TAG'd edge is in 'queue_next', so we don't add in twice */
+ BLI_LINKSTACK_DECLARE(queue_next, BMEdge *);
BLI_LINKSTACK_INIT(queue);
BLI_LINKSTACK_INIT(queue_next);
{
+ /* Set indexes and initial distances for selected vertices. */
BMIter viter;
BMVert *v;
int i;
@@ -308,7 +335,6 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
float dist;
BM_elem_index_set(v, i); /* set_inline */
- BM_elem_flag_disable(v, BM_ELEM_TAG);
if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
dist = FLT_MAX;
@@ -317,7 +343,6 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
}
}
else {
- BLI_LINKSTACK_PUSH(queue, v);
dist = 0.0f;
if (index != NULL) {
index[i] = i;
@@ -329,103 +354,99 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
bm->elem_index_dirty &= ~BM_VERT;
}
- /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
- float *dists_prev = MEM_dupallocN(dists);
- int *index_prev = MEM_dupallocN(index); /* may be NULL */
+ {
+ /* Add edges with at least one selected vertex to the queue. */
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ BMVert *v1 = e->v1;
+ BMVert *v2 = e->v2;
+ int i1 = BM_elem_index_get(v1);
+ int i2 = BM_elem_index_get(v2);
+
+ if (dists[i1] != FLT_MAX || dists[i2] != FLT_MAX) {
+ BLI_LINKSTACK_PUSH(queue, e);
+ }
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
do {
- BMVert *v;
- LinkNode *lnk;
-
- /* this is correct but slow to do each iteration,
- * instead sync the dist's while clearing BM_ELEM_TAG (below) */
-#if 0
- memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
-#endif
-
- while ((v = BLI_LINKSTACK_POP(queue))) {
- BLI_assert(dists[BM_elem_index_get(v)] != FLT_MAX);
-
- /* connected edge-verts */
- if (v->e != NULL) {
- BMEdge *e_iter, *e_first;
-
- e_iter = e_first = v->e;
-
- /* would normally use BM_EDGES_OF_VERT, but this runs so often,
- * its faster to iterate on the data directly */
- do {
-
- if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == 0) {
+ BMEdge *e;
+
+ while ((e = BLI_LINKSTACK_POP(queue))) {
+ BMVert *v1 = e->v1;
+ BMVert *v2 = e->v2;
+ int i1 = BM_elem_index_get(v1);
+ int i2 = BM_elem_index_get(v2);
+
+ if (e->l == NULL || (dists[i1] == FLT_MAX || dists[i2] == FLT_MAX)) {
+ /* Propagate along edge from vertex with smallest to largest distance. */
+ if (dists[i1] > dists[i2]) {
+ SWAP(int, i1, i2);
+ SWAP(BMVert *, v1, v2);
+ }
- /* edge distance */
- {
- BMVert *v_other = BM_edge_other_vert(e_iter, v);
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
- }
+ if (bmesh_test_dist_add(v2, v1, NULL, dists, index, mtx)) {
+ /* Add adjacent loose edges to the queue, or all edges if this is a loose edge.
+ * Other edges are handled by propagation across edges below. */
+ BMEdge *e_other;
+ BMIter eiter;
+ BM_ITER_ELEM (e_other, &eiter, v2, BM_EDGES_OF_VERT) {
+ if (e_other != e && BM_elem_flag_test(e_other, BM_ELEM_TAG) == 0 &&
+ (e->l == NULL || e_other->l == NULL)) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, e_other);
}
+ }
+ }
+ }
- /* face distance */
- if (e_iter->l) {
- BMLoop *l_iter_radial, *l_first_radial;
- /**
- * imaginary edge diagonally across quad.
- * \note This takes advantage of the rules of winding that we
- * know 2 or more of a verts edges wont reference the same face twice.
- * Also, if the edge is hidden, the face will be hidden too.
- */
- l_iter_radial = l_first_radial = e_iter->l;
-
- do {
- if ((l_iter_radial->v == v) && (l_iter_radial->f->len == 4) &&
- (BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0)) {
- BMVert *v_other = l_iter_radial->next->next->v;
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
- }
+ if (e->l != NULL) {
+ /* Propagate across edge to vertices in adjacent faces. */
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
+ for (BMLoop *l_other = l->next->next; l_other != l; l_other = l_other->next) {
+ BMVert *v_other = l_other->v;
+ BLI_assert(!ELEM(v_other, v1, v2));
+
+ if (bmesh_test_dist_add(v_other, v1, v2, dists, index, mtx)) {
+ /* Add adjacent edges to the queue, if they are ready to propagate across/along.
+ * Always propagate along loose edges, and for other edges only propagate across
+ * if both vertices have a known distances. */
+ BMEdge *e_other;
+ BMIter eiter;
+ BM_ITER_ELEM (e_other, &eiter, v_other, BM_EDGES_OF_VERT) {
+ if (e_other != e && BM_elem_flag_test(e_other, BM_ELEM_TAG) == 0 &&
+ (e_other->l == NULL ||
+ dists[BM_elem_index_get(BM_edge_other_vert(e_other, v_other))] != FLT_MAX)) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, e_other);
}
- } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
+ }
}
}
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
+ }
}
}
- /* clear for the next loop */
- for (lnk = queue_next; lnk; lnk = lnk->next) {
- BMVert *v_link = lnk->link;
- const int i = BM_elem_index_get(v_link);
+ /* Clear for the next loop. */
+ for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
+ BMEdge *e_link = lnk->link;
- BM_elem_flag_disable(v_link, BM_ELEM_TAG);
-
- /* keep in sync, avoid having to do full memcpy each iteration */
- dists_prev[i] = dists[i];
- if (index != NULL) {
- index_prev[i] = index[i];
- }
+ BM_elem_flag_disable(e_link, BM_ELEM_TAG);
}
BLI_LINKSTACK_SWAP(queue, queue_next);
- /* none should be tagged now since 'queue_next' is empty */
- BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
-
+ /* None should be tagged now since 'queue_next' is empty. */
+ BLI_assert(BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
} while (BLI_LINKSTACK_SIZE(queue));
BLI_LINKSTACK_FREE(queue);
BLI_LINKSTACK_FREE(queue_next);
-
- MEM_freeN(dists_prev);
- if (index_prev != NULL) {
- MEM_freeN(index_prev);
- }
}
/** \} */
@@ -1445,7 +1466,7 @@ static void mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tcld,
*
* Interpolate from every other loop (not ideal)
* However values will only be taken from loops which overlap other mdisps.
- * */
+ */
const bool update_loop_mdisps = is_moved && do_loop_mdisps && (tcld->cd_loop_mdisp_offset != -1);
if (update_loop_mdisps) {
float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c
index 1807e9adcd1..b1024f5efe4 100644
--- a/source/blender/editors/transform/transform_convert_mesh_skin.c
+++ b/source/blender/editors/transform/transform_convert_mesh_skin.c
@@ -55,9 +55,7 @@ static float *mesh_skin_transdata_center(const struct TransIslandData *island_da
if (island_data->center && island_index != -1) {
return island_data->center[island_index];
}
- else {
- return eve->co;
- }
+ return eve->co;
}
static void mesh_skin_transdata_create(TransDataBasic *td,
diff --git a/source/blender/editors/transform/transform_convert_tracking.c b/source/blender/editors/transform/transform_convert_tracking.c
index c3f48adca68..f8199e8011f 100644
--- a/source/blender/editors/transform/transform_convert_tracking.c
+++ b/source/blender/editors/transform/transform_convert_tracking.c
@@ -52,6 +52,7 @@ typedef struct TransDataTracking {
float (*smarkers)[2];
int markersnr;
+ int framenr;
MovieTrackingMarker *markers;
/* marker transformation from curves editor */
@@ -73,9 +74,25 @@ enum transDataTracking_Mode {
*
* \{ */
-static void markerToTransDataInit(TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+typedef struct TransformInitContext {
+ SpaceClip *space_clip;
+
+ TransInfo *t;
+ TransDataContainer *tc;
+
+ /* MOTE: There pointers will be `nullptr` during counting step.
+ * This means, that the transformation data initialization functions are to increment
+ * `tc->data_len` instead of filling in the transformation data when these pointers are
+ * `nullptr`. For simplicity, check the `current.td` against `nullptr`.
+ * Do not `tc->data_len` when filling in the transformation data. */
+ struct {
+ TransData *td;
+ TransData2D *td2d;
+ TransDataTracking *tdt;
+ } current;
+} TransformInitContext;
+
+static void markerToTransDataInit(TransformInitContext *init_context,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
int area,
@@ -84,8 +101,19 @@ static void markerToTransDataInit(TransData *td,
const float off[2],
const float aspect[2])
{
+ TransData *td = init_context->current.td;
+ TransData2D *td2d = init_context->current.td2d;
+ TransDataTracking *tdt = init_context->current.tdt;
+
+ if (td == NULL) {
+ init_context->tc->data_len++;
+ return;
+ }
+
int anchor = area == TRACK_AREA_POINT && off;
+ tdt->flag = marker->flag;
+ tdt->framenr = marker->framenr;
tdt->mode = transDataTracking_ModeTracks;
if (anchor) {
@@ -143,23 +171,20 @@ static void markerToTransDataInit(TransData *td,
unit_m3(td->mtx);
unit_m3(td->smtx);
+
+ init_context->current.td++;
+ init_context->current.td2d++;
+ init_context->current.tdt++;
}
-static void trackToTransData(const int framenr,
- TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void trackToTransData(TransformInitContext *init_context,
+ const int framenr,
MovieTrackingTrack *track,
const float aspect[2])
{
MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
- tdt->flag = marker->flag;
- marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
-
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_POINT,
@@ -170,16 +195,14 @@ static void trackToTransData(const int framenr,
if (track->flag & SELECT) {
markerToTransDataInit(
- td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
+ init_context, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
}
if (track->pat_flag & SELECT) {
int a;
for (a = 0; a < 4; a++) {
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_PAT,
@@ -191,9 +214,7 @@ static void trackToTransData(const int framenr,
}
if (track->search_flag & SELECT) {
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_SEARCH,
@@ -202,9 +223,7 @@ static void trackToTransData(const int framenr,
NULL,
aspect);
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_SEARCH,
@@ -213,15 +232,43 @@ static void trackToTransData(const int framenr,
NULL,
aspect);
}
+
+ if (init_context->current.td != NULL) {
+ marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+ }
}
-static void planeMarkerToTransDataInit(TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void trackToTransDataIfNeeded(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingTrack *track,
+ const float aspect[2])
+{
+ if (!TRACK_VIEW_SELECTED(init_context->space_clip, track)) {
+ return;
+ }
+ if (track->flag & TRACK_LOCKED) {
+ return;
+ }
+ trackToTransData(init_context, framenr, track, aspect);
+}
+
+static void planeMarkerToTransDataInit(TransformInitContext *init_context,
MovieTrackingPlaneTrack *plane_track,
+ MovieTrackingPlaneMarker *plane_marker,
float corner[2],
const float aspect[2])
{
+ TransData *td = init_context->current.td;
+ TransData2D *td2d = init_context->current.td2d;
+ TransDataTracking *tdt = init_context->current.tdt;
+
+ if (td == NULL) {
+ init_context->tc->data_len++;
+ return;
+ }
+
+ tdt->flag = plane_marker->flag;
+ tdt->framenr = plane_marker->framenr;
tdt->mode = transDataTracking_ModePlaneTracks;
tdt->plane_track = plane_track;
@@ -247,24 +294,38 @@ static void planeMarkerToTransDataInit(TransData *td,
unit_m3(td->mtx);
unit_m3(td->smtx);
+
+ init_context->current.td++;
+ init_context->current.td2d++;
+ init_context->current.tdt++;
}
-static void planeTrackToTransData(const int framenr,
- TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void planeTrackToTransData(TransformInitContext *init_context,
+ const int framenr,
MovieTrackingPlaneTrack *plane_track,
const float aspect[2])
{
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
- int i;
- tdt->flag = plane_marker->flag;
- plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+ for (int i = 0; i < 4; i++) {
+ planeMarkerToTransDataInit(
+ init_context, plane_track, plane_marker, plane_marker->corners[i], aspect);
+ }
- for (i = 0; i < 4; i++) {
- planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspect);
+ if (init_context->current.td != NULL) {
+ plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+ }
+}
+
+static void planeTrackToTransDataIfNeeded(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingPlaneTrack *plane_track,
+ const float aspect[2])
+{
+ if (!PLANE_TRACK_VIEW_SELECTED(plane_track)) {
+ return;
}
+ planeTrackToTransData(init_context, framenr, plane_track, aspect);
}
static void transDataTrackingFree(TransInfo *UNUSED(t),
@@ -284,101 +345,53 @@ static void transDataTrackingFree(TransInfo *UNUSED(t),
static void createTransTrackingTracksData(bContext *C, TransInfo *t)
{
- TransData *td;
- TransData2D *td2d;
- SpaceClip *sc = CTX_wm_space_clip(C);
- MovieClip *clip = ED_space_clip_get_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
- MovieTrackingTrack *track;
- MovieTrackingPlaneTrack *plane_track;
- TransDataTracking *tdt;
- int framenr = ED_space_clip_get_clip_frame_number(sc);
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ const ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ const ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
+ const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- /* count */
- tc->data_len = 0;
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- tc->data_len++; /* offset */
+ TransformInitContext init_context = {NULL};
+ init_context.space_clip = space_clip;
+ init_context.t = t;
+ init_context.tc = tc;
- if (track->flag & SELECT) {
- tc->data_len++;
- }
+ /* Count required tranformation data. */
- if (track->pat_flag & SELECT) {
- tc->data_len += 4;
- }
-
- if (track->search_flag & SELECT) {
- tc->data_len += 2;
- }
- }
+ tc->data_len = 0;
- track = track->next;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
}
- for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- tc->data_len += 4;
- }
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
+ planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
}
if (tc->data_len == 0) {
return;
}
- td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
- td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
- "TransTracking TransData2D");
- tdt = tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
- "TransTracking TransDataTracking");
-
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
+ tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D");
+ tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
+ "TransTracking TransDataTracking");
tc->custom.type.free_cb = transDataTrackingFree;
- /* create actual data */
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- trackToTransData(framenr, td, td2d, tdt, track, t->aspect);
-
- /* offset */
- td++;
- td2d++;
- tdt++;
+ init_context.current.td = tc->data;
+ init_context.current.td2d = tc->data_2d;
+ init_context.current.tdt = tc->custom.type.data;
- if (track->flag & SELECT) {
- td++;
- td2d++;
- tdt++;
- }
-
- if (track->pat_flag & SELECT) {
- td += 4;
- td2d += 4;
- tdt += 4;
- }
+ /* Create actual transformation data. */
- if (track->search_flag & SELECT) {
- td += 2;
- td2d += 2;
- tdt += 2;
- }
- }
-
- track = track->next;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
}
- for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- planeTrackToTransData(framenr, td, td2d, tdt, plane_track, t->aspect);
- td += 4;
- td2d += 4;
- tdt += 4;
- }
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
+ planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
}
}
@@ -560,17 +573,17 @@ void createTransTrackingData(bContext *C, TransInfo *t)
static void cancelTransTracking(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- SpaceClip *sc = t->area->spacedata.first;
- int i, framenr = ED_space_clip_get_clip_frame_number(sc);
TransDataTracking *tdt_array = tc->custom.type.data;
- i = 0;
+ int i = 0;
while (i < tc->data_len) {
TransDataTracking *tdt = &tdt_array[i];
if (tdt->mode == transDataTracking_ModeTracks) {
MovieTrackingTrack *track = tdt->track;
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, tdt->framenr);
+
+ BLI_assert(marker != NULL);
marker->flag = tdt->flag;
@@ -606,7 +619,10 @@ static void cancelTransTracking(TransInfo *t)
}
else if (tdt->mode == transDataTracking_ModePlaneTracks) {
MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
- MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track,
+ tdt->framenr);
+
+ BLI_assert(plane_marker != NULL);
plane_marker->flag = tdt->flag;
i += 3;
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 3c82365fdb4..7eaed2e1924 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -704,7 +704,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
/* skip strokes that are invalid for current view */
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index c19dd4598cf..508189c5d77 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -299,83 +299,93 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
void applyProject(TransInfo *t)
{
- /* XXX FLICKER IN OBJECT MODE */
- if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0) {
- float tvec[3];
- int i;
+ if (!t->tsnap.project) {
+ return;
+ }
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float iloc[3], loc[3], no[3];
- float mval_fl[2];
- if (td->flag & TD_SKIP) {
- continue;
- }
+ if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
+ return;
+ }
- if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
- continue;
- }
+ if (doForceIncrementSnap(t)) {
+ return;
+ }
- copy_v3_v3(iloc, td->loc);
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, iloc);
- }
- else if (t->flag & T_OBJECT) {
- BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(iloc, td->ob->obmat[3]);
- }
+ float tvec[3];
+ int i;
+
+ /* XXX FLICKER IN OBJECT MODE */
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ float iloc[3], loc[3], no[3];
+ float mval_fl[2];
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+
+ if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
+ continue;
+ }
- if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
- V3D_PROJ_RET_OK) {
- if (ED_transform_snap_object_project_view3d(
- t->tsnap.object_context,
- t->depsgraph,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = t->tsnap.modeSelect,
- .use_object_edit_cage = (t->flag & T_EDIT) != 0,
- .use_occlusion_test = false,
- .use_backface_culling = t->tsnap.use_backface_culling,
- },
- mval_fl,
- NULL,
- 0,
- loc,
- no)) {
+ copy_v3_v3(iloc, td->loc);
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, iloc);
+ }
+ else if (t->flag & T_OBJECT) {
+ BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
+ copy_v3_v3(iloc, td->ob->obmat[3]);
+ }
+
+ if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
+ V3D_PROJ_RET_OK) {
+ if (ED_transform_snap_object_project_view3d(
+ t->tsnap.object_context,
+ t->depsgraph,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = t->tsnap.modeSelect,
+ .use_object_edit_cage = (t->flag & T_EDIT) != 0,
+ .use_occlusion_test = false,
+ .use_backface_culling = t->tsnap.use_backface_culling,
+ },
+ mval_fl,
+ NULL,
+ 0,
+ loc,
+ no)) {
#if 0
if (tc->use_local_mat) {
mul_m4_v3(tc->imat, loc);
}
#endif
- sub_v3_v3v3(tvec, loc, iloc);
+ sub_v3_v3v3(tvec, loc, iloc);
- mul_m3_v3(td->smtx, tvec);
+ mul_m3_v3(td->smtx, tvec);
- add_v3_v3(td->loc, tvec);
+ add_v3_v3(td->loc, tvec);
- if (t->tsnap.align && (t->flag & T_OBJECT)) {
- /* handle alignment as well */
- const float *original_normal;
- float mat[3][3];
+ if (t->tsnap.align && (t->flag & T_OBJECT)) {
+ /* handle alignment as well */
+ const float *original_normal;
+ float mat[3][3];
- /* In pose mode, we want to align normals with Y axis of bones... */
- original_normal = td->axismtx[2];
+ /* In pose mode, we want to align normals with Y axis of bones... */
+ original_normal = td->axismtx[2];
- rotation_between_vecs_to_mat3(mat, original_normal, no);
+ rotation_between_vecs_to_mat3(mat, original_normal, no);
- transform_data_ext_rotate(td, mat, true);
+ transform_data_ext_rotate(td, mat, true);
- /* TODO support constraints for rotation too? see ElementRotation */
- }
+ /* TODO support constraints for rotation too? see ElementRotation */
}
}
+ }
#if 0 /* TODO: sipport this? */
constraintTransLim(t, td);
#endif
- }
}
}
}
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 533416bf85e..860eaa37816 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -70,6 +70,17 @@
/** We only need this locally. */
static CLG_LogRef LOG = {"ed.undo"};
+/**
+ * \warning Values are used in #ED_undo_gpencil_step,
+ * which should eventually be replaced with the undo-system.
+ */
+enum eUndoStepDir {
+ STEP_REDO = 1,
+ STEP_UNDO = -1,
+ /** Only used when the undo step name or index is passed to #ed_undo_step_impl. */
+ STEP_NONE = 0,
+};
+
/* -------------------------------------------------------------------- */
/** \name Generic Undo System Access
*
@@ -171,13 +182,16 @@ void ED_undo_push(bContext *C, const char *str)
/**
* \note Also check #undo_history_exec in bottom if you change notifiers.
*/
-static int ed_undo_step_impl(
- bContext *C, int step, const char *undoname, int undo_index, ReportList *reports)
+static int ed_undo_step_impl(bContext *C,
+ enum eUndoStepDir step,
+ const char *undo_name,
+ const int undo_index,
+ ReportList *reports)
{
/* Mutually exclusives, ensure correct input. */
- BLI_assert(((undoname || undo_index != -1) && !step) ||
- (!(undoname || undo_index != -1) && step));
- CLOG_INFO(&LOG, 1, "name='%s', step=%d", undoname, step);
+ BLI_assert(((undo_name || undo_index != -1) && (step == STEP_NONE)) ||
+ (!(undo_name || undo_index != -1) && (step != STEP_NONE)));
+ CLOG_INFO(&LOG, 1, "name='%s', index=%d, step=%d", undo_name, undo_index, step);
wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = CTX_data_scene(C);
ScrArea *area = CTX_wm_area(C);
@@ -196,8 +210,12 @@ static int ed_undo_step_impl(
/* TODO(campbell): undo_system: use undo system */
/* grease pencil can be can be used in plenty of spaces, so check it first */
+ /* FIXME: This gpencil undo effectively only supports the one step undo/redo, undo based on name
+ * or index is fully not implemented.
+ * FIXME: However, it seems to never be used in current code (`ED_gpencil_session_active` seems
+ * to always return false). */
if (ED_gpencil_session_active()) {
- return ED_undo_gpencil_step(C, step, undoname);
+ return ED_undo_gpencil_step(C, (int)step);
}
if (area && (area->spacetype == SPACE_VIEW3D)) {
Object *obact = CTX_data_active_object(C);
@@ -207,9 +225,9 @@ static int ed_undo_step_impl(
}
UndoStep *step_data_from_name = NULL;
- int step_for_callback = step;
- if (undoname != NULL) {
- step_data_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undoname);
+ enum eUndoStepDir step_for_callback = step;
+ if (undo_name != NULL) {
+ step_data_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undo_name);
if (step_data_from_name == NULL) {
return OPERATOR_CANCELLED;
}
@@ -218,14 +236,14 @@ static int ed_undo_step_impl(
/* Pointers match on redo. */
step_for_callback = (BLI_findindex(&wm->undo_stack->steps, step_data_from_name) <
BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active)) ?
- 1 :
- -1;
+ STEP_UNDO :
+ STEP_REDO;
}
else if (undo_index != -1) {
step_for_callback = (undo_index <
BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active)) ?
- 1 :
- -1;
+ STEP_UNDO :
+ STEP_REDO;
}
/* App-Handlers (pre). */
@@ -240,14 +258,14 @@ static int ed_undo_step_impl(
/* Undo System */
{
- if (undoname) {
+ if (undo_name) {
BKE_undosys_step_undo_with_data(wm->undo_stack, C, step_data_from_name);
}
else if (undo_index != -1) {
BKE_undosys_step_undo_from_index(wm->undo_stack, C, undo_index);
}
else {
- if (step == 1) {
+ if (step == STEP_UNDO) {
BKE_undosys_step_undo(wm->undo_stack, C);
}
else {
@@ -310,19 +328,19 @@ static int ed_undo_step_impl(
return OPERATOR_FINISHED;
}
-static int ed_undo_step_direction(bContext *C, int step, ReportList *reports)
+static int ed_undo_step_direction(bContext *C, enum eUndoStepDir step, ReportList *reports)
{
return ed_undo_step_impl(C, step, NULL, -1, reports);
}
static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList *reports)
{
- return ed_undo_step_impl(C, 0, undo_name, -1, reports);
+ return ed_undo_step_impl(C, STEP_NONE, undo_name, -1, reports);
}
-static int ed_undo_step_by_index(bContext *C, int index, ReportList *reports)
+static int ed_undo_step_by_index(bContext *C, const int undo_index, ReportList *reports)
{
- return ed_undo_step_impl(C, 0, NULL, index, reports);
+ return ed_undo_step_impl(C, STEP_NONE, NULL, undo_index, reports);
}
void ED_undo_grouped_push(bContext *C, const char *str)
@@ -340,11 +358,11 @@ void ED_undo_grouped_push(bContext *C, const char *str)
void ED_undo_pop(bContext *C)
{
- ed_undo_step_direction(C, 1, NULL);
+ ed_undo_step_direction(C, STEP_UNDO, NULL);
}
void ED_undo_redo(bContext *C)
{
- ed_undo_step_direction(C, -1, NULL);
+ ed_undo_step_direction(C, STEP_REDO, NULL);
}
void ED_undo_push_op(bContext *C, wmOperator *op)
@@ -448,7 +466,7 @@ static int ed_undo_exec(bContext *C, wmOperator *op)
{
/* "last operator" should disappear, later we can tie this with undo stack nicer */
WM_operator_stack_clear(CTX_wm_manager(C));
- int ret = ed_undo_step_direction(C, 1, op->reports);
+ int ret = ed_undo_step_direction(C, STEP_UNDO, op->reports);
if (ret & OPERATOR_FINISHED) {
/* Keep button under the cursor active. */
WM_event_add_mousemove(CTX_wm_window(C));
@@ -477,7 +495,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op)
static int ed_redo_exec(bContext *C, wmOperator *op)
{
- int ret = ed_undo_step_direction(C, -1, op->reports);
+ int ret = ed_undo_step_direction(C, STEP_REDO, op->reports);
if (ret & OPERATOR_FINISHED) {
/* Keep button under the cursor active. */
WM_event_add_mousemove(CTX_wm_window(C));
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
index e2f4d34ff40..f80ad60eb07 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
@@ -110,11 +110,11 @@ static bool dependsOnTime(GpencilModifierData *md)
return (mmd->flag & GP_NOISE_USE_RANDOM) != 0;
}
-static float *noise_table(int len, int seed)
+static float *noise_table(int len, int offset, int seed)
{
float *table = MEM_callocN(sizeof(float) * len, __func__);
for (int i = 0; i < len; i++) {
- table[i] = BLI_hash_int_01(BLI_hash_int_2d(seed, i + 1));
+ table[i] = BLI_hash_int_01(BLI_hash_int_2d(seed, i + offset + 1));
}
return table;
}
@@ -172,11 +172,19 @@ static void deformStroke(GpencilModifierData *md,
/* Sanitize as it can create out of bound reads. */
float noise_scale = clamp_f(mmd->noise_scale, 0.0f, 1.0f);
- int len = ceilf(gps->totpoints * noise_scale) + 1;
- float *noise_table_position = (mmd->factor > 0.0f) ? noise_table(len, seed + 2) : NULL;
- float *noise_table_strength = (mmd->factor_strength > 0.0f) ? noise_table(len, seed + 3) : NULL;
- float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ? noise_table(len, seed) : NULL;
- float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ? noise_table(len, seed + 4) : NULL;
+ int len = ceilf(gps->totpoints * noise_scale) + 2;
+ float *noise_table_position = (mmd->factor > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed + 2) :
+ NULL;
+ float *noise_table_strength = (mmd->factor_strength > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed + 3) :
+ NULL;
+ float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed) :
+ NULL;
+ float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed + 4) :
+ NULL;
/* Calculate stroke normal. */
if (gps->totpoints > 2) {
@@ -225,24 +233,27 @@ static void deformStroke(GpencilModifierData *md,
cross_v3_v3v3(vec2, vec1, normal);
normalize_v3(vec2);
- float noise = table_sample(noise_table_position, i * noise_scale);
+ float noise = table_sample(noise_table_position,
+ i * noise_scale + fractf(mmd->noise_offset));
madd_v3_v3fl(&pt->x, vec2, (noise * 2.0f - 1.0f) * weight * mmd->factor * 0.1f);
}
if (mmd->factor_thickness > 0.0f) {
- float noise = table_sample(noise_table_thickness, i * noise_scale);
+ float noise = table_sample(noise_table_thickness,
+ i * noise_scale + fractf(mmd->noise_offset));
pt->pressure *= max_ff(1.0f + (noise * 2.0f - 1.0f) * weight * mmd->factor_thickness, 0.0f);
CLAMP_MIN(pt->pressure, GPENCIL_STRENGTH_MIN);
}
if (mmd->factor_strength > 0.0f) {
- float noise = table_sample(noise_table_strength, i * noise_scale);
+ float noise = table_sample(noise_table_strength,
+ i * noise_scale + fractf(mmd->noise_offset));
pt->strength *= max_ff(1.0f - noise * weight * mmd->factor_strength, 0.0f);
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
}
if (mmd->factor_uvs > 0.0f) {
- float noise = table_sample(noise_table_uvs, i * noise_scale);
+ float noise = table_sample(noise_table_uvs, i * noise_scale + fractf(mmd->noise_offset));
pt->uv_rot += (noise * 2.0f - 1.0f) * weight * mmd->factor_uvs * M_PI_2;
CLAMP(pt->uv_rot, -M_PI_2, M_PI_2);
}
@@ -292,6 +303,8 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "factor_thickness", 0, IFACE_("Thickness"), ICON_NONE);
uiItemR(col, ptr, "factor_uvs", 0, IFACE_("UV"), ICON_NONE);
uiItemR(col, ptr, "noise_scale", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "noise_offset", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "seed", 0, NULL, ICON_NONE);
gpencil_modifier_panel_end(layout, ptr);
}
@@ -316,7 +329,6 @@ static void random_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetActive(layout, RNA_boolean_get(ptr, "random"));
uiItemR(layout, ptr, "step", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE);
}
static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 014c70033fc..625ad604b7c 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -200,7 +200,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
*
* WARNING: this function creates a lot of aliases/attributes, make sure to keep the attribute
* name short to avoid overflowing the name-buffer.
- * */
+ */
void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count)
{
/* Sanity check. Maximum can be upgraded if needed. */
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 3f444172499..eb31b0e9f87 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -1878,7 +1878,7 @@ static void execute_scene(struct Depsgraph *depsgraph,
/*---------------------------------------------------
* plugin interface
- * */
+ */
void itasc_initialize_tree(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *ob,
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h
index 08aa1936a6f..c92d764a104 100644
--- a/source/blender/imbuf/intern/IMB_allocimbuf.h
+++ b/source/blender/imbuf/intern/IMB_allocimbuf.h
@@ -32,7 +32,7 @@ struct ImBuf;
void imb_refcounter_lock_init(void);
void imb_refcounter_lock_exit(void);
-#ifdef WIN32
+#ifndef WIN32
void imb_mmap_lock_init(void);
void imb_mmap_lock_exit(void);
void imb_mmap_lock(void);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 8dfb3ada7d6..bfb7bc93ac7 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -53,7 +53,7 @@ void imb_refcounter_lock_exit(void)
BLI_spin_end(&refcounter_spin);
}
-#ifdef WIN32
+#ifndef WIN32
static SpinLock mmap_spin;
void imb_mmap_lock_init(void)
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index cce264624ce..343c8cd8f64 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -425,7 +425,7 @@ static int check_pixel_assigned(
*
* When a mask is given, only effect pixels with a mask value of 1,
* defined as #BAKE_MASK_MARGIN in rendercore.c
- * */
+ */
void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
{
const int width = ibuf->x;
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index f0daa4543e1..50210650f05 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -23,13 +23,13 @@
*/
#ifdef _WIN32
-# include "mmap_win.h"
# include <io.h>
# include <stddef.h>
# include <sys/types.h>
#endif
#include "BLI_fileops.h"
+#include "BLI_mmap.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -186,20 +186,19 @@ ImBuf *IMB_loadifffile(
size = BLI_file_descriptor_size(file);
imb_mmap_lock();
- mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
+ BLI_mmap_file *mmap_file = BLI_mmap_open(file);
imb_mmap_unlock();
-
- if (mem == (unsigned char *)-1) {
+ if (mmap_file == NULL) {
fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
return NULL;
}
+ mem = BLI_mmap_get_pointer(mmap_file);
+
ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
imb_mmap_lock();
- if (munmap(mem, size)) {
- fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
- }
+ BLI_mmap_free(mmap_file);
imb_mmap_unlock();
return ibuf;
@@ -292,14 +291,15 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int
size = BLI_file_descriptor_size(file);
imb_mmap_lock();
- mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
+ BLI_mmap_file *mmap_file = BLI_mmap_open(file);
imb_mmap_unlock();
-
- if (mem == (unsigned char *)-1) {
+ if (mmap_file == NULL) {
fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
return;
}
+ mem = BLI_mmap_get_pointer(mmap_file);
+
const ImFileType *type = IMB_file_type_from_ibuf(ibuf);
if (type != NULL) {
if (type->load_tile != NULL) {
@@ -308,9 +308,7 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int
}
imb_mmap_lock();
- if (munmap(mem, size)) {
- fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
- }
+ BLI_mmap_free(mmap_file);
imb_mmap_unlock();
}
diff --git a/source/blender/io/alembic/exporter/abc_archive.cc b/source/blender/io/alembic/exporter/abc_archive.cc
index 68ad2089a3e..90a4baf97bc 100644
--- a/source/blender/io/alembic/exporter/abc_archive.cc
+++ b/source/blender/io/alembic/exporter/abc_archive.cc
@@ -112,7 +112,7 @@ static OArchive *create_archive(std::ofstream *abc_ostream,
*
* If 'time_relative' is true, samples are returned as time (in seconds) from params.frame_start.
* If 'time_relative' is false, samples are returned as fractional frames from 0.
- * */
+ */
static void get_shutter_samples(double scene_fps,
const AlembicExportParams &params,
int nr_of_samples,
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 263ce2203e9..61a93982e36 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -254,7 +254,7 @@ typedef struct IDOverrideLibrary {
/**
* ID is the first thing included in all serializable types. It
* provides a common handle to place all data in double-linked lists.
- * */
+ */
/* 2 characters for ID code and 64 for actual name */
#define MAX_ID_NAME 66
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 4b020019062..e373500a0ed 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -47,10 +47,13 @@ typedef struct BrushClone {
char _pad[4];
} BrushClone;
+#define GPENCIL_MIN_FILL_FAC 0.05f
+
typedef struct BrushGpencilSettings {
/** Amount of smoothing to apply to newly created strokes. */
float draw_smoothfac;
- char _pad2[4];
+ /** Fill zoom factor */
+ float fill_factor;
/** Amount of alpha strength to apply to newly created strokes. */
float draw_strength;
/** Amount of jitter to apply to newly created strokes. */
@@ -75,8 +78,8 @@ typedef struct BrushGpencilSettings {
float fill_threshold;
/** Number of pixel to consider the leak is too small (x 2). */
short fill_leak;
- /** Fill zoom factor */
- short fill_factor;
+ char _pad2[2];
+
int flag2;
/** Number of simplify steps. */
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index c8e09225432..e3dcd283efa 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -242,10 +242,12 @@ typedef struct DynamicPaintBrushSettings {
/** For fast RNA access. */
struct DynamicPaintModifierData *pmd;
- /* NOTE: Storing the particle system pointer here is very weak, as it prevents modfiers' data
+ /**
+ * \note Storing the particle system pointer here is very weak, as it prevents modifiers' data
* copying to be self-sufficient (extra external code needs to ensure the pointer remains valid
* when the modifier data is copied from one object to another). See e.g.
- * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`. */
+ * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`.
+ */
struct ParticleSystem *psys;
int flags;
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index fdb77bfd196..399bf6f0a6d 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -152,6 +152,7 @@
.factor_thickness = 0.0f, \
.factor_uvs = 0.0f, \
.noise_scale = 0.0f, \
+ .noise_offset = 0.0f, \
.step = 4, \
.layer_pass = 0, \
.seed = 1, \
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 9ac40495887..1f7283a1c70 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -107,6 +107,8 @@ typedef struct NoiseGpencilModifierData {
float factor_uvs;
/** Noise Frequency scaling */
float noise_scale;
+ float noise_offset;
+ char _pad[4];
/** How many frames before recalculate randoms. */
int step;
/** Custom index for passes. */
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 949b0bb5bf5..1dbfd547673 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -512,6 +512,11 @@ typedef struct bGPDlayer {
int act_mask;
char _pad2[4];
+ /** Layer transforms. */
+ float location[3], rotation[3], scale[3];
+ float layer_mat[4][4], layer_invmat[4][4];
+ char _pad3[4];
+
bGPDlayer_Runtime runtime;
} bGPDlayer;
@@ -574,7 +579,9 @@ typedef struct bGPdata_Runtime {
/** Temp stroke used for drawing. */
struct bGPDstroke *sbuffer_gps;
- char _pad[2];
+ /** Animation playing flag. */
+ short playing;
+
/** Material index of the stroke. */
short matid;
@@ -840,6 +847,8 @@ typedef enum eGP_DrawMode {
((flag & (GP_VERTEX_MASK_SELECTMODE_POINT | GP_VERTEX_MASK_SELECTMODE_STROKE | \
GP_VERTEX_MASK_SELECTMODE_SEGMENT)))
+#define GPENCIL_PLAY_ON(gpd) ((gpd) && ((gpd)->runtime.playing == 1))
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 3de4299e0bd..29421430e5d 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -984,10 +984,12 @@ enum {
typedef struct ParticleSystemModifierData {
ModifierData modifier;
- /* NOTE: Storing the particle system pointer here is very weak, as it prevents modfiers' data
+ /**
+ * \note Storing the particle system pointer here is very weak, as it prevents modifiers' data
* copying to be self-sufficient (extra external code needs to ensure the pointer remains valid
* when the modifier data is copied from one object to another). See e.g.
- * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`. */
+ * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`.
+ */
struct ParticleSystem *psys;
/** Final Mesh - its topology may differ from orig mesh. */
struct Mesh *mesh_final;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 03f5d3f8d47..a1ccf11b8e3 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -63,6 +63,9 @@ struct wmTimer;
/* Defined in `buttons_intern.h`. */
typedef struct SpaceProperties_Runtime SpaceProperties_Runtime;
+/* Defined in `node_intern.h`. */
+typedef struct SpaceNode_Runtime SpaceNode_Runtime;
+
/* -------------------------------------------------------------------- */
/** \name SpaceLink (Base)
* \{ */
@@ -1518,19 +1521,17 @@ typedef struct SpaceNode {
/** Context, no need to save in file? well... pinning... */
struct ID *id, *from;
- /** Menunr: browse id block in header. */
+
short flag;
- char _pad1[2];
- /** Internal state variables. */
- float aspect;
- char _pad2[4];
+
+ /** Direction for offsetting nodes on insertion. */
+ char insert_ofs_dir;
+ char _pad1;
/** Offset for drawing the backdrop. */
float xof, yof;
/** Zoom for backdrop. */
float zoom;
- /** Mouse pos for drawing socketless link and adding nodes. */
- float cursor[2];
/**
* XXX nodetree pointer info is all in the path stack now,
@@ -1541,33 +1542,25 @@ typedef struct SpaceNode {
*/
ListBase treepath;
- struct bNodeTree *nodetree, *edittree;
+ /* The tree farthest down in the group heirarchy. */
+ struct bNodeTree *edittree;
+
+ struct bNodeTree *nodetree;
/* tree type for the current node tree */
char tree_idname[64];
/** Treetype: as same nodetree->type. */
int treetype DNA_DEPRECATED;
- char _pad3[4];
/** Texfrom object, world or brush. */
short texfrom;
/** Shader from object or world. */
short shaderfrom;
- /** Currently on 0/1, for auto compo. */
- short recalc;
-
- /** Direction for offsetting nodes on insertion. */
- char insert_ofs_dir;
- char _pad4;
-
- /** Temporary data for modal linking operator. */
- ListBase linkdrag;
- /* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
- /** Temporary data for node insert offset (in UI called Auto-offset). */
- struct NodeInsertOfsData *iofsd;
/** Grease-pencil data. */
struct bGPdata *gpd;
+
+ SpaceNode_Runtime *runtime;
} SpaceNode;
/* SpaceNode.flag */
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 5b6b706c83c..5a8bbdc08a1 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -141,7 +141,7 @@ typedef struct MovieTrackingTrack {
/** Count of markers in track. */
int markersnr;
/** Most recently used marker. */
- int last_marker;
+ int _pad;
/** Markers in track. */
MovieTrackingMarker *markers;
@@ -251,8 +251,6 @@ typedef struct MovieTrackingPlaneTrack {
} MovieTrackingPlaneTrack;
typedef struct MovieTrackingSettings {
- int flag;
-
/* ** default tracker settings */
/** Model of the motion for this track. */
short default_motion_model;
@@ -309,8 +307,6 @@ typedef struct MovieTrackingSettings {
/* set object scale */
/** Distance between two bundles used for object scaling. */
float object_distance;
-
- char _pad3[4];
} MovieTrackingSettings;
typedef struct MovieTrackingStabilization {
@@ -526,11 +522,6 @@ typedef enum eTrackFrameMatch {
TRACK_MATCH_PREVIOS_FRAME = 1,
} eTrackFrameMatch;
-/* MovieTrackingSettings->flag */
-enum {
- TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED = (1 << 0),
- TRACKING_SETTINGS_SHOW_EXTRA_EXPANDED = (1 << 1),
-};
/* MovieTrackingSettings->motion_flag */
enum {
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index eb7779213fd..db34cf83fa9 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -48,12 +48,6 @@ set(SRC
../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
)
-if(WIN32 AND NOT UNIX)
- list(APPEND SRC
- ../../../../intern/guardedalloc/intern/mmap_win.c
- )
-endif()
-
# SRC_DNA_INC is defined in the parent dir
add_cc_flags_custom_test(makesdna)
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 54d2bc88d16..843e6935416 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -397,13 +397,11 @@ static int add_type(const char *str, int size)
}
/**
- *
* Because of the weird way of tokenizing, we have to 'cast' function
* pointers to ... (*f)(), whatever the original signature. In fact,
* we add name and type at the same time... There are two special
* cases, unfortunately. These are explicitly checked.
- *
- * */
+ */
static int add_name(const char *str)
{
char buf[255]; /* stupid limit, change it :) */
@@ -479,17 +477,16 @@ static int add_name(const char *str)
}
/*
- * Put )(void) at the end? Maybe )(). Should check this with
- * old sdna. Actually, sometimes )(), sometimes )(void...)
+ * Put `)(void)` at the end? Maybe `)()`. Should check this with
+ * old `sdna`. Actually, sometimes `)()`, sometimes `)(void...)`
* Alas.. such is the nature of brain-damage :(
*
- * Sorted it out: always do )(), except for headdraw and
- * windraw, part of ScrArea. This is important, because some
+ * Sorted it out: always do )(), except for `headdraw` and
+ * `windraw`, part of #ScrArea. This is important, because some
* linkers will treat different fp's differently when called
* !!! This has to do with interference in byte-alignment and
- * the way args are pushed on the stack.
- *
- * */
+ * the way arguments are pushed on the stack.
+ */
buf[i] = 0;
DEBUG_PRINTF(3, "Name before chomping: %s\n", buf);
if ((strncmp(buf, "(*headdraw", 10) == 0) || (strncmp(buf, "(*windraw", 9) == 0)) {
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 72cdaecb2c3..94cfd8464ae 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -189,7 +189,6 @@ set(SRC
../../../../intern/guardedalloc/intern/mallocn.c
../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c
../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
- ../../../../intern/guardedalloc/intern/mmap_win.c
# Needed for defaults.
../../../../release/datafiles/userdef/userdef_default.c
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index e9e00ff6f71..bec3db10905 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -4758,8 +4758,14 @@ static const char *cpp_classes =
"class CollectionIterator {\n"
"public:\n"
" CollectionIterator() : iter(), t(iter.ptr), init(false) { iter.valid = false; }\n"
+ " CollectionIterator(const PointerRNA &ptr) : CollectionIterator() { this->begin(ptr); }\n"
" ~CollectionIterator(void) { if (init) Tend(&iter); };\n"
"\n"
+ " CollectionIterator(const CollectionIterator &other) = delete;\n"
+ " CollectionIterator(CollectionIterator &&other) = delete;\n"
+ " CollectionIterator &operator=(const CollectionIterator &other) = delete;\n"
+ " CollectionIterator &operator=(CollectionIterator &&other) = delete;\n"
+ "\n"
" operator bool(void)\n"
" { return iter.valid != 0; }\n"
" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator++() { Tnext(&iter); t = "
@@ -4777,9 +4783,6 @@ static const char *cpp_classes =
"true; }\n"
"\n"
"private:\n"
- " const CollectionIterator<T, Tbegin, Tnext, Tend>& operator = "
- "(const CollectionIterator<T, Tbegin, Tnext, Tend>& /*copy*/) {}\n"
- ""
" CollectionPropertyIterator iter;\n"
" T t;\n"
" bool init;\n"
@@ -4794,6 +4797,8 @@ static const char *cpp_classes =
"\n"
" void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n"
" { iter.begin(ptr); }\n"
+ " CollectionIterator<T, Tbegin, Tnext, Tend> begin()\n"
+ " { return CollectionIterator<T, Tbegin, Tnext, Tend>(ptr); }\n"
" CollectionIterator<T, Tbegin, Tnext, Tend> end()\n"
" { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n"
""
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 2af6c04147c..4f98c6e8e07 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1464,13 +1464,13 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
/* fill factor size */
- prop = RNA_def_property(srna, "fill_factor", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "fill_factor");
- RNA_def_property_range(prop, 1, 8);
+ prop = RNA_def_property(srna, "fill_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "fill_factor");
+ RNA_def_property_range(prop, GPENCIL_MIN_FILL_FAC, 8.0f);
RNA_def_property_ui_text(
prop,
- "Resolution",
- "Multiplier for fill resolution, higher resolution is more accurate but slower");
+ "Precision",
+ "Factor for fill boundary accuracy, higher values are more accurate but slower");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 81e20003d8f..dec25c0143f 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -182,6 +182,16 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
+static void rna_GpencilLayerMatrix_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bGPDlayer *gpl = (bGPDlayer *)ptr->data;
+
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
+ rna_GPencil_update(bmain, scene, ptr);
+}
+
static void rna_GPencil_curve_edit_mode_toggle(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ToolSettings *ts = scene->toolsettings;
@@ -2012,6 +2022,45 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+ /* Layer transforms. */
+ prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "location");
+ RNA_def_property_ui_text(prop, "Location", "Values for change location");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
+
+ prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
+ RNA_def_property_float_sdna(prop, NULL, "rotation");
+ RNA_def_property_ui_text(prop, "Rotation", "Values for changes in rotation");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
+
+ prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "scale");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Scale", "Values for changes in scale");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
+
+ /* Layer matrix. */
+ prop = RNA_def_property(srna, "matrix_layer", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "layer_mat");
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
+ RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(prop, "Matrix Layer", "Local Layer transformation matrix");
+
+ /* Layer inverse matrix. */
+ prop = RNA_def_property(srna, "matrix_inverse_layer", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "layer_invmat");
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
+ RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(
+ prop, "Matrix Layer Inverse", "Local Layer transformation inverse matrix");
+
/* Flags */
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 89eb989a442..71d5a53adb2 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -489,7 +489,7 @@ static void rna_def_modifier_gpencilnoise(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_ui_text(prop, "Seed", "Random seed");
+ RNA_def_property_ui_text(prop, "Noise Seed", "Random seed");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "noise_scale", PROP_FLOAT, PROP_FACTOR);
@@ -498,6 +498,13 @@ static void rna_def_modifier_gpencilnoise(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Noise Scale", "Scale the noise frequency");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+ prop = RNA_def_property(srna, "noise_offset", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "noise_offset");
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0, 100.0, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Noise Offset", "Offset the noise along the strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
prop = RNA_def_property(srna, "use_custom_curve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_CUSTOM_CURVE);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index c929e3ab1aa..826e1202efc 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1279,12 +1279,22 @@ static int rna_property_override_diff_propptr(Main *bmain,
0);
if (is_id) {
- /* For now, once we deal with nodetrees we'll want to get rid of that one. */
- // BLI_assert(no_ownership);
+ /* Owned IDs (the ones we want to actually compare in depth, instead of just comparing pointer
+ * values) should be always properly tagged as 'virtual' overrides. */
+ ID *id = propptr_a->owner_id;
+ if (id != NULL && !ID_IS_OVERRIDE_LIBRARY(id)) {
+ id = propptr_b->owner_id;
+ if (id != NULL && !ID_IS_OVERRIDE_LIBRARY(id)) {
+ id = NULL;
+ }
+ }
+
+ BLI_assert(no_ownership || id == NULL || ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id));
+ UNUSED_VARS_NDEBUG(id);
}
if (override) {
- if (no_ownership /* || is_id */ || is_null || is_type_diff || !is_valid_for_diffing) {
+ if (no_ownership || is_null || is_type_diff || !is_valid_for_diffing) {
/* In case this pointer prop does not own its data (or one is NULL), do not compare structs!
* This is a quite safe path to infinite loop, among other nasty issues.
* Instead, just compare pointers themselves. */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 2ee84f70752..160d93dea58 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2279,6 +2279,20 @@ static bool rna_SpaceNodeEditor_tree_type_poll(void *Cv, bNodeTreeType *type)
}
}
+static void rna_SpaceNodeEditor_cursor_location_get(PointerRNA *ptr, float value[2])
+{
+ const SpaceNode *snode = (SpaceNode *)ptr->data;
+
+ ED_node_cursor_location_get(snode, value);
+}
+
+static void rna_SpaceNodeEditor_cursor_location_set(PointerRNA *ptr, const float value[2])
+{
+ SpaceNode *snode = (SpaceNode *)ptr->data;
+
+ ED_node_cursor_location_set(snode, value);
+}
+
const EnumPropertyItem *RNA_enum_node_tree_types_itemf_impl(bContext *C, bool *r_free)
{
return rna_node_tree_type_itemf(C, rna_SpaceNodeEditor_tree_type_poll, r_free);
@@ -2346,9 +2360,13 @@ static void rna_SpaceNodeEditor_cursor_location_from_region(SpaceNode *snode,
{
ARegion *region = CTX_wm_region(C);
- UI_view2d_region_to_view(&region->v2d, x, y, &snode->cursor[0], &snode->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ float cursor_location[2];
+
+ UI_view2d_region_to_view(&region->v2d, x, y, &cursor_location[0], &cursor_location[1]);
+ cursor_location[0] /= UI_DPI_FAC;
+ cursor_location[1] /= UI_DPI_FAC;
+
+ ED_node_cursor_location_set(snode, cursor_location);
}
static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr,
@@ -6815,11 +6833,13 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_enum_items(prop, backdrop_channels_items);
RNA_def_property_ui_text(prop, "Display Channels", "Channels of the image to draw");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
-
/* the mx/my "cursor" in the node editor is used only by operators to store the mouse position */
prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
- RNA_def_property_float_sdna(prop, NULL, "cursor");
+ RNA_def_property_float_funcs(prop,
+ "rna_SpaceNodeEditor_cursor_location_get",
+ "rna_SpaceNodeEditor_cursor_location_set",
+ NULL);
RNA_def_property_ui_text(prop, "Cursor Location", "Location for adding new nodes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 1870c660efd..bcf75fb284f 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -976,22 +976,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, cleanup_items);
RNA_def_property_ui_text(prop, "Action", "Cleanup action to execute");
- /* ** default tracker settings ** */
- prop = RNA_def_property(srna, "show_default_expanded", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED);
- RNA_def_property_ui_text(
- prop, "Show Expanded", "Show default options expanded in the user interface");
- RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
-
- /* ** extra tracker settings ** */
- prop = RNA_def_property(srna, "show_extra_expanded", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_EXTRA_EXPANDED);
- RNA_def_property_ui_text(
- prop, "Show Expanded", "Show extra options expanded in the user interface");
- RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
-
/* solver settings */
prop = RNA_def_property(srna, "use_tripod_solver", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 5ef17aeddd1..6da2ecba6a7 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -221,18 +221,21 @@ class GeometryNodesEvaluator {
const blender::nodes::DataTypeConversions &conversions_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
+ Depsgraph *depsgraph_;
public:
GeometryNodesEvaluator(const Map<const DOutputSocket *, GMutablePointer> &group_input_data,
Vector<const DInputSocket *> group_outputs,
blender::nodes::MultiFunctionByNode &mf_by_node,
const PersistentDataHandleMap &handle_map,
- const Object *self_object)
+ const Object *self_object,
+ Depsgraph *depsgraph)
: group_outputs_(std::move(group_outputs)),
mf_by_node_(mf_by_node),
conversions_(blender::nodes::get_implicit_type_conversions()),
handle_map_(handle_map),
- self_object_(self_object)
+ self_object_(self_object),
+ depsgraph_(depsgraph)
{
for (auto item : group_input_data.items()) {
this->forward_to_inputs(*item.key, item.value);
@@ -306,7 +309,8 @@ class GeometryNodesEvaluator {
/* Execute the node. */
GValueMap<StringRef> node_outputs_map{allocator_};
- GeoNodeExecParams params{bnode, node_inputs_map, node_outputs_map, handle_map_, self_object_};
+ GeoNodeExecParams params{
+ bnode, node_inputs_map, node_outputs_map, handle_map_, self_object_, depsgraph_};
this->execute_node(node, params);
/* Forward computed outputs to linked input sockets. */
@@ -926,7 +930,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
group_outputs.append(&socket_to_compute);
GeometryNodesEvaluator evaluator{
- group_inputs, group_outputs, mf_by_node, handle_map, ctx->object};
+ group_inputs, group_outputs, mf_by_node, handle_map, ctx->object, ctx->depsgraph};
Vector<GMutablePointer> results = evaluator.execute();
BLI_assert(results.size() == 1);
GMutablePointer result = results[0];
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index ba370b401f3..b59907cc1e9 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -486,9 +486,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/*
* Normal Calculation (for face flipping)
* Sort edge verts for correct face flipping
- * NOT REALLY NEEDED but face flipping is nice.
- *
- * */
+ * NOT REALLY NEEDED but face flipping is nice. */
/* Notice!
*
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index f278d6b4107..3820c0f0009 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -24,6 +24,8 @@
#include "DNA_node_types.h"
+struct Depsgraph;
+
namespace blender::nodes {
using bke::BooleanReadAttribute;
@@ -54,18 +56,21 @@ class GeoNodeExecParams {
GValueMap<StringRef> &output_values_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
+ Depsgraph *depsgraph_;
public:
GeoNodeExecParams(const bNode &node,
GValueMap<StringRef> &input_values,
GValueMap<StringRef> &output_values,
const PersistentDataHandleMap &handle_map,
- const Object *self_object)
+ const Object *self_object,
+ Depsgraph *depsgraph)
: node_(node),
input_values_(input_values),
output_values_(output_values),
handle_map_(handle_map),
- self_object_(self_object)
+ self_object_(self_object),
+ depsgraph_(depsgraph)
{
}
@@ -163,6 +168,11 @@ class GeoNodeExecParams {
return self_object_;
}
+ Depsgraph *depsgraph() const
+ {
+ return depsgraph_;
+ }
+
/**
* Creates a read-only attribute based on node inputs. The method automatically detects which
* input with the given name is available.
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
index 0e7bb25e659..3ee7df7fe72 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
@@ -50,8 +50,7 @@ static void geo_node_attribute_randomize_update(bNodeTree *UNUSED(ntree), bNode
bNodeSocket *sock_min_float = sock_max_vector->next;
bNodeSocket *sock_max_float = sock_min_float->next;
- const int data_type = node->custom1;
-
+ const CustomDataType data_type = static_cast<CustomDataType>(node->custom1);
nodeSetSocketAvailability(sock_min_vector, data_type == CD_PROP_FLOAT3);
nodeSetSocketAvailability(sock_max_vector, data_type == CD_PROP_FLOAT3);
nodeSetSocketAvailability(sock_min_float, data_type == CD_PROP_FLOAT);
@@ -86,8 +85,11 @@ static void randomize_attribute_bool(BooleanWriteAttribute attribute,
attribute.apply_span();
}
-static void randomize_attribute_float(
- FloatWriteAttribute attribute, float min, float max, Span<uint32_t> hashes, const int seed)
+static void randomize_attribute_float(FloatWriteAttribute attribute,
+ const float min,
+ const float max,
+ Span<uint32_t> hashes,
+ const int seed)
{
MutableSpan<float> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@@ -97,8 +99,11 @@ static void randomize_attribute_float(
attribute.apply_span();
}
-static void randomize_attribute_float3(
- Float3WriteAttribute attribute, float3 min, float3 max, Span<uint32_t> hashes, const int seed)
+static void randomize_attribute_float3(Float3WriteAttribute attribute,
+ const float3 min,
+ const float3 max,
+ Span<uint32_t> hashes,
+ const int seed)
{
MutableSpan<float3> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@@ -129,8 +134,7 @@ Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &compo
}
else {
/* If there is no "id" attribute for per-point variation, just create it here. */
- RandomNumberGenerator rng;
- rng.seed(0);
+ RandomNumberGenerator rng(0);
for (const int i : hashes.index_range()) {
hashes[i] = rng.get_uint32();
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
index 2f1aa276532..eaf13b94eb9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -26,6 +26,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
+#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
@@ -217,13 +218,141 @@ BLI_NOINLINE static void eliminate_points_based_on_mask(Span<bool> elimination_m
}
}
-BLI_NOINLINE static void compute_remaining_point_data(const Mesh &mesh,
- Span<float3> bary_coords,
- Span<int> looptri_indices,
- MutableSpan<float3> r_normals,
- MutableSpan<int> r_ids,
- MutableSpan<float3> r_rotations)
+template<typename T>
+BLI_NOINLINE static void interpolate_attribute_point(const Mesh &mesh,
+ const Span<float3> bary_coords,
+ const Span<int> looptri_indices,
+ const Span<T> data_in,
+ MutableSpan<T> data_out)
{
+ BLI_assert(data_in.size() == mesh.totvert);
+ Span<MLoopTri> looptris = get_mesh_looptris(mesh);
+
+ for (const int i : bary_coords.index_range()) {
+ const int looptri_index = looptri_indices[i];
+ const MLoopTri &looptri = looptris[looptri_index];
+ const float3 &bary_coord = bary_coords[i];
+
+ const int v0_index = mesh.mloop[looptri.tri[0]].v;
+ const int v1_index = mesh.mloop[looptri.tri[1]].v;
+ const int v2_index = mesh.mloop[looptri.tri[2]].v;
+
+ const T &v0 = data_in[v0_index];
+ const T &v1 = data_in[v1_index];
+ const T &v2 = data_in[v2_index];
+
+ const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
+ data_out[i] = interpolated_value;
+ }
+}
+
+template<typename T>
+BLI_NOINLINE static void interpolate_attribute_corner(const Mesh &mesh,
+ const Span<float3> bary_coords,
+ const Span<int> looptri_indices,
+ const Span<T> data_in,
+ MutableSpan<T> data_out)
+{
+ BLI_assert(data_in.size() == mesh.totloop);
+ Span<MLoopTri> looptris = get_mesh_looptris(mesh);
+
+ for (const int i : bary_coords.index_range()) {
+ const int looptri_index = looptri_indices[i];
+ const MLoopTri &looptri = looptris[looptri_index];
+ const float3 &bary_coord = bary_coords[i];
+
+ const int loop_index_0 = looptri.tri[0];
+ const int loop_index_1 = looptri.tri[1];
+ const int loop_index_2 = looptri.tri[2];
+
+ const T &v0 = data_in[loop_index_0];
+ const T &v1 = data_in[loop_index_1];
+ const T &v2 = data_in[loop_index_2];
+
+ const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
+ data_out[i] = interpolated_value;
+ }
+}
+
+BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices,
+ const StringRef attribute_name,
+ const ReadAttribute &attribute_in,
+ GeometryComponent &component)
+{
+ const CustomDataType data_type = attribute_in.custom_data_type();
+ const AttributeDomain domain = attribute_in.domain();
+ if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
+ /* Not supported currently. */
+ return;
+ }
+
+ OutputAttributePtr attribute_out = component.attribute_try_get_for_output(
+ attribute_name, ATTR_DOMAIN_POINT, data_type);
+ if (!attribute_out) {
+ return;
+ }
+
+ attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+
+ Span data_in = attribute_in.get_span<T>();
+ MutableSpan data_out = attribute_out->get_span_for_write_only<T>();
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT: {
+ interpolate_attribute_point<T>(mesh, bary_coords, looptri_indices, data_in, data_out);
+ break;
+ }
+ case ATTR_DOMAIN_CORNER: {
+ interpolate_attribute_corner<T>(mesh, bary_coords, looptri_indices, data_in, data_out);
+ break;
+ }
+ default: {
+ BLI_assert(false);
+ break;
+ }
+ }
+ });
+ attribute_out.apply_span_and_save();
+}
+
+BLI_NOINLINE static void interpolate_existing_attributes(const MeshComponent &mesh_component,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ const Mesh &mesh = *mesh_component.get_for_read();
+
+ Set<std::string> attribute_names = mesh_component.attribute_names();
+ for (StringRefNull attribute_name : attribute_names) {
+ if (ELEM(attribute_name, "position", "normal", "id")) {
+ continue;
+ }
+
+ ReadAttributePtr attribute_in = mesh_component.attribute_try_get_for_read(attribute_name);
+ interpolate_attribute(
+ mesh, bary_coords, looptri_indices, attribute_name, *attribute_in, component);
+ }
+}
+
+BLI_NOINLINE static void compute_special_attributes(const Mesh &mesh,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ OutputAttributePtr id_attribute = component.attribute_try_get_for_output(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ OutputAttributePtr normal_attribute = component.attribute_try_get_for_output(
+ "normal", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ OutputAttributePtr rotation_attribute = component.attribute_try_get_for_output(
+ "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+
+ MutableSpan<int> ids = id_attribute->get_span_for_write_only<int>();
+ MutableSpan<float3> normals = normal_attribute->get_span_for_write_only<float3>();
+ MutableSpan<float3> rotations = rotation_attribute->get_span_for_write_only<float3>();
+
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
@@ -237,10 +366,24 @@ BLI_NOINLINE static void compute_remaining_point_data(const Mesh &mesh,
const float3 v1_pos = mesh.mvert[v1_index].co;
const float3 v2_pos = mesh.mvert[v2_index].co;
- r_ids[i] = (int)(bary_coord.hash()) + looptri_index;
- normal_tri_v3(r_normals[i], v0_pos, v1_pos, v2_pos);
- r_rotations[i] = normal_to_euler_rotation(r_normals[i]);
+ ids[i] = (int)(bary_coord.hash()) + looptri_index;
+ normal_tri_v3(normals[i], v0_pos, v1_pos, v2_pos);
+ rotations[i] = normal_to_euler_rotation(normals[i]);
}
+
+ id_attribute.apply_span_and_save();
+ normal_attribute.apply_span_and_save();
+ rotation_attribute.apply_span_and_save();
+}
+
+BLI_NOINLINE static void add_remaining_point_attributes(const MeshComponent &mesh_component,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ interpolate_existing_attributes(mesh_component, component, bary_coords, looptri_indices);
+ compute_special_attributes(
+ *mesh_component.get_for_read(), component, bary_coords, looptri_indices);
}
static void sample_mesh_surface_with_minimum_distance(const Mesh &mesh,
@@ -315,11 +458,6 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
break;
}
const int tot_points = positions.size();
- Array<float3> normals(tot_points);
- Array<int> stable_ids(tot_points);
- Array<float3> rotations(tot_points);
- compute_remaining_point_data(
- *mesh_in, bary_coords, looptri_indices, normals, stable_ids, rotations);
PointCloud *pointcloud = BKE_pointcloud_new_nomain(tot_points);
memcpy(pointcloud->co, positions.data(), sizeof(float3) * tot_points);
@@ -332,29 +470,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
geometry_set_out.get_component_for_write<PointCloudComponent>();
point_component.replace(pointcloud);
- {
- OutputAttributePtr stable_id_attribute = point_component.attribute_try_get_for_output(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
- MutableSpan<int> stable_ids_span = stable_id_attribute->get_span<int>();
- stable_ids_span.copy_from(stable_ids);
- stable_id_attribute.apply_span_and_save();
- }
-
- {
- OutputAttributePtr normals_attribute = point_component.attribute_try_get_for_output(
- "normal", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- MutableSpan<float3> normals_span = normals_attribute->get_span<float3>();
- normals_span.copy_from(normals);
- normals_attribute.apply_span_and_save();
- }
-
- {
- OutputAttributePtr rotations_attribute = point_component.attribute_try_get_for_output(
- "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- MutableSpan<float3> rotations_span = rotations_attribute->get_span<float3>();
- rotations_span.copy_from(rotations);
- rotations_attribute.apply_span_and_save();
- }
+ add_remaining_point_attributes(mesh_component, point_component, bary_coords, looptri_indices);
params.set_output("Geometry", std::move(geometry_set_out));
}
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index 2e4196af156..33192648d93 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -19,6 +19,7 @@
#include "FN_multi_function_network_evaluation.hh"
#include "BLI_color.hh"
+#include "BLI_float2.hh"
#include "BLI_float3.hh"
namespace blender::nodes {
@@ -191,27 +192,57 @@ static void add_implicit_conversion(DataTypeConversions &conversions,
static DataTypeConversions create_implicit_conversions()
{
DataTypeConversions conversions;
- add_implicit_conversion<float, int32_t>(conversions);
+ add_implicit_conversion<float, float2>(conversions);
add_implicit_conversion<float, float3>(conversions);
- add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<float, int32_t>(conversions);
add_implicit_conversion<float, bool>(conversions);
- add_implicit_conversion<bool, float>(conversions);
- add_implicit_conversion<float3, float>(
- conversions, "Vector Length", [](float3 a) { return a.length(); });
- add_implicit_conversion<int32_t, float3>(
- conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
- add_implicit_conversion<float3, Color4f>(
- conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
- add_implicit_conversion<Color4f, float3>(
- conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
add_implicit_conversion<float, Color4f>(
conversions, "float to Color4f", [](float a) { return Color4f(a, a, a, 1.0f); });
- add_implicit_conversion<Color4f, float>(
- conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
+
+ add_implicit_conversion<float2, float3>(conversions);
+ add_implicit_conversion<float2, float>(
+ conversions, "float2 to float", [](float2 a) { return a.length(); });
+ add_implicit_conversion<float2, int32_t>(
+ conversions, "float2 to int32_t", [](float2 a) { return (int32_t)a.length(); });
+ add_implicit_conversion<float2, bool>(
+ conversions, "float2 to bool", [](float2 a) { return a.length_squared() == 0.0f; });
+ add_implicit_conversion<float2, Color4f>(
+ conversions, "float2 to Color4f", [](float2 a) { return Color4f(a.x, a.y, 0.0f, 1.0f); });
+
add_implicit_conversion<float3, bool>(
conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; });
+ add_implicit_conversion<float3, float>(
+ conversions, "Vector Length", [](float3 a) { return a.length(); });
+ add_implicit_conversion<float3, int32_t>(
+ conversions, "float3 to int32_t", [](float3 a) { return (int)a.length(); });
+ add_implicit_conversion<float3, float2>(conversions);
+ add_implicit_conversion<float3, Color4f>(
+ conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
+
+ add_implicit_conversion<int32_t, bool>(conversions);
+ add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<int32_t, float2>(
+ conversions, "int32 to float2", [](int32_t a) { return float2((float)a); });
+ add_implicit_conversion<int32_t, float3>(
+ conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
+
+ add_implicit_conversion<bool, float>(conversions);
+ add_implicit_conversion<bool, int32_t>(conversions);
+ add_implicit_conversion<bool, float2>(
+ conversions, "boolean to float2", [](bool a) { return (a) ? float2(1.0f) : float2(0.0f); });
add_implicit_conversion<bool, float3>(
conversions, "boolean to float3", [](bool a) { return (a) ? float3(1.0f) : float3(0.0f); });
+ add_implicit_conversion<bool, Color4f>(conversions, "boolean to Color4f", [](bool a) {
+ return (a) ? Color4f(1.0f, 1.0f, 1.0f, 1.0f) : Color4f(0.0f, 0.0f, 0.0f, 1.0f);
+ });
+
+ add_implicit_conversion<Color4f, float>(
+ conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
+ add_implicit_conversion<Color4f, float2>(
+ conversions, "Color4f to float2", [](Color4f a) { return float2(a.r, a.g); });
+ add_implicit_conversion<Color4f, float3>(
+ conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
+
return conversions;
}
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 38122c45ef1..22c7a394906 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1079,7 +1079,12 @@ PyDoc_STRVAR(
" :arg cage: Get the mesh as a deformed cage.\n"
" :type cage: boolean\n"
" :arg face_normals: Calculate face normals.\n"
- " :type face_normals: boolean\n");
+ " :type face_normals: boolean\n"
+ "\n"
+ " .. deprecated:: 2.93\n"
+ "\n"
+ " The deform parameter is deprecated, assumed to be True, and will be removed in version "
+ "3.0.\n");
static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject *kw)
{
static const char *kwlist[] = {"object", "depsgraph", "deform", "cage", "face_normals", NULL};
@@ -1120,45 +1125,36 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
return NULL;
}
+ if (use_deform == false) {
+ PyErr_WarnEx(PyExc_FutureWarning,
+ "from_object(...): the deform parameter is deprecated, assumed to be True, and "
+ "will be removed in version 3.0",
+ 1);
+ }
+
const bool use_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
scene_eval = DEG_get_evaluated_scene(depsgraph);
ob_eval = DEG_get_evaluated_object(depsgraph, ob);
bool need_free = false;
/* Write the display mesh into the dummy mesh */
- if (use_deform) {
- if (use_render) {
- if (use_cage) {
- PyErr_SetString(PyExc_ValueError,
- "from_object(...): cage arg is unsupported when dependency graph "
- "evaluation mode is RENDER");
- return NULL;
- }
-
- me_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true);
- need_free = true;
- }
- else {
- if (use_cage) {
- me_eval = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &data_masks);
- }
- else {
- me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &data_masks);
- }
- }
- }
- else {
- /* !use_deform */
+ if (use_render) {
if (use_cage) {
PyErr_SetString(PyExc_ValueError,
- "from_object(...): cage arg is unsupported when deform=False");
+ "from_object(...): cage arg is unsupported when dependency graph "
+ "evaluation mode is RENDER");
return NULL;
}
- if (use_render) {
- me_eval = mesh_create_eval_no_deform_render(depsgraph, scene_eval, ob, &data_masks);
+
+ me_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true);
+ need_free = true;
+ }
+ else {
+ if (use_cage) {
+ me_eval = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &data_masks);
}
else {
- me_eval = mesh_create_eval_no_deform(depsgraph, scene_eval, ob, &data_masks);
+ me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &data_masks);
}
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a2125a5dff9..2242cecab20 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -8737,15 +8737,17 @@ void pyrna_free_types(void)
RNA_PROP_END;
}
-/* Note! MemLeak XXX
+/**
+ * \warning memory leak!
*
* There is currently a bug where moving the registration of a Python class does
- * not properly manage reference-counts from the Python class. As the srna owns
+ * not properly manage reference-counts from the Python class. As the `srna` owns
* the Python class this should not be so tricky, but changing the references as
* you'd expect when changing ownership crashes blender on exit so I had to comment out
- * the decref. This is not so bad because the leak only happens when re-registering (hold F8)
+ * the #Py_DECREF. This is not so bad because the leak only happens when re-registering
+ * (continuously running `SCRIPT_OT_reload`).
* - Should still be fixed - Campbell
- * */
+ */
PyDoc_STRVAR(pyrna_register_class_doc,
".. method:: register_class(cls)\n"
"\n"
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.h b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
index 70ddae4d724..cf1a7628267 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_api.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
@@ -301,7 +301,7 @@ void WM_gizmomap_draw(struct wmGizmoMap *gzmap,
void WM_gizmomap_add_handlers(struct ARegion *region, struct wmGizmoMap *gzmap);
bool WM_gizmomap_select_all(struct bContext *C, struct wmGizmoMap *gzmap, const int action);
bool WM_gizmomap_cursor_set(const struct wmGizmoMap *gzmap, struct wmWindow *win);
-void WM_gizmomap_message_subscribe(struct bContext *C,
+void WM_gizmomap_message_subscribe(const struct bContext *C,
struct wmGizmoMap *gzmap,
struct ARegion *region,
struct wmMsgBus *mbus);
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 479768c3536..12c6eb46c12 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -1156,7 +1156,7 @@ ListBase *wm_gizmomap_groups_get(wmGizmoMap *gzmap)
return &gzmap->groups;
}
-void WM_gizmomap_message_subscribe(bContext *C,
+void WM_gizmomap_message_subscribe(const bContext *C,
wmGizmoMap *gzmap,
ARegion *region,
struct wmMsgBus *mbus)
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index d50516dfab2..e32552063af 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -246,8 +246,7 @@ void WM_cursor_wait(bool val)
void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
{
/* Only grab cursor when not running debug.
- * It helps not to get a stuck WM when hitting a breakpoint
- * */
+ * It helps not to get a stuck WM when hitting a break-point. */
GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
GHOST_TAxisFlag mode_axis = GHOST_kAxisX | GHOST_kGrabAxisY;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 859336d0338..d08051dd5fb 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -543,13 +543,31 @@ void wm_event_do_notifiers(bContext *C)
ED_screen_do_listen(C, note);
LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
- ED_region_do_listen(win, NULL, region, note, scene);
+ wmRegionListenerParams region_params = {
+ .area = NULL,
+ .region = region,
+ .scene = scene,
+ .notifier = note,
+ };
+ ED_region_do_listen(&region_params);
}
ED_screen_areas_iter (win, screen, area) {
- ED_area_do_listen(win, area, note, scene);
+ wmSpaceTypeListenerParams area_params = {
+ .window = win,
+ .area = area,
+ .notifier = note,
+ .scene = scene,
+ };
+ ED_area_do_listen(&area_params);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- ED_region_do_listen(win, area, region, note, scene);
+ wmRegionListenerParams region_params = {
+ .area = area,
+ .region = region,
+ .scene = scene,
+ .notifier = note,
+ };
+ ED_region_do_listen(&region_params);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index 4c4fd2b1a8e..0e57a92b685 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -424,9 +424,8 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
wm_event_free_handler(&handler->head);
}
- /* if operator is blocking, grab cursor
- * This may end up grabbing twice, but we don't care.
- * */
+ /* If operator is blocking, grab cursor.
+ * This may end up grabbing twice, but we don't care. */
if (op->opm->type->flag & OPTYPE_BLOCKING) {
int bounds[4] = {-1, -1, -1, -1};
int wrap = WM_CURSOR_WRAP_NONE;