Modifiers: Simple Deform & Build, DerivedMesh → Mesh
This commit introduces `EditMeshData`. The fields in this struct are extracted from `EditDerivedBMesh` into their own struct `EditMeshData`, which can then also be used by the `Mesh` struct. This allows passing deformed vertices efficiently to the draw routines. The modifier code constructs a new Mesh instead of writing to ob->data; even when ob->data is a CoW copy, it can still be used by different objects and thus shouldn't be modified by a modifier.
This commit is contained in:
@@ -41,8 +41,13 @@
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
@@ -75,12 +80,11 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
|
||||
return true;
|
||||
}
|
||||
|
||||
static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(depsgraph),
|
||||
Object *UNUSED(ob), DerivedMesh *derivedData,
|
||||
ModifierApplyFlag UNUSED(flag))
|
||||
static Mesh *applyModifier(ModifierData *md, struct Depsgraph *depsgraph,
|
||||
Object *UNUSED(ob), struct Mesh *mesh,
|
||||
ModifierApplyFlag UNUSED(flag))
|
||||
{
|
||||
DerivedMesh *dm = derivedData;
|
||||
DerivedMesh *result;
|
||||
Mesh *result;
|
||||
BuildModifierData *bmd = (BuildModifierData *) md;
|
||||
int i, j, k;
|
||||
int numFaces_dst, numEdges_dst, numLoops_dst = 0;
|
||||
@@ -93,16 +97,16 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
|
||||
/* maps edge indices in new mesh to indices in old mesh */
|
||||
GHash *edgeHash = BLI_ghash_int_new("build ed apply gh");
|
||||
/* maps edge indices in old mesh to indices in new mesh */
|
||||
GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh");
|
||||
|
||||
const int numVert_src = dm->getNumVerts(dm);
|
||||
const int numEdge_src = dm->getNumEdges(dm);
|
||||
const int numPoly_src = dm->getNumPolys(dm);
|
||||
MPoly *mpoly_src = dm->getPolyArray(dm);
|
||||
MLoop *mloop_src = dm->getLoopArray(dm);
|
||||
MEdge *medge_src = dm->getEdgeArray(dm);
|
||||
MVert *mvert_src = dm->getVertArray(dm);
|
||||
|
||||
const int numVert_src = mesh->totvert;
|
||||
const int numEdge_src = mesh->totedge;
|
||||
const int numPoly_src = mesh->totpoly;
|
||||
MPoly *mpoly_src = mesh->mpoly;
|
||||
MLoop *mloop_src = mesh->mloop;
|
||||
MEdge *medge_src = mesh->medge;
|
||||
MVert *mvert_src = mesh->mvert;
|
||||
|
||||
vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap");
|
||||
edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap");
|
||||
@@ -112,13 +116,13 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
range_vn_i(edgeMap, numEdge_src, 0);
|
||||
range_vn_i(faceMap, numPoly_src, 0);
|
||||
|
||||
frac = (BKE_scene_frame_get(md->scene) - bmd->start) / bmd->length;
|
||||
struct Scene *scene = DEG_get_input_scene(depsgraph);
|
||||
frac = (BKE_scene_frame_get(scene) - bmd->start) / bmd->length;
|
||||
CLAMP(frac, 0.0f, 1.0f);
|
||||
|
||||
if (bmd->flag & MOD_BUILD_FLAG_REVERSE) {
|
||||
frac = 1.0f - frac;
|
||||
}
|
||||
|
||||
|
||||
numFaces_dst = numPoly_src * frac;
|
||||
numEdges_dst = numEdge_src * frac;
|
||||
|
||||
@@ -126,7 +130,6 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
if (numFaces_dst) {
|
||||
MPoly *mpoly, *mp;
|
||||
MLoop *ml, *mloop;
|
||||
MEdge *medge;
|
||||
uintptr_t hash_num, hash_num_alt;
|
||||
|
||||
if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
|
||||
@@ -159,11 +162,10 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
/* get the set of edges that will be in the new mesh (i.e. all edges
|
||||
* that have both verts in the new mesh)
|
||||
*/
|
||||
medge = medge_src;
|
||||
hash_num = 0;
|
||||
hash_num_alt = 0;
|
||||
for (i = 0; i < numEdge_src; i++, hash_num_alt++) {
|
||||
MEdge *me = medge + i;
|
||||
MEdge *me = medge_src + i;
|
||||
|
||||
if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) &&
|
||||
BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2)))
|
||||
@@ -173,6 +175,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
hash_num++;
|
||||
}
|
||||
}
|
||||
BLI_assert(hash_num == BLI_ghash_len(edgeHash));
|
||||
}
|
||||
else if (numEdges_dst) {
|
||||
MEdge *medge, *me;
|
||||
@@ -206,7 +209,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
/* get the set of edges that will be in the new mesh */
|
||||
for (i = 0; i < numEdges_dst; i++) {
|
||||
j = BLI_ghash_len(edgeHash);
|
||||
|
||||
|
||||
BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j),
|
||||
SET_INT_IN_POINTER(edgeMap[i]));
|
||||
BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(edgeMap[i]),
|
||||
@@ -229,11 +232,9 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
}
|
||||
}
|
||||
|
||||
/* now we know the number of verts, edges and faces, we can create
|
||||
* the mesh
|
||||
*/
|
||||
result = CDDM_from_template(dm, BLI_ghash_len(vertHash),
|
||||
BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst);
|
||||
/* now we know the number of verts, edges and faces, we can create the mesh. */
|
||||
result = BKE_mesh_from_template(mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash),
|
||||
0, numLoops_dst, numFaces_dst);
|
||||
|
||||
/* copy the vertices across */
|
||||
GHASH_ITER (gh_iter, vertHash) {
|
||||
@@ -243,45 +244,44 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));
|
||||
|
||||
source = mvert_src[oldIndex];
|
||||
dest = CDDM_get_vert(result, newIndex);
|
||||
dest = &result->mvert[newIndex];
|
||||
|
||||
DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
|
||||
CustomData_copy_data(&mesh->vdata, &result->vdata, oldIndex, newIndex, 1);
|
||||
*dest = source;
|
||||
}
|
||||
|
||||
|
||||
/* copy the edges across, remapping indices */
|
||||
for (i = 0; i < BLI_ghash_len(edgeHash); i++) {
|
||||
MEdge source;
|
||||
MEdge *dest;
|
||||
int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
|
||||
|
||||
|
||||
source = medge_src[oldIndex];
|
||||
dest = CDDM_get_edge(result, i);
|
||||
|
||||
dest = &result->medge[i];
|
||||
|
||||
source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
|
||||
source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
|
||||
|
||||
DM_copy_edge_data(dm, result, oldIndex, i, 1);
|
||||
|
||||
CustomData_copy_data(&mesh->edata, &result->edata, oldIndex, i, 1);
|
||||
*dest = source;
|
||||
}
|
||||
|
||||
mpoly_dst = CDDM_get_polys(result);
|
||||
/* mloop_dst = */ ml_dst = CDDM_get_loops(result);
|
||||
mpoly_dst = result->mpoly;
|
||||
ml_dst = result->mloop;
|
||||
|
||||
/* copy the faces across, remapping indices */
|
||||
k = 0;
|
||||
for (i = 0; i < numFaces_dst; i++) {
|
||||
MPoly *source;
|
||||
MPoly *dest;
|
||||
|
||||
|
||||
source = mpoly_src + faceMap[i];
|
||||
dest = mpoly_dst + i;
|
||||
DM_copy_poly_data(dm, result, faceMap[i], i, 1);
|
||||
|
||||
CustomData_copy_data(&mesh->pdata, &result->pdata, faceMap[i], i, 1);
|
||||
|
||||
*dest = *source;
|
||||
dest->loopstart = k;
|
||||
|
||||
DM_copy_loop_data(dm, result, source->loopstart, dest->loopstart, dest->totloop);
|
||||
CustomData_copy_data(&mesh->ldata, &result->ldata, source->loopstart, dest->loopstart, dest->totloop);
|
||||
|
||||
ml_src = mloop_src + source->loopstart;
|
||||
for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) {
|
||||
@@ -298,10 +298,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Depsgraph *UNUSED(dep
|
||||
MEM_freeN(edgeMap);
|
||||
MEM_freeN(faceMap);
|
||||
|
||||
if (dm->dirty & DM_DIRTY_NORMALS) {
|
||||
result->dirty |= DM_DIRTY_NORMALS;
|
||||
}
|
||||
|
||||
/* TODO(sybren): also copy flags & tags? */
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -319,14 +316,14 @@ ModifierTypeInfo modifierType_Build = {
|
||||
/* deformMatrices_DM */ NULL,
|
||||
/* deformVertsEM_DM */ NULL,
|
||||
/* deformMatricesEM_DM*/NULL,
|
||||
/* applyModifier_DM */ applyModifier,
|
||||
/* applyModifier_DM */ NULL,
|
||||
/* applyModifierEM_DM */NULL,
|
||||
|
||||
/* deformVerts */ NULL,
|
||||
/* deformMatrices */ NULL,
|
||||
/* deformVertsEM */ NULL,
|
||||
/* deformMatricesEM */ NULL,
|
||||
/* applyModifier */ NULL,
|
||||
/* applyModifier */ applyModifier,
|
||||
/* applyModifierEM */ NULL,
|
||||
|
||||
/* initData */ initData,
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_deform.h"
|
||||
@@ -180,11 +182,10 @@ static void simpleDeform_bend(const float factor, const int axis, const float dc
|
||||
|
||||
|
||||
/* simple deform modifier */
|
||||
static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
|
||||
static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct Mesh *mesh,
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
const float base_limit[2] = {0.0f, 0.0f};
|
||||
|
||||
int i;
|
||||
float smd_limit[2], smd_factor;
|
||||
SpaceTransform *transf = NULL, tmp_transf;
|
||||
@@ -281,7 +282,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
|
||||
}
|
||||
}
|
||||
|
||||
modifier_get_vgroup(ob, dm, smd->vgroup_name, &dvert, &vgroup);
|
||||
modifier_get_vgroup_mesh(ob, mesh, smd->vgroup_name, &dvert, &vgroup);
|
||||
const bool invert_vgroup = (smd->flag & MOD_SIMPLEDEFORM_FLAG_INVERT_VGROUP) != 0;
|
||||
const uint *axis_map = axis_map_table[(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? deform_axis : 2];
|
||||
|
||||
@@ -384,43 +385,21 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
|
||||
}
|
||||
|
||||
static void deformVerts(ModifierData *md, struct Depsgraph *UNUSED(depsgraph),
|
||||
Object *ob, DerivedMesh *derivedData,
|
||||
Object *ob, struct Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int numVerts,
|
||||
ModifierApplyFlag UNUSED(flag))
|
||||
{
|
||||
DerivedMesh *dm = derivedData;
|
||||
CustomDataMask dataMask = requiredDataMask(ob, md);
|
||||
|
||||
/* we implement requiredDataMask but thats not really useful since
|
||||
* mesh_calc_modifiers pass a NULL derivedData */
|
||||
if (dataMask)
|
||||
dm = get_dm(ob, NULL, dm, NULL, false, false);
|
||||
|
||||
SimpleDeformModifier_do((SimpleDeformModifierData *)md, ob, dm, vertexCos, numVerts);
|
||||
|
||||
if (dm != derivedData)
|
||||
dm->release(dm);
|
||||
SimpleDeformModifier_do((SimpleDeformModifierData *)md, ob, mesh, vertexCos, numVerts);
|
||||
}
|
||||
|
||||
static void deformVertsEM(ModifierData *md, struct Depsgraph *UNUSED(depsgraph),
|
||||
Object *ob, struct BMEditMesh *editData,
|
||||
DerivedMesh *derivedData,
|
||||
Object *ob, struct BMEditMesh *UNUSED(editData),
|
||||
struct Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = derivedData;
|
||||
CustomDataMask dataMask = requiredDataMask(ob, md);
|
||||
|
||||
/* we implement requiredDataMask but thats not really useful since
|
||||
* mesh_calc_modifiers pass a NULL derivedData */
|
||||
if (dataMask)
|
||||
dm = get_dm(ob, editData, dm, NULL, false, false);
|
||||
|
||||
SimpleDeformModifier_do((SimpleDeformModifierData *)md, ob, dm, vertexCos, numVerts);
|
||||
|
||||
if (dm != derivedData)
|
||||
dm->release(dm);
|
||||
SimpleDeformModifier_do((SimpleDeformModifierData *)md, ob, mesh, vertexCos, numVerts);
|
||||
}
|
||||
|
||||
|
||||
@@ -438,16 +417,16 @@ ModifierTypeInfo modifierType_SimpleDeform = {
|
||||
|
||||
/* copyData */ copyData,
|
||||
|
||||
/* deformVerts_DM */ deformVerts,
|
||||
/* deformVerts_DM */ NULL,
|
||||
/* deformMatrices_DM */ NULL,
|
||||
/* deformVertsEM_DM */ deformVertsEM,
|
||||
/* deformVertsEM_DM */ NULL,
|
||||
/* deformMatricesEM_DM*/NULL,
|
||||
/* applyModifier_DM */ NULL,
|
||||
/* applyModifierEM_DM */NULL,
|
||||
|
||||
/* deformVerts */ NULL,
|
||||
/* deformVerts */ deformVerts,
|
||||
/* deformMatrices */ NULL,
|
||||
/* deformVertsEM */ NULL,
|
||||
/* deformVertsEM */ deformVertsEM,
|
||||
/* deformMatricesEM */ NULL,
|
||||
/* applyModifier */ NULL,
|
||||
/* applyModifierEM */ NULL,
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math_vector.h"
|
||||
@@ -229,6 +231,20 @@ void modifier_get_vgroup(Object *ob, DerivedMesh *dm, const char *name, MDeformV
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO(sybren): replace the above function with this one, once we got rid of DerivedMesh for modifiers. */
|
||||
void modifier_get_vgroup_mesh(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
|
||||
{
|
||||
*defgrp_index = defgroup_name_index(ob, name);
|
||||
*dvert = NULL;
|
||||
|
||||
if (*defgrp_index != -1) {
|
||||
if (ob->type == OB_LATTICE)
|
||||
*dvert = BKE_lattice_deform_verts_get(ob);
|
||||
else if (mesh)
|
||||
*dvert = mesh->dvert;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* only called by BKE_modifier.h/modifier.c */
|
||||
void modifier_type_init(ModifierTypeInfo *types[])
|
||||
|
||||
@@ -51,5 +51,7 @@ struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct Deri
|
||||
struct DerivedMesh *get_dm_for_modifier(struct Object *ob, ModifierApplyFlag flag);
|
||||
void modifier_get_vgroup(struct Object *ob, struct DerivedMesh *dm,
|
||||
const char *name, struct MDeformVert **dvert, int *defgrp_index);
|
||||
void modifier_get_vgroup_mesh(struct Object *ob, struct Mesh *mesh,
|
||||
const char *name, struct MDeformVert **dvert, int *defgrp_index);
|
||||
|
||||
#endif /* __MOD_UTIL_H__ */
|
||||
|
||||
Reference in New Issue
Block a user