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:
authorCampbell Barton <ideasman42@gmail.com>2017-04-09 09:09:12 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-04-09 09:09:12 +0300
commitc800ee6bfe602d1cdfafc042228add3692bdb12e (patch)
treea02dad89cb052cdd388791509696e6bbf94cf2ae
parent79e862ad6b416968f3e0afa7a18f98ab11a4db03 (diff)
parent162e184ffd0f2e5f1584b95339df6cb3c429f017 (diff)
Merge branch 'master' into blender2.8
-rw-r--r--build_files/buildbot/config/blender_linux.cmake5
-rw-r--r--build_files/cmake/Modules/FindOpenImageIO.cmake2
-rw-r--r--build_files/cmake/Modules/GTestTesting.cmake3
-rw-r--r--intern/cycles/device/device_cuda.cpp2
-rw-r--r--intern/cycles/device/opencl/opencl_split.cpp2
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h329
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h1
-rw-r--r--intern/cycles/util/util_types.h2
-rw-r--r--intern/libmv/libmv/multiview/homography.cc2
-rw-r--r--release/scripts/modules/bpy_extras/keyconfig_utils.py72
-rw-r--r--source/blender/blenkernel/intern/idprop.c29
-rw-r--r--source/blender/blenlib/BLI_listbase.h1
-rw-r--r--source/blender/blenlib/intern/listbase.c34
-rw-r--r--tests/python/bl_pyapi_mathutils.py9
14 files changed, 312 insertions, 181 deletions
diff --git a/build_files/buildbot/config/blender_linux.cmake b/build_files/buildbot/config/blender_linux.cmake
index ed5417c1c6e..56f18967300 100644
--- a/build_files/buildbot/config/blender_linux.cmake
+++ b/build_files/buildbot/config/blender_linux.cmake
@@ -94,6 +94,10 @@ set(OPENCOLORIO_OPENCOLORIO_LIBRARY "${OPENCOLORIO_ROOT_DIR}/lib/libOpenColorIO.
set(OPENCOLORIO_TINYXML_LIBRARY "${OPENCOLORIO_ROOT_DIR}/lib/libtinyxml.a" CACHE STRING "" FORCE)
set(OPENCOLORIO_YAML-CPP_LIBRARY "${OPENCOLORIO_ROOT_DIR}/lib/libyaml-cpp.a" CACHE STRING "" FORCE)
+# Freetype
+set(FREETYPE_INCLUDE_DIRS "/usr/include/freetype2" CACHE STRING "" FORCE)
+set(FREETYPE_LIBRARY "/usr/lib${MULTILIB}/libfreetype.a" CACHE STRING "" FORCE)
+
# OpenImageIO
if(GLIBC EQUAL "2.19")
set(OPENIMAGEIO_LIBRARY
@@ -102,6 +106,7 @@ if(GLIBC EQUAL "2.19")
/usr/lib${MULTILIB}/libwebp.a
/usr/lib${MULTILIB}/liblzma.a
/usr/lib${MULTILIB}/libjbig.a
+ ${FREETYPE_LIBRARY}
CACHE STRING "" FORCE
)
endif()
diff --git a/build_files/cmake/Modules/FindOpenImageIO.cmake b/build_files/cmake/Modules/FindOpenImageIO.cmake
index 789097dfd51..d59f9cfcdfc 100644
--- a/build_files/cmake/Modules/FindOpenImageIO.cmake
+++ b/build_files/cmake/Modules/FindOpenImageIO.cmake
@@ -60,7 +60,7 @@ FIND_FILE(OPENIMAGEIO_IDIFF
NAMES
idiff
HINTS
- ${OPENIMAGEIO_ROOT_DIR}
+ ${_openimageio_SEARCH_DIRS}
PATH_SUFFIXES
bin
)
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake
index 0732e10133c..e688db35ef1 100644
--- a/build_files/cmake/Modules/GTestTesting.cmake
+++ b/build_files/cmake/Modules/GTestTesting.cmake
@@ -39,6 +39,9 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
${PTHREADS_LIBRARIES}
extern_glog
extern_gflags)
+ if(WITH_OPENMP_STATIC)
+ target_link_libraries(${NAME}_test ${OpenMP_LIBRARIES})
+ endif()
set_target_properties(${NAME}_test PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 606494f08ed..4c1a49878f5 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1613,7 +1613,7 @@ int2 CUDASplitKernel::split_kernel_local_size()
return make_int2(32, 1);
}
-int2 CUDASplitKernel::split_kernel_global_size(device_memory& /*kg*/, device_memory& /*data*/, DeviceTask */*task*/)
+int2 CUDASplitKernel::split_kernel_global_size(device_memory& /*kg*/, device_memory& /*data*/, DeviceTask * /*task*/)
{
/* TODO(mai): implement something here to detect ideal work size */
return make_int2(256, 256);
diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp
index 579dbc84f53..b8df57ec7b9 100644
--- a/intern/cycles/device/opencl/opencl_split.cpp
+++ b/intern/cycles/device/opencl/opencl_split.cpp
@@ -340,7 +340,7 @@ public:
return make_int2(64, 1);
}
- virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask */*task*/)
+ virtual int2 split_kernel_global_size(device_memory& kg, device_memory& data, DeviceTask * /*task*/)
{
cl_device_type type = OpenCLInfo::get_device_type(device->cdDevice);
/* Use small global size on CPU devices as it seems to be much faster. */
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index ae7c9b836c4..cad5f4d2959 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -316,184 +316,203 @@ template<typename T> struct texture_image {
return interp_3d_ex(x, y, z, interpolation);
}
- ccl_always_inline float4 interp_3d_ex(float x, float y, float z,
- int interpolation = INTERPOLATION_LINEAR)
+ ccl_always_inline float4 interp_3d_ex_closest(float x, float y, float z)
{
- if(UNLIKELY(!data))
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
- int ix, iy, iz, nix, niy, niz;
-
- if(interpolation == INTERPOLATION_CLOSEST) {
- frac(x*(float)width, &ix);
- frac(y*(float)height, &iy);
- frac(z*(float)depth, &iz);
-
- switch(extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- iz = wrap_periodic(iz, depth);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- /* Fall through. */
- case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
- break;
- default:
- kernel_assert(0);
+ int ix, iy, iz;
+ frac(x*(float)width, &ix);
+ frac(y*(float)height, &iy);
+ frac(z*(float)depth, &iz);
+
+ switch(extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+ break;
+ case EXTENSION_CLIP:
+ if(x < 0.0f || y < 0.0f || z < 0.0f ||
+ x > 1.0f || y > 1.0f || z > 1.0f)
+ {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- return read(data[ix + iy*width + iz*width*height]);
+ }
+ /* Fall through. */
+ case EXTENSION_EXTEND:
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
- else if(interpolation == INTERPOLATION_LINEAR) {
- float tx = frac(x*(float)width - 0.5f, &ix);
- float ty = frac(y*(float)height - 0.5f, &iy);
- float tz = frac(z*(float)depth - 0.5f, &iz);
- switch(extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- iz = wrap_periodic(iz, depth);
-
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- niz = wrap_periodic(iz+1, depth);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- /* Fall through. */
- case EXTENSION_EXTEND:
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
- niz = wrap_clamp(iz+1, depth);
+ return read(data[ix + iy*width + iz*width*height]);
+ }
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
- break;
- default:
- kernel_assert(0);
+ ccl_always_inline float4 interp_3d_ex_linear(float x, float y, float z)
+ {
+ int ix, iy, iz;
+ int nix, niy, niz;
+
+ float tx = frac(x*(float)width - 0.5f, &ix);
+ float ty = frac(y*(float)height - 0.5f, &iy);
+ float tz = frac(z*(float)depth - 0.5f, &iz);
+
+ switch(extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ niz = wrap_periodic(iz+1, depth);
+ break;
+ case EXTENSION_CLIP:
+ if(x < 0.0f || y < 0.0f || z < 0.0f ||
+ x > 1.0f || y > 1.0f || z > 1.0f)
+ {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- float4 r;
-
- r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + iz*width*height]);
- r += (1.0f - tz)*(1.0f - ty)*tx*read(data[nix + iy*width + iz*width*height]);
- r += (1.0f - tz)*ty*(1.0f - tx)*read(data[ix + niy*width + iz*width*height]);
- r += (1.0f - tz)*ty*tx*read(data[nix + niy*width + iz*width*height]);
-
- r += tz*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + niz*width*height]);
- r += tz*(1.0f - ty)*tx*read(data[nix + iy*width + niz*width*height]);
- r += tz*ty*(1.0f - tx)*read(data[ix + niy*width + niz*width*height]);
- r += tz*ty*tx*read(data[nix + niy*width + niz*width*height]);
-
- return r;
+ }
+ /* Fall through. */
+ case EXTENSION_EXTEND:
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ niz = wrap_clamp(iz+1, depth);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
- else {
- /* Tricubic b-spline interpolation. */
- const float tx = frac(x*(float)width - 0.5f, &ix);
- const float ty = frac(y*(float)height - 0.5f, &iy);
- const float tz = frac(z*(float)depth - 0.5f, &iz);
- int pix, piy, piz, nnix, nniy, nniz;
-
- switch(extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- iz = wrap_periodic(iz, depth);
- pix = wrap_periodic(ix-1, width);
- piy = wrap_periodic(iy-1, height);
- piz = wrap_periodic(iz-1, depth);
+ float4 r;
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- niz = wrap_periodic(iz+1, depth);
-
- nnix = wrap_periodic(ix+2, width);
- nniy = wrap_periodic(iy+2, height);
- nniz = wrap_periodic(iz+2, depth);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || z < 0.0f ||
- x > 1.0f || y > 1.0f || z > 1.0f)
- {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- /* Fall through. */
- case EXTENSION_EXTEND:
- pix = wrap_clamp(ix-1, width);
- piy = wrap_clamp(iy-1, height);
- piz = wrap_clamp(iz-1, depth);
+ r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + iz*width*height]);
+ r += (1.0f - tz)*(1.0f - ty)*tx*read(data[nix + iy*width + iz*width*height]);
+ r += (1.0f - tz)*ty*(1.0f - tx)*read(data[ix + niy*width + iz*width*height]);
+ r += (1.0f - tz)*ty*tx*read(data[nix + niy*width + iz*width*height]);
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
- niz = wrap_clamp(iz+1, depth);
+ r += tz*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + niz*width*height]);
+ r += tz*(1.0f - ty)*tx*read(data[nix + iy*width + niz*width*height]);
+ r += tz*ty*(1.0f - tx)*read(data[ix + niy*width + niz*width*height]);
+ r += tz*ty*tx*read(data[nix + niy*width + niz*width*height]);
- nnix = wrap_clamp(ix+2, width);
- nniy = wrap_clamp(iy+2, height);
- nniz = wrap_clamp(iz+2, depth);
+ return r;
+ }
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
- break;
- default:
- kernel_assert(0);
+ ccl_never_inline float4 interp_3d_ex_tricubic(float x, float y, float z)
+ {
+ int ix, iy, iz;
+ int nix, niy, niz;
+ /* Tricubic b-spline interpolation. */
+ const float tx = frac(x*(float)width - 0.5f, &ix);
+ const float ty = frac(y*(float)height - 0.5f, &iy);
+ const float tz = frac(z*(float)depth - 0.5f, &iz);
+ int pix, piy, piz, nnix, nniy, nniz;
+
+ switch(extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+
+ pix = wrap_periodic(ix-1, width);
+ piy = wrap_periodic(iy-1, height);
+ piz = wrap_periodic(iz-1, depth);
+
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ niz = wrap_periodic(iz+1, depth);
+
+ nnix = wrap_periodic(ix+2, width);
+ nniy = wrap_periodic(iy+2, height);
+ nniz = wrap_periodic(iz+2, depth);
+ break;
+ case EXTENSION_CLIP:
+ if(x < 0.0f || y < 0.0f || z < 0.0f ||
+ x > 1.0f || y > 1.0f || z > 1.0f)
+ {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- const int xc[4] = {pix, ix, nix, nnix};
- const int yc[4] = {width * piy,
- width * iy,
- width * niy,
- width * nniy};
- const int zc[4] = {width * height * piz,
- width * height * iz,
- width * height * niz,
- width * height * nniz};
- float u[4], v[4], w[4];
+ }
+ /* Fall through. */
+ case EXTENSION_EXTEND:
+ pix = wrap_clamp(ix-1, width);
+ piy = wrap_clamp(iy-1, height);
+ piz = wrap_clamp(iz-1, depth);
+
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ niz = wrap_clamp(iz+1, depth);
+
+ nnix = wrap_clamp(ix+2, width);
+ nniy = wrap_clamp(iy+2, height);
+ nniz = wrap_clamp(iz+2, depth);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
- /* Some helper macro to keep code reasonable size,
- * let compiler to inline all the matrix multiplications.
- */
+ const int xc[4] = {pix, ix, nix, nnix};
+ const int yc[4] = {width * piy,
+ width * iy,
+ width * niy,
+ width * nniy};
+ const int zc[4] = {width * height * piz,
+ width * height * iz,
+ width * height * niz,
+ width * height * nniz};
+ float u[4], v[4], w[4];
+
+ /* Some helper macro to keep code reasonable size,
+ * let compiler to inline all the matrix multiplications.
+ */
#define DATA(x, y, z) (read(data[xc[x] + yc[y] + zc[z]]))
#define COL_TERM(col, row) \
- (v[col] * (u[0] * DATA(0, col, row) + \
- u[1] * DATA(1, col, row) + \
- u[2] * DATA(2, col, row) + \
- u[3] * DATA(3, col, row)))
+ (v[col] * (u[0] * DATA(0, col, row) + \
+ u[1] * DATA(1, col, row) + \
+ u[2] * DATA(2, col, row) + \
+ u[3] * DATA(3, col, row)))
#define ROW_TERM(row) \
- (w[row] * (COL_TERM(0, row) + \
- COL_TERM(1, row) + \
- COL_TERM(2, row) + \
- COL_TERM(3, row)))
+ (w[row] * (COL_TERM(0, row) + \
+ COL_TERM(1, row) + \
+ COL_TERM(2, row) + \
+ COL_TERM(3, row)))
- SET_CUBIC_SPLINE_WEIGHTS(u, tx);
- SET_CUBIC_SPLINE_WEIGHTS(v, ty);
- SET_CUBIC_SPLINE_WEIGHTS(w, tz);
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+ SET_CUBIC_SPLINE_WEIGHTS(w, tz);
- /* Actual interpolation. */
- return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
+ /* Actual interpolation. */
+ return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
#undef COL_TERM
#undef ROW_TERM
#undef DATA
+ }
+
+ ccl_always_inline float4 interp_3d_ex(float x, float y, float z,
+ int interpolation = INTERPOLATION_LINEAR)
+ {
+
+ if(UNLIKELY(!data))
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ switch(interpolation) {
+ case INTERPOLATION_CLOSEST:
+ return interp_3d_ex_closest(x, y, z);
+ case INTERPOLATION_LINEAR:
+ return interp_3d_ex_linear(x, y, z);
+ default:
+ return interp_3d_ex_tricubic(x, y, z);
}
}
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 39e98c7dda6..c375d17a95f 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -33,6 +33,7 @@
#include <cuda.h>
#include <cuda_fp16.h>
#include <float.h>
+#include <stdint.h>
/* Qualifier wrappers for different names on different devices */
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index bf4a134b998..aa22f6a2c57 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -55,6 +55,7 @@
#endif
#define ccl_may_alias
#define ccl_always_inline __forceinline
+#define ccl_never_inline __declspec(noinline)
#define ccl_maybe_unused
#else
@@ -68,6 +69,7 @@
#define ccl_try_align(...) __attribute__((aligned(__VA_ARGS__)))
#define ccl_may_alias __attribute__((__may_alias__))
#define ccl_always_inline __attribute__((always_inline))
+#define ccl_never_inline __attribute__((noinline))
#define ccl_maybe_unused __attribute__((used))
#endif
diff --git a/intern/libmv/libmv/multiview/homography.cc b/intern/libmv/libmv/multiview/homography.cc
index ce533a3ead2..69177743f94 100644
--- a/intern/libmv/libmv/multiview/homography.cc
+++ b/intern/libmv/libmv/multiview/homography.cc
@@ -209,6 +209,8 @@ class HomographySymmetricGeometricCostFunctor {
return true;
}
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
const Vec2 x_;
const Vec2 y_;
};
diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py
index 6ecdd0c5e13..3203bc41b76 100644
--- a/release/scripts/modules/bpy_extras/keyconfig_utils.py
+++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py
@@ -141,6 +141,78 @@ KM_HIERARCHY = [
# -----------------------------------------------------------------------------
+# Add-on helpers to properly (un)register their own keymaps.
+
+# Example of keymaps_description:
+keymaps_description_doc = """
+keymaps_description is a tuple (((keymap_description), (tuple of keymap_item_descriptions))).
+keymap_description is a tuple (name, space_type, region_type, is_modal).
+keymap_item_description is a tuple ({kw_args_for_keymap_new}, (tuple of properties)).
+kw_args_for_keymap_new is a mapping which keywords match parameters of keymap.new() function.
+tuple of properties is a tuple of pairs (prop_name, prop_value) (properties being those of called operator).
+
+Example:
+
+KEYMAPS = (
+ # First, keymap identifiers (last bool is True for modal km).
+ (('Sequencer', 'SEQUENCE_EDITOR', 'WINDOW', False), (
+ # Then a tuple of keymap items, defined by a dict of kwargs for the km new func, and a tuple of tuples (name, val)
+ # for ops properties, if needing non-default values.
+ ({"idname": export_strips.SEQExportStrip.bl_idname, "type": 'P', "value": 'PRESS', "shift": True, "ctrl": True},
+ ()),
+ )),
+)
+"""
+
+
+def addon_keymap_register(wm, keymaps_description):
+ """
+ Register a set of keymaps for addons.
+
+ """ + keymaps_description_doc
+ kconf = wm.keyconfigs.addon
+ if not kconf:
+ return # happens in background mode...
+ for km_info, km_items in keymaps_description:
+ km_name, km_sptype, km_regtype, km_ismodal = km_info
+ kmap = [k for k in kconf.keymaps
+ if k.name == km_name and k.region_type == km_regtype and
+ k.space_type == km_sptype and k.is_modal == km_ismodal]
+ if kmap:
+ kmap = kmap[0]
+ else:
+ kmap = kconf.keymaps.new(km_name, region_type=km_regtype, space_type=km_sptype, modal=km_ismodal)
+ for kmi_kwargs, props in km_items:
+ kmi = kmap.keymap_items.new(**kmi_kwargs)
+ kmi.active = True
+ for prop, val in props:
+ setattr(kmi.properties, prop, val)
+
+
+def addon_keymap_unregister(wm, keymaps_description):
+ """
+ Unregister a set of keymaps for addons.
+
+ """ + keymaps_description_doc
+ # NOTE: We must also clean up user keyconfig, else, if user has customized one of add-on's shortcut, this
+ # customization remains in memory, and comes back when re-enabling the addon, causing a segfault... :/
+ kconfs = wm.keyconfigs
+ for kconf in (kconfs.user, kconfs.addon):
+ for km_info, km_items in keymaps_description:
+ km_name, km_sptype, km_regtype, km_ismodal = km_info
+ kmaps = (k for k in kconf.keymaps
+ if k.name == km_name and k.region_type == km_regtype and
+ k.space_type == km_sptype and k.is_modal == km_ismodal)
+ for kmap in kmaps:
+ for kmi_kwargs, props in km_items:
+ idname = kmi_kwargs["idname"]
+ for kmi in kmap.keymap_items:
+ if kmi.idname == idname:
+ kmap.keymap_items.remove(kmi)
+ # NOTE: We won't remove addons keymaps themselves, other addons might also use them!
+
+
+# -----------------------------------------------------------------------------
# Utility functions
def km_exists_in(km, export_keymaps):
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 65d3f9e93fc..769a1460700 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -504,14 +504,9 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src)
break;
default:
{
- IDProperty *tmp = other;
- IDProperty *copy = IDP_CopyProperty(prop);
-
- BLI_insertlinkafter(&dest->data.group, other, copy);
- BLI_remlink(&dest->data.group, tmp);
-
- IDP_FreeProperty(tmp);
- MEM_freeN(tmp);
+ BLI_insertlinkreplace(&dest->data.group, other, IDP_CopyProperty(prop));
+ IDP_FreeProperty(other);
+ MEM_freeN(other);
break;
}
}
@@ -531,11 +526,9 @@ void IDP_SyncGroupTypes(IDProperty *dst, const IDProperty *src, const bool do_ar
if ((prop_dst->type != prop_src->type || prop_dst->subtype != prop_src->subtype) ||
(do_arraylen && ELEM(prop_dst->type, IDP_ARRAY, IDP_IDPARRAY) && (prop_src->len != prop_dst->len)))
{
- IDP_FreeFromGroup(dst, prop_dst);
- prop_dst = IDP_CopyProperty(prop_src);
-
- dst->len++;
- BLI_insertlinkbefore(&dst->data.group, prop_dst_next, prop_dst);
+ BLI_insertlinkreplace(&dst->data.group, prop_dst, IDP_CopyProperty(prop_src));
+ IDP_FreeProperty(prop_dst);
+ MEM_freeN(prop_dst);
}
else if (prop_dst->type == IDP_GROUP) {
IDP_SyncGroupTypes(prop_dst, prop_src, do_arraylen);
@@ -560,11 +553,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src)
for (prop = src->data.group.first; prop; prop = prop->next) {
for (loop = dest->data.group.first; loop; loop = loop->next) {
if (STREQ(loop->name, prop->name)) {
- IDProperty *copy = IDP_CopyProperty(prop);
-
- BLI_insertlinkafter(&dest->data.group, loop, copy);
-
- BLI_remlink(&dest->data.group, loop);
+ BLI_insertlinkreplace(&dest->data.group, loop, IDP_CopyProperty(prop));
IDP_FreeProperty(loop);
MEM_freeN(loop);
break;
@@ -591,9 +580,7 @@ void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop
BLI_assert(prop_exist == IDP_GetPropertyFromGroup(group, prop->name));
if ((prop_exist = IDP_GetPropertyFromGroup(group, prop->name))) {
- BLI_insertlinkafter(&group->data.group, prop_exist, prop);
-
- BLI_remlink(&group->data.group, prop_exist);
+ BLI_insertlinkreplace(&group->data.group, prop_exist, prop);
IDP_FreeProperty(prop_exist);
MEM_freeN(prop_exist);
}
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 4ec222c073e..5f57f46066f 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -67,6 +67,7 @@ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1);
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1);
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1);
+void BLI_insertlinkreplace(ListBase *listbase, void *v_l_src, void *v_l_dst) ATTR_NONNULL(1, 2, 3);
void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2);
void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1, 2);
bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL();
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 3bf0dfa09fa..abc4a773328 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -370,6 +370,40 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
}
}
+
+/**
+ * Insert a link in place of another, without changing it's position in the list.
+ *
+ * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`.
+ * - `vreplacelink` *must* be in the list.
+ * - `vnewlink` *must not* be in the list.
+ */
+void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
+{
+ Link *l_old = vreplacelink;
+ Link *l_new = vnewlink;
+
+ /* update adjacent links */
+ if (l_old->next != NULL) {
+ l_old->next->prev = l_new;
+ }
+ if (l_old->prev != NULL) {
+ l_old->prev->next = l_new;
+ }
+
+ /* set direct links */
+ l_new->next = l_old->next;
+ l_new->prev = l_old->prev;
+
+ /* update list */
+ if (listbase->first == l_old) {
+ listbase->first = l_new;
+ }
+ if (listbase->last == l_old) {
+ listbase->last = l_new;
+ }
+}
+
/**
* Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move
* item if new position would exceed list (could optionally move to head/tail).
diff --git a/tests/python/bl_pyapi_mathutils.py b/tests/python/bl_pyapi_mathutils.py
index 7761b6cb7b1..9ca0376192a 100644
--- a/tests/python/bl_pyapi_mathutils.py
+++ b/tests/python/bl_pyapi_mathutils.py
@@ -260,6 +260,11 @@ class KDTreeTesting(unittest.TestCase):
k.balance()
return k
+ def assertAlmostEqualVector(self, first, second, places=7, msg=None, delta=None):
+ self.assertAlmostEqual(first[0], second[0], places=places, msg=msg, delta=delta)
+ self.assertAlmostEqual(first[1], second[1], places=places, msg=msg, delta=delta)
+ self.assertAlmostEqual(first[2], second[2], places=places, msg=msg, delta=delta)
+
def test_kdtree_single(self):
co = (0,) * 3
index = 2
@@ -360,12 +365,12 @@ class KDTreeTesting(unittest.TestCase):
ret_regular = k_odd.find(co)
self.assertEqual(ret_regular[1] % 2, 1)
ret_filter = k_all.find(co, lambda i: (i % 2) == 1)
- self.assertEqual(ret_regular, ret_filter)
+ self.assertAlmostEqualVector(ret_regular, ret_filter)
ret_regular = k_evn.find(co)
self.assertEqual(ret_regular[1] % 2, 0)
ret_filter = k_all.find(co, lambda i: (i % 2) == 0)
- self.assertEqual(ret_regular, ret_filter)
+ self.assertAlmostEqualVector(ret_regular, ret_filter)
# filter out all values (search odd tree for even values and the reverse)