From 19e627cab34a04a3d01b2e3a868b7bf91d56e8f9 Mon Sep 17 00:00:00 2001
From: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Tue, 18 Mar 2014 18:54:41 +0600
Subject: [PATCH] Backport revisions for the final 2.70 release

e6a359a, 9437927, a205700, d908c90, a6e3471, deef641,
4080673, 0141265, 0c6e744, f959e3d, ade6646, caf5d90,
5febb09, d08e6ab, 22873ea, 3d031d1, c450ea2, 60cab47,
ed26edb, df25dbf, f127f49.
---
 extern/carve/lib/intersect_face_division.cpp  |  4 ++++
 .../patches/face_hole_merge_workaround.patch  | 14 +++++++++++++
 extern/carve/patches/series                   |  1 +
 intern/cycles/render/tables.cpp               |  5 ++++-
 release/scripts/addons                        |  2 +-
 release/scripts/modules/bpy/ops.py            |  5 ++++-
 .../bl_operators/uvcalc_smart_project.py      | 10 ++++-----
 source/blender/blenkernel/BKE_blender.h       |  2 +-
 source/blender/blenkernel/intern/image.c      |  1 +
 source/blender/blenkernel/intern/object.c     |  5 +++++
 .../blenkernel/intern/particle_system.c       | 21 ++++++++++++++++---
 source/blender/bmesh/operators/bmo_connect.c  |  3 ++-
 .../blender/bmesh/operators/bmo_subdivide.c   |  2 +-
 .../blender/bmesh/tools/bmesh_bisect_plane.c  |  4 +---
 source/blender/bmesh/tools/bmesh_path.c       |  8 +++++++
 .../operations/COM_MapUVOperation.cpp         |  5 +++--
 .../editors/interface/interface_handlers.c    |  2 +-
 .../editors/interface/interface_regions.c     |  3 +++
 .../editors/interface/interface_templates.c   | 10 +++++++++
 .../blender/editors/render/render_internal.c  |  7 ++++++-
 .../editors/space_sequencer/sequencer_edit.c  |  7 +++++--
 .../editors/space_view3d/view3d_edit.c        |  7 +++++--
 .../editors/transform/transform_conversions.c |  4 ++--
 source/blender/makesdna/DNA_particle_types.h  |  4 ++--
 .../modifiers/intern/MOD_laplaciandeform.c    |  2 +-
 .../render/intern/source/convertblender.c     |  2 ++
 .../windowmanager/intern/wm_operators.c       |  6 +++---
 27 files changed, 113 insertions(+), 33 deletions(-)
 create mode 100644 extern/carve/patches/face_hole_merge_workaround.patch

diff --git a/extern/carve/lib/intersect_face_division.cpp b/extern/carve/lib/intersect_face_division.cpp
index e826948128c..0016724e16c 100644
--- a/extern/carve/lib/intersect_face_division.cpp
+++ b/extern/carve/lib/intersect_face_division.cpp
@@ -719,6 +719,10 @@ namespace {
           unassigned--;
         }
       }
