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--extern/carve/carve-capi.cc45
-rw-r--r--extern/carve/carve-util.cc12
-rw-r--r--extern/carve/carve-util.h39
-rw-r--r--extern/carve/include/carve/config.h18
-rw-r--r--extern/carve/include/carve/mesh_ops.hpp2
-rw-r--r--extern/carve/lib/triangulator.cpp18
-rw-r--r--extern/carve/patches/clang_is_heap_fix.patch42
-rw-r--r--extern/carve/patches/files/config.h18
-rw-r--r--extern/carve/patches/series2
-rw-r--r--extern/libmv/ChangeLog8
-rw-r--r--extern/libmv/libmv/simple_pipeline/bundle.cc2
-rw-r--r--extern/rangetree/range_tree.hh4
-rw-r--r--intern/cycles/app/cycles_standalone.cpp4
-rw-r--r--intern/cycles/blender/blender_object.cpp7
-rw-r--r--intern/cycles/blender/blender_session.cpp14
-rw-r--r--intern/cycles/device/device.cpp11
-rw-r--r--intern/cycles/device/device.h8
-rw-r--r--intern/cycles/device/device_cuda.cpp13
-rw-r--r--intern/cycles/device/device_multi.cpp5
-rw-r--r--intern/cycles/render/buffers.cpp4
-rw-r--r--intern/cycles/render/buffers.h3
-rw-r--r--intern/cycles/render/session.cpp14
-rw-r--r--intern/cycles/render/session.h6
m---------release/scripts/addons0
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py23
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py15
-rw-r--r--release/scripts/startup/bl_ui/space_image.py2
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py5
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h3
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h1
-rw-r--r--source/blender/blenkernel/depsgraph_private.h1
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c10
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c36
-rw-r--r--source/blender/blenkernel/intern/displist.c2
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c11
-rw-r--r--source/blender/blenkernel/intern/image.c10
-rw-r--r--source/blender/blenkernel/intern/library.c26
-rw-r--r--source/blender/blenkernel/intern/mask.c1
-rw-r--r--source/blender/blenkernel/intern/material.c3
-rw-r--r--source/blender/blenkernel/intern/movieclip.c13
-rw-r--r--source/blender/blenkernel/intern/node.c17
-rw-r--r--source/blender/blenkernel/intern/object.c11
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c12
-rw-r--r--source/blender/blenkernel/intern/sequencer.c40
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c18
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c31
-rw-r--r--source/blender/bmesh/tools/bmesh_wireframe.c58
-rw-r--r--source/blender/compositor/COM_defines.h9
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp5
-rw-r--r--source/blender/editors/include/ED_view3d.h2
-rw-r--r--source/blender/editors/interface/interface_handlers.c39
-rw-r--r--source/blender/editors/interface/interface_layout.c4
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c2
-rw-r--r--source/blender/editors/object/object_add.c7
-rw-r--r--source/blender/editors/screen/screen_edit.c21
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c15
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h4
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c46
-rw-r--r--source/blender/editors/space_clip/clip_editor.c4
-rw-r--r--source/blender/editors/space_clip/clip_ops.c15
-rw-r--r--source/blender/editors/space_clip/space_clip.c5
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c5
-rw-r--r--source/blender/editors/space_node/drawnode.c7
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h5
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c15
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c17
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c6
-rw-r--r--source/blender/editors/transform/transform_constraints.c6
-rw-r--r--source/blender/editors/transform/transform_conversions.c8
-rw-r--r--source/blender/editors/util/numinput.c47
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.cpp13
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.cpp8
-rw-r--r--source/blender/imbuf/intern/IMB_allocimbuf.h3
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c23
-rw-r--r--source/blender/imbuf/intern/module.c6
-rw-r--r--source/blender/imbuf/intern/moviecache.c12
-rw-r--r--source/blender/imbuf/intern/tiff.c2
-rw-r--r--source/blender/imbuf/intern/util.c1
-rw-r--r--source/blender/makesrna/intern/rna_access.c8
-rw-r--r--source/blender/makesrna/intern/rna_color.c15
-rw-r--r--source/blender/makesrna/intern/rna_particle.c3
-rw-r--r--source/blender/makesrna/intern/rna_rna.c4
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c2
-rw-r--r--source/blender/render/intern/source/bake.c2
-rw-r--r--source/blender/render/intern/source/convertblender.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c5
-rw-r--r--source/blender/windowmanager/intern/wm_window.c11
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp11
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.cpp3
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp19
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp14
103 files changed, 816 insertions, 339 deletions
diff --git a/extern/carve/carve-capi.cc b/extern/carve/carve-capi.cc
index a65d1a8d766..af9ecad685d 100644
--- a/extern/carve/carve-capi.cc
+++ b/extern/carve/carve-capi.cc
@@ -38,7 +38,7 @@ typedef std::pair<int, int> OrigIndex;
typedef std::pair<MeshSet<3>::vertex_t *, MeshSet<3>::vertex_t *> VertexPair;
typedef carve::interpolate::VertexAttr<OrigIndex> OrigVertMapping;
typedef carve::interpolate::FaceAttr<OrigIndex> OrigFaceMapping;
-typedef carve::interpolate::FaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
+typedef carve::interpolate::SwapableFaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
typedef carve::interpolate::SimpleFaceEdgeAttr<bool> FaceEdgeTriangulatedFlag;
typedef struct CarveMeshDescr {
@@ -522,6 +522,39 @@ public:
}
};
+template <typename Interpolator>
+void copyFaceEdgeAttrs(const MeshSet<3> *poly,
+ Interpolator *old_interpolator,
+ Interpolator *new_interpolator)
+{
+ for (MeshSet<3>::const_face_iter face_iter = poly->faceBegin();
+ face_iter != poly->faceEnd();
+ ++face_iter)
+ {
+ const MeshSet<3>::face_t *face = *face_iter;
+
+ for (int edge_index = 0;
+ edge_index < face->nEdges();
+ ++edge_index)
+ {
+ new_interpolator->copyAttribute(face,
+ edge_index,
+ old_interpolator);
+ }
+ }
+}
+
+template <typename Interpolator>
+void cleanupFaceEdgeAttrs(const MeshSet<3> *left,
+ const MeshSet<3> *right,
+ Interpolator *interpolator)
+{
+ Interpolator new_interpolator;
+ copyFaceEdgeAttrs(left, interpolator, &new_interpolator);
+ copyFaceEdgeAttrs(right, interpolator, &new_interpolator);
+ interpolator->swapAttributes(&new_interpolator);
+}
+
} // namespace
CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
@@ -698,7 +731,15 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
// intersecting that meshes tessellation of operation result can't be
// done properly. The only way to make such situations working is to
// union intersecting meshes of the same operand.
- carve_unionIntersections(&csg, &left, &right);
+ if (carve_unionIntersections(&csg, &left, &right)) {
+ cleanupFaceEdgeAttrs(left,
+ right,
+ &output_descr->face_edge_triangulated_flag);
+ cleanupFaceEdgeAttrs(left,
+ right,
+ &output_descr->orig_face_edge_mapping);
+ }
+
left_mesh->poly = left;
right_mesh->poly = right;
diff --git a/extern/carve/carve-util.cc b/extern/carve/carve-util.cc
index ac6dcbc1a94..b268dae9dd6 100644
--- a/extern/carve/carve-util.cc
+++ b/extern/carve/carve-util.cc
@@ -486,14 +486,15 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
// TODO(sergey): This function is to be totally re-implemented to make it
// more clear what's going on and hopefully optimize it as well.
-void carve_unionIntersections(carve::csg::CSG *csg,
+bool carve_unionIntersections(carve::csg::CSG *csg,
MeshSet<3> **left_r,
MeshSet<3> **right_r)
{
MeshSet<3> *left = *left_r, *right = *right_r;
+ bool changed = false;
if (left->meshes.size() == 1 && right->meshes.size() == 0) {
- return;
+ return false;
}
MeshSet<3>::aabb_t leftAABB = left->getAABB();
@@ -503,14 +504,19 @@ void carve_unionIntersections(carve::csg::CSG *csg,
right = unionIntersectingMeshes(csg, right, leftAABB);
if (left != *left_r) {
+ changed = true;
delete *left_r;
}
- if (right != *right_r)
+ if (right != *right_r) {
+ changed = true;
delete *right_r;
+ }
*left_r = left;
*right_r = right;
+
+ return changed;
}
static inline void add_newell_cross_v3_v3v3(const Vector &v_prev,
diff --git a/extern/carve/carve-util.h b/extern/carve/carve-util.h
index a658b2fea96..f650810e9e3 100644
--- a/extern/carve/carve-util.h
+++ b/extern/carve/carve-util.h
@@ -70,7 +70,7 @@ void carve_getRescaleMinMax(const carve::mesh::MeshSet<3> *left,
carve::geom3d::Vector *min,
carve::geom3d::Vector *max);
-void carve_unionIntersections(carve::csg::CSG *csg,
+bool carve_unionIntersections(carve::csg::CSG *csg,
carve::mesh::MeshSet<3> **left_r,
carve::mesh::MeshSet<3> **right_r);
@@ -115,8 +115,8 @@ namespace carve {
attrs.find(new_edge_iter->vert);
if (found == attrs.end()) {
for (const_edge_iter_t orig_edge_iter = orig_face->begin();
- orig_edge_iter != orig_face->end();
- ++orig_edge_iter)
+ orig_edge_iter != orig_face->end();
+ ++orig_edge_iter)
{
if ((orig_edge_iter->vert->v - new_edge_iter->vert->v).length2() < 1e-5) {
attrs[new_edge_iter->vert] = attrs[orig_edge_iter->vert];
@@ -236,6 +236,20 @@ namespace carve {
attrs[std::make_pair(f, e)] = attr;
}
+ void copyAttribute(const meshset_t::face_t *face,
+ unsigned edge,
+ SimpleFaceEdgeAttr<attr_t> *interpolator) {
+ key_t key(face, edge);
+ typename attrmap_t::const_iterator fv = interpolator->attrs.find(key);
+ if (fv != interpolator->attrs.end()) {
+ attrs[key] = (*fv).second;
+ }
+ }
+
+ void swapAttributes(SimpleFaceEdgeAttr<attr_t> *interpolator) {
+ attrs.swap(interpolator->attrs);
+ }
+
SimpleFaceEdgeAttr() : Interpolator() {
}
@@ -243,6 +257,25 @@ namespace carve {
}
};
+ template<typename attr_t>
+ class SwapableFaceEdgeAttr : public FaceEdgeAttr<attr_t> {
+ public:
+ typedef carve::mesh::MeshSet<3> meshset_t;
+
+ void copyAttribute(const meshset_t::face_t *face,
+ unsigned edge,
+ SwapableFaceEdgeAttr<attr_t> *interpolator) {
+ typename FaceEdgeAttr<attr_t>::key_t key(face, edge);
+ typename FaceEdgeAttr<attr_t>::attrmap_t::const_iterator fv = interpolator->attrs.find(key);
+ if (fv != interpolator->attrs.end()) {
+ this->attrs[key] = (*fv).second;
+ }
+ }
+
+ void swapAttributes(SwapableFaceEdgeAttr<attr_t> *interpolator) {
+ this->attrs.swap(interpolator->attrs);
+ }
+ };
} // namespace interpolate
} // namespace carve
diff --git a/extern/carve/include/carve/config.h b/extern/carve/include/carve/config.h
index fdae2d2843f..3533c1a6710 100644
--- a/extern/carve/include/carve/config.h
+++ b/extern/carve/include/carve/config.h
@@ -10,3 +10,21 @@
# define HAVE_STDINT_H
#endif
+
+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
+//
+// TODO(sergey): Move it some some more generic header with platform-specific
+// declarations.
+
+// Indicates whether __is_heap is available
+#undef HAVE_IS_HEAP
+
+#ifdef __GNUC__
+// NeyBSD doesn't have __is_heap
+# ifndef __NetBSD__
+# define HAVE_IS_HEAP
+# ifdef _LIBCPP_VERSION
+# define __is_heap is_heap
+# endif // _LIBCPP_VERSION
+# endif // !__NetBSD__
+#endif // __GNUC__
diff --git a/extern/carve/include/carve/mesh_ops.hpp b/extern/carve/include/carve/mesh_ops.hpp
index 02b1bde4e45..3b71feb0e6c 100644
--- a/extern/carve/include/carve/mesh_ops.hpp
+++ b/extern/carve/include/carve/mesh_ops.hpp
@@ -580,7 +580,7 @@ namespace carve {
std::vector<VertexInfo *> queue;
void checkheap() {
-#ifdef __GNUC__
+#if defined(HAVE_IS_HEAP)
CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
#endif
}
diff --git a/extern/carve/lib/triangulator.cpp b/extern/carve/lib/triangulator.cpp
index 820fed07db7..eb36e86af5d 100644
--- a/extern/carve/lib/triangulator.cpp
+++ b/extern/carve/lib/triangulator.cpp
@@ -27,24 +27,6 @@
#include <algorithm>
-// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
-//
-// TODO(sergey): Move it some some more generic header with platform-specific
-// declarations.
-
-// Indicates whether __is_heap is available
-#undef HAVE_IS_HEAP
-
-#ifdef __GNUC__
-// NeyBSD doesn't have __is_heap
-# ifndef __NetBSD__
-# define HAVE_IS_HEAP
-# ifdef _LIBCPP_VERSION
-# define __is_heap is_heap
-# endif // _LIBCPP_VERSION
-# endif // !__NetBSD__
-#endif // __GNUC__
-
namespace {
// private code related to hole patching.
diff --git a/extern/carve/patches/clang_is_heap_fix.patch b/extern/carve/patches/clang_is_heap_fix.patch
index a00710b9540..524a8e0420c 100644
--- a/extern/carve/patches/clang_is_heap_fix.patch
+++ b/extern/carve/patches/clang_is_heap_fix.patch
@@ -1,31 +1,27 @@
-diff -r 2e6e59022e6e lib/triangulator.cpp
---- a/lib/triangulator.cpp Fri Nov 09 09:35:35 2012 +1100
-+++ b/lib/triangulator.cpp Thu Jan 09 16:13:17 2014 +0600
-@@ -27,6 +27,23 @@
+diff -r e82d852e4fb0 include/carve/mesh_ops.hpp
+--- a/include/carve/mesh_ops.hpp Wed Jan 15 13:16:14 2014 +1100
++++ b/include/carve/mesh_ops.hpp Fri Mar 28 14:34:04 2014 +0600
+@@ -580,7 +580,7 @@
+ std::vector<VertexInfo *> queue;
- #include <algorithm>
+ void checkheap() {
+-#ifdef __GNUC__
++#if defined(HAVE_IS_HEAP)
+ CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
+ #endif
+ }
+diff -r e82d852e4fb0 lib/triangulator.cpp
+--- a/lib/triangulator.cpp Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/triangulator.cpp Fri Mar 28 14:34:04 2014 +0600
+@@ -27,7 +27,6 @@
-+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
-+//
-+// TODO(sergey): Move it some some more generic header with platform-specific
-+// declarations.
-+
-+// Indicates whether __is_heap is available
-+#undef HAVE_IS_HEAP
-+
-+#ifdef __GNUC__
-+// NeyBSD doesn't have __is_heap
-+# ifndef __NetBSD__
-+# define HAVE_IS_HEAP
-+# ifdef _LIBCPP_VERSION
-+# define __is_heap is_heap
-+# endif // _LIBCPP_VERSION
-+# endif // !__NetBSD__
-+#endif // __GNUC__
+ #include <algorithm>
+-
namespace {
// private code related to hole patching.
-@@ -122,7 +139,7 @@
+
+@@ -122,7 +121,7 @@
std::vector<vertex_info *> queue;
void checkheap() {
diff --git a/extern/carve/patches/files/config.h b/extern/carve/patches/files/config.h
index fdae2d2843f..3533c1a6710 100644
--- a/extern/carve/patches/files/config.h
+++ b/extern/carve/patches/files/config.h
@@ -10,3 +10,21 @@
# define HAVE_STDINT_H
#endif
+
+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
+//
+// TODO(sergey): Move it some some more generic header with platform-specific
+// declarations.
+
+// Indicates whether __is_heap is available
+#undef HAVE_IS_HEAP
+
+#ifdef __GNUC__
+// NeyBSD doesn't have __is_heap
+# ifndef __NetBSD__
+# define HAVE_IS_HEAP
+# ifdef _LIBCPP_VERSION
+# define __is_heap is_heap
+# endif // _LIBCPP_VERSION
+# endif // !__NetBSD__
+#endif // __GNUC__
diff --git a/extern/carve/patches/series b/extern/carve/patches/series
index 286d594bbef..529bf43a858 100644
--- a/extern/carve/patches/series
+++ b/extern/carve/patches/series
@@ -8,5 +8,5 @@ strict_flags.patch
interpolator_reorder.patch
mesh_simplify_dissolve_edges.patch
memory_leak_fix.patch
-mavc_fix.patch
+msvc_fix.patch
face_hole_merge_workaround.patch
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
index 641d2518fb8..2e8e99af0eb 100644
--- a/extern/libmv/ChangeLog
+++ b/extern/libmv/ChangeLog
@@ -1,3 +1,11 @@
+commit 901b146f28825d3e05f4157ca2a34ae00261b91a
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Mar 26 17:44:09 2014 +0600
+
+ Fix bad memory write in BA code when having zero-weighted tracks
+
+ Issue was really stupid and caused by the wrong vector initialization.
+
commit b1381540305d69c702eb2f051bd543fb5c1c3e2c
Author: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Thu Feb 6 18:01:58 2014 +0600
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc
index 09523340ed7..f571b0fcaab 100644
--- a/extern/libmv/libmv/simple_pipeline/bundle.cc
+++ b/extern/libmv/libmv/simple_pipeline/bundle.cc
@@ -416,7 +416,7 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
vector<Marker> markers = tracks.AllMarkers();
// N-th element denotes whether track N is a constant zero-weigthed track.
- vector<bool> zero_weight_tracks_flags(tracks.MaxTrack(), true);
+ vector<bool> zero_weight_tracks_flags(tracks.MaxTrack() + 1, true);
// Residual blocks with 10 parameters are unwieldly with Ceres, so pack the
// intrinsics into a single block and rely on local parameterizations to
diff --git a/extern/rangetree/range_tree.hh b/extern/rangetree/range_tree.hh
index a88c70281b6..919e0b04933 100644
--- a/extern/rangetree/range_tree.hh
+++ b/extern/rangetree/range_tree.hh
@@ -79,10 +79,6 @@ struct RangeTree {
TreeIter iter = tree.find(Range(t));
assert(iter != tree.end());
Range cur = *iter;
- TreeIter prev = iter;
- TreeIter next = iter;
- --prev;
- ++next;
/* Remove the original range (note that this does not
invalidate the prev/next iterators) */
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index fdee92a5eb0..75ecb78b200 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -188,7 +188,9 @@ static void display_info(Progress& progress)
static void display()
{
- options.session->draw(session_buffer_params());
+ static DeviceDrawParams draw_params = DeviceDrawParams();
+
+ options.session->draw(session_buffer_params(), draw_params);
display_info(options.session->progress);
}
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 2ea0b27dff8..6ffc8c81ce6 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -432,6 +432,11 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
/* object loop */
BL::Scene::objects_iterator b_ob;
BL::Scene b_sce = b_scene;
+ /* modifier result type (not exposed as enum in C++ API)
+ * 1 : eModifierMode_Realtime
+ * 2 : eModifierMode_Render
+ */
+ int dupli_settings = preview ? 1 : 2;
bool cancel = false;
@@ -446,7 +451,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
if(b_ob->is_duplicator() && !object_render_hide_duplis(*b_ob)) {
/* dupli objects */
- b_ob->dupli_list_create(b_scene, 2);
+ b_ob->dupli_list_create(b_scene, dupli_settings);
BL::Object::dupli_list_iterator b_dup;
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index ef578493901..09e7472caf2 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -592,16 +592,14 @@ bool BlenderSession::draw(int w, int h)
/* draw */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ DeviceDrawParams draw_params;
- if(session->params.display_buffer_linear)
- b_engine.bind_display_space_shader(b_scene);
-
- bool draw_ok = !session->draw(buffer_params);
+ if(session->params.display_buffer_linear) {
+ draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
+ draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine);
+ }
- if(session->params.display_buffer_linear)
- b_engine.unbind_display_space_shader();
-
- return draw_ok;
+ return !session->draw(buffer_params, draw_params);
}
void BlenderSession::get_status(string& status, string& substatus)
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index a3264f0c516..7fd1b79f6bc 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -53,7 +53,8 @@ void Device::pixels_free(device_memory& mem)
mem_free(mem);
}
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params)
{
pixels_copy_from(rgba, y, w, h);
@@ -80,6 +81,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
glEnable(GL_TEXTURE_2D);
+ if(draw_params.bind_display_space_shader_cb) {
+ draw_params.bind_display_space_shader_cb();
+ }
+
glPushMatrix();
glTranslatef(0.0f, (float)dy, 0.0f);
@@ -98,6 +103,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
glPopMatrix();
+ if(draw_params.unbind_display_space_shader_cb) {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glDeleteTextures(1, &texid);
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index bd309e35788..fba44485810 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -69,6 +69,11 @@ public:
/* Device */
+struct DeviceDrawParams {
+ boost::function<void(void)> bind_display_space_shader_cb;
+ boost::function<void(void)> unbind_display_space_shader_cb;
+};
+
class Device {
protected:
Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {}
@@ -121,7 +126,8 @@ public:
/* opengl drawing */
virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int dy, int width, int height, bool transparent);
+ int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params);
#ifdef WITH_NETWORK
/* networking */
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 0fbb48cf431..029293d2a04 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -892,7 +892,8 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent)
+ void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params)
{
if(!background) {
PixelMem pmem = pixel_mem_map[mem.device_pointer];
@@ -925,6 +926,10 @@ public:
glColor3f(1.0f, 1.0f, 1.0f);
+ if(draw_params.bind_display_space_shader_cb) {
+ draw_params.bind_display_space_shader_cb();
+ }
+
glPushMatrix();
glTranslatef(0.0f, (float)dy, 0.0f);
@@ -943,6 +948,10 @@ public:
glPopMatrix();
+ if(draw_params.unbind_display_space_shader_cb) {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
if(transparent)
glDisable(GL_BLEND);
@@ -954,7 +963,7 @@ public:
return;
}
- Device::draw_pixels(mem, y, w, h, dy, width, height, transparent);
+ Device::draw_pixels(mem, y, w, h, dy, width, height, transparent, draw_params);
}
void thread_run(DeviceTask *task)
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 27b9de0769e..5cb1069d244 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -233,7 +233,8 @@ public:
mem.device_pointer = tmp;
}
- void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+ void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params)
{
device_ptr tmp = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -247,7 +248,7 @@ public:
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[tmp];
- sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent);
+ sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent, draw_params);
i++;
}
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index da1b7484b77..fc65922fc87 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -358,14 +358,14 @@ void DisplayBuffer::draw_set(int width, int height)
draw_height = height;
}
-void DisplayBuffer::draw(Device *device)
+void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
{
if(draw_width != 0 && draw_height != 0) {
glPushMatrix();
glTranslatef(params.full_x, params.full_y, 0.0f);
device_memory& rgba = rgba_data();
- device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent);
+ device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent, draw_params);
glPopMatrix();
}
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 81eaf41077f..27ab20bbafd 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -31,6 +31,7 @@
CCL_NAMESPACE_BEGIN
class Device;
+struct DeviceDrawParams;
struct float4;
/* Buffer Parameters
@@ -114,7 +115,7 @@ public:
void write(Device *device, const string& filename);
void draw_set(int width, int height);
- void draw(Device *device);
+ void draw(Device *device, const DeviceDrawParams& draw_params);
bool draw_ready();
device_memory& rgba_data();
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 0805a685467..2b799972a97 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -151,7 +151,7 @@ void Session::reset_gpu(BufferParams& buffer_params, int samples)
pause_cond.notify_all();
}
-bool Session::draw_gpu(BufferParams& buffer_params)
+bool Session::draw_gpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
{
/* block for buffer access */
thread_scoped_lock display_lock(display_mutex);
@@ -170,7 +170,7 @@ bool Session::draw_gpu(BufferParams& buffer_params)
gpu_need_tonemap_cond.notify_all();
}
- display->draw(device);
+ display->draw(device, draw_params);
if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
return false;
@@ -315,7 +315,7 @@ void Session::reset_cpu(BufferParams& buffer_params, int samples)
pause_cond.notify_all();
}
-bool Session::draw_cpu(BufferParams& buffer_params)
+bool Session::draw_cpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
{
thread_scoped_lock display_lock(display_mutex);
@@ -324,7 +324,7 @@ bool Session::draw_cpu(BufferParams& buffer_params)
/* then verify the buffers have the expected size, so we don't
* draw previous results in a resized window */
if(!buffer_params.modified(display->params)) {
- display->draw(device);
+ display->draw(device, draw_params);
if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
return false;
@@ -624,12 +624,12 @@ void Session::run()
progress.set_update();
}
-bool Session::draw(BufferParams& buffer_params)
+bool Session::draw(BufferParams& buffer_params, DeviceDrawParams &draw_params)
{
if(device_use_gl)
- return draw_gpu(buffer_params);
+ return draw_gpu(buffer_params, draw_params);
else
- return draw_cpu(buffer_params);
+ return draw_cpu(buffer_params, draw_params);
}
void Session::reset_(BufferParams& buffer_params, int samples)
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 1227edf81b6..e2a7076f250 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -128,7 +128,7 @@ public:
~Session();
void start();
- bool draw(BufferParams& params);
+ bool draw(BufferParams& params, DeviceDrawParams& draw_params);
void wait();
bool ready_to_reset();
@@ -155,11 +155,11 @@ protected:
void reset_(BufferParams& params, int samples);
void run_cpu();
- bool draw_cpu(BufferParams& params);
+ bool draw_cpu(BufferParams& params, DeviceDrawParams& draw_params);
void reset_cpu(BufferParams& params, int samples);
void run_gpu();
- bool draw_gpu(BufferParams& params);
+ bool draw_gpu(BufferParams& params, DeviceDrawParams& draw_params);
void reset_gpu(BufferParams& params, int samples);
bool acquire_tile(Device *tile_device, RenderTile& tile);
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 6c32300be8cc8d48a3e02055dc43bea2ab98a52
+Subproject ee2cd7105d505a4f6b4613aba26598f532f97f3
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 70df5a9df21..1a8bd44e846 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -232,17 +232,28 @@ def islandIntersectUvIsland(source, target, SourceOffset):
return 0 # NO INTERSECTION
+def rotate_uvs(uv_points, angle):
+
+ if angle != 0.0:
+ mat = Matrix.Rotation(angle, 2)
+ for uv in uv_points:
+ uv[:] = mat * uv
+
+
def optiRotateUvIsland(faces):
uv_points = [uv for f in faces for uv in f.uv]
angle = geometry.box_fit_2d(uv_points)
if angle != 0.0:
- mat = Matrix.Rotation(angle, 2)
- i = 0 # count the serialized uv/vectors
- for f in faces:
- for j, k in enumerate(range(i, len(f.v) + i)):
- f.uv[j][:] = mat * uv_points[k]
- i += len(f.v)
+ rotate_uvs(uv_points, angle)
+
+ # orient them vertically (could be an option)
+ minx, miny, maxx, maxy = boundsIsland(faces)
+ w, h = maxx - minx, maxy - miny
+ if h < w:
+ from math import pi
+ angle = pi / 2.0
+ rotate_uvs(uv_points, angle)
# Takes an island list and tries to find concave, hollow areas to pack smaller islands into.
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index dc01c2c8f3d..5c8257ca52b 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -123,9 +123,9 @@ class CLIP_HT_header(Header):
row = layout.row()
row.template_ID(sc, "clip", open="clip.open")
- layout.prop(sc, "mode", text="")
-
if clip:
+ layout.prop(sc, "mode", text="")
+
row = layout.row()
row.template_ID(sc, "mask", new="mask.new")
@@ -1332,17 +1332,6 @@ class CLIP_MT_tracking_specials(Menu):
text="Unlock Tracks").action = 'UNLOCK'
-class CLIP_MT_select_mode(Menu):
- bl_label = "Select Mode"
-
- def draw(self, context):
- layout = self.layout
-
- layout.operator_context = 'INVOKE_REGION_WIN'
-
- layout.operator_enum("clip.mode_set", "mode")
-
-
class CLIP_MT_camera_presets(Menu):
"""Predefined tracking camera intrinsics"""
bl_label = "Camera Presets"
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index fce924484b3..9bf6aaa1703 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -296,7 +296,7 @@ class IMAGE_MT_uvs(Menu):
layout.prop(uv, "use_live_unwrap")
layout.operator("uv.unwrap")
layout.operator("uv.pin", text="Unpin").clear = True
- layout.operator("uv.pin")
+ layout.operator("uv.pin").clear = False
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 98c855d9419..5cc3df386b3 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1365,18 +1365,23 @@ class VIEW3D_MT_make_single_user(Menu):
props = layout.operator("object.make_single_user", text="Object")
props.object = True
+ props.obdata = props.material = props.texture = props.animation = False
props = layout.operator("object.make_single_user", text="Object & Data")
props.object = props.obdata = True
+ props.material = props.texture = props.animation = False
props = layout.operator("object.make_single_user", text="Object & Data & Materials+Tex")
props.object = props.obdata = props.material = props.texture = True
+ props.animation = False
props = layout.operator("object.make_single_user", text="Materials+Tex")
props.material = props.texture = True
+ props.object = props.obdata = props.animation = False
props = layout.operator("object.make_single_user", text="Object Animation")
props.animation = True
+ props.object = props.obdata = props.material = props.texture = False
class VIEW3D_MT_make_links(Menu):
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index ec595320d6a..c6f6579ec48 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -49,7 +49,7 @@ extern "C" {
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR
+#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE release
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index a9d5ea75208..e85f594daba 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -144,6 +144,7 @@ void BKE_nurb_knot_calc_v(struct Nurb *nu);
/* nurb checks if they can be drawn, also clamp order func */
bool BKE_nurb_check_valid_u(struct Nurb *nu);
bool BKE_nurb_check_valid_v(struct Nurb *nu);
+bool BKE_nurb_check_valid_uv(struct Nurb *nu);
bool BKE_nurb_order_clamp_u(struct Nurb *nu);
bool BKE_nurb_order_clamp_v(struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 05bb01a4490..5652e714209 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -157,7 +157,7 @@ void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Obje
/* ************************ DAG querying ********************* */
struct Object *DAG_get_node_object(void *node_v);
-const char *DAG_get_node_name(void *node_v);
+const char *DAG_get_node_name(struct Scene *scene, void *node_v);
short DAG_get_eval_flags_for_object(struct Scene *scene, void *object);
bool DAG_is_acyclic(struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 5c92cc7b34b..44a9885cd87 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -49,6 +49,7 @@ struct PropertyRNA;
void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BKE_libblock_copy_nolib(struct ID *id) ATTR_NONNULL();
void *BKE_libblock_copy(struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 72c4c21d587..2ad6c54fb67 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -167,7 +167,8 @@ void BKE_object_tfm_protected_restore(struct Object *ob,
void BKE_object_handle_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx,
struct Scene *scene, struct Object *ob,
- struct RigidBodyWorld *rbw);
+ struct RigidBodyWorld *rbw,
+ const bool do_proxy_update);
void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 0cbb9215868..ea47f0ba47d 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -99,6 +99,7 @@ typedef struct SeqRenderData {
int motion_blur_samples;
float motion_blur_shutter;
bool skip_cache;
+ bool is_proxy_render;
} SeqRenderData;
SeqRenderData BKE_sequencer_new_render_data(struct EvaluationContext *eval_ctx, struct Main *bmain,
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index e61d47e87f4..0ab633701c1 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -129,6 +129,7 @@ typedef struct DagForest {
int numNodes;
bool is_acyclic;
int time; /* for flushing/tagging, compare with node->lasttime */
+ bool ugly_hack_sorry; /* prevent type check */
} DagForest;
// queue operations
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 3088f2ccf9b..b0c293720c4 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -894,7 +894,7 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
AnimData *adt = BKE_animdata_from_id(id); \
NtId_Type *ntp = (NtId_Type *)id; \
if (ntp->nodetree) { \
- AnimData *adt2 = BKE_animdata_from_id((ID *)ntp); \
+ AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
if (adt2) func(id, adt2, user_data); \
} \
if (adt) func(id, adt, user_data); \
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 1fe01fa9637..cb15b5dbd78 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3798,6 +3798,16 @@ bool BKE_nurb_check_valid_v(struct Nurb *nu)
return true;
}
+bool BKE_nurb_check_valid_uv(struct Nurb *nu)
+{
+ if (!BKE_nurb_check_valid_u(nu))
+ return false;
+ if ((nu->pntsv > 1) && !BKE_nurb_check_valid_v(nu))
+ return false;
+
+ return true;
+}
+
bool BKE_nurb_order_clamp_u(struct Nurb *nu)
{
bool changed = false;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index af321302984..dc467a5f215 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -305,6 +305,7 @@ DagForest *dag_init(void)
DagForest *forest;
/* use callocN to init all zero */
forest = MEM_callocN(sizeof(DagForest), "DAG root");
+ forest->ugly_hack_sorry = true;
return forest;
}
@@ -995,7 +996,6 @@ DagNode *dag_find_node(DagForest *forest, void *fob)
return NULL;
}
-static int ugly_hack_sorry = 1; /* prevent type check */
static int dag_print_dependencies = 0; /* debugging */
/* no checking of existence, use dag_find_node first or dag_get_node */
@@ -1008,7 +1008,7 @@ DagNode *dag_add_node(DagForest *forest, void *fob)
node->ob = fob;
node->color = DAG_WHITE;
- if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */
+ if (forest->ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */
if (forest->numNodes) {
((DagNode *) forest->DagNode.last)->next = node;
forest->DagNode.last = node;
@@ -1116,28 +1116,28 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel
fob1->child = itA;
}
-static const char *dag_node_name(DagNode *node)
+static const char *dag_node_name(DagForest *dag, DagNode *node)
{
if (node->ob == NULL)
return "null";
- else if (ugly_hack_sorry)
+ else if (dag->ugly_hack_sorry)
return ((ID *)(node->ob))->name + 2;
else
return ((bPoseChannel *)(node->ob))->name;
}
-static void dag_node_print_dependencies(DagNode *node)
+static void dag_node_print_dependencies(DagForest *dag, DagNode *node)
{
DagAdjList *itA;
- printf("%s depends on:\n", dag_node_name(node));
+ printf("%s depends on:\n", dag_node_name(dag, node));
for (itA = node->parent; itA; itA = itA->next)
- printf(" %s through %s\n", dag_node_name(itA->node), itA->name);
+ printf(" %s through %s\n", dag_node_name(dag, itA->node), itA->name);
printf("\n");
}
-static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
+static int dag_node_print_dependency_recurs(DagForest *dag, DagNode *node, DagNode *endnode)
{
DagAdjList *itA;
@@ -1150,8 +1150,8 @@ static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
return 1;
for (itA = node->parent; itA; itA = itA->next) {
- if (dag_node_print_dependency_recurs(itA->node, endnode)) {
- printf(" %s depends on %s through %s.\n", dag_node_name(node), dag_node_name(itA->node), itA->name);
+ if (dag_node_print_dependency_recurs(dag, itA->node, endnode)) {
+ printf(" %s depends on %s through %s.\n", dag_node_name(dag, node), dag_node_name(dag, itA->node), itA->name);
return 1;
}
}
@@ -1166,8 +1166,8 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode,
for (node = dag->DagNode.first; node; node = node->next)
node->color = DAG_WHITE;
- printf(" %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name);
- dag_node_print_dependency_recurs(startnode, endnode);
+ printf(" %s depends on %s through %s.\n", dag_node_name(dag, endnode), dag_node_name(dag, startnode), name);
+ dag_node_print_dependency_recurs(dag, startnode, endnode);
printf("\n");
}
@@ -1201,7 +1201,7 @@ static void dag_check_cycle(DagForest *dag)
/* debugging print */
if (dag_print_dependencies)
for (node = dag->DagNode.first; node; node = node->next)
- dag_node_print_dependencies(node);
+ dag_node_print_dependencies(dag, node);
/* tag nodes unchecked */
for (node = dag->DagNode.first; node; node = node->next)
@@ -2836,7 +2836,7 @@ void DAG_pose_sort(Object *ob)
int skip = 0;
dag = dag_init();
- ugly_hack_sorry = 0; /* no ID structs */
+ dag->ugly_hack_sorry = false; /* no ID structs */
rootnode = dag_add_node(dag, NULL); /* node->ob becomes NULL */
@@ -2963,8 +2963,6 @@ void DAG_pose_sort(Object *ob)
free_forest(dag);
MEM_freeN(dag);
-
- ugly_hack_sorry = 1;
}
/* ************************ DAG FOR THREADED UPDATE ********************* */
@@ -3083,14 +3081,14 @@ Object *DAG_get_node_object(void *node_v)
}
/* Returns node name, used for debug output only, atm. */
-const char *DAG_get_node_name(void *node_v)
+const char *DAG_get_node_name(Scene *scene, void *node_v)
{
DagNode *node = node_v;
- return dag_node_name(node);
+ return dag_node_name(scene->theDag, node);
}
-short DAG_get_eval_flags_for_object(struct Scene *scene, void *object)
+short DAG_get_eval_flags_for_object(Scene *scene, void *object)
{
DagNode *node;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 9582d87c540..af3246a1b61 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1212,7 +1212,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution);
for (nu = nubase.first; nu; nu = nu->next) {
- if (forRender || nu->hide == 0) {
+ if ((forRender || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
int resolu = nu->resolu, resolv = nu->resolv;
if (renderResolution) {
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index b3e0bfa387b..c2ddd0cac4b 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -1744,10 +1744,8 @@ static void statvis_calc_overhang(
bool is_max;
/* fallback */
- const char col_fallback[2][4] = {
- {64, 64, 64, 255}, /* gray */
- {0, 0, 0, 255}, /* max color */
- };
+ unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */
+ unsigned char col_fallback_max[4] = {0, 0, 0, 255}; /* max color */
BLI_assert(min <= max);
@@ -1762,7 +1760,7 @@ static void statvis_calc_overhang(
{
float fcol[3];
weight_to_rgb(fcol, 1.0f);
- rgb_float_to_uchar((unsigned char *)col_fallback[1], fcol);
+ rgb_float_to_uchar(col_fallback_max, fcol);
}
/* now convert into global space */
@@ -1779,7 +1777,8 @@ static void statvis_calc_overhang(
rgb_float_to_uchar(r_face_colors[index], fcol);
}
else {
- copy_v4_v4_char((char *)r_face_colors[index], (const char *)(col_fallback[is_max]));
+ unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
+ copy_v4_v4_char((char *)r_face_colors[index], (const char *)fallback);
}
}
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index b8b126c4c8e..35751867b1a 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -3058,7 +3058,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
if (ima->type == IMA_TYPE_MULTILAYER)
/* keeps render result, stores ibufs in listbase, allows saving */
ibuf = image_get_ibuf_multilayer(ima, iuser);
-
}
else if (ima->source == IMA_SRC_GENERATED) {
/* generated is: ibuf is allocated dynamically */
@@ -3076,9 +3075,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
/* always verify entirely, and potentially
* returns pointer to release later */
ibuf = image_get_render_result(ima, iuser, lock_r);
- if (ibuf) {
- ibuf->userflags |= IB_PERSISTENT;
- }
}
else if (ima->type == IMA_TYPE_COMPOSITE) {
/* requires lock/unlock, otherwise don't return image */
@@ -3097,10 +3093,14 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
image_assign_ibuf(ima, ibuf, 0, frame);
}
- ibuf->userflags |= IB_PERSISTENT;
}
}
}
+
+ /* We only want movies and sequences to be memory limited. */
+ if (ibuf != NULL && !ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ ibuf->userflags |= IB_PERSISTENT;
+ }
}
BKE_image_tag_time(ima);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 0bd1f97a279..f831378ca5a 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -808,6 +808,32 @@ void *BKE_libblock_copy_ex(Main *bmain, ID *id)
return idn;
}
+void *BKE_libblock_copy_nolib(ID *id)
+{
+ ID *idn;
+ size_t idn_len;
+
+ idn = alloc_libblock_notest(GS(id->name));
+ assert(idn != NULL);
+
+ BLI_strncpy(idn->name, id->name, sizeof(idn->name));
+
+ idn_len = MEM_allocN_len(idn);
+ if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
+ const char *cp = (const char *)id;
+ char *cpn = (char *)idn;
+
+ memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
+ }
+
+ id->newid = idn;
+ idn->flag |= LIB_NEW;
+
+ BKE_libblock_copy_data(idn, id, false);
+
+ return idn;
+}
+
void *BKE_libblock_copy(ID *id)
{
return BKE_libblock_copy_ex(G.main, id);
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 9b7886ece97..d08b7316e61 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -734,6 +734,7 @@ Mask *BKE_mask_new(Main *bmain, const char *name)
return mask;
}
+/* TODO(sergey): Use generic BKE_libblock_copy_nolib() instead. */
Mask *BKE_mask_copy_nolib(Mask *mask)
{
Mask *mask_new;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 5f6331315f8..f3e38d84c33 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -256,8 +256,7 @@ Material *localize_material(Material *ma)
Material *man;
int a;
- man = BKE_libblock_copy(&ma->id);
- BLI_remlink(&G.main->mat, man);
+ man = BKE_libblock_copy_nolib(&ma->id);
/* no increment for texture ID users, in previewrender.c it prevents decrement */
for (a = 0; a < MAX_MTEX; a++) {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index a41b47809eb..c8fe99bab91 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -279,17 +279,8 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in
movieclip_open_anim_file(clip);
if (clip->anim) {
- int dur;
- int fra;
-
- dur = IMB_anim_get_duration(clip->anim, tc);
- fra = framenr - clip->start_frame + clip->frame_offset;
-
- if (fra < 0)
- fra = 0;
-
- if (fra > (dur - 1))
- fra = dur - 1;
+ int dur = IMB_anim_get_duration(clip->anim, tc);
+ int fra = framenr - clip->start_frame + clip->frame_offset;
ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy);
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index d6225560e32..4fbc5c3f2d9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1114,20 +1114,13 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
if (ntree == NULL) return NULL;
- if (bmain) {
- /* is ntree part of library? */
- if (BLI_findindex(&bmain->nodetree, ntree) != -1)
- newtree = BKE_libblock_copy(&ntree->id);
- else
- newtree = NULL;
+ /* is ntree part of library? */
+ if (bmain && BLI_findindex(&bmain->nodetree, ntree) >= 0) {
+ newtree = BKE_libblock_copy(&ntree->id);
}
- else
- newtree = NULL;
-
- if (newtree == NULL) {
- newtree = MEM_dupallocN(ntree);
+ else {
+ newtree = BKE_libblock_copy_nolib(&ntree->id);
newtree->id.lib = NULL; /* same as owning datablock id.lib */
- BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
}
id_us_plus((ID *)newtree->gpd);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 0970af46a6b..674c16383af 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2843,7 +2843,8 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
Scene *scene, Object *ob,
- RigidBodyWorld *rbw)
+ RigidBodyWorld *rbw,
+ const bool do_proxy_update)
{
if (ob->recalc & OB_RECALC_ALL) {
/* speed optimization for animation lookups */
@@ -3036,8 +3037,10 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
/* the no-group proxy case, we call update */
if (ob->proxy_group == NULL) {
- // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
- BKE_object_handle_update(eval_ctx, scene, ob->proxy);
+ if (do_proxy_update) {
+ // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
+ BKE_object_handle_update(eval_ctx, scene, ob->proxy);
+ }
}
}
}
@@ -3048,7 +3051,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
*/
void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL);
+ BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL, true);
}
void BKE_object_sculpt_modifiers_changed(Object *ob)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 3a6e710d68c..ed0f8b2d8e4 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3779,7 +3779,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
return 0;
if (pa) {
- i = (pa->num_dmcache == DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache;
+ i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache;
if (i >= dm->getNumTessFaces(dm))
i = -1;
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 110e91711f0..37eba4657ff 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1270,7 +1270,7 @@ static void scene_update_all_bases(EvaluationContext *eval_ctx, Scene *scene, Sc
for (base = scene->base.first; base; base = base->next) {
Object *object = base->object;
- BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world);
+ BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, true);
if (object->dup_group && (object->transflag & OB_DUPLIGROUP))
BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, object, object->dup_group);
@@ -1304,9 +1304,11 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
double start_time = 0.0;
bool add_to_stats = false;
- PRINT("Thread %d: update object %s\n", threadid, object->id.name);
-
if (G.debug & G_DEBUG_DEPSGRAPH) {
+ if (object->recalc & OB_RECALC_ALL) {
+ printf("Thread %d: update object %s\n", threadid, object->id.name);
+ }
+
start_time = PIL_check_seconds_timer();
if (object->recalc & OB_RECALC_ALL) {
@@ -1319,7 +1321,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
* separately from main thread because of we've got no idea about
* dependencies inside the group.
*/
- BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world);
+ BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, false);
/* Calculate statistics. */
if (add_to_stats) {
@@ -1335,7 +1337,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
}
else {
PRINT("Threda %d: update node %s\n", threadid,
- DAG_get_node_name(node));
+ DAG_get_node_name(scene, node));
}
/* Update will decrease child's valency and schedule child with zero valency. */
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 86cf04eded8..7b9262320af 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1467,8 +1467,8 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
ibuf = seq_render_strip(context, seq, cfra);
- rectx = (proxy_render_size * context->scene->r.xsch) / 100;
- recty = (proxy_render_size * context->scene->r.ysch) / 100;
+ rectx = (proxy_render_size * ibuf->x) / 100;
+ recty = (proxy_render_size * ibuf->y) / 100;
if (ibuf->x != rectx || ibuf->y != recty) {
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
@@ -1562,6 +1562,7 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
(scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
(scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100);
render_context.skip_cache = true;
+ render_context.is_proxy_render = true;
for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) {
if (context->size_flags & IMB_PROXY_25) {
@@ -1919,10 +1920,14 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float
* - Premultiply
*/
-int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *UNUSED(context), Sequence *seq, float UNUSED(cfra))
+int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, Sequence *seq, float UNUSED(cfra))
{
float mul;
+ if (context->is_proxy_render) {
+ return FALSE;
+ }
+
if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
return TRUE;
}
@@ -2806,8 +2811,12 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
if (ibuf == NULL)
ibuf = do_render_strip_uncached(context, seq, cfra);
- if (ibuf)
+ if (ibuf) {
+ if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
+ is_proxy_image = (context->preview_render_size != 100);
+ }
BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ }
}
}
@@ -2826,8 +2835,11 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
sequencer_imbuf_assign_spaces(context->scene, ibuf);
}
- if (ibuf->x != context->rectx || ibuf->y != context->recty)
+ if (context->is_proxy_render == false &&
+ (ibuf->x != context->rectx || ibuf->y != context->recty))
+ {
use_preprocess = TRUE;
+ }
if (use_preprocess)
ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
@@ -4011,11 +4023,19 @@ void BKE_sequencer_offset_animdata(Scene *scene, Sequence *seq, int ofs)
for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) {
if (strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
unsigned int i;
- for (i = 0; i < fcu->totvert; i++) {
- BezTriple *bezt = &fcu->bezt[i];
- bezt->vec[0][0] += ofs;
- bezt->vec[1][0] += ofs;
- bezt->vec[2][0] += ofs;
+ if (fcu->bezt) {
+ for (i = 0; i < fcu->totvert; i++) {
+ BezTriple *bezt = &fcu->bezt[i];
+ bezt->vec[0][0] += ofs;
+ bezt->vec[1][0] += ofs;
+ bezt->vec[2][0] += ofs;
+ }
+ }
+ if (fcu->fpt) {
+ for (i = 0; i < fcu->totvert; i++) {
+ FPoint *fpt = &fcu->fpt[i];
+ fpt->vec[0] += ofs;
+ }
}
}
}
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index a7e3c12e5d7..1dfdc5c3c74 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -205,14 +205,16 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
return false;
}
- /* get remaining two faces */
- f = e->l->f;
- f2 = e->l->radial_next->f;
-
- if (f != f2) {
- /* join two remaining faces */
- if (!BM_faces_join_pair(bm, f, f2, e, true)) {
- return false;
+ if (e->l) {
+ /* get remaining two faces */
+ f = e->l->f;
+ f2 = e->l->radial_next->f;
+
+ if (f != f2) {
+ /* join two remaining faces */
+ if (!BM_faces_join_pair(bm, f, f2, e, true)) {
+ return false;
+ }
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index a255c534736..29522b62707 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -395,6 +395,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
const float depth = BMO_slot_float_get(op->slots_in, "depth");
+ /* store vert coords in normals, needed for 'use_edge_rail' */
+#define USE_VERTNORMAL_HACK
+
int edge_info_len = 0;
BMIter iter;
@@ -453,6 +456,11 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
BM_elem_index_set(e, -1); /* set_dirty! */
}
+
+#ifdef USE_VERTNORMAL_HACK
+ copy_v3_v3(e->v1->no, e->v1->co);
+ copy_v3_v3(e->v2->no, e->v2->co);
+#endif
}
bm->elem_index_dirty |= BM_EDGE;
@@ -564,6 +572,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
/* in some cases the edge doesn't split off */
if (r_vout_len == 1) {
+#ifdef USE_VERTNORMAL_HACK
+ copy_v3_v3(vout[0]->no, vout[0]->co);
+#endif
MEM_freeN(vout);
continue;
}
@@ -575,6 +586,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
int vert_edge_tag_tot = 0;
int vecpair[2];
+#ifdef USE_VERTNORMAL_HACK
+ copy_v3_v3(v_split->no, v_split->co);
+#endif
+
/* find adjacent */
BM_ITER_ELEM (e, &iter, v_split, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(e, BM_ELEM_TAG) &&
@@ -628,9 +643,22 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
if (l_other_a->v == l_other_b->v) {
/* both edges faces are adjacent, but we don't need to know the shared edge
* having both verts is enough. */
- sub_v3_v3v3(tvec, l_other_a->v->co, v_split->co);
+ const float *co_other;
+
+ /* note that we can't use 'l_other_a->v' directly since it
+ * may be inset and give a feedback loop. */
+#ifdef USE_VERTNORMAL_HACK
+ co_other = l_other_a->v->no;
+#else
+ co_other = l_other_a->v->co;
+#endif
+
+ sub_v3_v3v3(tvec, co_other, v_split->co);
is_mid = false;
}
+
+ /* distable gives odd results at times, see [#39288] */
+#if 0
else if (compare_v3v3(f_a->no, f_b->no, 0.001f) == false) {
/* epsilon increased to fix [#32329] */
@@ -645,6 +673,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
copy_v3_v3(tvec, tno);
is_mid = false;
}
+#endif
}
normalize_v3(tvec);
diff --git a/source/blender/bmesh/tools/bmesh_wireframe.c b/source/blender/bmesh/tools/bmesh_wireframe.c
index db4601d6134..824a4164559 100644
--- a/source/blender/bmesh/tools/bmesh_wireframe.c
+++ b/source/blender/bmesh/tools/bmesh_wireframe.c
@@ -529,8 +529,62 @@ void BM_mesh_wireframe(
}
if (use_replace) {
- for (i = 0; i < totvert_orig; i++) {
- BM_vert_kill(bm, verts_src[i]);
+
+ if (use_tag) {
+ /* only remove faces which are original and used to make wire,
+ * use 'verts_pos' and 'verts_neg' to avoid a feedback loop. */
+
+ /* vertex must be from 'verts_src' */
+#define VERT_DUPE_TEST_ORIG(v) (verts_neg[BM_elem_index_get(v)] != NULL)
+#define VERT_DUPE_TEST(v) (verts_pos[BM_elem_index_get(v)] != NULL)
+#define VERT_DUPE_CLEAR(v) { verts_pos[BM_elem_index_get(v)] = NULL; } (void)0
+
+ /* first ensure we keep all verts which are used in faces that weren't
+ * entirely made into wire. */
+ BM_ITER_MESH (f_src, &iter, bm, BM_FACES_OF_MESH) {
+ int mix_flag = 0;
+ BMLoop *l_iter, *l_first;
+
+ /* skip new faces */
+ if (BM_elem_index_get(f_src) == -1) {
+ continue;
+ }
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ mix_flag |= (VERT_DUPE_TEST_ORIG(l_iter->v) ? 1 : 2);
+ if (mix_flag == (1 | 2)) {
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (mix_flag == (1 | 2)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ VERT_DUPE_CLEAR(l_iter->v);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ /* now remove any verts which were made into wire by all faces */
+ for (i = 0; i < totvert_orig; i++) {
+ v_src = verts_src[i];
+ BLI_assert(i == BM_elem_index_get(v_src));
+ if (VERT_DUPE_TEST(v_src)) {
+ BM_vert_kill(bm, v_src);
+ }
+ }
+
+#undef VERT_DUPE_TEST_ORIG
+#undef VERT_DUPE_TEST
+#undef VERT_DUPE_CLEAR
+
+ }
+ else {
+ /* simple case, no tags - replace all */
+ for (i = 0; i < totvert_orig; i++) {
+ BM_vert_kill(bm, verts_src[i]);
+ }
}
}
diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index 3b0e9f239bb..6c07aadc3aa 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -109,4 +109,13 @@ typedef enum OrderOfChunks {
#define COM_BLUR_BOKEH_PIXELS 512
+/**
+ * The fast gaussien blur is not an accurate blur.
+ * This setting can be used to increase/decrease the
+ * amount of the input data. (dependent area of interest)
+ *
+ * Fix for: T39307
+ */
+#define COM_FAST_GAUSSIAN_MULTIPLIER 3
+
#endif /* __COM_DEFINES_H__ */
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index a6be9254f6f..ff53ef22e29 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -47,10 +47,11 @@ bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output)
{
// m_data->sizex * m_size should be enough? For some reason there
// seem to be errors in the boundary between tiles.
- int sx = this->m_data->sizex * this->m_size * 2;
+ float size = this->m_size * COM_FAST_GAUSSIAN_MULTIPLIER;
+ int sx = this->m_data->sizex * size;
if (sx < 1)
sx = 1;
- int sy = this->m_data->sizey * this->m_size * 2;
+ int sy = this->m_data->sizey * size;
if (sy < 1)
sy = 1;
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 0aff3b81ec9..1cd41bd110d 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -93,6 +93,8 @@ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist
void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
+void ED_view3d_lastview_store(struct RegionView3D *rv3d);
+
/* Depth buffer */
void ED_view3d_depth_update(struct ARegion *ar);
float ED_view3d_depth_read_cached(struct ViewContext *vc, int x, int y);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index f1c0df23fc9..0768d556911 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2374,6 +2374,11 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->selextend = 0;
data->selstartx = 0.0f;
+#ifdef USE_DRAG_MULTINUM
+ /* this can happen from multi-drag */
+ data->applied_interactive = false;
+#endif
+
/* set cursor pos to the end of the text */
but->editstr = data->str;
but->pos = len;
@@ -3477,10 +3482,21 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
}
else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
- if (data->dragchange)
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- else
+ if (data->dragchange) {
+#ifdef USE_DRAG_MULTINUM
+ /* if we started multibutton but didnt drag, then edit */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ click = 1;
+ }
+ else
+#endif
+ {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else {
click = 1;
+ }
}
else if (event->type == MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
@@ -3763,10 +3779,21 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
}
else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
- if (data->dragchange)
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- else
+ if (data->dragchange) {
+#ifdef USE_DRAG_MULTINUM
+ /* if we started multibutton but didnt drag, then edit */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ click = 1;
+ }
+ else
+#endif
+ {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else {
click = 1;
+ }
}
else if (event->type == MOUSEMOVE) {
#ifdef USE_DRAG_MULTINUM
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index b5255eb0516..55f35a93692 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -888,7 +888,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
EnumPropertyItem *item, *item_array = NULL;
bool free;
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
- uiLayout *column = uiLayoutColumn(split, false);
+ uiLayout *column = uiLayoutColumn(split, layout->align);
RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, NULL, &free);
for (item = item_array; item->identifier; item++) {
@@ -912,7 +912,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
if (item->name) {
uiBut *but;
if (item != item_array) {
- column = uiLayoutColumn(split, false);
+ column = uiLayoutColumn(split, layout->align);
/* inconsistent, but menus with labels do not look good flipped */
block->flag |= UI_BLOCK_NO_FLIP;
}
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 2ca5301c89c..aa3a2c83243 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -503,7 +503,7 @@ void MESH_OT_inset(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "use_boundary", true, "Boundary", "Inset face boundaries");
RNA_def_boolean(ot->srna, "use_even_offset", true, "Offset Even", "Scale the offset to give more even thickness");
RNA_def_boolean(ot->srna, "use_relative_offset", false, "Offset Relative", "Scale the offset by surrounding geometry");
- RNA_def_boolean(ot->srna, "use_edge_rail", true, "Edge Rail", "Inset the region along existing edges");
+ RNA_def_boolean(ot->srna, "use_edge_rail", false, "Edge Rail", "Inset the region along existing edges");
prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f);
/* use 1 rather then 10 for max else dragging the button moves too far */
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index b29fafea90d..182a9f70968 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1478,8 +1478,13 @@ static void curvetomesh(Main *bmain, Scene *scene, Object *ob)
convert_ensure_curve_cache(bmain, scene, ob);
BKE_mesh_from_nurbs(ob); /* also does users */
- if (ob->type == OB_MESH)
+ if (ob->type == OB_MESH) {
BKE_object_free_modifiers(ob);
+
+ /* Game engine defaults for mesh objects */
+ ob->body_type = OB_BODY_TYPE_STATIC;
+ ob->gameflag = OB_PROP | OB_COLLISION;
+ }
}
static int convert_poll(bContext *C)
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 66fa5787e5d..23ead971cd3 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1514,19 +1514,22 @@ void ED_screen_set(bContext *C, bScreen *sc)
/* we put timer to sleep, so screen_exit has to think there's no timer */
oldscreen->animtimer = NULL;
- if (wt)
+ if (wt) {
WM_event_timer_sleep(wm, win, wt, true);
-
+ }
+
ED_screen_exit(C, win, oldscreen);
/* Same scene, "transfer" playback to new screen. */
- if (oldscene == sc->scene) {
- sc->animtimer = wt;
- }
- /* Else, stop playback. */
- else {
- oldscreen->animtimer = wt;
- ED_screen_animation_play(C, 0, 0);
+ if (wt) {
+ if (oldscene == sc->scene) {
+ sc->animtimer = wt;
+ }
+ /* Else, stop playback. */
+ else {
+ oldscreen->animtimer = wt;
+ ED_screen_animation_play(C, 0, 0);
+ }
}
win->screen = sc;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 2cb28ebba90..0d0ce259174 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2848,6 +2848,10 @@ static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar,
{
RegionView3D *rv3d = ar->regiondata;
+ if (persp == RV3D_CAMOB) {
+ ED_view3d_lastview_store(rv3d);
+ }
+
rv3d->viewlock = viewlock;
rv3d->view = view;
rv3d->persp = persp;
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 1a5ccc8f8bd..a3e69a1024b 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -45,6 +45,7 @@
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_image.h"
+#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_colortools.h"
@@ -60,6 +61,10 @@
* removed eventually (TODO) */
#include "sculpt_intern.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
/* TODOs:
*
* Some of the cursor drawing code is doing non-draw stuff
@@ -197,6 +202,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
pool = BKE_image_pool_new();
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
+
#pragma omp parallel for schedule(static)
for (j = 0; j < size; j++) {
int i;
@@ -241,7 +249,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (col) {
float rgba[4];
- paint_get_tex_pixel_col(mtex, x, y, rgba, pool);
+ paint_get_tex_pixel_col(mtex, x, y, rgba, pool, omp_get_thread_num());
buffer[index * 4] = rgba[0] * 255;
buffer[index * 4 + 1] = rgba[1] * 255;
@@ -249,7 +257,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
buffer[index * 4 + 3] = rgba[3] * 255;
}
else {
- float avg = paint_get_tex_pixel(mtex, x, y, pool);
+ float avg = paint_get_tex_pixel(mtex, x, y, pool, omp_get_thread_num());
avg += br->texture_sample_bias;
@@ -272,6 +280,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
}
}
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
+
if (pool)
BKE_image_pool_free(pool);
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 6dd42380a11..af9ac6dd89d 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -198,8 +198,8 @@ void paint_calc_redraw_planes(float planes[4][4],
const struct rcti *screen_rect);
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
-float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool);
-void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool);
+float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
+void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread);
int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface);
void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]);
void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index e6efba4fa0c..de09709fcce 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -164,26 +164,25 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
return len_v3(delta) / scale;
}
-float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool)
+float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
{
float intensity, rgba[4];
float co[3] = {u, v, 0.0f};
externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
return intensity;
}
-void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool)
+void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread)
{
float co[3] = {u, v, 0.0f};
int hasrgb;
float intensity;
hasrgb = externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);
-
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
if (!hasrgb) {
rgba[0] = intensity;
rgba[1] = intensity;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index a04e15d3729..ae729248f7e 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -153,6 +153,10 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index,
vp_handle->dists_sq[index] = dist_sq;
}
+ else if (vp_handle->dists_sq[index] != FLT_MAX) {
+ /* already initialized & couldn't project this 'co' */
+ return;
+ }
}
/* continue with regular functionality */
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index d74e9c9e17b..35de6af2531 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -104,6 +104,19 @@
#include <omp.h>
#endif
+#if defined(__APPLE__)
+#include <sys/sysctl.h>
+
+/* Query how many cores not counting HT aka physical cores we've got. */
+static int system_physical_thread_count(void)
+{
+ int pcount;
+ size_t pcount_len = sizeof(pcount);
+ sysctlbyname("hw.physicalcpu", &pcount, &pcount_len, NULL, 0);
+ return pcount;
+}
+#endif /* __APPLE__ */
+
void ED_sculpt_get_average_stroke(Object *ob, float stroke[3])
{
if (ob->sculpt->last_stroke_valid && ob->sculpt->average_stroke_counter > 0) {
@@ -230,7 +243,7 @@ typedef struct StrokeCache {
float initial_mouse[2];
/* Pre-allocated temporary storage used during smoothing */
- int num_threads;
+ int num_threads, max_threads;
float (**tmpgrid_co)[3], (**tmprow_co)[3];
float **tmpgrid_mask, **tmprow_mask;
@@ -924,6 +937,7 @@ static float tex_strength(SculptSession *ss, Brush *br,
MTex *mtex = &br->mtex;
float avg = 1;
float rgba[4];
+ int thread_num;
if (!mtex->tex) {
avg = 1;
@@ -966,7 +980,12 @@ static float tex_strength(SculptSession *ss, Brush *br,
x += br->mtex.ofs[0];
y += br->mtex.ofs[1];
- avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool);
+#ifdef _OPENMP
+ thread_num = omp_get_thread_num();
+#else
+ thread_num = 0;
+#endif
+ avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool, thread_num);
avg += br->texture_sample_bias;
}
@@ -3766,16 +3785,21 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
* Justification: Empirically I've found that two threads per
* processor gives higher throughput. */
if (sd->flags & SCULPT_USE_OPENMP) {
- cache->num_threads = 2 * omp_get_num_procs();
- omp_set_num_threads(cache->num_threads);
- }
- else
+#if defined(__APPLE__)
+ cache->num_threads = system_physical_thread_count();
+#else
+ cache->num_threads = omp_get_num_procs();
#endif
- {
- (void)sd;
+ }
+ else {
cache->num_threads = 1;
}
-
+ cache->max_threads = omp_get_max_threads();
+ omp_set_num_threads(cache->num_threads);
+#else
+ (void)sd;
+ cache->num_threads = 1;
+#endif
if (ss->multires) {
int i, gridsize, array_mem_size;
BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
@@ -3802,6 +3826,10 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
static void sculpt_omp_done(SculptSession *ss)
{
+#ifdef _OPENMP
+ omp_set_num_threads(ss->cache->max_threads);
+#endif
+
if (ss->multires) {
int i;
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 18652aabefe..d417776b1f2 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -974,6 +974,10 @@ static bool prefetch_check_early_out(const bContext *C)
int first_uncached_frame, end_frame;
int clip_len;
+ if (clip == NULL) {
+ return true;
+ }
+
clip_len = BKE_movieclip_get_duration(clip);
/* check whether all the frames from prefetch range are cached */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index bb6c50d6224..0e152dbebcf 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -110,10 +110,21 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2])
}
if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) {
+ float dx, dy;
+
ED_space_clip_get_size(sc, &width, &height);
- sc->xof += ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
- sc->yof += ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
+ dx = ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
+ dy= ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
+
+ if (sc->flag & SC_LOCK_SELECTION) {
+ sc->xlockof += dx;
+ sc->ylockof += dy;
+ }
+ else {
+ sc->xof += dx;
+ sc->yof += dy;
+ }
}
}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 2f1d78b2ccd..c56bc33ef15 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -577,7 +577,10 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "sequence", TRUE);
/* mode */
- WM_keymap_add_menu(keymap, "CLIP_MT_select_mode", TABKEY, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", TABKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.mode");
+ RNA_string_set(kmi->ptr, "value_1", "TRACKING");
+ RNA_string_set(kmi->ptr, "value_2", "MASK");
WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 6f44b47ed61..2b7bb01cea1 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1309,10 +1309,13 @@ static void track_markers_updatejob(void *tmv)
static void track_markers_endjob(void *tmv)
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
+ wmWindowManager *wm = tmj->main->wm.first;
tmj->clip->tracking_context = NULL;
tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra);
- ED_update_for_newframe(tmj->main, tmj->scene, 0);
+ if (wm != NULL) {
+ ED_update_for_newframe(tmj->main, tmj->scene, 0);
+ }
BKE_tracking_context_sync(tmj->context);
BKE_tracking_context_finish(tmj->context);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index effb8eb7de5..f51d6cc3660 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -37,6 +37,7 @@
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -923,7 +924,7 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN
PointerRNA scene = CTX_data_pointer_get(C, "scene");
if (scene.data) {
PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
- if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+ if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0))
uiItemL(layout, IFACE_("SSS not supported on GPU"), ICON_ERROR);
}
@@ -933,12 +934,12 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN
static void node_shader_buts_volume(uiLayout *layout, bContext *C, PointerRNA *UNUSED(ptr))
{
- /* SSS does not work on GPU yet */
+ /* Volume does not work on GPU yet */
PointerRNA scene = CTX_data_pointer_get(C, "scene");
if (scene.data) {
PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
- if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+ if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0))
uiItemL(layout, IFACE_("Volumes not supported on GPU"), ICON_ERROR);
}
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index d44a3e60a3f..4db63a462e7 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -481,7 +481,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
char newname[sizeof(bone->name)];
/* always make current object active */
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+ tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
ob = OBACT;
/* restore bone name */
@@ -498,8 +498,10 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
char newname[sizeof(pchan->name)];
/* always make current pose-bone active */
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+ tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
ob = OBACT;
+
+ BLI_assert(ob->type == OB_ARMATURE);
/* restore bone name */
BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
@@ -1154,7 +1156,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
active = OL_DRAWSEL_NORMAL;
}
else {
- active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE);
+ active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false);
}
}
else {
@@ -1295,7 +1297,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
active = OL_DRAWSEL_ACTIVE;
}
else {
- if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE)) {
+ if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false)) {
glColor4ub(220, 220, 255, alpha);
active = OL_DRAWSEL_ACTIVE;
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index b1278c7cc07..317d33dd3e2 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -180,9 +180,8 @@ void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
eOLDrawState tree_element_type_active(
struct bContext *C, struct Scene *scene, struct SpaceOops *soops,
TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive);
-eOLDrawState tree_element_active(
- struct bContext *C, struct Scene *scene, SpaceOops *soops,
- TreeElement *te, const eOLSetState set);
+eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops,
+ TreeElement *te, const eOLSetState set, const bool handle_all_types);
int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive);
/* outliner_edit.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 688695e3ded..51db965b791 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -801,14 +801,17 @@ static eOLDrawState tree_element_active_keymap_item(
/* ---------------------------------------------- */
/* generic call for ID data check or make/check active in UI */
-eOLDrawState tree_element_active(
- bContext *C, Scene *scene, SpaceOops *soops,
- TreeElement *te, const eOLSetState set)
+eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te,
+ const eOLSetState set, const bool handle_all_types)
{
-
switch (te->idcode) {
- /* Note: no ID_OB: objects are handled specially to allow multiple
+ /* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple
* selection. See do_outliner_item_activate. */
+ case ID_OB:
+ if (handle_all_types) {
+ return tree_element_set_active_object(C, scene, soops, te, set, false);
+ }
+ break;
case ID_MA:
return tree_element_active_material(C, scene, soops, te, set);
case ID_WO:
@@ -952,7 +955,7 @@ static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Sp
WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
}
else { // rest of types
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+ tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 1464d39ff23..3a9d97001fb 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2296,7 +2296,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
float facx = BLI_rcti_size_x(&v2d->mask) / winx;
float facy = BLI_rcti_size_y(&v2d->mask) / winy;
- BLI_rctf_resize(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1);
+ BLI_rctf_resize(&v2d->cur, floorf(winx * facx * ratio + 0.5f), floorf(winy * facy * ratio + 0.5f));
ED_region_tag_redraw(CTX_wm_region(C));
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ea81bb2b857..57d6f053426 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -3590,9 +3590,8 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
if (!rv3d->smooth_timer) {
/* store settings of current view before allowing overwriting with camera view
* only if we're not currently in a view transition */
- copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
- rv3d->lview = rv3d->view;
- rv3d->lpersp = rv3d->persp;
+
+ ED_view3d_lastview_store(rv3d);
}
#if 0
@@ -4733,6 +4732,18 @@ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], co
BKE_object_apply_mat4(ob, mat, true, true);
}
+/**
+ * Use to store the last view, before entering camera view.
+ */
+void ED_view3d_lastview_store(RegionView3D *rv3d)
+{
+ copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
+ rv3d->lview = rv3d->view;
+ if (rv3d->persp != RV3D_CAMOB) {
+ rv3d->lpersp = rv3d->persp;
+ }
+}
+
BGpic *ED_view3D_background_image_new(View3D *v3d)
{
BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 83e4f112a8c..20ef59708a6 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -417,11 +417,7 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
ED_view3d_context_user_region(C, &v3d, &ar);
rv3d = ar->regiondata;
- copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
- rv3d->lview = rv3d->view;
- if (rv3d->persp != RV3D_CAMOB) {
- rv3d->lpersp = rv3d->persp;
- }
+ ED_view3d_lastview_store(rv3d);
BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 24f51635e07..5eca44c1ba5 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -137,7 +137,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
snapGridIncrement(t, vec);
- if (t->num.flag & T_NULL_ONE) {
+ if (t->flag & T_NULL_ONE) {
if (!(t->con.mode & CON_AXIS0))
vec[0] = 1.0f;
@@ -970,13 +970,13 @@ static void setNearestAxis3d(TransInfo *t)
sub_v2_v2v2(axis, axis_2d, t->center2d);
axis[2] = 0.0f;
- if (normalize_v3(axis) != 0.0f) {
+ if (normalize_v3(axis) > 1e-3f) {
project_v3_v3v3(proj, mvec, axis);
sub_v3_v3v3(axis, mvec, proj);
len[i] = normalize_v3(axis);
}
else {
- len[i] = 10000000000.0f;
+ len[i] = 1e10f;
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index bb0a74f1e09..e49e5c941a6 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -3845,13 +3845,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
}
/* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...):
- * - Check if we've got entire BezTriple selected and we're rotating that point,
+ * - Check if we've got entire BezTriple selected and we're scaling/rotating that point,
* then check if we're using auto-handles.
* - If so, change them auto-handles to aligned handles so that handles get affected too
*/
- if ((t->mode == TFM_ROTATION) &&
- ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) &&
- ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM))
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) &&
+ ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) &&
+ ELEM(t->mode, TFM_ROTATION, TFM_RESIZE))
{
if (hdata && (sel1) && (sel3)) {
bezt->h1 = HD_ALIGN;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 1f3725a961a..4c097ca7da6 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -321,8 +321,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_org[idx] = n->val[idx];
n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE);
- idx += event->ctrl ? -1 : 1;
- idx %= idx_max + 1;
+ idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1);
n->idx = idx;
n->val[idx] = n->val_org[idx];
if (n->val_flag[idx] & NUM_EDITED) {
@@ -334,42 +333,48 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
}
return true;
case PADPERIOD:
+ case PERIODKEY:
/* Force numdot, some OSs/countries generate a comma char in this case, sic... (T37992) */
ascii[0] = '.';
utf8_buf = ascii;
break;
+#if 0 /* Those keys are not directly accessible in all layouts, preventing to generate matching events.
+ * So we use a hack (ascii value) instead, see below.
+ */
case EQUALKEY:
- /* XXX Advanced mode toggle, hack around keyboards without direct access to '=' nor '*'... */
- ascii[0] = '=';
- break;
case PADASTERKEY:
- /* XXX Advanced mode toggle, hack around keyboards without direct access to '=' nor '*'... */
- ascii[0] = '*';
+ if (!(n->flag & NUM_EDIT_FULL)) {
+ n->flag |= NUM_EDIT_FULL;
+ n->val_flag[idx] |= NUM_EDITED;
+ return true;
+ }
+ else if (event->ctrl) {
+ n->flag &= ~NUM_EDIT_FULL;
+ return true;
+ }
break;
+#endif
case PADMINUS:
case MINUSKEY:
if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
n->val_flag[idx] ^= NUM_NEGATE;
updated = true;
- break;
}
- /* fall-through */
+ break;
case PADSLASHKEY:
case SLASHKEY:
if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
n->val_flag[idx] ^= NUM_INVERSE;
updated = true;
- break;
}
- /* fall-through */
+ break;
case CKEY:
if (event->ctrl) {
/* Copy current str to the copypaste buffer. */
WM_clipboard_text_set(n->str, 0);
updated = true;
- break;
}
- /* fall-through */
+ break;
case VKEY:
if (event->ctrl) {
/* extract the first line from the clipboard */
@@ -377,9 +382,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len);
if (pbuf) {
- bool success;
-
- success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
+ const bool success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
MEM_freeN(pbuf);
if (!success) {
@@ -389,15 +392,17 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[idx] |= NUM_EDITED;
}
updated = true;
- break;
}
- /* fall-through */
+ break;
default:
- utf8_buf = event->utf8_buf;
- ascii[0] = event->ascii;
break;
}
+ if (!updated && !utf8_buf && (event->utf8_buf[0] || event->ascii)) {
+ utf8_buf = event->utf8_buf;
+ ascii[0] = event->ascii;
+ }
+
/* XXX Hack around keyboards without direct access to '=' nor '*'... */
if (ELEM(ascii[0], '=', '*')) {
if (!(n->flag & NUM_EDIT_FULL)) {
@@ -411,7 +416,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
}
}
- if (utf8_buf && !utf8_buf[0] && ascii[0]) {
+ if ((!utf8_buf || !utf8_buf[0]) && ascii[0]) {
/* Fallback to ascii. */
utf8_buf = ascii;
}
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp
index e517bf4f196..fbfa5b331e6 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.cpp
+++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp
@@ -557,17 +557,20 @@ void FitCurveWrapper::FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, V
if (maxError < iterationError) {
for (i = 0; i < maxIterations; i++) {
uPrime = Reparameterize(d, first, last, u, bezCurve);
- bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2);
- maxError = ComputeMaxError(d, first, last,
- bezCurve, uPrime, &splitPoint);
+
+ free((void *)u);
+ free((void *)bezCurve);
+ u = uPrime;
+
+ bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);
+ maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
+
if (maxError < error) {
DrawBezierCurve(3, bezCurve);
free((void *)u);
free((void *)bezCurve);
return;
}
- free((void *)u);
- u = uPrime;
}
}
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index abe13b85cd2..a750cf2f7cf 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -577,10 +577,10 @@ void transformVertex(const Vec3r& vert, const Matrix44r& matrix, Vec3r& res)
void transformVertices(const vector<Vec3r>& vertices, const Matrix44r& trans, vector<Vec3r>& res)
{
- for (vector<Vec3r>::const_iterator v = vertices.begin(); v != vertices.end(); v++) {
- Vec3r *res_tmp = new Vec3r;
- transformVertex(*v, trans, *res_tmp);
- res.push_back(*res_tmp);
+ size_t i;
+ res.resize(vertices.size());
+ for (i = 0; i < vertices.size(); i++) {
+ transformVertex(vertices[i], trans, res[i]);
}
}
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h
index 02b738cc2cd..f4d6d869f1b 100644
--- a/source/blender/imbuf/intern/IMB_allocimbuf.h
+++ b/source/blender/imbuf/intern/IMB_allocimbuf.h
@@ -35,6 +35,9 @@
struct ImBuf;
+void imb_refcounter_lock_init(void);
+void imb_refcounter_lock_exit(void);
+
bool imb_addencodedbufferImBuf(struct ImBuf *ibuf);
bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index d7ca381bae6..d0e81f2f383 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -49,6 +49,19 @@
#include "MEM_CacheLimiterC-Api.h"
#include "BLI_utildefines.h"
+#include "BLI_threads.h"
+
+static SpinLock refcounter_spin;
+
+void imb_refcounter_lock_init(void)
+{
+ BLI_spin_init(&refcounter_spin);
+}
+
+void imb_refcounter_lock_exit(void)
+{
+ BLI_spin_end(&refcounter_spin);
+}
void imb_freemipmapImBuf(ImBuf *ibuf)
{
@@ -154,10 +167,18 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf)
void IMB_freeImBuf(ImBuf *ibuf)
{
if (ibuf) {
+ bool needs_free = false;
+
+ BLI_spin_lock(&refcounter_spin);
if (ibuf->refcounter > 0) {
ibuf->refcounter--;
}
else {
+ needs_free = true;
+ }
+ BLI_spin_unlock(&refcounter_spin);
+
+ if (needs_free) {
imb_freerectImBuf(ibuf);
imb_freerectfloatImBuf(ibuf);
imb_freetilesImBuf(ibuf);
@@ -177,7 +198,9 @@ void IMB_freeImBuf(ImBuf *ibuf)
void IMB_refImBuf(ImBuf *ibuf)
{
+ BLI_spin_lock(&refcounter_spin);
ibuf->refcounter++;
+ BLI_spin_unlock(&refcounter_spin);
}
ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c
index 9141dad6f9c..4097deb00ed 100644
--- a/source/blender/imbuf/intern/module.c
+++ b/source/blender/imbuf/intern/module.c
@@ -26,12 +26,17 @@
#include <stddef.h>
+
+#include "BLI_utildefines.h"
+
+#include "IMB_allocimbuf.h"
#include "IMB_imbuf.h"
#include "IMB_filetype.h"
#include "IMB_colormanagement_intern.h"
void IMB_init(void)
{
+ imb_refcounter_lock_init();
imb_filetypes_init();
imb_tile_cache_init();
colormanagement_init();
@@ -42,5 +47,6 @@ void IMB_exit(void)
imb_tile_cache_exit();
imb_filetypes_exit();
colormanagement_exit();
+ imb_refcounter_lock_exit();
}
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 07ce3c39d73..f699afd3475 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -200,6 +200,18 @@ static size_t IMB_get_size_in_memory(ImBuf *ibuf)
int a;
size_t size = 0, channel_size = 0;
+ /* Persistent images should have no affect on how "normal"
+ * images are cached.
+ *
+ * This is a bit arbitrary, but would make it so only movies
+ * and sequences are memory limited, keeping textures in the
+ * memory in order to avoid constant file reload on viewport
+ * update.
+ */
+ if (ibuf->userflags & IB_PERSISTENT) {
+ return 0;
+ }
+
size += sizeof(ImBuf);
if (ibuf->rect)
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 05e9a4fa134..eb8f94cbc6e 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -859,7 +859,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
if (TIFFWriteEncodedStrip(image, 0,
(bitspersample == 16) ? (unsigned char *)pixels16 : pixels,
- ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
+ (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
{
fprintf(stderr,
"imb_savetiff: Could not write encoded TIFF.\n");
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 7efd0223368..087f26dda44 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -179,6 +179,7 @@ const char *imb_ext_audio[] = {
".aif",
".aiff",
".m4a",
+ ".mka",
NULL
};
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 86ef2f1b74f..2f867fe95e1 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -2035,7 +2035,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0)
values[0] = RNA_property_int_get(ptr, prop);
else
@@ -2124,7 +2124,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0)
IDP_Int(idprop) = values[0];
else
@@ -2297,7 +2297,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0)
values[0] = RNA_property_float_get(ptr, prop);
else if (idprop->subtype == IDP_FLOAT) {
@@ -2392,7 +2392,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0) {
if (idprop->type == IDP_FLOAT)
IDP_Float(idprop) = values[0];
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 408f99bd96a..a55be8e285f 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -62,6 +62,7 @@
#include "ED_node.h"
#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
static int rna_CurveMapping_curves_length(PointerRNA *ptr)
{
@@ -609,10 +610,24 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain)
}
if (seq_found) {
+ if (seq->anim) {
+ IMB_free_anim(seq->anim);
+ seq->anim = NULL;
+ }
+
BKE_sequence_invalidate_cache(scene, seq);
BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
}
else {
+ SEQ_BEGIN(scene->ed, seq);
+ {
+ if (seq->anim) {
+ IMB_free_anim(seq->anim);
+ seq->anim = NULL;
+ }
+ }
+ SEQ_END;
+
BKE_sequencer_cache_cleanup();
BKE_sequencer_preprocessed_cache_cleanup();
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 31e87f44a6a..f6f133c5114 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -475,7 +475,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
if (particle_no < totpart) {
/* get uvco & mcol */
- num = particle->num_dmcache;
+ num = (ELEM(particle->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ?
+ particle->num : particle->num_dmcache;
if (num == DMCACHE_NOTFOUND)
if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 479f70531e5..ae0841b4e28 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -821,7 +821,9 @@ static EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA
(ptr->type == &RNA_EnumProperty) ||
(C == NULL))
{
- return eprop->item;
+ if (eprop->item) {
+ return eprop->item;
+ }
}
return eprop->itemf(C, ptr, prop, r_free);
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 16f51bdd34f..142e5cadfd1 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -1515,7 +1515,7 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis
ret = PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
+ PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_height));
return ret;
}
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 977c30ff20a..59a2a0d78fc 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -981,6 +981,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
int a, vdone = false, result = BAKE_RESULT_OK;
bool use_mask = false;
bool use_displacement_buffer = false;
+ bool do_manage = BKE_scene_check_color_management_enabled(re->scene);
re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
@@ -1040,6 +1041,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
}
handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC);
handles[a].ssamp.shi[0].thread = a;
+ handles[a].ssamp.shi[0].do_manage = do_manage;
handles[a].ssamp.tot = 1;
handles[a].type = type;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 0d09fa0401e..7d662f8f338 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -5873,7 +5873,9 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
re->lay= lay;
/* renderdata setup and exceptions */
- re->r= scene->r;
+ BLI_freelistN(&re->r.layers);
+ re->r = scene->r;
+ BLI_duplicatelist(&re->r.layers, &scene->r.layers);
RE_init_threadcount(re);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 74768f925f8..4bf65879ad6 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1413,7 +1413,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
if (op->type->flag & OPTYPE_MACRO) {
for (op = op->macro.first; op; op = op->next) {
- uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
}
}
@@ -1816,14 +1815,14 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
/* label for 'a' bugfix releases, or 'Release Candidate 1'...
* avoids recreating splash for version updates */
- if (false) {
+ if (true) {
/* placed after the version number in the image,
* placing y is tricky to match baseline */
int x = 260 - (2 * UI_DPI_WINDOW_FAC);
int y = 242 + (4 * UI_DPI_WINDOW_FAC);
int w = 240;
- const char *version_suffix = "Release Candidate";
+ const char *version_suffix = "a";
/* hack to have text draw 'text_sel' */
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 6a2ef471be0..9fa64bf65b3 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -373,15 +373,20 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
if (win->eventstate == NULL)
win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state");
+#ifdef __APPLE__
+ /* set the state here, else OSX would nor recignize changed screen resolution */
+ GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
+#endif
/* store actual window size in blender window */
bounds = GHOST_GetClientBounds(win->ghostwin);
win->sizex = GHOST_GetWidthRectangle(bounds);
win->sizey = GHOST_GetHeightRectangle(bounds);
GHOST_DisposeRectangle(bounds);
-
- /* set the state */
+
+#ifndef __APPLE__
+ /* set the state here, so minimized state comes up correct on windows */
GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
-
+#endif
/* until screens get drawn, make it nice gray */
glClearColor(0.55, 0.55, 0.55, 0.0);
/* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 0ec54412485..365bce34a60 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -938,11 +938,12 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated;
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
- if (bucketCreated) {
- // this is needed to free up memory afterwards
- converter->RegisterPolyMaterial(polymat);
- converter->RegisterBlenderMaterial(bl_mat);
- }
+
+ // this is needed to free up memory afterwards.
+ // the converter will also prevent duplicates from being registered,
+ // so just register everything.
+ converter->RegisterPolyMaterial(polymat);
+ converter->RegisterBlenderMaterial(bl_mat);
return bucket;
}
diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp
index be85d89775f..75beb5d0e0e 100644
--- a/source/gameengine/Converter/BlenderWorldInfo.cpp
+++ b/source/gameengine/Converter/BlenderWorldInfo.cpp
@@ -61,6 +61,7 @@
#include "BLI_math.h"
#include "BKE_global.h"
+#include "BKE_scene.h"
/* end of blender include block */
@@ -86,7 +87,7 @@ BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World *ble
copy_v3_v3(m_backgroundcolor, &blenderworld->horr);
copy_v3_v3(m_ambientcolor, &blenderworld->ambr);
- if (blenderscene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if (BKE_scene_check_color_management_enabled(blenderscene)) {
linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor);
linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor);
linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor);
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index c0c28d15ad3..854e9fe7327 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -233,8 +233,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
Scene *sce;
/**
- * Find the specified scene by name, or the first
- * scene if nothing matches (shouldn't happen).
+ * Find the specified scene by name, or NULL if nothing matches.
*/
if ((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
return sce;
@@ -246,7 +245,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
return sce;
}
- return (Scene*)m_maggie->scene.first;
+ return NULL;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 3aa5a9f4f0e..e6b22420d90 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -1702,6 +1702,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
{
Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
+ if (!scene)
+ return NULL;
return CreateScene(scene);
}
@@ -1717,8 +1719,12 @@ void KX_KetsjiEngine::AddScheduledScenes()
{
STR_String scenename = *scenenameit;
KX_Scene* tmpscene = CreateScene(scenename);
- m_scenes.push_back(tmpscene);
- PostProcessScene(tmpscene);
+ if (tmpscene) {
+ m_scenes.push_back(tmpscene);
+ PostProcessScene(tmpscene);
+ } else {
+ printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr());
+ }
}
m_addingOverlayScenes.clear();
}
@@ -1731,9 +1737,12 @@ void KX_KetsjiEngine::AddScheduledScenes()
{
STR_String scenename = *scenenameit;
KX_Scene* tmpscene = CreateScene(scenename);
- m_scenes.insert(m_scenes.begin(),tmpscene);
- PostProcessScene(tmpscene);
-
+ if (tmpscene) {
+ m_scenes.insert(m_scenes.begin(),tmpscene);
+ PostProcessScene(tmpscene);
+ } else {
+ printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr());
+ }
}
m_addingBackgroundScenes.clear();
}
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index e85b57f1769..abbe65738d4 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -395,10 +395,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
return;
const int *viewport = canvas->GetViewPort();
- RAS_Rect rect = canvas->GetWindowArea();
- int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1;
- if (texturewidth != rect_width || textureheight != rect_height)
+ if (texturewidth != viewport[2] || textureheight != viewport[3])
{
UpdateOffsetMatrix(canvas);
UpdateCanvasTextureCoord(viewport);
@@ -414,22 +412,22 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if (need_depth) {
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], viewport[2], viewport[3], 0);
}
if (need_luminance) {
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1], viewport[2], viewport[3], 0);
}
// reverting to texunit 0, without this we get bug [#28462]
glActiveTextureARB(GL_TEXTURE0);
- canvas->SetViewPort(0, 0, rect_width-1, rect_height-1);
// We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport,
// but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen.
RAS_Rect scissor_rect = canvas->GetDisplayArea();
+
glScissor(scissor_rect.GetLeft() + viewport[0],
scissor_rect.GetBottom() + viewport[1],
scissor_rect.GetWidth() + 1,
@@ -459,7 +457,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], viewport[2], viewport[3], 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
@@ -473,8 +471,6 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
glEnable(GL_DEPTH_TEST);
- //We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517]
- canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1);
EndShaderProgram();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);