Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Sun, 9 Apr 2017 06:09:12 +0000 (16:09 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 9 Apr 2017 06:09:12 +0000 (16:09 +1000)
14 files changed:
build_files/buildbot/config/blender_linux.cmake
build_files/cmake/Modules/FindOpenImageIO.cmake
build_files/cmake/Modules/GTestTesting.cmake
intern/cycles/device/device_cuda.cpp
intern/cycles/device/opencl/opencl_split.cpp
intern/cycles/kernel/kernel_compat_cpu.h
intern/cycles/kernel/kernel_compat_cuda.h
intern/cycles/util/util_types.h
intern/libmv/libmv/multiview/homography.cc
release/scripts/modules/bpy_extras/keyconfig_utils.py
source/blender/blenkernel/intern/idprop.c
source/blender/blenlib/BLI_listbase.h
source/blender/blenlib/intern/listbase.c
tests/python/bl_pyapi_mathutils.py

index ed5417c1c6e653e83f96fec3235cce9d9ed8b033..56f18967300ea24b365a8beae566d9b664b5950a 100644 (file)
@@ -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()
index 789097dfd516d363417fcd194ece95f7c2592b97..d59f9cfcdfc932347939d582d4807fecf5650972 100644 (file)
@@ -60,7 +60,7 @@ FIND_FILE(OPENIMAGEIO_IDIFF
   NAMES
     idiff
   HINTS
-    ${OPENIMAGEIO_ROOT_DIR}
+    ${_openimageio_SEARCH_DIRS}
   PATH_SUFFIXES
     bin
 )
index 0732e10133c7643a098a55ae692d3b521ca4b5d9..e688db35ef12be6e9ff58948bad2e8b3431e54eb 100644 (file)
@@ -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}"
index 606494f08eda0deb43edad6c360ffc7bf304e0d4..4c1a49878f5d80dcc5d20e96b4fa8d1b22c56e5b 100644 (file)
@@ -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);
index 579dbc84f53e1729e181d9acf9fd9a3a2a827d6d..b8df57ec7b91dc6a7810aa86cd47683f6328be3e 100644 (file)
@@ -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. */
index ae7c9b836c4ea5f557eb50abe098500b88d731b9..cad5f4d295938884fc71014330cb2099911748b2 100644 (file)
@@ -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);
                }
        }
 
index 39e98c7dda61739e8c9ad260dfb498ada12796a9..c375d17a95f0bb7db6afb53b9eb57f020c97d454 100644 (file)
@@ -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 */
 
index bf4a134b9982dc66e92e2a91b326c79245daafde..aa22f6a2c57cc37c231d58ddc04460d38c70a54f 100644 (file)
@@ -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
index ce533a3ead21d635655c40f2b4191f9d324ddb17..69177743f94885861c8aff9691142735dd1500b2 100644 (file)
@@ -209,6 +209,8 @@ class HomographySymmetricGeometricCostFunctor {
     return true;
   }
 
+  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
   const Vec2 x_;
   const Vec2 y_;
 };
index 6ecdd0c5e139d691c37d5eb3f06ac4ff1738a2fa..3203bc41b760d3cfb23a3ca579ac08f151c7ddcd 100644 (file)
@@ -140,6 +140,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
 
index 65d3f9e93fce900dc8aa5eb46a1ac30d11be25ab..769a14607003a4691a081952876102f5b7973d28 100644 (file)
@@ -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);
        }
index 4ec222c073e29ab376f0479ff6810c277b357532..5f57f46066f7bae1822ed4f71a82956be954e157 100644 (file)
@@ -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();
index 3bf0dfa09faff55f852684f8c6c986addac22a27..abc4a77332823596b741b4c24901c6d953d447f7 100644 (file)
@@ -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).
index 7761b6cb7b1532f992da4322a11eb3ad07f2524e..9ca0376192aa71594266c9ebe9a8e94b0a4a96fe 100644 (file)
@@ -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)