+
+      if (!removed.size())
+        throw carve::exception("Failed to merge holes");
+
       for (std::set<int>::iterator f = removed.begin(); f != removed.end(); ++f) {
         for (unsigned i = 0; i < containing_faces.size(); ++i) {
           containing_faces[i].erase(std::remove(containing_faces[i].begin(),
diff --git a/extern/carve/patches/face_hole_merge_workaround.patch b/extern/carve/patches/face_hole_merge_workaround.patch
new file mode 100644
index 00000000000..834e03a4b12
--- /dev/null
+++ b/extern/carve/patches/face_hole_merge_workaround.patch
@@ -0,0 +1,14 @@
+diff -r e82d852e4fb0 lib/intersect_face_division.cpp
+--- a/lib/intersect_face_division.cpp	Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/intersect_face_division.cpp	Thu Mar 13 15:39:26 2014 +0600
+@@ -719,6 +719,10 @@
+           unassigned--;
+         }
+       }
++
++      if (!removed.size())
++        throw carve::exception("Failed to merge holes");
++
+       for (std::set<int>::iterator f = removed.begin(); f != removed.end(); ++f) {
+         for (unsigned i = 0; i < containing_faces.size(); ++i) {
+           containing_faces[i].erase(std::remove(containing_faces[i].begin(),
diff --git a/extern/carve/patches/series b/extern/carve/patches/series
index 62a24d9d730..286d594bbef 100644
--- a/extern/carve/patches/series
+++ b/extern/carve/patches/series
@@ -9,3 +9,4 @@ interpolator_reorder.patch
 mesh_simplify_dissolve_edges.patch
 memory_leak_fix.patch
 mavc_fix.patch
+face_hole_merge_workaround.patch
diff --git a/intern/cycles/render/tables.cpp b/intern/cycles/render/tables.cpp
index be0d4afbe2c..a8d502c432d 100644
--- a/intern/cycles/render/tables.cpp
+++ b/intern/cycles/render/tables.cpp
@@ -39,7 +39,10 @@ void LookupTables::device_update(Device *device, DeviceScene *dscene)
 	if(!need_update)
 		return;
 
-	device->tex_alloc("__lookup_table", dscene->lookup_table);
+	device->tex_free(dscene->lookup_table);
+
+	if(lookup_tables.size() > 0)
+		device->tex_alloc("__lookup_table", dscene->lookup_table);
 
 	need_update = false;
 }
diff --git a/release/scripts/addons b/release/scripts/addons
index 8ad356e3324..6c32300be8c 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 8ad356e3324cddef42d41f9b9b588ef1ebd2f8bf
+Subproject commit 6c32300be8cc8d48a3e02055dc43bea2ab98a525
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 1d71bffbd84..e457c087ab8 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -204,7 +204,10 @@ class BPyOpsSubModOp(object):
         import bpy
         idname = self.idname()
         as_string = op_as_string(idname)
-        op_class = getattr(bpy.types, idname)
+        # XXX You never quite know what you get from bpy.types, with operators... Operator and OperatorProperties
+        #     are shadowing each other, and not in the same way for native ops and py ones! See T39158.
+        # op_class = getattr(bpy.types, idname)
+        op_class = op_get_rna(idname)
         descr = op_class.bl_rna.description
         # XXX, workaround for not registering
         # every __doc__ to save time on load.
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 74fb9e98c82..70df5a9df21 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -23,7 +23,7 @@ import bpy
 from bpy.types import Operator
 
 DEG_TO_RAD = 0.017453292519943295 # pi/180.0
-SMALL_NUM = 0.000001  # see bug [#31598] why we dont have smaller values
+SMALL_NUM = 0.00000001  # see bug [#31598] why we dont have smaller values
 
 global USER_FILL_HOLES
 global USER_FILL_HOLES_QUALITY
@@ -594,10 +594,10 @@ def packIslands(islandList):
             # recalc width and height
             w, h = maxx-minx, maxy-miny
 
-        if w < 0.00001 or h < 0.00001:
-            del islandList[islandIdx]
-            islandIdx -=1
-            continue
+        if w < SMALL_NUM:
+            w = SMALL_NUM
+        if h < SMALL_NUM:
+            h = SMALL_NUM
 
         """Save the offset to be applied later,
         we could apply to the UVs now and allign them to the bottom left hand area
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index d35ff80265f..ec595320d6a 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -51,7 +51,7 @@ extern "C" {
 /* can be left blank, otherwise a,b,c... etc with no quotes */
 #define BLENDER_VERSION_CHAR   
 /* alpha/beta/rc/release, docs use this */
-#define BLENDER_VERSION_CYCLE   rc
+#define BLENDER_VERSION_CYCLE   release
 
 extern char versionstr[]; /* from blender.c */
 
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 55699bc0aae..b8b126c4c8e 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -3620,6 +3620,7 @@ ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
 				IMB_refImBuf(ibuf);
 				break;
 			}
+			IMB_moviecacheIter_step(iter);
 		}
 		IMB_moviecacheIter_free(iter);
 	}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 43dbc34f3d3..0970af46a6b 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -331,6 +331,10 @@ void BKE_object_free_derived_caches(Object *ob)
 			free_path(ob->curve_cache->path);
 			ob->curve_cache->path = NULL;
 		}
+
+		/* Signal for viewport to run DAG workarounds. */
+		MEM_freeN(ob->curve_cache);
+		ob->curve_cache = NULL;
 	}
 }
 
@@ -1282,6 +1286,7 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
 	psysn->pdd = NULL;
 	psysn->effectors = NULL;
 	psysn->tree = NULL;
+	psysn->bvhtree = NULL;
 	
 	BLI_listbase_clear(&psysn->pathcachebufs);
 	BLI_listbase_clear(&psysn->childcachebufs);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 3f4c53692e5..e7c2bf605c3 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -109,6 +109,8 @@
 
 #endif // WITH_MOD_FLUID
 
+static ThreadRWMutex psys_bvhtree_rwlock = BLI_RWLOCK_INITIALIZER;
+
 /************************************************/
 /*			Reacting to system events			*/
 /************************************************/
@@ -2209,15 +2211,22 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
 	if (psys) {
 		PARTICLE_P;
 		int totpart = 0;
+		bool need_rebuild;
 
-		if (!psys->bvhtree || psys->bvhtree_frame != cfra) {
+		BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ);
+		need_rebuild = !psys->bvhtree || psys->bvhtree_frame != cfra;
+		BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
+		
+		if (need_rebuild) {
 			LOOP_SHOWN_PARTICLES {
 				totpart++;
 			}
 			
+			BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_WRITE);
+			
 			BLI_bvhtree_free(psys->bvhtree);
 			psys->bvhtree = BLI_bvhtree_new(totpart, 0.0, 4, 6);
-
+			
 			LOOP_SHOWN_PARTICLES {
 				if (pa->alive == PARS_ALIVE) {
 					if (pa->state.time == cfra)
@@ -2227,8 +2236,10 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
 				}
 			}
 			BLI_bvhtree_balance(psys->bvhtree);
-
+			
 			psys->bvhtree_frame = cfra;
+			
+			BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
 		}
 	}
 }
@@ -2546,7 +2557,11 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3],
 			break;
 		}
 		else {
+			BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ);
+			
 			BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr);
+			
+			BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
 		}
 	}
 }
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 3d2c8c3d020..6e2bc0d0edf 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -48,7 +48,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f)
 
 	BMIter liter;
 	BMFace *f_new;
-	BMLoop *l, *l_new;
+	BMLoop *l;
 	BMLoop *l_last;
 	unsigned int i;
 
@@ -96,6 +96,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f)
 	}
 
 	for (i = 0; i < STACK_SIZE(verts_pair); i++) {
+		BMLoop *l_new;
 		BMLoop *l_a, *l_b;
 
 		if ((l_a = BM_face_vert_share_loop(f, verts_pair[i][0])) &&
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 723595771a1..1e93340d8a3 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -135,7 +135,6 @@ typedef struct SubDPattern {
  * edge subdivision */
 static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new)
 {
-	BMLoop *l_new;
 	BMLoop *l_a, *l_b;
 	BMFace *f;
 
@@ -146,6 +145,7 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace
 
 	if (f) {
 		BMFace *f_new;
+		BMLoop *l_new;
 
 		f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false);
 		
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index 7a33dc40f8e..f4318933deb 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -136,16 +136,14 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
 	if ((STACK_SIZE(vert_split_arr) > 1) &&
 	    (use_dirs[0] && use_dirs[2]))
 	{
-		BMLoop *l_new;
-
 		if (LIKELY(STACK_SIZE(vert_split_arr) == 2)) {
+			BMLoop *l_new;
 			BMLoop *l_a, *l_b;
 
 			l_a = BM_face_vert_share_loop(f, vert_split_arr[0]);
 			l_b = BM_face_vert_share_loop(f, vert_split_arr[1]);
 
 			/* common case, just cut the face once */
-			l_new = NULL;
 			BM_face_split(bm, f, l_a, l_b, &l_new, NULL, true);
 			if (l_new) {
 				if (oflag_center) {
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index 9fc1996e51a..060d0dd969b 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -193,6 +193,14 @@ static void edgetag_add_adjacent(Heap *heap, BMEdge *e1, BMEdge **edges_prev, fl
 	const int e1_index = BM_elem_index_get(e1);
 
 	BM_ITER_ELEM (v, &viter, e1, BM_VERTS_OF_EDGE) {
+
+		/* don't walk over previous vertex */
+		if ((edges_prev[e1_index]) &&
+		    (BM_vert_in_edge(edges_prev[e1_index], v)))
+		{
+			continue;
+		}
+
 		BM_ITER_ELEM (e2, &eiter, v, BM_EDGES_OF_VERT) {
 			if (!BM_elem_flag_test(e2, BM_ELEM_TAG)) {
 				/* we know 'e2' is not visited, check it out! */
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp
index 292f073548a..87ad1d6afa4 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp
@@ -29,6 +29,7 @@ MapUVOperation::MapUVOperation() : NodeOperation()
 	this->addOutputSocket(COM_DT_COLOR);
 	this->m_alpha = 0.0f;
 	this->setComplex(true);
+	setResolutionInputSocketIndex(1);
 
 	this->m_inputUVProgram = NULL;
 	this->m_inputColorProgram = NULL;
@@ -84,8 +85,8 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
 	else {
 		float col[4];
 		m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR);
-		r_u = col[0] * width;
-		r_v = col[1] * height;
+		r_u = col[0] * m_inputColorProgram->getWidth();
+		r_v = col[1] * m_inputColorProgram->getHeight();
 		r_alpha = col[2];
 		return true;
 	}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 079b64f852c..f1c0df23fc9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2911,7 +2911,7 @@ static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleBut
 	ARegion *ar = CTX_wm_region(C);
 	uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
 
-	if (labelbut && labelbut->type == TEX) {
+	if (labelbut && labelbut->type == TEX && !(labelbut->flag & UI_BUT_DISABLED)) {
 		/* exit listrow */
 		data->cancel = true;
 		button_activate_exit(C, but, data, false, false);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 3d7492c9753..7d0fc858180 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1901,6 +1901,9 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
 		case USER_CP_SQUARE_HV:
 			square_picker(block, ptr, prop, UI_GRAD_HV);
 			break;
+		default:
+			circle_picker(block, ptr, prop);
+			break;
 	}
 	
 	/* mode */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index dcfb2e5cfbc..d04a67baa50 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2254,6 +2254,11 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
 			but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
 			                     -1, 0.0, 0.0, UI_GRAD_HV, 0, "");
 			break;
+		default:
+			but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+								 -1, 0.0, 0.0, 0, 0, "");
+			break;
+
 	}
 
 	if (lock) {
@@ -2293,6 +2298,11 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
 				uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
 				               -1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
 				break;
+			default:
+				uiItemS(row);
+				uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
+							   -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
+				break;
 		}
 	}
 }
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 35f17ec22af..eae15e7766d 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -131,7 +131,12 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
 	ColorManagedViewSettings *view_settings;
 	ColorManagedDisplaySettings *display_settings;
 
-	if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) {
+	/* Exception for exr tiles -- display buffer conversion happens here,
+	 * NOT in the color management pipeline.
+	 */
+	if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID &&
+	    rr->do_exr_tile == false)
+	{
 		/* The whole image buffer it so be color managed again anyway. */
 		return;
 	}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 0a37496c88a..1464d39ff23 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1,5 +1,5 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
+ * ***** begin GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -1901,6 +1901,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
 
 	while (seq) {
 		if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
+			Sequence *seq_next;
+
 			/* remove seq so overlap tests don't conflict,
 			 * see seq_free_sequence below for the real free'ing */
 			BLI_remlink(ed->seqbasep, seq);
@@ -1944,8 +1946,9 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
 				start_ofs += step;
 			}
 
+			seq_next = seq->next;
 			BKE_sequence_free(scene, seq);
-			seq = seq->next;
+			seq = seq_next;
 		}
 		else {
 			seq = seq->next;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 55950579637..ea81bb2b857 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -1049,6 +1049,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
 static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
 {
 	RegionView3D *rv3d = ar->regiondata;
+	const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
 
 	BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
 
@@ -1057,9 +1058,11 @@ static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
 
 	if (rv3d->persp != RV3D_PERSP) {
 		if (rv3d->persp == RV3D_CAMOB) {
-			view3d_persp_switch_from_camera(v3d, rv3d, rv3d->lpersp);
+			/* If autopersp and previous view was an axis one, switch back to PERSP mode, else reuse previous mode. */
+			char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
+			view3d_persp_switch_from_camera(v3d, rv3d, persp);
 		}
-		else if ((U.uiflag & USER_AUTOPERSP) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+		else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
 			rv3d->persp = RV3D_PERSP;
 		}
 	}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 8dc0c6ddaa8..bb0a74f1e09 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -6588,7 +6588,7 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
 
 			td->flag = 0;
 			td->loc = td2d->loc;
-			copy_v3_v3(td->center, bezt->vec[1]);
+			mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
 			copy_v3_v3(td->iloc, td->loc);
 
 			memset(td->axismtx, 0, sizeof(td->axismtx));
@@ -6636,7 +6636,7 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
 
 		td->flag = 0;
 		td->loc = td2d->loc;
-		copy_v3_v3(td->center, bezt->vec[1]);
+		mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
 		copy_v3_v3(td->iloc, td->loc);
 
 		memset(td->axismtx, 0, sizeof(td->axismtx));
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 7b06f2a46db..a2a724b6a32 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -304,8 +304,8 @@ typedef struct ParticleSystem {
 	ParticleSpring *fluid_springs;
 	int tot_fluidsprings, alloc_fluidsprings;
 
-	struct KDTree *tree;								/* used for interactions with self and other systems */
-	struct BVHTree *bvhtree;								/* used for interactions with self and other systems */
+	struct KDTree *tree;					/* used for interactions with self and other systems */
+	struct BVHTree *bvhtree;				/* used for interactions with self and other systems */
 
 	struct ParticleDrawData *pdd;
 
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index 9ed99fc4aed..8e2a58b2236 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -808,7 +808,7 @@ static void copyData(ModifierData *md, ModifierData *target)
 	modifier_copyData_generic(md, target);
 
 	tlmd->vertexco = MEM_dupallocN(lmd->vertexco);
-	tlmd->cache_system = MEM_dupallocN(lmd->cache_system);
+	tlmd->cache_system = NULL;
 }
 
 static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 833acb68a7c..0d09fa0401e 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -5036,6 +5036,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
 					if (!allow_render_object(re, obd, nolamps, onlyselected, actob))
 						continue;
 
+					copy_m4_m4(obd->obmat, dob->mat);
+
 					if (allow_render_dupli_instance(re, dob, obd)) {
 						ParticleSystem *psys;
 						ObjectRen *obr = NULL;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 29ba7b09e5c..74768f925f8 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1816,7 +1816,7 @@ 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 (1) {
+	if (false) {
 		/* placed after the version number in the image,
 		 * placing y is tricky to match baseline */
 		int x = 260 - (2 * UI_DPI_WINDOW_FAC);
@@ -1870,6 +1870,8 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
 	split = uiLayoutSplit(layout, 0.0f, FALSE);
 	col = uiLayoutColumn(split, FALSE);
 	uiItemL(col, IFACE_("Links"), ICON_NONE);
+	uiItemStringO(col, IFACE_("Support an Open Animation Movie"), ICON_URL, "WM_OT_url_open", "url",
+	              "http://cloud.blender.org/gooseberry");
 	uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url",
 	              "http://www.blender.org/foundation/donation-payment/");
 	uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url",
@@ -1879,8 +1881,6 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
 	uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url",
 	              "http://wiki.blender.org/index.php/Doc:2.6/Manual");
 	uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
-	uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url",
-	              "http://www.blender.org/community/user-community");
 	if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
 		BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
 		                               STRINGIFY(BLENDER_VERSION_CHAR) "_release",
-- 
GitLab