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:
authorJulian Eisel <eiseljulian@gmail.com>2017-03-06 15:00:46 +0300
committerJulian Eisel <eiseljulian@gmail.com>2017-03-06 15:00:46 +0300
commita5cba9aab9a2ade00caefc1a7697f8fbd3f7304f (patch)
treeb34138ac968663a47cdd2b09a26ea68aeeba2377
parentdc9a7f861fa43fecae7450ee254a711b061c0c26 (diff)
parentb498db06eb43f1e036f16cb346bf4cbb6d20e6d5 (diff)
Merge branch 'master' into blender2.8
Conflicts: source/blender/editors/space_nla/nla_draw.c source/blender/editors/space_view3d/view3d_draw.c
-rw-r--r--CMakeLists.txt20
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp1
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h7
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py4
-rw-r--r--source/blender/blenlib/BLI_rect.h2
-rw-r--r--source/blender/blenlib/BLI_task.h2
-rw-r--r--source/blender/blenlib/intern/rct.c16
-rw-r--r--source/blender/blenlib/intern/task.c21
-rw-r--r--source/blender/blenloader/intern/versioning_270.c11
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.h2
-rw-r--r--source/blender/editors/armature/armature_select.c10
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c5
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/interface/interface_handlers.c3
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c53
-rw-r--r--source/blender/editors/metaball/mball_edit.c5
-rw-r--r--source/blender/editors/render/render_opengl.c11
-rw-r--r--source/blender/editors/space_nla/nla_draw.c2
-rw-r--r--source/blender/editors/space_node/node_edit.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c6
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c1
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c101
-rw-r--r--source/blender/python/intern/gpu_offscreen.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c26
-rw-r--r--source/blender/windowmanager/wm.h1
31 files changed, 235 insertions, 112 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e16f0cddfd7..ee9b420dc36 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -520,18 +520,20 @@ endif()
option(WITH_LEGACY_DEPSGRAPH "Build Blender with legacy dependency graph" ON)
mark_as_advanced(WITH_LEGACY_DEPSGRAPH)
-# Use hardcoded paths or find_package to find externals
-option(WITH_WINDOWS_FIND_MODULES "Use find_package to locate libraries" OFF)
-mark_as_advanced(WITH_WINDOWS_FIND_MODULES)
+if(WIN32)
+ # Use hardcoded paths or find_package to find externals
+ option(WITH_WINDOWS_FIND_MODULES "Use find_package to locate libraries" OFF)
+ mark_as_advanced(WITH_WINDOWS_FIND_MODULES)
-option(WITH_WINDOWS_CODESIGN "Use signtool to sign the final binary." OFF)
-mark_as_advanced(WITH_WINDOWS_CODESIGN)
+ option(WITH_WINDOWS_CODESIGN "Use signtool to sign the final binary." OFF)
+ mark_as_advanced(WITH_WINDOWS_CODESIGN)
-set(WINDOWS_CODESIGN_PFX CACHE FILEPATH "Path to pfx file to use for codesigning.")
-mark_as_advanced(WINDOWS_CODESIGN_PFX)
+ set(WINDOWS_CODESIGN_PFX CACHE FILEPATH "Path to pfx file to use for codesigning.")
+ mark_as_advanced(WINDOWS_CODESIGN_PFX)
-set(WINDOWS_CODESIGN_PFX_PASSWORD CACHE STRING "password for pfx file used for codesigning.")
-mark_as_advanced(WINDOWS_CODESIGN_PFX_PASSWORD)
+ set(WINDOWS_CODESIGN_PFX_PASSWORD CACHE STRING "password for pfx file used for codesigning.")
+ mark_as_advanced(WINDOWS_CODESIGN_PFX_PASSWORD)
+endif()
# avoid using again
option_defaults_clear()
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 15594d340be..f9d65aa2363 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -365,6 +365,7 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
if(!m_status)
return false;
+ m_pitch->setPitch(m_user_pitch);
m_reader->seek((int)(position * m_reader->getSpecs().rate));
if(m_status == AUD_STATUS_STOPPED)
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index bcfa24b06a8..d6220ebf562 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -350,7 +350,12 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
FFMPEG_INLINE
int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame * picture)
{
- int64_t pts = picture->pkt_pts;
+ int64_t pts;
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 34, 100)
+ pts = picture->pts;
+#else
+ pts = picture->pkt_pts;
+#endif
if (pts == AV_NOPTS_VALUE) {
pts = picture->pkt_dts;
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index ef10e279bb4..0b9e7fd7305 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -319,7 +319,7 @@ class QuickSmoke(Operator):
def execute(self, context):
if not bpy.app.build_options.mod_smoke:
- self.report({'ERROR'}, "Build without Smoke modifier support")
+ self.report({'ERROR'}, "Built without Smoke modifier support")
return {'CANCELLED'}
fake_context = context.copy()
@@ -568,7 +568,7 @@ class QuickFluid(Operator):
def execute(self, context):
if not bpy.app.build_options.mod_fluid:
- self.report({'ERROR'}, "Build without Fluid modifier support")
+ self.report({'ERROR'}, "Built without Fluid modifier support")
return {'CANCELLED'}
fake_context = context.copy()
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index 59bf3644912..484a679f76a 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -47,6 +47,8 @@ bool BLI_rcti_is_empty(const struct rcti *rect);
bool BLI_rctf_is_empty(const struct rctf *rect);
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
+void BLI_rctf_init_pt_size(struct rctf *rect, const float xy[2], float size);
+void BLI_rcti_init_pt_size(struct rcti *rect, const int xy[2], int size);
void BLI_rcti_init_minmax(struct rcti *rect);
void BLI_rctf_init_minmax(struct rctf *rect);
void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]);
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
index cd2054a5ec3..d27bf4dad20 100644
--- a/source/blender/blenlib/BLI_task.h
+++ b/source/blender/blenlib/BLI_task.h
@@ -95,8 +95,6 @@ void BLI_task_pool_push_from_thread(TaskPool *pool, TaskRunFunction run,
void BLI_task_pool_work_and_wait(TaskPool *pool);
/* cancel all tasks, keep worker threads running */
void BLI_task_pool_cancel(TaskPool *pool);
-/* stop all worker threads */
-void BLI_task_pool_stop(TaskPool *pool);
/* set number of threads allowed to be used by this pool */
void BLI_pool_set_num_threads(TaskPool *pool, int num_threads);
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index ac73a981b45..e01a4714131 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -351,6 +351,22 @@ void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
}
}
+void BLI_rctf_init_pt_size(rctf *rect, const float xy[2], float size)
+{
+ rect->xmin = xy[0] - size;
+ rect->xmax = xy[0] + size;
+ rect->ymin = xy[1] - size;
+ rect->ymax = xy[1] + size;
+}
+
+void BLI_rcti_init_pt_size(rcti *rect, const int xy[2], int size)
+{
+ rect->xmin = xy[0] - size;
+ rect->xmax = xy[0] + size;
+ rect->ymin = xy[1] - size;
+ rect->ymax = xy[1] + size;
+}
+
void BLI_rcti_init_minmax(rcti *rect)
{
rect->xmin = rect->ymin = INT_MAX;
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index a65ef881afd..5d16fd9229c 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -180,9 +180,9 @@ BLI_INLINE TaskMemPool *get_task_mempool(TaskPool *pool, const int thread_id)
static Task *task_alloc(TaskPool *pool, const int thread_id)
{
- assert(thread_id <= pool->scheduler->num_threads);
+ BLI_assert(thread_id <= pool->scheduler->num_threads);
if (thread_id != -1) {
- assert(thread_id >= 0);
+ BLI_assert(thread_id >= 0);
TaskMemPool *mem_pool = get_task_mempool(pool, thread_id);
/* Try to re-use task memory from a thread local storage. */
if (mem_pool->num_tasks > 0) {
@@ -204,8 +204,8 @@ static Task *task_alloc(TaskPool *pool, const int thread_id)
static void task_free(TaskPool *pool, Task *task, const int thread_id)
{
task_data_free(task, thread_id);
- assert(thread_id >= 0);
- assert(thread_id <= pool->scheduler->num_threads);
+ BLI_assert(thread_id >= 0);
+ BLI_assert(thread_id <= pool->scheduler->num_threads);
TaskMemPool *mem_pool = get_task_mempool(pool, thread_id);
if (mem_pool->num_tasks < MEMPOOL_SIZE - 1) {
/* Successfully allowed the task to be re-used later. */
@@ -357,8 +357,8 @@ TaskScheduler *BLI_task_scheduler_create(int num_threads)
/* Add background-only thread if needed. */
if (num_threads == 0) {
- scheduler->background_thread_only = true;
- num_threads = 1;
+ scheduler->background_thread_only = true;
+ num_threads = 1;
}
/* launch threads that will be waiting for work */
@@ -565,7 +565,7 @@ TaskPool *BLI_task_pool_create_background(TaskScheduler *scheduler, void *userda
void BLI_task_pool_free(TaskPool *pool)
{
- BLI_task_pool_stop(pool);
+ BLI_task_pool_cancel(pool);
BLI_mutex_end(&pool->num_mutex);
BLI_condition_end(&pool->num_cond);
@@ -708,13 +708,6 @@ void BLI_task_pool_cancel(TaskPool *pool)
pool->do_cancel = false;
}
-void BLI_task_pool_stop(TaskPool *pool)
-{
- task_scheduler_clear(pool->scheduler, pool);
-
- BLI_assert(pool->num == 0);
-}
-
bool BLI_task_pool_canceled(TaskPool *pool)
{
return pool->do_cancel;
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 12045dfdb83..be15070d0cc 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1598,6 +1598,17 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
} FOREACH_NODETREE_END
}
+
+ if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) {
+ for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_SurfaceDeform) {
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ unit_m4(smd->mat);
+ }
+ }
+ }
+ }
}
{
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 2b38af80fc9..87c0f17c937 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -980,7 +980,7 @@ bool BM_mesh_intersect(
struct BMLoop *(*looptris)[3], const int looptris_tot,
int (*test_fn)(BMFace *f, void *user_data), void *user_data,
const bool use_self, const bool use_separate, const bool use_dissolve, const bool use_island_connect,
- const int boolean_mode,
+ const bool use_edge_tag, const int boolean_mode,
const float eps)
{
struct ISectState s;
@@ -1516,7 +1516,7 @@ bool BM_mesh_intersect(
BM_mesh_edgesplit(bm, false, true, false);
}
- else if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
+ else if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE || use_edge_tag) {
GSetIterator gs_iter;
/* no need to clear for boolean */
diff --git a/source/blender/bmesh/tools/bmesh_intersect.h b/source/blender/bmesh/tools/bmesh_intersect.h
index d0cc41654eb..51926a01710 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.h
+++ b/source/blender/bmesh/tools/bmesh_intersect.h
@@ -30,7 +30,7 @@ bool BM_mesh_intersect(
struct BMLoop *(*looptris)[3], const int looptris_tot,
int (*test_fn)(BMFace *f, void *user_data), void *user_data,
const bool use_self, const bool use_separate, const bool use_dissolve, const bool use_island_connect,
- const int boolean_mode,
+ const bool use_edge_tag, const int boolean_mode,
const float eps);
enum {
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 4634213fb54..a9acb41fcf6 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -303,17 +303,11 @@ static EditBone *get_nearest_editbonepoint(
ebone_next_act = NULL;
}
- rect.xmin = mval[0] - 5;
- rect.xmax = mval[0] + 5;
- rect.ymin = mval[1] - 5;
- rect.ymax = mval[1] + 5;
+ BLI_rcti_init_pt_size(&rect, mval, 5);
hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, true);
if (hits == 0) {
- rect.xmin = mval[0] - 12;
- rect.xmax = mval[0] + 12;
- rect.ymin = mval[1] - 12;
- rect.ymax = mval[1] + 12;
+ BLI_rcti_init_pt_size(&rect, mval, 12);
hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, true);
}
/* See if there are any selected bones in this group */
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 4d9ba351c3a..aa355f24d00 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -1907,10 +1907,7 @@ static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], c
view3d_set_viewcontext(C, &vc);
- rect.xmin = mval[0] - 5;
- rect.xmax = mval[0] + 5;
- rect.ymin = mval[1] - 5;
- rect.ymax = mval[1] + 5;
+ BLI_rcti_init_pt_size(&rect, mval, 5);
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index b192a6c5c08..e8944f1e654 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -47,6 +47,7 @@ struct Main;
struct MetaElem;
struct Nurb;
struct Object;
+struct RV3DMatrixStore;
struct RegionView3D;
struct Scene;
struct SceneLayer;
@@ -334,8 +335,8 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d);
#endif
int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
-void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
-void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt);
+struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
+void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
bool ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index ce93e5df6d2..7cad790ab34 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -7721,7 +7721,8 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
if (ui_but_is_cursor_warp(but)) {
#ifdef USE_CONT_MOUSE_CORRECT
- if (data->ungrab_mval[0] != FLT_MAX) {
+ /* stereo3d has issues with changing cursor location so rather avoid */
+ if (data->ungrab_mval[0] != FLT_MAX && !WM_stereo3d_enabled(data->window, false)) {
int mouse_ungrab_xy[2];
ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]);
mouse_ungrab_xy[0] = data->ungrab_mval[0];
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index de93211bec4..bc9088401db 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -137,6 +137,12 @@ enum {
ISECT_SEL_UNSEL = 1,
};
+enum {
+ ISECT_SEPARATE_ALL = 0,
+ ISECT_SEPARATE_CUT = 1,
+ ISECT_SEPARATE_NONE = 2,
+};
+
static int edbm_intersect_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -144,7 +150,9 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
BMesh *bm = em->bm;
const int mode = RNA_enum_get(op->ptr, "mode");
int (*test_fn)(BMFace *, void *);
- bool use_separate = RNA_boolean_get(op->ptr, "use_separate");
+ bool use_separate_all = false;
+ bool use_separate_cut = false;
+ const int separate_mode = RNA_enum_get(op->ptr, "separate_mode");
const float eps = RNA_float_get(op->ptr, "threshold");
bool use_self;
bool has_isect;
@@ -160,15 +168,42 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
break;
}
+ switch (separate_mode) {
+ case ISECT_SEPARATE_ALL:
+ use_separate_all = true;
+ break;
+ case ISECT_SEPARATE_CUT:
+ if (use_self == false) {
+ use_separate_cut = true;
+ }
+ else {
+ /* we could support this but would require more advanced logic inside 'BM_mesh_intersect'
+ * for now just separate all */
+ use_separate_all = true;
+ }
+ break;
+ default: /* ISECT_SEPARATE_NONE */
+ break;
+ }
has_isect = BM_mesh_intersect(
bm,
em->looptris, em->tottri,
test_fn, NULL,
- use_self, use_separate, true, true,
+ use_self, use_separate_all, true, true, true,
-1,
eps);
+ if (use_separate_cut) {
+ /* detach selected/un-selected faces */
+ BMOperator bmop;
+ EDBM_op_init(em, &bmop, op, "split geom=%hf use_only_faces=%b", BM_ELEM_SELECT, true);
+ BMO_op_exec(em->bm, &bmop);
+ if (!EDBM_op_finish(em, &bmop, op, true)) {
+ /* should never happen! */
+ BKE_report(op->reports, RPT_ERROR, "Error separating");
+ }
+ }
if (has_isect) {
edbm_intersect_select(em);
@@ -190,6 +225,16 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem isect_separate_items[] = {
+ {ISECT_SEPARATE_ALL, "ALL", 0, "All",
+ "Separate all geometry from intersections"},
+ {ISECT_SEPARATE_CUT, "CUT", 0, "Cut",
+ "Cut into geometry keeping each side separate (Selected/Unselected only)"},
+ {ISECT_SEPARATE_NONE, "NONE", 0, "Merge",
+ "Merge all geometry from the intersection"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
/* identifiers */
ot->name = "Intersect (Knife)";
ot->description = "Cut an intersection into faces";
@@ -201,7 +246,7 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "mode", isect_mode_items, ISECT_SEL_UNSEL, "Source", "");
- RNA_def_boolean(ot->srna, "use_separate", true, "Separate", "");
+ RNA_def_enum(ot->srna, "separate_mode", isect_separate_items, ISECT_SEPARATE_CUT, "Separate Mode", "");
RNA_def_float_distance(ot->srna, "threshold", 0.000001f, 0.0, 0.01, "Merge threshold", "", 0.0, 0.001);
/* flags */
@@ -239,7 +284,7 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
bm,
em->looptris, em->tottri,
test_fn, NULL,
- false, false, true, true,
+ false, false, true, true, true,
boolean_operation,
eps);
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index ed5bf4a92b4..9c42d3eb08f 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -592,10 +592,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
view3d_set_viewcontext(C, &vc);
- rect.xmin = mval[0] - 12;
- rect.xmax = mval[0] + 12;
- rect.ymin = mval[1] - 12;
- rect.ymax = mval[1] + 12;
+ BLI_rcti_init_pt_size(&rect, mval, 12);
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index fed98f96023..21a7ec0d06c 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -889,14 +889,15 @@ static void write_result_func(TaskPool * __restrict pool,
*/
ReportList reports;
BKE_reports_init(&reports, oglrender->reports->flag & ~RPT_PRINT);
- /* Do actual save logic here, depending on the file format. */
+ /* Do actual save logic here, depending on the file format.
+ *
+ * NOTE: We have to construct temporary scene with proper scene->r.cfra.
+ * This is because underlying calls do not use r.cfra but use scene
+ * for that.
+ */
Scene tmp_scene = *scene;
tmp_scene.r.cfra = cfra;
if (is_movie) {
- /* We have to construct temporary scene with proper scene->r.cfra.
- * This is because underlying calls do not use r.cfra but use scene
- * for that.
- */
ok = RE_WriteRenderViewsMovie(&reports,
rr,
&tmp_scene,
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 65582b994e8..ae9a9e3a36b 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -1,4 +1,3 @@
-
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -308,6 +307,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
*/
for (cfra = strip->start; cfra <= strip->end; cfra += 1.0f) {
float y = evaluate_fcurve(fcu, cfra); /* assume this to be in 0-1 range */
+ CLAMP(y, 0.0f, 1.0f);
immVertex2f(pos, cfra, ((y * yheight) + yminc));
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 8a61857675c..54ddd9aed46 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1069,12 +1069,9 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
/* check if we click in a socket */
for (node = snode->edittree->nodes.first; node; node = node->next) {
-
- rect.xmin = cursor[0] - (NODE_SOCKSIZE + 4);
- rect.ymin = cursor[1] - (NODE_SOCKSIZE + 4);
- rect.xmax = cursor[0] + (NODE_SOCKSIZE + 4);
- rect.ymax = cursor[1] + (NODE_SOCKSIZE + 4);
-
+
+ BLI_rctf_init_pt_size(&rect, cursor, NODE_SOCKSIZE + 4);
+
if (!(node->flag & NODE_HIDDEN)) {
/* extra padding inside and out - allow dragging on the text areas too */
if (in_out == SOCK_IN) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 84a845ee250..ef8b0c3c240 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -62,6 +62,8 @@
#include "ED_keyframing.h"
#include "ED_armature.h"
+#include "ED_keyframing.h"
+#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_gpencil.h"
@@ -1659,8 +1661,6 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
BLF_color4ubv(BLF_default(), axis_col[i]);
BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
}
-
- /* BLF_draw disabled blending for us */
}
#ifdef WITH_INPUT_NDOF
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 9c94dfb1d01..51963778ef8 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -1674,7 +1674,7 @@ struct RV3DMatrixStore {
float pixsize;
};
-void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
+struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
{
struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
@@ -1687,7 +1687,7 @@ void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
return (void *)rv3dmat;
}
-void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt)
+void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt)
{
struct RV3DMatrixStore *rv3dmat = rv3dmat_pt;
copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 79cb99ee443..131095c8c47 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -4872,11 +4872,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
rect.ymax = mval[1] + 1;
}
else {
- rect.xmax = mval[0] + margin;
- rect.ymax = mval[1] + margin;
-
- rect.xmin = mval[0] - margin;
- rect.ymin = mval[1] - margin;
+ BLI_rcti_init_pt_size(&rect, mval, margin);
}
view3d_update_depths_rect(ar, &depth_temp, &rect);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index e1bbe40ea38..687a9a398d9 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1179,10 +1179,8 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
/* case not a border select */
if (input->xmin == input->xmax) {
- rect.xmin = input->xmin - 12; /* seems to be default value for bones only now */
- rect.xmax = input->xmin + 12;
- rect.ymin = input->ymin - 12;
- rect.ymax = input->ymin + 12;
+ /* seems to be default value for bones only now */
+ BLI_rctf_init_pt_size(&rect, (const float[2]){input->xmin, input->ymin}, 12);
}
else {
BLI_rctf_rcti_copy(&rect, input);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 0c17909db23..32b43c7ea55 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1594,6 +1594,7 @@ typedef struct SurfaceDeformModifierData {
float falloff;
unsigned int numverts, numpoly;
int flags;
+ float mat[4][4];
} SurfaceDeformModifierData;
/* Surface Deform modifier flags */
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 51020566de6..6aadd10480e 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -303,6 +303,7 @@ static DerivedMesh *applyModifier_bmesh(
use_separate,
use_dissolve,
use_island_connect,
+ false,
bmd->operation,
bmd->double_threshold);
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index d0a68e9803c..556a00052c6 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -40,8 +40,9 @@ typedef struct SDefBindCalcData {
const MPoly * const mpoly;
const MEdge * const medge;
const MLoop * const mloop;
- const MVert * const mvert;
+ float (* const targetCos)[3];
float (* const vertexCos)[3];
+ float imat[4][4];
const float falloff;
int success;
} SDefBindCalcData;
@@ -81,7 +82,7 @@ typedef struct SDefBindWeightData {
typedef struct SDefDeformData {
const SDefVert * const bind_verts;
- const MVert * const mvert;
+ float (* const targetCos)[3];
float (* const vertexCos)[3];
} SDefDeformData;
@@ -267,23 +268,25 @@ BLI_INLINE void sortPolyVertsTri(unsigned int *indices, const MLoop * const mloo
BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float point_co[3])
{
- const MVert * const mvert = data->mvert;
BVHTreeNearest nearest = {.dist_sq = FLT_MAX, .index = -1};
const MPoly *poly;
const MEdge *edge;
const MLoop *loop;
+ float t_point[3];
float max_dist = FLT_MAX;
float dist;
unsigned int index = 0;
- BLI_bvhtree_find_nearest(data->treeData->tree, point_co, &nearest, data->treeData->nearest_callback, data->treeData);
+ mul_v3_m4v3(t_point, data->imat, point_co);
+
+ BLI_bvhtree_find_nearest(data->treeData->tree, t_point, &nearest, data->treeData->nearest_callback, data->treeData);
poly = &data->mpoly[data->looptri[nearest.index].poly];
loop = &data->mloop[poly->loopstart];
for (int i = 0; i < poly->totloop; i++, loop++) {
edge = &data->medge[loop->e];
- dist = dist_squared_to_line_segment_v3(point_co, mvert[edge->v1].co, mvert[edge->v2].co);
+ dist = dist_squared_to_line_segment_v3(point_co, data->targetCos[edge->v1], data->targetCos[edge->v2]);
if (dist < max_dist) {
max_dist = dist;
@@ -292,7 +295,7 @@ BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float p
}
edge = &data->medge[index];
- if (len_squared_v3v3(point_co, mvert[edge->v1].co) < len_squared_v3v3(point_co, mvert[edge->v2].co)) {
+ if (len_squared_v3v3(point_co, data->targetCos[edge->v1]) < len_squared_v3v3(point_co, data->targetCos[edge->v2])) {
return edge->v1;
}
else {
@@ -441,7 +444,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData * const data,
}
for (int j = 0; j < poly->totloop; j++, loop++) {
- copy_v3_v3(bpoly->coords[j], data->mvert[loop->v].co);
+ copy_v3_v3(bpoly->coords[j], data->targetCos[loop->v]);
/* Find corner and edge indices within poly loop array */
if (loop->v == nearest) {
@@ -830,8 +833,8 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
sortPolyVertsEdge(sdbind->vert_inds, &data->mloop[bpoly->loopstart],
bpoly->edge_inds[bpoly->dominant_edge], bpoly->numverts);
- copy_v3_v3(v1, data->mvert[sdbind->vert_inds[0]].co);
- copy_v3_v3(v2, data->mvert[sdbind->vert_inds[1]].co);
+ copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
+ copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
copy_v3_v3(v3, bpoly->centroid);
mid_v3_v3v3v3(cent, v1, v2, v3);
@@ -872,9 +875,9 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
sortPolyVertsTri(sdbind->vert_inds, &data->mloop[bpoly->loopstart], bpoly->edge_vert_inds[0], bpoly->numverts);
- copy_v3_v3(v1, data->mvert[sdbind->vert_inds[0]].co);
- copy_v3_v3(v2, data->mvert[sdbind->vert_inds[1]].co);
- copy_v3_v3(v3, data->mvert[sdbind->vert_inds[2]].co);
+ copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
+ copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
+ copy_v3_v3(v3, data->targetCos[sdbind->vert_inds[2]]);
mid_v3_v3v3v3(cent, v1, v2, v3);
normal_tri_v3(norm, v1, v2, v3);
@@ -902,14 +905,14 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
}
static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)[3],
- unsigned int numverts, unsigned int tnumpoly, DerivedMesh *tdm)
+ unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, DerivedMesh *tdm)
{
BVHTreeFromMesh treeData = {NULL};
+ const MVert *mvert = tdm->getVertArray(tdm);
const MPoly *mpoly = tdm->getPolyArray(tdm);
const MEdge *medge = tdm->getEdgeArray(tdm);
const MLoop *mloop = tdm->getLoopArray(tdm);
unsigned int tnumedges = tdm->getNumEdges(tdm);
- unsigned int tnumverts = tdm->getNumVerts(tdm);
int adj_result;
SDefAdjacencyArray *vert_edges;
SDefAdjacency *adj_array;
@@ -973,15 +976,29 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)
.medge = medge,
.mloop = mloop,
.looptri = tdm->getLoopTriArray(tdm),
- .mvert = tdm->getVertArray(tdm),
+ .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetBindVertArray"),
.bind_verts = smd->verts,
.vertexCos = vertexCos,
.falloff = smd->falloff,
.success = MOD_SDEF_BIND_RESULT_SUCCESS};
+ if (data.targetCos == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ freeData((ModifierData *)smd);
+ return false;
+ }
+
+ invert_m4_m4(data.imat, smd->mat);
+
+ for (int i = 0; i < tnumverts; i++) {
+ mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
+ }
+
BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, bindVert,
numverts > 10000, false);
+ MEM_freeN(data.targetCos);
+
if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
modifier_setError((ModifierData *)smd, "Out of memory");
freeData((ModifierData *)smd);
@@ -1017,7 +1034,6 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
{
const SDefDeformData * const data = (SDefDeformData *)userdata;
const SDefBind *sdbind = data->bind_verts[index].binds;
- const MVert * const mvert = data->mvert;
float * const vertexCos = data->vertexCos[index];
float norm[3], temp[3];
@@ -1028,7 +1044,7 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
float (*coords)[3] = MEM_mallocN(sizeof(*coords) * sdbind->numverts, "SDefDoPolyCoords");
for (int k = 0; k < sdbind->numverts; k++) {
- copy_v3_v3(coords[k], mvert[sdbind->vert_inds[k]].co);
+ copy_v3_v3(coords[k], data->targetCos[sdbind->vert_inds[k]]);
}
normal_poly_v3(norm, coords, sdbind->numverts);
@@ -1036,9 +1052,9 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
/* ---------- looptri mode ---------- */
if (sdbind->mode == MOD_SDEF_MODE_LOOPTRI) {
- madd_v3_v3fl(temp, mvert[sdbind->vert_inds[0]].co, sdbind->vert_weights[0]);
- madd_v3_v3fl(temp, mvert[sdbind->vert_inds[1]].co, sdbind->vert_weights[1]);
- madd_v3_v3fl(temp, mvert[sdbind->vert_inds[2]].co, sdbind->vert_weights[2]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
}
else {
/* ---------- ngon mode ---------- */
@@ -1053,8 +1069,8 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
float cent[3];
mid_v3_v3_array(cent, coords, sdbind->numverts);
- madd_v3_v3fl(temp, mvert[sdbind->vert_inds[0]].co, sdbind->vert_weights[0]);
- madd_v3_v3fl(temp, mvert[sdbind->vert_inds[1]].co, sdbind->vert_weights[1]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
madd_v3_v3fl(temp, cent, sdbind->vert_weights[2]);
}
}
@@ -1068,11 +1084,11 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
}
}
-static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts)
+static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
DerivedMesh *tdm;
- unsigned int tnumpoly;
+ unsigned int tnumverts, tnumpoly;
/* Exit function if bind flag is not set (free bind data if any) */
if (!(smd->flags & MOD_SDEF_BIND)) {
@@ -1089,11 +1105,17 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
tdm = smd->target->derivedFinal;
}
+ tnumverts = tdm->getNumVerts(tdm);
tnumpoly = tdm->getNumPolys(tdm);
/* If not bound, execute bind */
if (!(smd->verts)) {
- if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tdm)) {
+ float tmp_mat[4][4];
+
+ invert_m4_m4(tmp_mat, ob->obmat);
+ mul_m4_m4m4(smd->mat, tmp_mat, smd->target->obmat);
+
+ if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, tdm)) {
smd->flags &= ~MOD_SDEF_BIND;
return;
}
@@ -1113,29 +1135,44 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
/* Actual vertex location update starts here */
SDefDeformData data = {.bind_verts = smd->verts,
- .mvert = tdm->getVertArray(tdm),
+ .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetVertArray"),
.vertexCos = vertexCos};
- BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, deformVert,
- numverts > 10000, false);
+ if (data.targetCos != NULL) {
+ bool tdm_vert_alloc;
+ const MVert * const mvert = DM_get_vert_array(tdm, &tdm_vert_alloc);
+
+ for (int i = 0; i < tnumverts; i++) {
+ mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
+ }
+
+ BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, deformVert,
+ numverts > 10000, false);
+
+ if (tdm_vert_alloc) {
+ MEM_freeN((void *)mvert);
+ }
+
+ MEM_freeN(data.targetCos);
+ }
tdm->release(tdm);
}
-static void deformVerts(ModifierData *md, Object *UNUSED(ob),
+static void deformVerts(ModifierData *md, Object *ob,
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag UNUSED(flag))
{
- surfacedeformModifier_do(md, vertexCos, numVerts);
+ surfacedeformModifier_do(md, vertexCos, numVerts, ob);
}
-static void deformVertsEM(ModifierData *md, Object *UNUSED(ob),
+static void deformVertsEM(ModifierData *md, Object *ob,
struct BMEditMesh *UNUSED(editData),
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3], int numVerts)
{
- surfacedeformModifier_do(md, vertexCos, numVerts);
+ surfacedeformModifier_do(md, vertexCos, numVerts, ob);
}
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c
index 5b4e7da4290..da8e5d69f02 100644
--- a/source/blender/python/intern/gpu_offscreen.c
+++ b/source/blender/python/intern/gpu_offscreen.c
@@ -203,7 +203,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a
ARegion *ar;
GPUFX *fx;
GPUFXSettings fx_settings;
- void *rv3d_mats;
+ struct RV3DMatrixStore *rv3d_mats;
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 1a831846af7..a2aca589f72 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -3275,6 +3275,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
GHOST_TEventCursorData *cd = customdata;
copy_v2_v2_int(&event.x, &cd->x);
+ wm_stereo3d_mouse_offset_apply(win, &event.x);
+
event.type = MOUSEMOVE;
wm_event_add_mousemove(win, &event);
copy_v2_v2_int(&evt->x, &event.x);
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 6b3f530133f..bd22cb191c7 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -394,6 +394,32 @@ bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check)
return true;
}
+/**
+ * If needed, this adjusts \a r_mouse_xy so that drawn cursor and handled mouse position are matching visually.
+*/
+void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy)
+{
+ if (!WM_stereo3d_enabled(win, false))
+ return;
+
+ if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
+ const int half_x = win->sizex / 2;
+ /* right half of the screen */
+ if (r_mouse_xy[0] > half_x) {
+ r_mouse_xy[0] -= half_x;
+ }
+ r_mouse_xy[0] *= 2;
+ }
+ else if (win->stereo3d_format->display_mode == S3D_DISPLAY_TOPBOTTOM) {
+ const int half_y = win->sizey / 2;
+ /* upper half of the screen */
+ if (r_mouse_xy[1] > half_y) {
+ r_mouse_xy[1] -= half_y;
+ }
+ r_mouse_xy[1] *= 2;
+ }
+}
+
/************************** Stereo 3D operator **********************************/
typedef struct Stereo3dData {
Stereo3dFormat stereo3d_format;
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 3dd294128e2..f63246580ea 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -80,6 +80,7 @@ void wm_autosave_location(char *filepath);
/* wm_stereo.c */
void wm_method_draw_stereo3d(const bContext *C, wmWindow *win);
+void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy);
int wm_stereo3d_set_exec(bContext *C, wmOperator *op);
int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *event);
void wm_stereo3d_set_draw(bContext *C, wmOperator *op);