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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-06-13 06:14:07 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-06-13 06:19:34 +0300
commit9f5833798caf9581c2d781f4e2f8b95acb1560e0 (patch)
tree2c216f13fb90244a2160959faa754f0e327836d7 /source
parenta35de34eb78aba5e08938066c0ecdcb05f677a8f (diff)
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%.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_armature.h11
-rw-r--r--source/blender/blenkernel/BKE_curve.h11
-rw-r--r--source/blender/blenkernel/BKE_lattice.h10
-rw-r--r--source/blender/blenkernel/intern/armature_deform.c150
-rw-r--r--source/blender/blenkernel/intern/curve_deform.c200
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c113
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c55
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c43
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c17
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)