Fix a crash with duplivert, and move to evaluated mesh in object_dupli.c
There are still lots of issues/TODOs here though, like missing 'cage' for editmesh, etc.
This commit is contained in:
parent
3d2f596d94
commit
3e6f37b936
|
@ -44,18 +44,19 @@
|
|||
#include "DNA_anim_types.h"
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_vfont_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_font.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_iterators.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
|
@ -389,7 +390,7 @@ static const DupliGenerator gen_dupli_frames = {
|
|||
|
||||
/* OB_DUPLIVERTS */
|
||||
typedef struct VertexDupliData {
|
||||
DerivedMesh *dm;
|
||||
Mesh *me_eval;
|
||||
BMEditMesh *edit_btmesh;
|
||||
int totvert;
|
||||
float (*orco)[3];
|
||||
|
@ -459,37 +460,15 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
|
|||
static void make_child_duplis_verts(const DupliContext *ctx, void *userdata, Object *child)
|
||||
{
|
||||
VertexDupliData *vdd = userdata;
|
||||
DerivedMesh *dm = vdd->dm;
|
||||
Mesh *me_eval = vdd->me_eval;
|
||||
|
||||
vdd->inst_ob = child;
|
||||
invert_m4_m4(child->imat, child->obmat);
|
||||
/* relative transform from parent to child space */
|
||||
mul_m4_m4m4(vdd->child_imat, child->imat, ctx->object->obmat);
|
||||
|
||||
if (vdd->edit_btmesh) {
|
||||
dm->foreachMappedVert(dm, vertex_dupli__mapFunc, vdd,
|
||||
vdd->use_rotation ? DM_FOREACH_USE_NORMAL : 0);
|
||||
}
|
||||
else {
|
||||
int a, totvert = vdd->totvert;
|
||||
float vec[3], no[3];
|
||||
|
||||
if (vdd->use_rotation) {
|
||||
for (a = 0; a < totvert; a++) {
|
||||
dm->getVertCo(dm, a, vec);
|
||||
dm->getVertNo(dm, a, no);
|
||||
|
||||
vertex_dupli__mapFunc(vdd, a, vec, no, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (a = 0; a < totvert; a++) {
|
||||
dm->getVertCo(dm, a, vec);
|
||||
|
||||
vertex_dupli__mapFunc(vdd, a, vec, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
BKE_mesh_foreach_mapped_vert(me_eval, vertex_dupli__mapFunc, vdd,
|
||||
vdd->use_rotation ? MESH_FOREACH_USE_NORMAL : 0);
|
||||
}
|
||||
|
||||
static void make_duplis_verts(const DupliContext *ctx)
|
||||
|
@ -504,32 +483,31 @@ static void make_duplis_verts(const DupliContext *ctx)
|
|||
|
||||
/* gather mesh info */
|
||||
{
|
||||
Mesh *me = parent->data;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(parent);
|
||||
CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH);
|
||||
vdd.edit_btmesh = BKE_editmesh_from_object(parent);
|
||||
|
||||
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER) {
|
||||
vdd.dm = mesh_create_derived_render(ctx->depsgraph, scene, parent, dm_mask);
|
||||
}
|
||||
else if (em) {
|
||||
vdd.dm = editbmesh_get_derived_cage(ctx->depsgraph, scene, parent, em, dm_mask);
|
||||
/* We do not need any render-smecific handling anymore, depsgraph takes care of that. */
|
||||
if (vdd.edit_btmesh != NULL) {
|
||||
/* XXX TODO replace with equivalent of editbmesh_get_derived_cage when available. */
|
||||
vdd.me_eval = mesh_get_eval_deform(ctx->depsgraph, scene, parent, dm_mask);
|
||||
}
|
||||
else {
|
||||
vdd.dm = mesh_get_derived_final(ctx->depsgraph, scene, parent, dm_mask);
|
||||
vdd.me_eval = mesh_get_eval_final(ctx->depsgraph, scene, parent, dm_mask);
|
||||
}
|
||||
vdd.edit_btmesh = me->edit_btmesh;
|
||||
|
||||
if (use_texcoords)
|
||||
vdd.orco = vdd.dm->getVertDataArray(vdd.dm, CD_ORCO);
|
||||
else
|
||||
if (use_texcoords) {
|
||||
vdd.orco = CustomData_get_layer(&vdd.me_eval->vdata, CD_ORCO);
|
||||
}
|
||||
else {
|
||||
vdd.orco = NULL;
|
||||
}
|
||||
|
||||
vdd.totvert = vdd.dm->getNumVerts(vdd.dm);
|
||||
vdd.totvert = vdd.me_eval->totvert;
|
||||
}
|
||||
|
||||
make_child_duplis(ctx, &vdd, make_child_duplis_verts);
|
||||
|
||||
vdd.dm->release(vdd.dm);
|
||||
vdd.me_eval = NULL;
|
||||
}
|
||||
|
||||
static const DupliGenerator gen_dupli_verts = {
|
||||
|
@ -654,7 +632,7 @@ static const DupliGenerator gen_dupli_verts_font = {
|
|||
|
||||
/* OB_DUPLIFACES */
|
||||
typedef struct FaceDupliData {
|
||||
DerivedMesh *dm;
|
||||
Mesh *me_eval;
|
||||
int totface;
|
||||
MPoly *mpoly;
|
||||
MLoop *mloop;
|
||||
|
@ -778,36 +756,34 @@ static void make_duplis_faces(const DupliContext *ctx)
|
|||
BMEditMesh *em = BKE_editmesh_from_object(parent);
|
||||
CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);
|
||||
|
||||
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER) {
|
||||
fdd.dm = mesh_create_derived_render(ctx->depsgraph, scene, parent, dm_mask);
|
||||
}
|
||||
else if (em) {
|
||||
fdd.dm = editbmesh_get_derived_cage(ctx->depsgraph, scene, parent, em, dm_mask);
|
||||
/* We do not need any render-smecific handling anymore, depsgraph takes care of that. */
|
||||
if (em != NULL) {
|
||||
/* XXX TODO replace with equivalent of editbmesh_get_derived_cage when available. */
|
||||
fdd.me_eval = mesh_get_eval_deform(ctx->depsgraph, scene, parent, dm_mask);
|
||||
}
|
||||
else {
|
||||
fdd.dm = mesh_get_derived_final(ctx->depsgraph, scene, parent, dm_mask);
|
||||
fdd.me_eval = mesh_get_eval_final(ctx->depsgraph, scene, parent, dm_mask);
|
||||
}
|
||||
|
||||
if (use_texcoords) {
|
||||
CustomData *ml_data = fdd.dm->getLoopDataLayout(fdd.dm);
|
||||
const int uv_idx = CustomData_get_render_layer(ml_data, CD_MLOOPUV);
|
||||
fdd.orco = fdd.dm->getVertDataArray(fdd.dm, CD_ORCO);
|
||||
fdd.mloopuv = CustomData_get_layer_n(ml_data, CD_MLOOPUV, uv_idx);
|
||||
fdd.orco = CustomData_get_layer(&fdd.me_eval->vdata, CD_ORCO);
|
||||
const int uv_idx = CustomData_get_render_layer(&fdd.me_eval->ldata, CD_MLOOPUV);
|
||||
fdd.mloopuv = CustomData_get_layer_n(&fdd.me_eval->ldata, CD_MLOOPUV, uv_idx);
|
||||
}
|
||||
else {
|
||||
fdd.orco = NULL;
|
||||
fdd.mloopuv = NULL;
|
||||
}
|
||||
|
||||
fdd.totface = fdd.dm->getNumPolys(fdd.dm);
|
||||
fdd.mpoly = fdd.dm->getPolyArray(fdd.dm);
|
||||
fdd.mloop = fdd.dm->getLoopArray(fdd.dm);
|
||||
fdd.mvert = fdd.dm->getVertArray(fdd.dm);
|
||||
fdd.totface = fdd.me_eval->totpoly;
|
||||
fdd.mpoly = fdd.me_eval->mpoly;
|
||||
fdd.mloop = fdd.me_eval->mloop;
|
||||
fdd.mvert = fdd.me_eval->mvert;
|
||||
}
|
||||
|
||||
make_child_duplis(ctx, &fdd, make_child_duplis_faces);
|
||||
|
||||
fdd.dm->release(fdd.dm);
|
||||
fdd.me_eval = NULL;
|
||||
}
|
||||
|
||||
static const DupliGenerator gen_dupli_faces = {
|
||||
|
|
Loading…
Reference in New Issue