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--CMakeLists.txt2
-rw-r--r--build_files/build_environment/cmake/options.cmake4
-rw-r--r--doc/python_api/sphinx_doc_gen.py3
-rw-r--r--intern/cycles/kernel/bvh/bvh_nodes.h2
-rw-r--r--intern/cycles/kernel/kernel_shadow.h2
-rw-r--r--intern/cycles/kernel/split/kernel_shadow_blocked_dl.h8
-rw-r--r--intern/cycles/render/image.cpp8
-rw-r--r--intern/cycles/util/util_math.h2
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py19
-rw-r--r--release/scripts/modules/rna_info.py35
-rw-r--r--source/blender/blenkernel/intern/mesh.c10
-rw-r--r--source/blender/blenkernel/intern/sequencer.c3
-rw-r--r--source/blender/blenlib/BLI_dial.h4
-rw-r--r--source/blender/blenlib/BLI_kdtree.h4
-rw-r--r--source/blender/blenlib/intern/BLI_dial.c4
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c120
-rw-r--r--source/blender/blenlib/intern/math_matrix.c3
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c112
-rw-r--r--source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp77
-rw-r--r--source/blender/compositor/operations/COM_MovieClipAttributeOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.cpp4
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c4
-rw-r--r--source/blender/editors/space_action/action_select.c2
-rw-r--r--source/blender/editors/transform/transform.c42
-rw-r--r--source/blender/imbuf/intern/colormanagement.c17
-rw-r--r--source/blender/makesrna/intern/rna_wm.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c4
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c2
29 files changed, 348 insertions, 165 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d520ee023f..21f01eac28c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -291,7 +291,7 @@ if(WITH_X11)
endif()
if(UNIX AND NOT APPLE)
- option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" ON)
+ option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON)
else()
# not an option for other OS's
diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake
index 465ca3c034c..6dbf3f46b1a 100644
--- a/build_files/build_environment/cmake/options.cmake
+++ b/build_files/build_environment/cmake/options.cmake
@@ -66,9 +66,9 @@ if(WIN32)
set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "/MT /Zi /O2 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
if(WITH_OPTIMIZED_DEBUG)
- set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
- else()
set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/MTd /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ else()
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
endif()
set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "/MT /O1 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 7b3d05e5a6e..75064f2c5ef 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1013,9 +1013,9 @@ def pymodule2sphinx(basepath, module_name, module, title):
context_type_map = {
"active_base": ("ObjectBase", False),
"active_bone": ("EditBone", False),
+ "active_gpencil_brush": ("GPencilSculptBrush", False),
"active_gpencil_frame": ("GreasePencilLayer", True),
"active_gpencil_layer": ("GPencilLayer", True),
- "active_gpencil_brush": ("GPencilSculptBrush", False),
"active_gpencil_palette": ("GPencilPalette", True),
"active_gpencil_palettecolor": ("GPencilPaletteColor", True),
"active_node": ("Node", False),
@@ -1069,6 +1069,7 @@ context_type_map = {
"selected_bones": ("EditBone", True),
"selected_editable_bases": ("ObjectBase", True),
"selected_editable_bones": ("EditBone", True),
+ "selected_editable_fcurves": ("FCurce", True),
"selected_editable_objects": ("Object", True),
"selected_editable_sequences": ("Sequence", True),
"selected_nodes": ("Node", True),
diff --git a/intern/cycles/kernel/bvh/bvh_nodes.h b/intern/cycles/kernel/bvh/bvh_nodes.h
index 74a9ebf14e4..5f1dd434a44 100644
--- a/intern/cycles/kernel/bvh/bvh_nodes.h
+++ b/intern/cycles/kernel/bvh/bvh_nodes.h
@@ -615,7 +615,7 @@ ccl_device_forceinline int bvh_node_intersect_robust(KernelGlobals *kg,
const float3& P,
const float3& dir,
const ssef& isect_near,
- const ssef& isect_far,
+ const ssef& isect_far,
const ssef& tsplat,
const ssef Psplat[3],
const ssef idirsplat[3],
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index b91aba6e03c..bb6bdc7fbd0 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -204,7 +204,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
}
# ifdef __VOLUME__
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
- /* Apply attenuation from current volume shader/ */
+ /* Apply attenuation from current volume shader. */
kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
}
# endif
diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h
index 50c9acec4ee..19bfee6d039 100644
--- a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h
+++ b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h
@@ -89,10 +89,10 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg)
float3 shadow;
if(!shadow_blocked(kg,
- emission_sd,
- state,
- &ray,
- &shadow))
+ emission_sd,
+ state,
+ &ray,
+ &shadow))
{
/* accumulate */
path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 80ec77f8b4a..bb94b9bb82a 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -522,6 +522,10 @@ bool ImageManager::file_load_image(Image *img,
vector<StorageType> pixels_storage;
StorageType *pixels;
const size_t max_size = max(max(width, height), depth);
+ if(max_size == 0) {
+ /* Don't bother with invalid images. */
+ return false;
+ }
if(texture_limit > 0 && max_size > texture_limit) {
pixels_storage.resize(((size_t)width)*height*depth*4);
pixels = &pixels_storage[0];
@@ -529,6 +533,10 @@ bool ImageManager::file_load_image(Image *img,
else {
pixels = (StorageType*)tex_img.resize(width, height, depth);
}
+ if(pixels == NULL) {
+ /* Could be that we've run out of memory. */
+ return false;
+ }
bool cmyk = false;
const size_t num_pixels = ((size_t)width) * height * depth;
if(in) {
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 348e652eadd..fb04d49bcd9 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -224,7 +224,7 @@ ccl_device_inline bool isfinite_safe(float f)
{
/* By IEEE 754 rule, 2*Inf equals Inf */
unsigned int x = __float_as_uint(f);
- return (f == f) && (x == 0 || x == (1 << 31) || (f != 2.0f*f)) && !((x << 1) > 0xff000000u);
+ return (f == f) && (x == 0 || x == (1u << 31) || (f != 2.0f*f)) && !((x << 1) > 0xff000000u);
}
ccl_device_inline float ensure_finite(float v)
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 966a1fe877c..185a0e73279 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -37,6 +37,7 @@ __all__ = (
"register_module",
"register_manual_map",
"unregister_manual_map",
+ "register_classes_factory",
"register_submodule_factory",
"make_rna_paths",
"manual_map",
@@ -702,6 +703,24 @@ def unregister_module(module, verbose=False):
print("done.\n")
+def register_classes_factory(classes):
+ """
+ Utility function to create register and unregister functions
+ which simply registers and unregisters a sequence of classes.
+ """
+ def register():
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
+
+ def unregister():
+ from bpy.utils import unregister_class
+ for cls in reversed(classes):
+ unregister_class(cls)
+
+ return register, unregister
+
+
def register_submodule_factory(module_name, submodule_names):
"""
Utility function to create register and unregister functions
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index 94f5e9e17bb..03f43486371 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -82,6 +82,32 @@ def float_as_string(f):
return val_str
+def get_py_class_from_rna(rna_type):
+ """ Get's the Python type for a class which isn't necessarily added to ``bpy.types``.
+ """
+ identifier = rna_type.identifier
+ py_class = getattr(bpy.types, identifier, None)
+ if py_class is not None:
+ return py_class
+
+ def subclasses_recurse(cls):
+ for c in cls.__subclasses__():
+ # is_registered
+ if "bl_rna" in cls.__dict__:
+ yield c
+ yield from subclasses_recurse(c)
+
+ while py_class is None:
+ base = rna_type.base
+ if base is None:
+ raise Exception("can't find type")
+ py_class_base = getattr(bpy.types, base.identifier, None)
+ if py_class_base is not None:
+ for cls in subclasses_recurse(py_class_base):
+ if cls.bl_rna.identifier == identifier:
+ return cls
+
+
class InfoStructRNA:
__slots__ = (
"bl_rna",
@@ -146,7 +172,8 @@ class InfoStructRNA:
def _get_py_visible_attrs(self):
attrs = []
- py_class = getattr(bpy.types, self.identifier)
+ py_class = get_py_class_from_rna(self.bl_rna)
+
for attr_str in dir(py_class):
if attr_str.startswith("_"):
continue
@@ -437,7 +464,11 @@ class InfoOperatorRNA:
self.args.append(prop)
def get_location(self):
- op_class = getattr(bpy.types, self.identifier)
+ try:
+ op_class = getattr(bpy.types, self.identifier)
+ except AttributeError:
+ # defined in C.
+ return None, None
op_func = getattr(op_class, "execute", None)
if op_func is None:
op_func = getattr(op_class, "invoke", None)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 1204effffdc..8f41f0611d4 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2112,6 +2112,11 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac
short (*clnors)[2] = NULL;
bool free_polynors = false;
+ /* Note that we enforce computing clnors when the clnor space array is requested by caller here.
+ * However, we obviously only use the autosmooth angle threshold only in case autosmooth is enabled. */
+ const bool use_split_normals = (r_lnors_spacearr != NULL) || ((mesh->flag & ME_AUTOSMOOTH) != 0);
+ const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : (float)M_PI;
+
if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
r_loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
memset(r_loopnors, 0, sizeof(float[3]) * mesh->totloop);
@@ -2140,10 +2145,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac
BKE_mesh_normals_loop_split(
mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly,
- /* Note that we enforce computing clnors when the clnor space array is requested by caller here.
- * However, we obviously only use the autosmooth angle threshold only in case autosmooth is enabled. */
- r_lnors_spacearr != NULL, (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : (float)M_PI,
- r_lnors_spacearr, clnors, NULL);
+ use_split_normals, split_angle, r_lnors_spacearr, clnors, NULL);
if (free_polynors) {
MEM_freeN(polynors);
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 5f58af7e538..4818c7a0217 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -484,9 +484,12 @@ void BKE_sequencer_editing_free(Scene *scene)
static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf)
{
+#if 0
+ /* Bute buffer is supposed to be in sequencer working space already. */
if (ibuf->rect != NULL) {
IMB_colormanagement_assign_rect_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
}
+#endif
if (ibuf->rect_float != NULL) {
IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
}
diff --git a/source/blender/blenlib/BLI_dial.h b/source/blender/blenlib/BLI_dial.h
index ad7680fe03e..71ab57bb61a 100644
--- a/source/blender/blenlib/BLI_dial.h
+++ b/source/blender/blenlib/BLI_dial.h
@@ -52,8 +52,8 @@
typedef struct Dial Dial;
-Dial *BLI_dial_initialize(float start_position[2], float threshold);
+Dial *BLI_dial_initialize(const float start_position[2], float threshold);
-float BLI_dial_angle(Dial *dial, float current_position[2]);
+float BLI_dial_angle(Dial *dial, const float current_position[2]);
#endif /* __BLI_DIAL_H__ */
diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h
index aa54e1c823c..18908f8c551 100644
--- a/source/blender/blenlib/BLI_kdtree.h
+++ b/source/blender/blenlib/BLI_kdtree.h
@@ -66,6 +66,10 @@ void BLI_kdtree_range_search_cb(
const KDTree *tree, const float co[3], float range,
bool (*search_cb)(void *user_data, int index, const float co[3], float dist_sq), void *user_data);
+int BLI_kdtree_calc_duplicates_fast(
+ const KDTree *tree, const float range, bool use_index_order,
+ int *doubles);
+
/* Normal use is deprecated */
/* remove __normal functions when last users drop */
int BLI_kdtree_find_nearest_n__normal(
diff --git a/source/blender/blenlib/intern/BLI_dial.c b/source/blender/blenlib/intern/BLI_dial.c
index cfbb52847fd..89f18fa10b4 100644
--- a/source/blender/blenlib/intern/BLI_dial.c
+++ b/source/blender/blenlib/intern/BLI_dial.c
@@ -46,7 +46,7 @@ struct Dial {
};
-Dial *BLI_dial_initialize(float start_position[2], float threshold)
+Dial *BLI_dial_initialize(const float start_position[2], float threshold)
{
Dial *dial = MEM_callocN(sizeof(Dial), "dial");
@@ -56,7 +56,7 @@ Dial *BLI_dial_initialize(float start_position[2], float threshold)
return dial;
}
-float BLI_dial_angle(Dial *dial, float current_position[2])
+float BLI_dial_angle(Dial *dial, const float current_position[2])
{
float current_direction[2];
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
index a81f9b28b83..84ac339cc4d 100644
--- a/source/blender/blenlib/intern/BLI_kdtree.c
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -674,3 +674,123 @@ finally:
if (stack != defaultstack)
MEM_freeN(stack);
}
+
+/**
+ * Use when we want to loop over nodes ordered by index.
+ * Requires indices to be aligned with nodes.
+ */
+static uint *kdtree_order(const KDTree *tree)
+{
+ const KDTreeNode *nodes = tree->nodes;
+ uint *order = MEM_mallocN(sizeof(uint) * tree->totnode, __func__);
+ for (uint i = 0; i < tree->totnode; i++) {
+ order[nodes[i].index] = i;
+ }
+ return order;
+}
+
+/* -------------------------------------------------------------------- */
+/** \name BLI_kdtree_calc_duplicates_fast
+ * \{ */
+
+struct DeDuplicateParams {
+ /* Static */
+ const KDTreeNode *nodes;
+ float range;
+ float range_sq;
+ int *duplicates;
+ int *duplicates_found;
+
+ /* Per Search */
+ float search_co[3];
+ int search;
+};
+
+static void deduplicate_recursive(const struct DeDuplicateParams *p, uint i)
+{
+ const KDTreeNode *node = &p->nodes[i];
+ if (p->search_co[node->d] + p->range <= node->co[node->d]) {
+ if (node->left != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->left);
+ }
+ }
+ else if (p->search_co[node->d] - p->range >= node->co[node->d]) {
+ if (node->right != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->right);
+ }
+ }
+ else {
+ if ((p->search != node->index) && (p->duplicates[node->index] == -1)) {
+ if (compare_len_squared_v3v3(node->co, p->search_co, p->range_sq)) {
+ p->duplicates[node->index] = (int)p->search;
+ *p->duplicates_found += 1;
+ }
+ }
+ if (node->left != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->left);
+ }
+ if (node->right != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->right);
+ }
+ }
+}
+
+/**
+ * Find duplicate points in \a range.
+ * Favors speed over quality since it doesn't find the best target vertex for merging.
+ * Nodes are looped over, duplicates are added when found.
+ * Nevertheless results are predictable.
+ *
+ * \param range: Coordinates in this range are candidates to be merged.
+ * \param use_index_order: Loop over the coordinates ordered by #KDTreeNode.index
+ * At the expense of some performance, this ensures the layout of the tree doesn't influence
+ * the iteration order.
+ * \param duplicates: An array of int's the length of #KDTree.totnode
+ * Values initialized to -1 are candidates to me merged.
+ * Setting the index to it's own position in the array prevents it from being touched,
+ * although it can still be used as a target.
+ * \returns The numebr of merges found (includes any merges already in the \a duplicates array).
+ *
+ * \note Merging is always a single step (target indices wont be marked for merging).
+ */
+int BLI_kdtree_calc_duplicates_fast(
+ const KDTree *tree, const float range, bool use_index_order,
+ int *duplicates)
+{
+ int found = 0;
+ struct DeDuplicateParams p = {
+ .nodes = tree->nodes,
+ .range = range,
+ .range_sq = range * range,
+ .duplicates = duplicates,
+ .duplicates_found = &found,
+ };
+
+ if (use_index_order) {
+ uint *order = kdtree_order(tree);
+ for (uint i = 0; i < tree->totnode; i++) {
+ const uint node_index = order[i];
+ const int index = (int)i;
+ if (ELEM(duplicates[index], -1, index)) {
+ p.search = index;
+ copy_v3_v3(p.search_co, tree->nodes[node_index].co);
+ deduplicate_recursive(&p, tree->root);
+ }
+ }
+ MEM_freeN(order);
+ }
+ else {
+ for (uint i = 0; i < tree->totnode; i++) {
+ const uint node_index = i;
+ const int index = p.nodes[node_index].index;
+ if (ELEM(duplicates[index], -1, index)) {
+ p.search = index;
+ copy_v3_v3(p.search_co, tree->nodes[node_index].co);
+ deduplicate_recursive(&p, tree->root);
+ }
+ }
+ }
+ return found;
+}
+
+/** \} */
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 33e4dec107f..3559500bf63 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -1728,6 +1728,9 @@ void rotate_m4(float mat[4][4], const char axis, const float angle)
mat[0][col] = temp;
}
break;
+ default:
+ BLI_assert(0);
+ break;
}
}
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index f2f5debe73a..d8e6f250adf 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -30,6 +30,7 @@
#include "BLI_math.h"
#include "BLI_alloca.h"
+#include "BLI_kdtree.h"
#include "BLI_stackdefines.h"
#include "BLI_stack.h"
@@ -277,29 +278,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BMO_mesh_delete_oflag_context(bm, ELE_DEL, DEL_ONLYTAGGED);
}
-static int vergaverco(const void *e1, const void *e2)
-{
- const BMVert *v1 = *(const void **)e1, *v2 = *(const void **)e2;
- float x1 = v1->co[0] + v1->co[1] + v1->co[2];
- float x2 = v2->co[0] + v2->co[1] + v2->co[2];
-
- if (x1 > x2) return 1;
- else if (x1 < x2) return -1;
-
- const int i1 = BM_elem_index_get(v1);
- const int i2 = BM_elem_index_get(v2);
-
- if (i1 > i2) return 1;
- else if (i1 < i2) return -1;
-
- else return 0;
-}
-
-// #define VERT_TESTED 1 // UNUSED
-#define VERT_DOUBLE 2
-#define VERT_TARGET 4
#define VERT_KEEP 8
-// #define VERT_MARK 16 // UNUSED
#define VERT_IN 32
#define EDGE_MARK 1
@@ -591,83 +570,62 @@ static void bmesh_find_doubles_common(
BMesh *bm, BMOperator *op,
BMOperator *optarget, BMOpSlot *optarget_slot)
{
- BMVert **verts;
- int verts_len;
+ const BMOpSlot *slot_verts = BMO_slot_get(op->slots_in, "verts");
+ BMVert * const *verts = (BMVert **)slot_verts->data.buf;
+ const int verts_len = slot_verts->len;
- int i, j, keepvert = 0;
+ bool has_keep_vert = false;
+ bool found_duplicates = false;
const float dist = BMO_slot_float_get(op->slots_in, "dist");
- const float dist_sq = dist * dist;
- const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
/* Test whether keep_verts arg exists and is non-empty */
if (BMO_slot_exists(op->slots_in, "keep_verts")) {
BMOIter oiter;
- keepvert = BMO_iter_new(&oiter, op->slots_in, "keep_verts", BM_VERT) != NULL;
+ has_keep_vert = BMO_iter_new(&oiter, op->slots_in, "keep_verts", BM_VERT) != NULL;
}
- /* get the verts as an array we can sort */
- verts = BMO_slot_as_arrayN(op->slots_in, "verts", &verts_len);
-
- /* Ensure indices are different so we have a predictable order when values match. */
- for (i = 0; i < verts_len; i++) {
- BM_elem_index_set(verts[i], i); /* set_dirty! */
- }
- bm->elem_index_dirty |= BM_VERT;
-
- /* sort by vertex coordinates added together */
- qsort(verts, verts_len, sizeof(BMVert *), vergaverco);
-
/* Flag keep_verts */
- if (keepvert) {
+ if (has_keep_vert) {
BMO_slot_buffer_flag_enable(bm, op->slots_in, "keep_verts", BM_VERT, VERT_KEEP);
}
- for (i = 0; i < verts_len; i++) {
- BMVert *v_check = verts[i];
-
- if (BMO_vert_flag_test(bm, v_check, VERT_DOUBLE | VERT_TARGET)) {
- continue;
+ int *duplicates = MEM_mallocN(sizeof(int) * verts_len, __func__);
+ {
+ KDTree *tree = BLI_kdtree_new(verts_len);
+ for (int i = 0; i < verts_len; i++) {
+ BLI_kdtree_insert(tree, i, verts[i]->co);
+ if (has_keep_vert && BMO_vert_flag_test(bm, verts[i], VERT_KEEP)) {
+ duplicates[i] = i;
+ }
+ else {
+ duplicates[i] = -1;
+ }
}
- for (j = i + 1; j < verts_len; j++) {
- BMVert *v_other = verts[j];
-
- /* a match has already been found, (we could check which is best, for now don't) */
- if (BMO_vert_flag_test(bm, v_other, VERT_DOUBLE | VERT_TARGET)) {
- continue;
- }
+ BLI_kdtree_balance(tree);
+ found_duplicates = BLI_kdtree_calc_duplicates_fast(tree, dist, false, duplicates) != 0;
+ BLI_kdtree_free(tree);
+ }
- /* Compare sort values of the verts using 3x tolerance (allowing for the tolerance
- * on each of the three axes). This avoids the more expensive length comparison
- * for most vertex pairs. */
- if ((v_other->co[0] + v_other->co[1] + v_other->co[2]) -
- (v_check->co[0] + v_check->co[1] + v_check->co[2]) > dist3)
- {
- break;
+ if (found_duplicates) {
+ for (int i = 0; i < verts_len; i++) {
+ BMVert *v_check = verts[i];
+ if (duplicates[i] == -1) {
+ /* nop (others can use as target) */
}
-
- if (keepvert) {
- if (BMO_vert_flag_test(bm, v_other, VERT_KEEP) == BMO_vert_flag_test(bm, v_check, VERT_KEEP))
- continue;
+ else if (duplicates[i] == i) {
+ /* keep (others can use as target) */
}
-
- if (compare_len_squared_v3v3(v_check->co, v_other->co, dist_sq)) {
-
- /* If one vert is marked as keep, make sure it will be the target */
- if (BMO_vert_flag_test(bm, v_other, VERT_KEEP)) {
- SWAP(BMVert *, v_check, v_other);
- }
-
- BMO_vert_flag_enable(bm, v_other, VERT_DOUBLE);
- BMO_vert_flag_enable(bm, v_check, VERT_TARGET);
-
- BMO_slot_map_elem_insert(optarget, optarget_slot, v_other, v_check);
+ else {
+ BMVert *v_other = verts[duplicates[i]];
+ BLI_assert(ELEM(duplicates[duplicates[i]], -1, duplicates[i]));
+ BMO_slot_map_elem_insert(optarget, optarget_slot, v_check, v_other);
}
}
}
- MEM_freeN(verts);
+ MEM_freeN(duplicates);
}
void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)
diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp
index 41f7da7c49f..0c2da8415f8 100644
--- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp
+++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp
@@ -28,55 +28,58 @@ extern "C" {
MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation()
{
this->addOutputSocket(COM_DT_VALUE);
- this->m_valueSet = false;
this->m_framenumber = 0;
this->m_attribute = MCA_X;
this->m_invert = false;
}
-void MovieClipAttributeOperation::executePixelSampled(float output[4],
- float /*x*/, float /*y*/,
- PixelSampler /*sampler*/)
+void MovieClipAttributeOperation::initExecution()
{
- /* TODO(sergey): This code isn't really thread-safe. */
- if (!this->m_valueSet) {
- float loc[2], scale, angle;
- loc[0] = 0.0f;
- loc[1] = 0.0f;
- scale = 1.0f;
- angle = 0.0f;
- if (this->m_clip) {
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_clip, this->m_framenumber);
- BKE_tracking_stabilization_data_get(this->m_clip, clip_framenr, getWidth(), getHeight(), loc, &scale, &angle);
- }
- switch (this->m_attribute) {
- case MCA_SCALE:
- this->m_value = scale;
- break;
- case MCA_ANGLE:
- this->m_value = angle;
- break;
- case MCA_X:
- this->m_value = loc[0];
- break;
- case MCA_Y:
- this->m_value = loc[1];
- break;
+ float loc[2], scale, angle;
+ loc[0] = 0.0f;
+ loc[1] = 0.0f;
+ scale = 1.0f;
+ angle = 0.0f;
+ int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(
+ this->m_clip, this->m_framenumber);
+ BKE_tracking_stabilization_data_get(this->m_clip,
+ clip_framenr,
+ getWidth(), getHeight(),
+ loc, &scale, &angle);
+ switch (this->m_attribute) {
+ case MCA_SCALE:
+ this->m_value = scale;
+ break;
+ case MCA_ANGLE:
+ this->m_value = angle;
+ break;
+ case MCA_X:
+ this->m_value = loc[0];
+ break;
+ case MCA_Y:
+ this->m_value = loc[1];
+ break;
+ }
+ if (this->m_invert) {
+ if (this->m_attribute != MCA_SCALE) {
+ this->m_value = -this->m_value;
}
- if (this->m_invert) {
- if (this->m_attribute != MCA_SCALE) {
- this->m_value = -this->m_value;
- }
- else {
- this->m_value = 1.0f / this->m_value;
- }
+ else {
+ this->m_value = 1.0f / this->m_value;
}
- this->m_valueSet = true;
}
+}
+
+void MovieClipAttributeOperation::executePixelSampled(float output[4],
+ float /*x*/, float /*y*/,
+ PixelSampler /*sampler*/)
+{
output[0] = this->m_value;
}
-void MovieClipAttributeOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+void MovieClipAttributeOperation::determineResolution(
+ unsigned int resolution[2],
+ unsigned int preferredResolution[2])
{
resolution[0] = preferredResolution[0];
resolution[1] = preferredResolution[1];
diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
index 731b9debaf0..659f54c1ca2 100644
--- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
+++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
@@ -39,16 +39,18 @@ class MovieClipAttributeOperation : public NodeOperation {
private:
MovieClip *m_clip;
float m_value;
- bool m_valueSet;
int m_framenumber;
bool m_invert;
MovieClipAttribute m_attribute;
+
public:
/**
* Default constructor
*/
MovieClipAttributeOperation();
-
+
+ void initExecution();
+
/**
* the inner loop of this program
*/
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp
index 117ae743ee7..46e155e43b5 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.cpp
+++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp
@@ -271,9 +271,9 @@ bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, Read
{
rcti newInput;
- newInput.xmax = (input->xmax - m_offsetX) * this->m_relX;
+ newInput.xmax = (input->xmax - m_offsetX) * this->m_relX + 1;
newInput.xmin = (input->xmin - m_offsetX) * this->m_relX;
- newInput.ymax = (input->ymax - m_offsetY) * this->m_relY;
+ newInput.ymax = (input->ymax - m_offsetY) * this->m_relY + 1;
newInput.ymin = (input->ymin - m_offsetY) * this->m_relY;
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index 9227f9b1097..90d44503013 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -252,8 +252,10 @@ bool ED_gplayer_frames_delete(bGPDlayer *gpl)
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
gpfn = gpf->next;
- if (gpf->flag & GP_FRAME_SELECT)
- changed |= BKE_gpencil_layer_delframe(gpl, gpf);
+ if (gpf->flag & GP_FRAME_SELECT) {
+ BKE_gpencil_layer_delframe(gpl, gpf);
+ changed = true;
+ }
}
return changed;
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 4bcc9f7b811..83e2a85db49 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -117,8 +117,8 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t
/* Interpolate all values */
interp_v3_v3v3(&pt->x, &prev->x, &next->x, factor);
- pt->pressure = interpf(prev->pressure, next->pressure, factor);
- pt->strength = interpf(prev->strength, next->strength, factor);
+ pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor);
+ pt->strength = interpf(prev->strength, next->strength, 1.0f - factor);
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
}
}
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 553be0ad290..17edbc6cc1d 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -262,6 +262,7 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
{
/* loop over data selecting */
switch (ale->type) {
+#if 0 /* XXXX: Keyframes are not currently shown here */
case ANIMTYPE_GPDATABLOCK:
{
bGPdata *gpd = ale->data;
@@ -271,6 +272,7 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
}
break;
}
+#endif
case ANIMTYPE_GPLAYER:
ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
break;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index fadc0dc3b60..6a11029d933 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -8401,8 +8401,15 @@ static void initTimeSlide(TransInfo *t)
TransData *td = t->data;
for (i = 0; i < t->total; i++, td++) {
- if (min > *(td->val)) min = *(td->val);
- if (max < *(td->val)) max = *(td->val);
+ AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
+ float val = *(td->val);
+
+ /* strip/action time to global (mapped) time */
+ if (adt)
+ val = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_MAP);
+
+ if (min > val) min = val;
+ if (max < val) max = val;
}
if (min == max) {
@@ -8477,25 +8484,38 @@ static void applyTimeSlideValue(TransInfo *t, float sval)
*/
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
float cval = t->values[0];
-
- /* apply NLA-mapping to necessary values */
- if (adt)
- cval = BKE_nla_tweakedit_remap(adt, cval, NLATIME_CONVERT_UNMAP);
-
+
/* only apply to data if in range */
if ((sval > minx) && (sval < maxx)) {
float cvalc = CLAMPIS(cval, minx, maxx);
+ float ival = td->ival;
float timefac;
-
+
+ /* NLA mapping magic here works as follows:
+ * - "ival" goes from strip time to global time
+ * - calculation is performed into td->val in global time
+ * (since sval and min/max are all in global time)
+ * - "td->val" then gets put back into strip time
+ */
+ if (adt) {
+ /* strip to global */
+ ival = BKE_nla_tweakedit_remap(adt, ival, NLATIME_CONVERT_MAP);
+ }
+
/* left half? */
- if (td->ival < sval) {
- timefac = (sval - td->ival) / (sval - minx);
+ if (ival < sval) {
+ timefac = (sval - ival) / (sval - minx);
*(td->val) = cvalc - timefac * (cvalc - minx);
}
else {
- timefac = (td->ival - sval) / (maxx - sval);
+ timefac = (ival - sval) / (maxx - sval);
*(td->val) = cvalc + timefac * (maxx - cvalc);
}
+
+ if (adt) {
+ /* global to strip */
+ *(td->val) = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_UNMAP);
+ }
}
}
}
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 1f3be8d73bb..f510ded6b60 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -47,6 +47,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_filetype.h"
+#include "IMB_filter.h"
#include "IMB_moviecache.h"
#include "MEM_guardedalloc.h"
@@ -1635,12 +1636,13 @@ static void *do_processor_transform_thread(void *handle_v)
if (float_from_byte) {
IMB_buffer_float_from_byte(float_buffer, byte_buffer,
IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- true,
+ false,
width, height, width, width);
- IMB_colormanagement_processor_apply(handle->cm_processor,
- float_buffer,
- width, height, channels,
- predivide);
+ IMB_colormanagement_processor_apply(handle->cm_processor,
+ float_buffer,
+ width, height, channels,
+ predivide);
+ IMB_premultiply_rect_float(float_buffer, 4, width, height);
}
else {
if (byte_buffer != NULL) {
@@ -1776,14 +1778,15 @@ void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, unsig
*/
IMB_buffer_float_from_byte(float_buffer, byte_buffer,
IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- true,
+ false,
width, height, width, width);
+ IMB_premultiply_rect_float(float_buffer, 4, width, height);
return;
}
cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
processor_transform_apply_threaded(byte_buffer, float_buffer,
width, height, channels,
- cm_processor, true, true);
+ cm_processor, false, true);
IMB_colormanagement_processor_free(cm_processor);
}
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 156f8f85485..689a6406375 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1553,6 +1553,7 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_register_funcs(srna, "rna_Operator_register", "rna_Operator_unregister", "rna_Operator_instance");
#endif
RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
+ RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1638,7 +1639,7 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Operator Properties", "Input properties of an Operator");
RNA_def_struct_refine_func(srna, "rna_OperatorProperties_refine");
RNA_def_struct_idprops_func(srna, "rna_OperatorProperties_idprops");
- RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_PUBLIC_NAMESPACE_INHERIT);
+ RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES);
}
static void rna_def_macro_operator(BlenderRNA *brna)
@@ -1656,6 +1657,7 @@ static void rna_def_macro_operator(BlenderRNA *brna)
"rna_Operator_instance");
#endif
RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
+ RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index b8ff0588581..6598d402f72 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -200,12 +200,12 @@ static int bpy_slot_from_py(
{
/* XXX - BMesh operator design is crappy here, operator slot should define matrix size,
* not the caller! */
- unsigned short size;
MatrixObject *pymat;
if (!Matrix_ParseAny(value, &pymat)) {
return -1;
}
- if ((size = (pymat->num_col) != pymat->num_row) || (!ELEM(size, 3, 4))) {
+ const ushort size = pymat->num_col;
+ if ((size != pymat->num_row) || (!ELEM(size, 3, 4))) {
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix",
opname, slot_name);
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 3afde45195c..9d57adca946 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -53,7 +53,7 @@ static void operator_properties_init(wmOperatorType *ot)
*
* Note the 'no_struct_map' function is used since the actual struct name is already used by the operator.
*/
- RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
+ RNA_def_struct_identifier_no_struct_map(ot->srna, ot->idname);
if (pyrna_deferred_register_class(ot->srna, py_class) != 0) {
PyErr_Print(); /* failed to register operator props */