diff options
Diffstat (limited to 'source/blender')
27 files changed, 215 insertions, 100 deletions
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); |