From 9f5833798caf9581c2d781f4e2f8b95acb1560e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 13 Jun 2020 13:14:07 +1000 Subject: Modifier: skip edit-mesh conversion for armature, curve & lattice This is an improvement over 2.7x which converted edit-mesh to mesh (CDDM) for all 3 modifiers. Overall this increases performance in edit-mode by around 15-20%. --- source/blender/blenkernel/BKE_armature.h | 11 ++ source/blender/blenkernel/BKE_curve.h | 11 ++ source/blender/blenkernel/BKE_lattice.h | 10 ++ source/blender/blenkernel/intern/armature_deform.c | 150 ++++++++++++---- source/blender/blenkernel/intern/curve_deform.c | 200 +++++++++++++++------ source/blender/blenkernel/intern/lattice_deform.c | 113 ++++++++++-- source/blender/modifiers/intern/MOD_armature.c | 55 +++--- source/blender/modifiers/intern/MOD_curve.c | 43 +++-- source/blender/modifiers/intern/MOD_lattice.c | 17 +- 9 files changed, 446 insertions(+), 164 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 30a1644af39..7572c3cb452 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -28,6 +28,7 @@ extern "C" { #endif +struct BMEditMesh; struct Bone; struct Depsgraph; struct ListBase; @@ -371,6 +372,16 @@ void BKE_armature_deform_coords_with_mesh(struct Object *ob_arm, const char *defgrp_name, const struct Mesh *me_target); +void BKE_armature_deform_coords_with_editmesh(struct Object *ob_arm, + struct Object *ob_target, + float (*vert_coords)[3], + float (*vert_deform_mats)[3][3], + int vert_coords_len, + int deformflag, + float (*vert_coords_prev)[3], + const char *defgrp_name, + struct BMEditMesh *em_target); + /** \} */ #ifdef __cplusplus diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 417dbd49855..81e595aa94d 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -29,6 +29,7 @@ extern "C" { #endif +struct BMEditMesh; struct BezTriple; struct Curve; struct Depsgraph; @@ -316,6 +317,16 @@ void BKE_curve_deform_coords(struct Object *ob_curve, const int defgrp_index, const short flag, const short defaxis); + +void BKE_curve_deform_coords_with_editmesh(Object *ob_curve, + Object *ob_target, + float (*vert_coords)[3], + const int vert_coords_len, + const int defgrp_index, + const short flag, + const short defaxis, + struct BMEditMesh *em_target); + void BKE_curve_deform_co(struct Object *ob_curve, struct Object *ob_target, const float orco[3], diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 922f7278034..045bea613f3 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -30,6 +30,7 @@ extern "C" { #endif +struct BMEditMesh; struct BPoint; struct Depsgraph; struct Lattice; @@ -123,6 +124,15 @@ void BKE_lattice_deform_coords_with_mesh(struct Object *ob_lattice, const char *defgrp_name, const float influence, const struct Mesh *me_target); + +void BKE_lattice_deform_coords_with_editmesh(struct Object *ob_lattice, + struct Object *ob_target, + float (*vert_coords)[3], + const int vert_coords_len, + const short flag, + const char *defgrp_name, + const float influence, + struct BMEditMesh *em_target); /** \} */ #ifdef __cplusplus diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index cee487e2244..e180070f518 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -48,6 +48,7 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_deform.h" +#include "BKE_editmesh.h" #include "BKE_lattice.h" #include "DEG_depsgraph_build.h" @@ -261,13 +262,17 @@ typedef struct ArmatureUserdata { float premat[4][4]; float postmat[4][4]; + + /** Specific data types. */ + struct { + int cd_dvert_offset; + } bmesh; } ArmatureUserdata; -static void armature_vert_task(void *__restrict userdata, - const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) +static void armature_vert_task_with_dvert(const ArmatureUserdata *data, + const int i, + const MDeformVert *dvert) { - const ArmatureUserdata *data = userdata; float(*const vert_coords)[3] = data->vert_coords; float(*const vert_deform_mats)[3][3] = data->vert_deform_mats; float(*const vert_coords_prev)[3] = data->vert_coords_prev; @@ -276,7 +281,6 @@ static void armature_vert_task(void *__restrict userdata, const bool use_dverts = data->use_dverts; const int armature_def_nr = data->armature_def_nr; - const MDeformVert *dvert; DualQuat sumdq, *dq = NULL; bPoseChannel *pchan; float *co, dco[3]; @@ -300,27 +304,6 @@ static void armature_vert_task(void *__restrict userdata, } } - if (use_dverts || armature_def_nr != -1) { - if (data->me_target) { - BLI_assert(i < data->me_target->totvert); - if (data->me_target->dvert != NULL) { - dvert = data->me_target->dvert + i; - } - else { - dvert = NULL; - } - } - else if (data->dverts && i < data->dverts_len) { - dvert = data->dverts + i; - } - else { - dvert = NULL; - } - } - else { - dvert = NULL; - } - if (armature_def_nr != -1 && dvert) { armature_weight = BKE_defvert_find_weight(dvert, armature_def_nr); @@ -434,6 +417,51 @@ static void armature_vert_task(void *__restrict userdata, } } +static void armature_vert_task(void *__restrict userdata, + const int i, + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + const ArmatureUserdata *data = userdata; + const MDeformVert *dvert; + if (data->use_dverts || data->armature_def_nr != -1) { + if (data->me_target) { + BLI_assert(i < data->me_target->totvert); + if (data->me_target->dvert != NULL) { + dvert = data->me_target->dvert + i; + } + else { + dvert = NULL; + } + } + else if (data->dverts && i < data->dverts_len) { + dvert = data->dverts + i; + } + else { + dvert = NULL; + } + } + else { + dvert = NULL; + } + + armature_vert_task_with_dvert(data, i, dvert); +} + +static void armature_vert_task_editmesh(void *__restrict userdata, MempoolIterData *iter) +{ + const ArmatureUserdata *data = userdata; + BMVert *v = (BMVert *)iter; + MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(v, data->bmesh.cd_dvert_offset); + armature_vert_task_with_dvert(data, BM_elem_index_get(v), dvert); +} + +static void armature_vert_task_editmesh_no_dvert(void *__restrict userdata, MempoolIterData *iter) +{ + const ArmatureUserdata *data = userdata; + BMVert *v = (BMVert *)iter; + armature_vert_task_with_dvert(data, BM_elem_index_get(v), NULL); +} + static void armature_deform_coords_impl(Object *ob_arm, Object *ob_target, float (*vert_coords)[3], @@ -443,6 +471,7 @@ static void armature_deform_coords_impl(Object *ob_arm, float (*vert_coords_prev)[3], const char *defgrp_name, const Mesh *me_target, + BMEditMesh *em_target, bGPDstroke *gps_target) { bArmature *arm = ob_arm->data; @@ -456,6 +485,7 @@ static void armature_deform_coords_impl(Object *ob_arm, int i, dverts_len = 0; /* safety for vertexgroup overflow */ bool use_dverts = false; int armature_def_nr; + int cd_dvert_offset = -1; /* in editmode, or not an armature */ if (arm->edbo || (ob_arm->pose == NULL)) { @@ -476,10 +506,12 @@ static void armature_deform_coords_impl(Object *ob_arm, defbase_len = BLI_listbase_count(&ob_target->defbase); if (ob_target->type == OB_MESH) { - Mesh *me = ob_target->data; - dverts = me->dvert; - if (dverts) { - dverts_len = me->totvert; + if (em_target == NULL) { + Mesh *me = ob_target->data; + dverts = me->dvert; + if (dverts) { + dverts_len = me->totvert; + } } } else if (ob_target->type == OB_LATTICE) { @@ -501,7 +533,11 @@ static void armature_deform_coords_impl(Object *ob_arm, if (deformflag & ARM_DEF_VGROUP) { if (ELEM(ob_target->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) { /* if we have a Mesh, only use dverts if it has them */ - if (me_target) { + if (em_target) { + cd_dvert_offset = CustomData_get_offset(&em_target->bm->vdata, CD_MDEFORMVERT); + use_dverts = (cd_dvert_offset != -1); + } + else if (me_target) { use_dverts = (me_target->dvert != NULL); } else if (dverts) { @@ -543,6 +579,10 @@ static void armature_deform_coords_impl(Object *ob_arm, .dverts_len = dverts_len, .pchan_from_defbase = pchan_from_defbase, .defbase_len = defbase_len, + .bmesh = + { + .cd_dvert_offset = cd_dvert_offset, + }, }; float obinv[4][4]; @@ -551,10 +591,25 @@ static void armature_deform_coords_impl(Object *ob_arm, mul_m4_m4m4(data.postmat, obinv, ob_arm->obmat); invert_m4_m4(data.premat, data.postmat); - TaskParallelSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.min_iter_per_thread = 32; - BLI_task_parallel_range(0, vert_coords_len, &data, armature_vert_task, &settings); + if (em_target != NULL) { + /* While this could cause an extra loop over mesh data, in most cases this will + * have already been properly set. */ + BM_mesh_elem_index_ensure(em_target->bm, BM_VERT); + + if (use_dverts) { + BLI_task_parallel_mempool(em_target->bm->vpool, &data, armature_vert_task_editmesh, true); + } + else { + BLI_task_parallel_mempool( + em_target->bm->vpool, &data, armature_vert_task_editmesh_no_dvert, true); + } + } + else { + TaskParallelSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.min_iter_per_thread = 32; + BLI_task_parallel_range(0, vert_coords_len, &data, armature_vert_task, &settings); + } if (pchan_from_defbase) { MEM_freeN(pchan_from_defbase); @@ -580,6 +635,7 @@ void BKE_armature_deform_coords_with_gpencil_stroke(Object *ob_arm, vert_coords_prev, defgrp_name, NULL, + NULL, gps_target); } @@ -602,6 +658,30 @@ void BKE_armature_deform_coords_with_mesh(Object *ob_arm, vert_coords_prev, defgrp_name, me_target, + NULL, + NULL); +} + +void BKE_armature_deform_coords_with_editmesh(Object *ob_arm, + Object *ob_target, + float (*vert_coords)[3], + float (*vert_deform_mats)[3][3], + int vert_coords_len, + int deformflag, + float (*vert_coords_prev)[3], + const char *defgrp_name, + BMEditMesh *em_target) +{ + armature_deform_coords_impl(ob_arm, + ob_target, + vert_coords, + vert_deform_mats, + vert_coords_len, + deformflag, + vert_coords_prev, + defgrp_name, + NULL, + em_target, NULL); } diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c index 36632982b5c..a8761799b12 100644 --- a/source/blender/blenkernel/intern/curve_deform.c +++ b/source/blender/blenkernel/intern/curve_deform.c @@ -37,6 +37,7 @@ #include "BKE_anim_path.h" #include "BKE_curve.h" +#include "BKE_editmesh.h" #include "BKE_lattice.h" #include "BKE_modifier.h" @@ -248,20 +249,23 @@ static bool calc_curve_deform( * #BKE_curve_deform and related functions. * \{ */ -void BKE_curve_deform_coords(Object *ob_curve, - Object *ob_target, - float (*vert_coords)[3], - const int vert_coords_len, - const MDeformVert *dvert, - const int defgrp_index, - const short flag, - const short defaxis) +static void curve_deform_coords_impl(Object *ob_curve, + Object *ob_target, + float (*vert_coords)[3], + const int vert_coords_len, + const MDeformVert *dvert, + const int defgrp_index, + const short flag, + const short defaxis, + BMEditMesh *em_target) { Curve *cu; int a; CurveDeform cd; const bool is_neg_axis = (defaxis > 2); const bool invert_vgroup = (flag & MOD_CURVE_INVERT_VGROUP) != 0; + bool use_dverts = false; + int cd_dvert_offset; if (ob_curve->type != OB_CURVE) { return; @@ -271,64 +275,124 @@ void BKE_curve_deform_coords(Object *ob_curve, init_curve_deform(ob_curve, ob_target, &cd); - /* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */ - if (is_neg_axis == false) { - cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = 0.0f; - cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 1.0f; + if (cu->flag & CU_DEFORM_BOUNDS_OFF) { + /* Dummy bounds. */ + if (is_neg_axis == false) { + cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = 0.0f; + cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 1.0f; + } + else { + /* Negative, these bounds give a good rest position. */ + cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = -1.0f; + cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 0.0f; + } } else { - /* negative, these bounds give a good rest position */ - cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = -1.0f; - cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 0.0f; + /* Set mesh min/max bounds. */ + INIT_MINMAX(cd.dmin, cd.dmax); } - if (dvert) { - const MDeformVert *dvert_iter; - float vec[3]; + if (em_target != NULL) { + cd_dvert_offset = CustomData_get_offset(&em_target->bm->vdata, CD_MDEFORMVERT); + if (cd_dvert_offset != -1) { + use_dverts = true; + } + } + else { + if (dvert != NULL) { + use_dverts = true; + } + } + if (use_dverts) { if (cu->flag & CU_DEFORM_BOUNDS_OFF) { - for (a = 0, dvert_iter = dvert; a < vert_coords_len; a++, dvert_iter++) { - const float weight = invert_vgroup ? - 1.0f - BKE_defvert_find_weight(dvert_iter, defgrp_index) : - BKE_defvert_find_weight(dvert_iter, defgrp_index); - - if (weight > 0.0f) { - mul_m4_v3(cd.curvespace, vert_coords[a]); - copy_v3_v3(vec, vert_coords[a]); - calc_curve_deform(ob_curve, vec, defaxis, &cd, NULL); - interp_v3_v3v3(vert_coords[a], vert_coords[a], vec, weight); - mul_m4_v3(cd.objectspace, vert_coords[a]); + +#define DEFORM_OP(dvert) \ + { \ + const float weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert, defgrp_index) : \ + BKE_defvert_find_weight(dvert, defgrp_index); \ + if (weight > 0.0f) { \ + float vec[3]; \ + mul_m4_v3(cd.curvespace, vert_coords[a]); \ + copy_v3_v3(vec, vert_coords[a]); \ + calc_curve_deform(ob_curve, vec, defaxis, &cd, NULL); \ + interp_v3_v3v3(vert_coords[a], vert_coords[a], vec, weight); \ + mul_m4_v3(cd.objectspace, vert_coords[a]); \ + } \ + } \ + ((void)0) + + if (em_target != NULL) { + BMIter iter; + BMVert *v; + BM_ITER_MESH_INDEX (v, &iter, em_target->bm, BM_VERTS_OF_MESH, a) { + dvert = BM_ELEM_CD_GET_VOID_P(v, cd_dvert_offset); + DEFORM_OP(dvert); } } + else { + for (a = 0; a < vert_coords_len; a++) { + DEFORM_OP(&dvert[a]); + } + } + +#undef DEFORM_OP } else { - /* set mesh min/max bounds */ - INIT_MINMAX(cd.dmin, cd.dmax); - - for (a = 0, dvert_iter = dvert; a < vert_coords_len; a++, dvert_iter++) { - const float weight = invert_vgroup ? - 1.0f - BKE_defvert_find_weight(dvert_iter, defgrp_index) : - BKE_defvert_find_weight(dvert_iter, defgrp_index); - if (weight > 0.0f) { - mul_m4_v3(cd.curvespace, vert_coords[a]); - minmax_v3v3_v3(cd.dmin, cd.dmax, vert_coords[a]); + +#define DEFORM_OP_MINMAX(dvert) \ + { \ + const float weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert, defgrp_index) : \ + BKE_defvert_find_weight(dvert, defgrp_index); \ + if (weight > 0.0f) { \ + mul_m4_v3(cd.curvespace, vert_coords[a]); \ + minmax_v3v3_v3(cd.dmin, cd.dmax, vert_coords[a]); \ + } \ + } \ + ((void)0) + + /* already in 'cd.curvespace', prev for loop */ +#define DEFORM_OP_CLAMPED(dvert) \ + { \ + const float weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert, defgrp_index) : \ + BKE_defvert_find_weight(dvert, defgrp_index); \ + if (weight > 0.0f) { \ + float vec[3]; \ + copy_v3_v3(vec, vert_coords[a]); \ + calc_curve_deform(ob_curve, vec, defaxis, &cd, NULL); \ + interp_v3_v3v3(vert_coords[a], vert_coords[a], vec, weight); \ + mul_m4_v3(cd.objectspace, vert_coords[a]); \ + } \ + } \ + ((void)0) + + if (em_target != NULL) { + BMIter iter; + BMVert *v; + BM_ITER_MESH_INDEX (v, &iter, em_target->bm, BM_VERTS_OF_MESH, a) { + dvert = BM_ELEM_CD_GET_VOID_P(v, cd_dvert_offset); + DEFORM_OP_MINMAX(dvert); + } + + BM_ITER_MESH_INDEX (v, &iter, em_target->bm, BM_VERTS_OF_MESH, a) { + dvert = BM_ELEM_CD_GET_VOID_P(v, cd_dvert_offset); + DEFORM_OP_CLAMPED(dvert); } } + else { - for (a = 0, dvert_iter = dvert; a < vert_coords_len; a++, dvert_iter++) { - const float weight = invert_vgroup ? - 1.0f - BKE_defvert_find_weight(dvert_iter, defgrp_index) : - BKE_defvert_find_weight(dvert_iter, defgrp_index); - - if (weight > 0.0f) { - /* already in 'cd.curvespace', prev for loop */ - copy_v3_v3(vec, vert_coords[a]); - calc_curve_deform(ob_curve, vec, defaxis, &cd, NULL); - interp_v3_v3v3(vert_coords[a], vert_coords[a], vec, weight); - mul_m4_v3(cd.objectspace, vert_coords[a]); + for (a = 0; a < vert_coords_len; a++) { + DEFORM_OP_MINMAX(&dvert[a]); + } + + for (a = 0; a < vert_coords_len; a++) { + DEFORM_OP_CLAMPED(&dvert[a]); } } } + +#undef DEFORM_OP_MINMAX +#undef DEFORM_OP_CLAMPED } else { if (cu->flag & CU_DEFORM_BOUNDS_OFF) { @@ -339,9 +403,6 @@ void BKE_curve_deform_coords(Object *ob_curve, } } else { - /* set mesh min max bounds */ - INIT_MINMAX(cd.dmin, cd.dmax); - for (a = 0; a < vert_coords_len; a++) { mul_m4_v3(cd.curvespace, vert_coords[a]); minmax_v3v3_v3(cd.dmin, cd.dmax, vert_coords[a]); @@ -356,6 +417,39 @@ void BKE_curve_deform_coords(Object *ob_curve, } } +void BKE_curve_deform_coords(Object *ob_curve, + Object *ob_target, + float (*vert_coords)[3], + const int vert_coords_len, + const MDeformVert *dvert, + const int defgrp_index, + const short flag, + const short defaxis) +{ + curve_deform_coords_impl( + ob_curve, ob_target, vert_coords, vert_coords_len, dvert, defgrp_index, flag, defaxis, NULL); +} + +void BKE_curve_deform_coords_with_editmesh(Object *ob_curve, + Object *ob_target, + float (*vert_coords)[3], + const int vert_coords_len, + const int defgrp_index, + const short flag, + const short defaxis, + BMEditMesh *em_target) +{ + curve_deform_coords_impl(ob_curve, + ob_target, + vert_coords, + vert_coords_len, + NULL, + defgrp_index, + flag, + defaxis, + em_target); +} + /* input vec and orco = local coord in armature space */ /* orco is original not-animated or deformed reference point */ /* result written in vec and mat */ diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c index 7468ae8b3a4..4dc3ed2397e 100644 --- a/source/blender/blenkernel/intern/lattice_deform.c +++ b/source/blender/blenkernel/intern/lattice_deform.c @@ -42,6 +42,7 @@ #include "BKE_curve.h" #include "BKE_displist.h" +#include "BKE_editmesh.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_modifier.h" @@ -283,19 +284,21 @@ typedef struct LatticeDeformUserdata { int defgrp_index; float fac; bool invert_vgroup; + + /** Specific data types. */ + struct { + int cd_dvert_offset; + } bmesh; } LatticeDeformUserdata; -static void lattice_deform_vert_task(void *__restrict userdata, - const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) +static void lattice_deform_vert_with_dvert(const LatticeDeformUserdata *data, + const int index, + const MDeformVert *dvert) { - const LatticeDeformUserdata *data = userdata; - - if (data->dvert != NULL) { + if (dvert != NULL) { const float weight = data->invert_vgroup ? - 1.0f - - BKE_defvert_find_weight(data->dvert + index, data->defgrp_index) : - BKE_defvert_find_weight(data->dvert + index, data->defgrp_index); + 1.0f - BKE_defvert_find_weight(dvert, data->defgrp_index) : + BKE_defvert_find_weight(dvert, data->defgrp_index); if (weight > 0.0f) { calc_latt_deform(data->lattice_deform_data, data->vert_coords[index], weight * data->fac); } @@ -305,6 +308,29 @@ static void lattice_deform_vert_task(void *__restrict userdata, } } +static void lattice_deform_vert_task(void *__restrict userdata, + const int index, + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + const LatticeDeformUserdata *data = userdata; + lattice_deform_vert_with_dvert(data, index, data->dvert ? &data->dvert[index] : NULL); +} + +static void lattice_vert_task_editmesh(void *__restrict userdata, MempoolIterData *iter) +{ + const LatticeDeformUserdata *data = userdata; + BMVert *v = (BMVert *)iter; + MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(v, data->bmesh.cd_dvert_offset); + lattice_deform_vert_with_dvert(data, BM_elem_index_get(v), dvert); +} + +static void lattice_vert_task_editmesh_no_dvert(void *__restrict userdata, MempoolIterData *iter) +{ + const LatticeDeformUserdata *data = userdata; + BMVert *v = (BMVert *)iter; + lattice_deform_vert_with_dvert(data, BM_elem_index_get(v), NULL); +} + static void lattice_deform_coords_impl(Object *ob_lattice, Object *ob_target, float (*vert_coords)[3], @@ -312,11 +338,13 @@ static void lattice_deform_coords_impl(Object *ob_lattice, const short flag, const char *defgrp_name, const float fac, - const Mesh *me_target) + const Mesh *me_target, + BMEditMesh *em_target) { LatticeDeformData *lattice_deform_data; const MDeformVert *dvert = NULL; int defgrp_index = -1; + int cd_dvert_offset = -1; if (ob_lattice->type != OB_LATTICE) { return; @@ -332,7 +360,10 @@ static void lattice_deform_coords_impl(Object *ob_lattice, if (defgrp_index != -1) { /* if there's derived data without deformverts, don't use vgroups */ - if (me_target) { + if (em_target) { + cd_dvert_offset = CustomData_get_offset(&em_target->bm->vdata, CD_MDEFORMVERT); + } + else if (me_target) { dvert = CustomData_get_layer(&me_target->vdata, CD_MDEFORMVERT); } else if (ob_target->type == OB_LATTICE) { @@ -351,12 +382,31 @@ static void lattice_deform_coords_impl(Object *ob_lattice, .defgrp_index = defgrp_index, .fac = fac, .invert_vgroup = (flag & MOD_LATTICE_INVERT_VGROUP) != 0, + .bmesh = + { + .cd_dvert_offset = cd_dvert_offset, + }, }; - TaskParallelSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.min_iter_per_thread = 32; - BLI_task_parallel_range(0, vert_coords_len, &data, lattice_deform_vert_task, &settings); + if (em_target != NULL) { + /* While this could cause an extra loop over mesh data, in most cases this will + * have already been properly set. */ + BM_mesh_elem_index_ensure(em_target->bm, BM_VERT); + + if (cd_dvert_offset != -1) { + BLI_task_parallel_mempool(em_target->bm->vpool, &data, lattice_vert_task_editmesh, true); + } + else { + BLI_task_parallel_mempool( + em_target->bm->vpool, &data, lattice_vert_task_editmesh_no_dvert, true); + } + } + else { + TaskParallelSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.min_iter_per_thread = 32; + BLI_task_parallel_range(0, vert_coords_len, &data, lattice_deform_vert_task, &settings); + } end_latt_deform(lattice_deform_data); } @@ -370,7 +420,7 @@ void BKE_lattice_deform_coords(Object *ob_lattice, float fac) { lattice_deform_coords_impl( - ob_lattice, ob_target, vert_coords, vert_coords_len, flag, defgrp_name, fac, NULL); + ob_lattice, ob_target, vert_coords, vert_coords_len, flag, defgrp_name, fac, NULL, NULL); } void BKE_lattice_deform_coords_with_mesh(Object *ob_lattice, @@ -382,8 +432,35 @@ void BKE_lattice_deform_coords_with_mesh(Object *ob_lattice, const float fac, const Mesh *me_target) { - lattice_deform_coords_impl( - ob_lattice, ob_target, vert_coords, vert_coords_len, flag, defgrp_name, fac, me_target); + lattice_deform_coords_impl(ob_lattice, + ob_target, + vert_coords, + vert_coords_len, + flag, + defgrp_name, + fac, + me_target, + NULL); +} + +void BKE_lattice_deform_coords_with_editmesh(struct Object *ob_lattice, + struct Object *ob_target, + float (*vert_coords)[3], + const int vert_coords_len, + const short flag, + const char *defgrp_name, + const float influence, + struct BMEditMesh *em_target) +{ + lattice_deform_coords_impl(ob_lattice, + ob_target, + vert_coords, + vert_coords_len, + flag, + defgrp_name, + influence, + NULL, + em_target); } /** \} */ diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index c8697f90b95..0cc0680804e 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -163,62 +163,47 @@ static void deformVerts(ModifierData *md, static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em, - Mesh *mesh, + Mesh *UNUSED(mesh), float (*vertexCos)[3], int numVerts) { ArmatureModifierData *amd = (ArmatureModifierData *)md; - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); - - /* TODO(Campbell): use edit-mode data only (remove this line). */ - if (mesh_src != NULL) { - BKE_mesh_wrapper_ensure_mdata(mesh_src); - } MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ - BKE_armature_deform_coords_with_mesh(amd->object, - ctx->object, - vertexCos, - NULL, - numVerts, - amd->deformflag, - amd->vert_coords_prev, - amd->defgrp_name, - mesh_src); + BKE_armature_deform_coords_with_editmesh(amd->object, + ctx->object, + vertexCos, + NULL, + numVerts, + amd->deformflag, + amd->vert_coords_prev, + amd->defgrp_name, + em); /* free cache */ MEM_SAFE_FREE(amd->vert_coords_prev); - - if (mesh_src != mesh) { - BKE_id_free(NULL, mesh_src); - } } static void deformMatricesEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em, - Mesh *mesh, + Mesh *UNUSED(mesh), float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { ArmatureModifierData *amd = (ArmatureModifierData *)md; - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); - BKE_armature_deform_coords_with_mesh(amd->object, - ctx->object, - vertexCos, - defMats, - numVerts, - amd->deformflag, - NULL, - amd->defgrp_name, - mesh_src); - - if (mesh_src != mesh) { - BKE_id_free(NULL, mesh_src); - } + BKE_armature_deform_coords_with_editmesh(amd->object, + ctx->object, + vertexCos, + defMats, + numVerts, + amd->deformflag, + NULL, + amd->defgrp_name, + em); } static void deformMatrices(ModifierData *md, diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index b55e48f46ce..a13bb07f678 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -34,6 +34,7 @@ #include "BKE_context.h" #include "BKE_curve.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" @@ -129,8 +130,9 @@ static void deformVerts(ModifierData *md, int defgrp_index = -1; MOD_get_vgroup(ctx->object, mesh_src, cmd->name, &dvert, &defgrp_index); - /* silly that defaxis and BKE_curve_deform_coords are off by 1 + /* Silly that defaxis and BKE_curve_deform_coords are off by 1 * but leave for now to save having to call do_versions */ + BKE_curve_deform_coords(cmd->object, ctx->object, vertexCos, @@ -147,22 +149,41 @@ static void deformVerts(ModifierData *md, static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *em, - Mesh *mesh, + BMEditMesh *em, + Mesh *UNUSED(mesh), float (*vertexCos)[3], int numVerts) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); + CurveModifierData *cmd = (CurveModifierData *)md; + bool use_dverts = false; + int defgrp_index = -1; - /* TODO(Campbell): use edit-mode data only (remove this line). */ - if (mesh_src != NULL) { - BKE_mesh_wrapper_ensure_mdata(mesh_src); + if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') { + defgrp_index = BKE_object_defgroup_name_index(ctx->object, cmd->name); + if (defgrp_index != -1) { + use_dverts = true; + } } - deformVerts(md, ctx, mesh_src, vertexCos, numVerts); - - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (use_dverts) { + BKE_curve_deform_coords_with_editmesh(cmd->object, + ctx->object, + vertexCos, + numVerts, + defgrp_index, + cmd->flag, + cmd->defaxis - 1, + em); + } + else { + BKE_curve_deform_coords(cmd->object, + ctx->object, + vertexCos, + numVerts, + NULL, + defgrp_index, + cmd->flag, + cmd->defaxis - 1); } } diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index a6eaf7e78aa..574ea969be4 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -130,23 +130,16 @@ static void deformVerts(ModifierData *md, static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em, - struct Mesh *mesh, + struct Mesh *UNUSED(mesh), float (*vertexCos)[3], int numVerts) { - struct Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, em, mesh, NULL, numVerts, false, false); - - /* TODO(Campbell): use edit-mode data only (remove this line). */ - if (mesh_src != NULL) { - BKE_mesh_wrapper_ensure_mdata(mesh_src); - } + LatticeModifierData *lmd = (LatticeModifierData *)md; - deformVerts(md, ctx, mesh_src, vertexCos, numVerts); + MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); - } + BKE_lattice_deform_coords_with_editmesh( + lmd->object, ctx->object, vertexCos, numVerts, lmd->flag, lmd->name, lmd->strength, em); } static void panel_draw(const bContext *C, Panel *panel) -- cgit v1.2.3