forked from bartvdbraak/blender
EditMesh: Avoid creating deform-vert layer every redraw
Getting a new edit-derived-bmesh was always creating a deform-vert array, even when it wasn't needed. Since this was called on redraw, in many cases it was doing it unnecessarily. Now pass in a custom-data mask and only fill in deform-verts when needed. Gives noticeable drawing speedup (~10-30% here).
This commit is contained in:
parent
493c6b622f
commit
b204bdad47
@ -694,7 +694,7 @@ DerivedMesh *mesh_create_derived_render(
|
||||
CustomDataMask dataMask);
|
||||
|
||||
DerivedMesh *getEditDerivedBMesh(
|
||||
struct BMEditMesh *em, struct Object *ob,
|
||||
struct BMEditMesh *em, struct Object *ob, CustomDataMask data_mask,
|
||||
float (*vertexCos)[3]);
|
||||
|
||||
DerivedMesh *mesh_create_derived_index_render(
|
||||
@ -723,7 +723,7 @@ DerivedMesh *mesh_create_derived_physics(
|
||||
CustomDataMask dataMask);
|
||||
|
||||
DerivedMesh *editbmesh_get_derived_base(
|
||||
struct Object *, struct BMEditMesh *em);
|
||||
struct Object *ob, struct BMEditMesh *em, CustomDataMask data_mask);
|
||||
DerivedMesh *editbmesh_get_derived_cage(
|
||||
struct Scene *scene, struct Object *,
|
||||
struct BMEditMesh *em, CustomDataMask dataMask);
|
||||
|
@ -1433,10 +1433,12 @@ static void calc_weightpaint_vert_array(
|
||||
Object *ob, DerivedMesh *dm, int const draw_flag, DMWeightColorInfo *dm_wcinfo,
|
||||
unsigned char (*r_wtcol_v)[4])
|
||||
{
|
||||
MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
|
||||
int numVerts = dm->getNumVerts(dm);
|
||||
BMEditMesh *em = (dm->type == DM_TYPE_EDITBMESH) ? BKE_editmesh_from_object(ob) : NULL;
|
||||
const int numVerts = dm->getNumVerts(dm);
|
||||
|
||||
if (dv && (ob->actdef != 0)) {
|
||||
if ((ob->actdef != 0) &&
|
||||
(CustomData_has_layer(em ? &em->bm->vdata : &dm->vertData, CD_MDEFORMVERT)))
|
||||
{
|
||||
unsigned char (*wc)[4] = r_wtcol_v;
|
||||
unsigned int i;
|
||||
|
||||
@ -1455,8 +1457,30 @@ static void calc_weightpaint_vert_array(
|
||||
}
|
||||
}
|
||||
|
||||
for (i = numVerts; i != 0; i--, wc++, dv++) {
|
||||
calc_weightpaint_vert_color((unsigned char *)wc, dv, dm_wcinfo, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
|
||||
/* editmesh won't have deform verts unless modifiers require it,
|
||||
* avoid having to create an array of deform-verts only for drawing
|
||||
* by reading from the bmesh directly. */
|
||||
if (em) {
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
|
||||
BLI_assert(cd_dvert_offset != -1);
|
||||
|
||||
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
||||
const MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
|
||||
calc_weightpaint_vert_color(
|
||||
(unsigned char *)wc, dv, dm_wcinfo,
|
||||
defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
|
||||
wc++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
|
||||
for (i = numVerts; i != 0; i--, wc++, dv++) {
|
||||
calc_weightpaint_vert_color(
|
||||
(unsigned char *)wc, dv, dm_wcinfo,
|
||||
defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
|
||||
}
|
||||
}
|
||||
|
||||
if (defbase_sel) {
|
||||
@ -2282,7 +2306,7 @@ static void editbmesh_calc_modifiers(
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
if (r_cage && cageIndex == -1) {
|
||||
*r_cage = getEditDerivedBMesh(em, ob, NULL);
|
||||
*r_cage = getEditDerivedBMesh(em, ob, dataMask, NULL);
|
||||
}
|
||||
|
||||
md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
||||
@ -2448,7 +2472,7 @@ static void editbmesh_calc_modifiers(
|
||||
}
|
||||
else {
|
||||
*r_cage = getEditDerivedBMesh(
|
||||
em, ob,
|
||||
em, ob, mask,
|
||||
deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
|
||||
}
|
||||
}
|
||||
@ -2484,7 +2508,7 @@ static void editbmesh_calc_modifiers(
|
||||
}
|
||||
else {
|
||||
/* this is just a copy of the editmesh, no need to calc normals */
|
||||
*r_final = getEditDerivedBMesh(em, ob, deformedVerts);
|
||||
*r_final = getEditDerivedBMesh(em, ob, dataMask, deformedVerts);
|
||||
deformedVerts = NULL;
|
||||
|
||||
/* In this case, we should never have weight-modifying modifiers in stack... */
|
||||
@ -2847,9 +2871,9 @@ DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh
|
||||
return em->derivedCage;
|
||||
}
|
||||
|
||||
DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
|
||||
DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em, CustomDataMask data_mask)
|
||||
{
|
||||
return getEditDerivedBMesh(em, obedit, NULL);
|
||||
return getEditDerivedBMesh(em, obedit, data_mask, NULL);
|
||||
}
|
||||
|
||||
/***/
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_crazyspace.h"
|
||||
@ -275,7 +276,13 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Scene *scene, Object *ob,
|
||||
|
||||
if (mti->type == eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
|
||||
if (!defmats) {
|
||||
dm = getEditDerivedBMesh(em, ob, NULL);
|
||||
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||
CustomDataMask data_mask = CD_MASK_BAREMESH;
|
||||
CDMaskLink *datamasks = modifiers_calcDataMasks(scene, ob, md, data_mask, required_mode, NULL, 0);
|
||||
data_mask = datamasks->mask;
|
||||
BLI_linklist_free((LinkNode *)datamasks, NULL);
|
||||
|
||||
dm = getEditDerivedBMesh(em, ob, data_mask, NULL);
|
||||
deformedVerts = editbmesh_get_vertex_cos(em, &numVerts);
|
||||
defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats");
|
||||
|
||||
|
@ -2226,16 +2226,17 @@ static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
|
||||
return &bmdm->em->bm->pdata;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \note This may be called per-draw,
|
||||
* avoid allocating large arrays where possible and keep this a thin wrapper for #BMesh.
|
||||
*/
|
||||
DerivedMesh *getEditDerivedBMesh(
|
||||
BMEditMesh *em,
|
||||
Object *UNUSED(ob),
|
||||
BMEditMesh *em, struct Object *UNUSED(ob),
|
||||
CustomDataMask data_mask,
|
||||
float (*vertexCos)[3])
|
||||
{
|
||||
EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
|
||||
BMesh *bm = em->bm;
|
||||
const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
|
||||
const int cd_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
|
||||
|
||||
bmdm->em = em;
|
||||
|
||||
@ -2304,6 +2305,9 @@ DerivedMesh *getEditDerivedBMesh(
|
||||
bmdm->vertexCos = (const float (*)[3])vertexCos;
|
||||
bmdm->dm.deformedOnly = (vertexCos != NULL);
|
||||
|
||||
const int cd_dvert_offset = (data_mask & CD_MASK_MDEFORMVERT) ?
|
||||
CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT) : -1;
|
||||
|
||||
if (cd_dvert_offset != -1) {
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
@ -2317,6 +2321,9 @@ DerivedMesh *getEditDerivedBMesh(
|
||||
}
|
||||
}
|
||||
|
||||
const int cd_skin_offset = (data_mask & CD_MASK_MVERT_SKIN) ?
|
||||
CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN) : -1;
|
||||
|
||||
if (cd_skin_offset != -1) {
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
|
@ -4250,12 +4250,15 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
|
||||
if (ob == obedit || drawlinked) {
|
||||
DerivedMesh *finalDM, *cageDM;
|
||||
|
||||
if (obedit != ob)
|
||||
finalDM = cageDM = editbmesh_get_derived_base(ob, em);
|
||||
else
|
||||
if (obedit != ob) {
|
||||
finalDM = cageDM = editbmesh_get_derived_base(
|
||||
ob, em, scene->customdata_mask);
|
||||
}
|
||||
else {
|
||||
cageDM = editbmesh_get_derived_cage_and_final(
|
||||
scene, ob, em, scene->customdata_mask,
|
||||
&finalDM);
|
||||
}
|
||||
|
||||
const bool use_material = ((me->drawflag & ME_DRAWEIGHT) == 0);
|
||||
|
||||
@ -8480,7 +8483,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
|
||||
DerivedMesh *dm = NULL, *edm = NULL;
|
||||
|
||||
if (ob->mode & OB_MODE_EDIT) {
|
||||
edm = editbmesh_get_derived_base(ob, me->edit_btmesh);
|
||||
edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH);
|
||||
DM_update_materials(edm, ob);
|
||||
}
|
||||
else {
|
||||
|
Loading…
Reference in New Issue
Block a user