forked from bartvdbraak/blender
Use looptri for MeshDeform modifier
This commit is contained in:
parent
b604d5ade0
commit
5983280b4f
@ -631,7 +631,6 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
|
|||||||
MLoopTri *mlooptri;
|
MLoopTri *mlooptri;
|
||||||
MPoly *mp;
|
MPoly *mp;
|
||||||
MLoop *ml;
|
MLoop *ml;
|
||||||
MFace *mf;
|
|
||||||
float solution, weight;
|
float solution, weight;
|
||||||
int *vertsflipped = NULL, *mask = NULL;
|
int *vertsflipped = NULL, *mask = NULL;
|
||||||
int a, tottri, j, bbone, firstsegment, lastsegment;
|
int a, tottri, j, bbone, firstsegment, lastsegment;
|
||||||
@ -644,15 +643,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
|
|||||||
*err_str = NULL;
|
*err_str = NULL;
|
||||||
|
|
||||||
/* bone heat needs triangulated faces */
|
/* bone heat needs triangulated faces */
|
||||||
BKE_mesh_tessface_ensure(me);
|
tottri = poly_to_tri_count(me->totpoly, me->totloop);
|
||||||
|
|
||||||
for (tottri = 0, a = 0, mf = me->mface; a < me->totface; mf++, a++) {
|
|
||||||
tottri++;
|
|
||||||
if (mf->v4) tottri++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tottri == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* count triangles and create mask */
|
/* count triangles and create mask */
|
||||||
if (ob->mode & OB_MODE_WEIGHT_PAINT &&
|
if (ob->mode & OB_MODE_WEIGHT_PAINT &&
|
||||||
@ -1062,8 +1053,8 @@ static int MESHDEFORM_OFFSET[7][3] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct MDefBoundIsect {
|
typedef struct MDefBoundIsect {
|
||||||
float co[3], uvw[4];
|
float co[3], uvw[3];
|
||||||
int nvert, v[4], facing;
|
int v[3], facing;
|
||||||
float len;
|
float len;
|
||||||
} MDefBoundIsect;
|
} MDefBoundIsect;
|
||||||
|
|
||||||
@ -1110,7 +1101,7 @@ typedef struct MeshDeformIsect {
|
|||||||
float vec[3];
|
float vec[3];
|
||||||
float lambda;
|
float lambda;
|
||||||
|
|
||||||
void *face;
|
const void *face;
|
||||||
int isect;
|
int isect;
|
||||||
float u, v;
|
float u, v;
|
||||||
|
|
||||||
@ -1182,7 +1173,10 @@ static int meshdeform_tri_intersect(const float orig[3], const float end[3], con
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct MeshRayCallbackData {
|
struct MeshRayCallbackData {
|
||||||
MFace *mface;
|
const MPoly *mpoly;
|
||||||
|
const MLoop *mloop;
|
||||||
|
const MLoopTri *looptri;
|
||||||
|
const float (*poly_nors)[3];
|
||||||
MeshDeformBind *mdb;
|
MeshDeformBind *mdb;
|
||||||
MeshDeformIsect *isec;
|
MeshDeformIsect *isec;
|
||||||
};
|
};
|
||||||
@ -1191,28 +1185,30 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
|
|||||||
{
|
{
|
||||||
struct MeshRayCallbackData *data = userdata;
|
struct MeshRayCallbackData *data = userdata;
|
||||||
MeshDeformBind *mdb = data->mdb;
|
MeshDeformBind *mdb = data->mdb;
|
||||||
MFace *mface = data->mface, *mf;
|
const MLoop *mloop = data->mloop;
|
||||||
|
const MLoopTri *looptri = data->looptri, *lt;
|
||||||
|
const float (*poly_nors)[3] = data->poly_nors;
|
||||||
MeshDeformIsect *isec = data->isec;
|
MeshDeformIsect *isec = data->isec;
|
||||||
float no[3], co[3], end[3], uvw[3], dist, face[4][3];
|
float no[3], co[3], end[3], uvw[3], dist;
|
||||||
|
float *face[3];
|
||||||
|
|
||||||
mf = mface + index;
|
lt = &looptri[index];
|
||||||
|
|
||||||
copy_v3_v3(face[0], mdb->cagecos[mf->v1]);
|
face[0] = mdb->cagecos[mloop[lt->tri[0]].v];
|
||||||
copy_v3_v3(face[1], mdb->cagecos[mf->v2]);
|
face[1] = mdb->cagecos[mloop[lt->tri[1]].v];
|
||||||
copy_v3_v3(face[2], mdb->cagecos[mf->v3]);
|
face[2] = mdb->cagecos[mloop[lt->tri[2]].v];
|
||||||
if (mf->v4)
|
|
||||||
copy_v3_v3(face[3], mdb->cagecos[mf->v4]);
|
|
||||||
|
|
||||||
add_v3_v3v3(end, isec->start, isec->vec);
|
add_v3_v3v3(end, isec->start, isec->vec);
|
||||||
|
|
||||||
if (!meshdeform_tri_intersect(ray->origin, end, face[0], face[1], face[2], co, uvw))
|
if (!meshdeform_tri_intersect(ray->origin, end, UNPACK3(face), co, uvw))
|
||||||
if (!mf->v4 || !meshdeform_tri_intersect(ray->origin, end, face[0], face[2], face[3], co, uvw))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!mf->v4)
|
if (poly_nors) {
|
||||||
normal_tri_v3(no, face[0], face[1], face[2]);
|
copy_v3_v3(no, poly_nors[lt->poly]);
|
||||||
else
|
}
|
||||||
normal_quad_v3(no, face[0], face[1], face[2], face[3]);
|
else {
|
||||||
|
normal_tri_v3(no, UNPACK3(face));
|
||||||
|
}
|
||||||
|
|
||||||
dist = len_v3v3(ray->origin, co) / len_v3(isec->vec);
|
dist = len_v3v3(ray->origin, co) / len_v3(isec->vec);
|
||||||
if (dist < hit->dist) {
|
if (dist < hit->dist) {
|
||||||
@ -1222,22 +1218,24 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
|
|||||||
|
|
||||||
isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f);
|
isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f);
|
||||||
isec->lambda = dist;
|
isec->lambda = dist;
|
||||||
isec->face = mf;
|
isec->face = lt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const float co1[3], const float co2[3])
|
static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const float co1[3], const float co2[3])
|
||||||
{
|
{
|
||||||
MDefBoundIsect *isect;
|
|
||||||
BVHTreeRayHit hit;
|
BVHTreeRayHit hit;
|
||||||
MeshDeformIsect isect_mdef;
|
MeshDeformIsect isect_mdef;
|
||||||
float (*cagecos)[3];
|
float (*cagecos)[3];
|
||||||
struct MeshRayCallbackData data = {
|
struct MeshRayCallbackData data = {
|
||||||
mdb->cagedm->getTessFaceArray(mdb->cagedm),
|
mdb->cagedm->getPolyArray(mdb->cagedm),
|
||||||
|
mdb->cagedm->getLoopArray(mdb->cagedm),
|
||||||
|
mdb->cagedm->getLoopTriArray(mdb->cagedm),
|
||||||
|
mdb->cagedm->getPolyDataArray(mdb->cagedm, CD_NORMAL), /* can be NULL */
|
||||||
mdb,
|
mdb,
|
||||||
&isect_mdef,
|
&isect_mdef,
|
||||||
};
|
};
|
||||||
MFace *mface1 = data.mface, *mface;
|
const MLoopTri *looptri = data.looptri, *lt;
|
||||||
float vert[4][3], len, end[3];
|
float vert[4][3], len, end[3];
|
||||||
// static float epsilon[3] = {1e-4, 1e-4, 1e-4};
|
// static float epsilon[3] = {1e-4, 1e-4, 1e-4};
|
||||||
|
|
||||||
@ -1263,8 +1261,9 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const
|
|||||||
if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec,
|
if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec,
|
||||||
0.0, &hit, harmonic_ray_callback, &data) != -1)
|
0.0, &hit, harmonic_ray_callback, &data) != -1)
|
||||||
{
|
{
|
||||||
|
MDefBoundIsect *isect;
|
||||||
len = isect_mdef.lambda;
|
len = isect_mdef.lambda;
|
||||||
isect_mdef.face = mface = mface1 + hit.index;
|
isect_mdef.face = lt = &looptri[hit.index];
|
||||||
|
|
||||||
/* create MDefBoundIsect */
|
/* create MDefBoundIsect */
|
||||||
isect = BLI_memarena_alloc(mdb->memarena, sizeof(*isect));
|
isect = BLI_memarena_alloc(mdb->memarena, sizeof(*isect));
|
||||||
@ -1278,21 +1277,18 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const
|
|||||||
if (isect->len < MESHDEFORM_LEN_THRESHOLD)
|
if (isect->len < MESHDEFORM_LEN_THRESHOLD)
|
||||||
isect->len = MESHDEFORM_LEN_THRESHOLD;
|
isect->len = MESHDEFORM_LEN_THRESHOLD;
|
||||||
|
|
||||||
isect->v[0] = mface->v1;
|
isect->v[0] = data.mloop[lt->tri[0]].v;
|
||||||
isect->v[1] = mface->v2;
|
isect->v[1] = data.mloop[lt->tri[1]].v;
|
||||||
isect->v[2] = mface->v3;
|
isect->v[2] = data.mloop[lt->tri[2]].v;
|
||||||
isect->v[3] = mface->v4;
|
|
||||||
isect->nvert = (mface->v4) ? 4 : 3;
|
|
||||||
|
|
||||||
isect->facing = isect_mdef.isect;
|
isect->facing = isect_mdef.isect;
|
||||||
|
|
||||||
/* compute mean value coordinates for interpolation */
|
/* compute mean value coordinates for interpolation */
|
||||||
cagecos = mdb->cagecos;
|
cagecos = mdb->cagecos;
|
||||||
copy_v3_v3(vert[0], cagecos[mface->v1]);
|
copy_v3_v3(vert[0], cagecos[isect->v[0]]);
|
||||||
copy_v3_v3(vert[1], cagecos[mface->v2]);
|
copy_v3_v3(vert[1], cagecos[isect->v[1]]);
|
||||||
copy_v3_v3(vert[2], cagecos[mface->v3]);
|
copy_v3_v3(vert[2], cagecos[isect->v[2]]);
|
||||||
if (mface->v4) copy_v3_v3(vert[3], cagecos[mface->v4]);
|
interp_weights_poly_v3(isect->uvw, vert, 3, isect->co);
|
||||||
interp_weights_poly_v3(isect->uvw, vert, isect->nvert, isect->co);
|
|
||||||
|
|
||||||
return isect;
|
return isect;
|
||||||
}
|
}
|
||||||
@ -1444,7 +1440,7 @@ static float meshdeform_boundary_phi(MeshDeformBind *UNUSED(mdb), MDefBoundIsect
|
|||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
for (a = 0; a < isect->nvert; a++)
|
for (a = 0; a < 3; a++)
|
||||||
if (isect->v[a] == cagevert)
|
if (isect->v[a] == cagevert)
|
||||||
return isect->uvw[a];
|
return isect->uvw[a];
|
||||||
|
|
||||||
@ -1774,7 +1770,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
|
|||||||
mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi");
|
mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi");
|
||||||
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
|
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
|
||||||
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
|
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
|
||||||
mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6);
|
mdb->bvhtree = bvhtree_from_mesh_looptri(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6);
|
||||||
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
|
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
|
||||||
|
|
||||||
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
|
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
|
||||||
|
Loading…
Reference in New Issue
Block a user