Ported Mesh Deform modifier
This modifier still has issues that are not related to this port: - While editing the deformation mesh, the deformed mesh doesn't update. This update only happens after exiting edit mode, making editing cumbersome. - Binding doesn't work yet. It works fine when binding in master and loading pre-bound in 2.8. This was also an issue before this port, and will be investigated separately.
This commit is contained in:
@@ -102,11 +102,15 @@ void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_t
|
||||
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
|
||||
|
||||
struct Mesh *BKE_mesh_new_nomain(int numVerts, int numEdges, int numTessFaces,int numLoops, int numPolys);
|
||||
struct Mesh * BKE_mesh_from_template(
|
||||
struct Mesh *BKE_mesh_from_template(
|
||||
const struct Mesh *me_src,
|
||||
int numVerts, int numEdges, int numTessFaces,
|
||||
int numLoops, int numPolys);
|
||||
|
||||
/* These functions construct a new Mesh, contrary to BKE_mesh_from_nurbs which modifies ob itself. */
|
||||
struct Mesh *BKE_new_mesh_nomain_from_curve(struct Object *ob);
|
||||
struct Mesh *BKE_new_mesh_nomain_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
|
||||
|
||||
bool BKE_mesh_ensure_edit_data(struct Mesh *me);
|
||||
bool BKE_mesh_clear_edit_data(struct Mesh *me);
|
||||
|
||||
@@ -182,6 +186,8 @@ int BKE_mesh_mselect_find(struct Mesh *me, int index, int type);
|
||||
int BKE_mesh_mselect_active_get(struct Mesh *me, int type);
|
||||
void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type);
|
||||
|
||||
void BKE_mesh_apply_vert_coords(struct Mesh *mesh, float (*vertCoords)[3]);
|
||||
|
||||
/* *** mesh_runtime.c *** */
|
||||
|
||||
void BKE_mesh_runtime_recalc_looptri(struct Mesh *mesh);
|
||||
|
||||
@@ -1497,6 +1497,58 @@ int BKE_mesh_nurbs_displist_to_mdata(
|
||||
return 0;
|
||||
}
|
||||
|
||||
Mesh *BKE_new_mesh_nomain_from_curve_displist(Object *ob, ListBase *dispbase)
|
||||
{
|
||||
Curve *cu = ob->data;
|
||||
Mesh *mesh;
|
||||
MVert *allvert;
|
||||
MEdge *alledge;
|
||||
MLoop *allloop;
|
||||
MPoly *allpoly;
|
||||
MLoopUV *alluv = NULL;
|
||||
int totvert, totedge, totloop, totpoly;
|
||||
bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
|
||||
|
||||
if (BKE_mesh_nurbs_displist_to_mdata(
|
||||
ob, dispbase, &allvert, &totvert, &alledge,
|
||||
&totedge, &allloop, &allpoly, (use_orco_uv) ? &alluv : NULL,
|
||||
&totloop, &totpoly) != 0)
|
||||
{
|
||||
/* Error initializing mdata. This often happens when curve is empty */
|
||||
return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
|
||||
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
||||
|
||||
memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));
|
||||
memcpy(mesh->medge, alledge, totedge * sizeof(MEdge));
|
||||
memcpy(mesh->mloop, allloop, totloop * sizeof(MLoop));
|
||||
memcpy(mesh->mpoly, allpoly, totpoly * sizeof(MPoly));
|
||||
|
||||
if (alluv) {
|
||||
const char *uvname = "Orco";
|
||||
CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
|
||||
}
|
||||
|
||||
MEM_freeN(allvert);
|
||||
MEM_freeN(alledge);
|
||||
MEM_freeN(allloop);
|
||||
MEM_freeN(allpoly);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
Mesh *BKE_new_mesh_nomain_from_curve(Object *ob)
|
||||
{
|
||||
ListBase disp = {NULL, NULL};
|
||||
|
||||
if (ob->curve_cache) {
|
||||
disp = ob->curve_cache->disp;
|
||||
}
|
||||
|
||||
return BKE_new_mesh_nomain_from_curve_displist(ob, &disp);
|
||||
}
|
||||
|
||||
/* this may fail replacing ob->data, be sure to check ob->type */
|
||||
void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name)
|
||||
@@ -2226,6 +2278,22 @@ void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
|
||||
(me->mselect[me->totselect - 1].type == type));
|
||||
}
|
||||
|
||||
|
||||
void BKE_mesh_apply_vert_coords(Mesh *mesh, float (*vertCoords)[3])
|
||||
{
|
||||
MVert *vert;
|
||||
int i;
|
||||
|
||||
/* this will just return the pointer if it wasn't a referenced layer */
|
||||
vert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
|
||||
mesh->mvert = vert;
|
||||
|
||||
for (i = 0; i < mesh->totvert; ++i, ++vert)
|
||||
copy_v3_v3(vert->co, vertCoords[i]);
|
||||
|
||||
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute 'split' (aka loop, or per face corner's) normals.
|
||||
*
|
||||
@@ -2781,7 +2849,6 @@ Mesh *BKE_mesh_new_from_object(
|
||||
return tmpmesh;
|
||||
}
|
||||
|
||||
|
||||
/* **** Depsgraph evaluation **** */
|
||||
|
||||
void BKE_mesh_eval_geometry(Depsgraph *depsgraph,
|
||||
|
||||
@@ -833,7 +833,7 @@ typedef struct MeshDeformBind {
|
||||
int size, size3;
|
||||
|
||||
/* meshes */
|
||||
DerivedMesh *cagedm;
|
||||
Mesh *cagemesh;
|
||||
float (*cagecos)[3];
|
||||
float (*vertexcos)[3];
|
||||
int totvert, totcagevert;
|
||||
@@ -863,7 +863,7 @@ typedef struct MeshDeformBind {
|
||||
const MLoop *mloop;
|
||||
const MLoopTri *looptri;
|
||||
const float (*poly_nors)[3];
|
||||
} cagedm_cache;
|
||||
} cagemesh_cache;
|
||||
} MeshDeformBind;
|
||||
|
||||
typedef struct MeshDeformIsect {
|
||||
@@ -888,9 +888,9 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
|
||||
{
|
||||
struct MeshRayCallbackData *data = userdata;
|
||||
MeshDeformBind *mdb = data->mdb;
|
||||
const MLoop *mloop = mdb->cagedm_cache.mloop;
|
||||
const MLoopTri *looptri = mdb->cagedm_cache.looptri, *lt;
|
||||
const float (*poly_nors)[3] = mdb->cagedm_cache.poly_nors;
|
||||
const MLoop *mloop = mdb->cagemesh_cache.mloop;
|
||||
const MLoopTri *looptri = mdb->cagemesh_cache.looptri, *lt;
|
||||
const float (*poly_nors)[3] = mdb->cagemesh_cache.poly_nors;
|
||||
MeshDeformIsect *isec = data->isec;
|
||||
float no[3], co[3], dist;
|
||||
float *face[3];
|
||||
@@ -954,9 +954,9 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const
|
||||
if (BLI_bvhtree_ray_cast_ex(mdb->bvhtree, isect_mdef.start, vec_normal,
|
||||
0.0, &hit, harmonic_ray_callback, &data, BVH_RAYCAST_WATERTIGHT) != -1)
|
||||
{
|
||||
const MLoop *mloop = mdb->cagedm_cache.mloop;
|
||||
const MLoopTri *lt = &mdb->cagedm_cache.looptri[hit.index];
|
||||
const MPoly *mp = &mdb->cagedm_cache.mpoly[lt->poly];
|
||||
const MLoop *mloop = mdb->cagemesh_cache.mloop;
|
||||
const MLoopTri *lt = &mdb->cagemesh_cache.looptri[hit.index];
|
||||
const MPoly *mp = &mdb->cagemesh_cache.mpoly[lt->poly];
|
||||
const float (*cagecos)[3] = mdb->cagecos;
|
||||
const float len = isect_mdef.lambda;
|
||||
MDefBoundIsect *isect;
|
||||
@@ -1131,8 +1131,8 @@ static void meshdeform_bind_floodfill(MeshDeformBind *mdb)
|
||||
|
||||
static float meshdeform_boundary_phi(const MeshDeformBind *mdb, const MDefBoundIsect *isect, int cagevert)
|
||||
{
|
||||
const MLoop *mloop = mdb->cagedm_cache.mloop;
|
||||
const MPoly *mp = &mdb->cagedm_cache.mpoly[isect->poly_index];
|
||||
const MLoop *mloop = mdb->cagemesh_cache.mloop;
|
||||
const MPoly *mp = &mdb->cagemesh_cache.mpoly[isect->poly_index];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mp->totloop; i++) {
|
||||
@@ -1447,7 +1447,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
|
||||
mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi");
|
||||
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
|
||||
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
|
||||
mdb->bvhtree = bvhtree_from_mesh_get(&mdb->bvhdata, mdb->cagedm, BVHTREE_FROM_LOOPTRI, 4);
|
||||
mdb->bvhtree = BKE_bvhtree_from_mesh_looptri(&mdb->bvhdata, mdb->cagemesh, FLT_EPSILON * 100, 4, 6);
|
||||
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
|
||||
|
||||
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
|
||||
@@ -1460,11 +1460,11 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
|
||||
|
||||
/* initialize data from 'cagedm' for reuse */
|
||||
{
|
||||
DerivedMesh *dm = mdb->cagedm;
|
||||
mdb->cagedm_cache.mpoly = dm->getPolyArray(dm);
|
||||
mdb->cagedm_cache.mloop = dm->getLoopArray(dm);
|
||||
mdb->cagedm_cache.looptri = dm->getLoopTriArray(dm);
|
||||
mdb->cagedm_cache.poly_nors = dm->getPolyDataArray(dm, CD_NORMAL); /* can be NULL */
|
||||
Mesh *me = mdb->cagemesh;
|
||||
mdb->cagemesh_cache.mpoly = me->mpoly;
|
||||
mdb->cagemesh_cache.mloop = me->mloop;
|
||||
mdb->cagemesh_cache.looptri = BKE_mesh_get_looptri_array(me);
|
||||
mdb->cagemesh_cache.poly_nors = CustomData_get_layer(&me->pdata, CD_NORMAL); /* can be NULL */
|
||||
}
|
||||
|
||||
/* make bounding box equal size in all directions, add padding, and compute
|
||||
@@ -1576,7 +1576,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
|
||||
}
|
||||
|
||||
void ED_mesh_deform_bind_callback(
|
||||
Scene *scene, MeshDeformModifierData *mmd, DerivedMesh *cagedm,
|
||||
Scene *scene, MeshDeformModifierData *mmd, Mesh *cagemesh,
|
||||
float *vertexcos, int totvert, float cagemat[4][4])
|
||||
{
|
||||
MeshDeformBind mdb;
|
||||
@@ -1592,12 +1592,12 @@ void ED_mesh_deform_bind_callback(
|
||||
mdb.vertexcos = MEM_callocN(sizeof(float) * 3 * totvert, "MeshDeformCos");
|
||||
mdb.totvert = totvert;
|
||||
|
||||
mdb.cagedm = cagedm;
|
||||
mdb.totcagevert = mdb.cagedm->getNumVerts(mdb.cagedm);
|
||||
mdb.cagemesh = cagemesh;
|
||||
mdb.totcagevert = mdb.cagemesh->totvert;
|
||||
mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.totcagevert, "MeshDeformBindCos");
|
||||
copy_m4_m4(mdb.cagemat, cagemat);
|
||||
|
||||
mvert = mdb.cagedm->getVertArray(mdb.cagedm);
|
||||
mvert = mdb.cagemesh->mvert;
|
||||
for (a = 0; a < mdb.totcagevert; a++)
|
||||
copy_v3_v3(mdb.cagecos[a], mvert[a].co);
|
||||
for (a = 0; a < mdb.totvert; a++)
|
||||
|
||||
@@ -43,7 +43,7 @@ struct Depsgraph;
|
||||
struct IDProperty;
|
||||
struct ListBase;
|
||||
struct MeshDeformModifierData;
|
||||
struct DerivedMesh;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
struct ReportList;
|
||||
struct Scene;
|
||||
@@ -230,7 +230,7 @@ struct Object *ED_pose_object_from_context(struct bContext *C);
|
||||
void ED_mesh_deform_bind_callback(
|
||||
struct Scene *scene,
|
||||
struct MeshDeformModifierData *mmd,
|
||||
struct DerivedMesh *cagedm,
|
||||
struct Mesh *cagemesh,
|
||||
float *vertexcos, int totvert, float cagemat[4][4]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
* (ONLY ADD NEW ITEMS AT THE END)
|
||||
*/
|
||||
|
||||
struct Mesh;
|
||||
|
||||
typedef enum ModifierType {
|
||||
eModifierType_None = 0,
|
||||
eModifierType_Subsurf = 1,
|
||||
@@ -718,7 +720,7 @@ typedef struct MeshDeformModifierData {
|
||||
float *bindcos; /* deprecated storage of cage coords */
|
||||
|
||||
/* runtime */
|
||||
void (*bindfunc)(struct Scene *scene, struct MeshDeformModifierData *mmd, struct DerivedMesh *cagedm,
|
||||
void (*bindfunc)(struct Scene *scene, struct MeshDeformModifierData *mmd, struct Mesh *cagemesh,
|
||||
float *vertexcos, int totvert, float cagemat[4][4]);
|
||||
} MeshDeformModifierData;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@@ -40,9 +41,10 @@
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_editmesh.h"
|
||||
@@ -273,17 +275,18 @@ static void meshdeform_vert_task(
|
||||
}
|
||||
|
||||
static void meshdeformModifier_do(
|
||||
ModifierData *md, struct Depsgraph *depsgraph, Object *ob, DerivedMesh *dm,
|
||||
ModifierData *md, Object *ob, Mesh *mesh,
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
|
||||
DerivedMesh *tmpdm, *cagedm;
|
||||
Mesh *cagemesh;
|
||||
MDeformVert *dvert = NULL;
|
||||
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
|
||||
float co[3], (*dco)[3], (*bindcagecos)[3];
|
||||
int a, totvert, totcagevert, defgrp_index;
|
||||
float (*cagecos)[3];
|
||||
MeshdeformUserdata data;
|
||||
bool free_cagemesh = false;
|
||||
|
||||
if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc))
|
||||
return;
|
||||
@@ -299,23 +302,24 @@ static void meshdeformModifier_do(
|
||||
* We'll support this case once granular dependency graph is landed.
|
||||
*/
|
||||
if (mmd->object->mode & OB_MODE_EDIT) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(mmd->object);
|
||||
tmpdm = editbmesh_get_derived_cage_and_final(depsgraph, md->scene, mmd->object, em, 0, &cagedm);
|
||||
if (tmpdm)
|
||||
tmpdm->release(tmpdm);
|
||||
/* TODO(Sybren): do we need to check the modifier mode in this case? */
|
||||
/* TODO(Sybren): should we get from BMEditMesh *em = BKE_editmesh_from_object(mmd->object) instead? */
|
||||
cagemesh = get_mesh_eval_for_modifier(ob, md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0);
|
||||
}
|
||||
else {
|
||||
cagemesh = get_mesh_eval_for_modifier(ob, md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0);
|
||||
}
|
||||
else
|
||||
cagedm = mmd->object->derivedFinal;
|
||||
|
||||
/* if we don't have one computed, use derivedmesh from data
|
||||
* without any modifiers */
|
||||
if (!cagedm) {
|
||||
cagedm = get_dm(mmd->object, NULL, NULL, NULL, false, false);
|
||||
if (cagedm)
|
||||
cagedm->needsFree = 1;
|
||||
if (!cagemesh) {
|
||||
cagemesh = get_mesh(mmd->object, NULL, NULL, NULL, false, false);
|
||||
if (cagemesh) {
|
||||
free_cagemesh = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cagedm) {
|
||||
if (!cagemesh) {
|
||||
modifier_setError(md, "Cannot get mesh from cage object");
|
||||
return;
|
||||
}
|
||||
@@ -334,35 +338,33 @@ static void meshdeformModifier_do(
|
||||
/* progress bar redraw can make this recursive .. */
|
||||
if (!recursive) {
|
||||
recursive = 1;
|
||||
mmd->bindfunc(md->scene, mmd, cagedm, (float *)vertexCos, numVerts, cagemat);
|
||||
mmd->bindfunc(md->scene, mmd, cagemesh, (float *)vertexCos, numVerts, cagemat);
|
||||
recursive = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* verify we have compatible weights */
|
||||
totvert = numVerts;
|
||||
totcagevert = cagedm->getNumVerts(cagedm);
|
||||
totcagevert = cagemesh->totvert;
|
||||
|
||||
if (mmd->totvert != totvert) {
|
||||
modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert);
|
||||
cagedm->release(cagedm);
|
||||
if (free_cagemesh) BKE_id_free(NULL, cagemesh);
|
||||
return;
|
||||
}
|
||||
else if (mmd->totcagevert != totcagevert) {
|
||||
modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert);
|
||||
cagedm->release(cagedm);
|
||||
if (free_cagemesh) BKE_id_free(NULL, cagemesh);
|
||||
return;
|
||||
}
|
||||
else if (mmd->bindcagecos == NULL) {
|
||||
modifier_setError(md, "Bind data missing");
|
||||
cagedm->release(cagedm);
|
||||
if (free_cagemesh) BKE_id_free(NULL, cagemesh);
|
||||
return;
|
||||
}
|
||||
|
||||
cagecos = MEM_malloc_arrayN(totcagevert, sizeof(*cagecos), "meshdeformModifier vertCos");
|
||||
|
||||
/* setup deformation data */
|
||||
cagedm->getVertCos(cagedm, cagecos);
|
||||
cagecos = BKE_mesh_vertexCos_get(cagemesh, NULL);
|
||||
bindcagecos = (float(*)[3])mmd->bindcagecos;
|
||||
|
||||
/* We allocate 1 element extra to make it possible to
|
||||
@@ -383,7 +385,7 @@ static void meshdeformModifier_do(
|
||||
copy_v3_v3(dco[a], co);
|
||||
}
|
||||
|
||||
modifier_get_vgroup(ob, dm, mmd->defgrp_name, &dvert, &defgrp_index);
|
||||
modifier_get_vgroup_mesh(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index);
|
||||
|
||||
/* Initialize data to be pass to the for body function. */
|
||||
data.mmd = mmd;
|
||||
@@ -406,36 +408,38 @@ static void meshdeformModifier_do(
|
||||
/* release cage derivedmesh */
|
||||
MEM_freeN(dco);
|
||||
MEM_freeN(cagecos);
|
||||
cagedm->release(cagedm);
|
||||
if (free_cagemesh) BKE_id_free(NULL, cagemesh);
|
||||
}
|
||||
|
||||
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx,
|
||||
DerivedMesh *derivedData,
|
||||
Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = get_dm(ctx->object, NULL, derivedData, NULL, false, false);
|
||||
Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false);
|
||||
|
||||
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
|
||||
|
||||
meshdeformModifier_do(md, ctx->depsgraph, ctx->object, dm, vertexCos, numVerts);
|
||||
meshdeformModifier_do(md, ctx->object, mesh, vertexCos, numVerts);
|
||||
|
||||
if (dm && dm != derivedData)
|
||||
dm->release(dm);
|
||||
if (mesh_src && mesh_src != mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
}
|
||||
}
|
||||
|
||||
static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx,
|
||||
struct BMEditMesh *UNUSED(editData),
|
||||
DerivedMesh *derivedData,
|
||||
Mesh *mesh,
|
||||
float (*vertexCos)[3],
|
||||
int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = get_dm(ctx->object, NULL, derivedData, NULL, false, false);
|
||||
Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false);
|
||||
|
||||
meshdeformModifier_do(md, ctx->depsgraph, ctx->object, dm, vertexCos, numVerts);
|
||||
meshdeformModifier_do(md, ctx->object, mesh, vertexCos, numVerts);
|
||||
|
||||
if (dm && dm != derivedData)
|
||||
dm->release(dm);
|
||||
if (mesh_src && mesh_src != mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
}
|
||||
}
|
||||
|
||||
#define MESHDEFORM_MIN_INFLUENCE 0.00001f
|
||||
@@ -512,16 +516,16 @@ ModifierTypeInfo modifierType_MeshDeform = {
|
||||
|
||||
/* 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,
|
||||
|
||||
@@ -46,8 +46,10 @@
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "BKE_modifier.h"
|
||||
@@ -57,6 +59,8 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
void modifier_init_texture(const Scene *scene, Tex *tex)
|
||||
{
|
||||
if (!tex)
|
||||
@@ -281,6 +285,47 @@ DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm,
|
||||
return dm;
|
||||
}
|
||||
|
||||
/* returns a mesh if mesh == NULL, for deforming modifiers that need it */
|
||||
Mesh *get_mesh(Object *ob, struct BMEditMesh *em, Mesh *mesh,
|
||||
float (*vertexCos)[3], bool use_normals, bool use_orco)
|
||||
{
|
||||
if (mesh) {
|
||||
/* pass */
|
||||
}
|
||||
else if (ob->type == OB_MESH) {
|
||||
struct BMeshToMeshParams bmtmp = {0};
|
||||
if (em) mesh = BKE_bmesh_to_mesh_nomain(em->bm, &bmtmp);
|
||||
else {
|
||||
BKE_id_copy_ex(NULL, ob->data, (ID **)&mesh,
|
||||
LIB_ID_CREATE_NO_MAIN |
|
||||
LIB_ID_CREATE_NO_USER_REFCOUNT |
|
||||
LIB_ID_CREATE_NO_DEG_TAG,
|
||||
false);
|
||||
}
|
||||
|
||||
if (vertexCos) {
|
||||
BKE_mesh_apply_vert_coords(mesh, vertexCos);
|
||||
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
||||
}
|
||||
|
||||
if (use_orco) {
|
||||
CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert);
|
||||
}
|
||||
}
|
||||
else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
|
||||
/* TODO(sybren): get evaluated mesh from depsgraph once that's properly generated for curves. */
|
||||
mesh = BKE_new_mesh_nomain_from_curve(ob);
|
||||
}
|
||||
|
||||
if (use_normals) {
|
||||
if (LIKELY(mesh)) {
|
||||
BKE_mesh_ensure_normals(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
/* Get derived mesh for other object, which is used as an operand for the modifier,
|
||||
* i.e. second operand for boolean modifier.
|
||||
*/
|
||||
|
||||
@@ -54,6 +54,8 @@ struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct De
|
||||
float (*vertexCos)[3], bool use_normals);
|
||||
struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm,
|
||||
float (*vertexCos)[3], bool use_normals, bool use_orco);
|
||||
struct Mesh *get_mesh(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh,
|
||||
float (*vertexCos)[3], bool use_normals, bool use_orco);
|
||||
struct DerivedMesh *get_dm_for_modifier(struct Object *ob, ModifierApplyFlag flag);
|
||||
struct Mesh *get_mesh_eval_for_modifier(struct Object *ob, ModifierApplyFlag flag);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user