Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/armature/meshlaplacian.c')
-rw-r--r--source/blender/editors/armature/meshlaplacian.c143
1 files changed, 70 insertions, 73 deletions
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index e7efd7936c0..346ed0002bd 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1113,9 +1113,6 @@ typedef struct MeshDeformBind {
/* direct solver */
int *varidx;
-
- BVHTree *bvhtree;
- BVHTreeFromMesh bvhdata;
} MeshDeformBind;
typedef struct MeshDeformIsect {
@@ -1133,9 +1130,8 @@ typedef struct MeshDeformIsect {
/* our own triangle intersection, so we can fully control the epsilons and
* prevent corner case from going wrong*/
-static int meshdeform_tri_intersect(const float orig[3], const float end[3], const float vert0[3],
- const float vert1[3], const float vert2[3],
- float r_isectco[3], float r_uvw[3])
+static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3],
+ float vert1[3], float vert2[3], float *isectco, float *uvw)
{
float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
float det, inv_det, u, v, dir[3], isectdir[3];
@@ -1152,10 +1148,8 @@ static int meshdeform_tri_intersect(const float orig[3], const float end[3], con
/* if determinant is near zero, ray lies in plane of triangle */
det = dot_v3v3(edge1, pvec);
- if (UNLIKELY(det == 0.0f)) {
+ if (det == 0.0f)
return 0;
- }
-
inv_det = 1.0f / det;
/* calculate distance from vert0 to ray origin */
@@ -1174,16 +1168,16 @@ static int meshdeform_tri_intersect(const float orig[3], const float end[3], con
if (v < -EPSILON || u + v > 1.0f + EPSILON)
return 0;
- r_isectco[0] = (1.0f - u - v) * vert0[0] + u * vert1[0] + v * vert2[0];
- r_isectco[1] = (1.0f - u - v) * vert0[1] + u * vert1[1] + v * vert2[1];
- r_isectco[2] = (1.0f - u - v) * vert0[2] + u * vert1[2] + v * vert2[2];
+ isectco[0] = (1.0f - u - v) * vert0[0] + u * vert1[0] + v * vert2[0];
+ isectco[1] = (1.0f - u - v) * vert0[1] + u * vert1[1] + v * vert2[1];
+ isectco[2] = (1.0f - u - v) * vert0[2] + u * vert1[2] + v * vert2[2];
- r_uvw[0] = 1.0f - u - v;
- r_uvw[1] = u;
- r_uvw[2] = v;
+ uvw[0] = 1.0f - u - v;
+ uvw[1] = u;
+ uvw[2] = v;
/* check if it is within the length of the line segment */
- sub_v3_v3v3(isectdir, r_isectco, orig);
+ sub_v3_v3v3(isectdir, isectco, orig);
if (dot_v3v3(dir, isectdir) < -EPSILON)
return 0;
@@ -1194,79 +1188,83 @@ static int meshdeform_tri_intersect(const float orig[3], const float end[3], con
return 1;
}
-static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
- {
- void **data = userdata;
- MeshDeformBind *mdb = data[1];
- MFace *mface = data[0], *mf;
- MeshDeformIsect *isec = data[2];
- float no[3], co[3], end[3], uvw[3], dist, face[4][3];
-
- mf = mface + index;
-
- copy_v3_v3(face[0], mdb->cagecos[mf->v1]);
- copy_v3_v3(face[1], mdb->cagecos[mf->v2]);
- copy_v3_v3(face[2], mdb->cagecos[mf->v3]);
- if (mf->v4)
- copy_v3_v3(face[3], mdb->cagecos[mf->v4]);
-
- add_v3_v3v3(end, isec->start, isec->vec);
-
- if (!meshdeform_tri_intersect(ray->origin, end, face[0], face[1], face[2], co, uvw))
- if (!mf->v4 || !meshdeform_tri_intersect(ray->origin, end, face[0], face[2], face[3], co, uvw))
- return;
-
- if (!mf->v4)
- normal_tri_v3(no, face[0], face[1], face[2]);
- else
- normal_quad_v3(no, face[0], face[1], face[2], face[3]);
-
- dist = len_v3v3(ray->origin, co)/len_v3(isec->vec);
- if (dist < hit->dist) {
- hit->index = index;
- hit->dist = dist;
- copy_v3_v3(hit->co, co);
-
- isec->isect = dot_v3v3(no, ray->direction) <= 0.0;
- isec->labda = dist;
- isec->face = mf;
+static int meshdeform_intersect(MeshDeformBind *mdb, MeshDeformIsect *isec)
+{
+ MFace *mface;
+ float face[4][3], co[3], uvw[3], len, nor[3], end[3];
+ int f, hit, is = 0, totface;
+
+ isec->labda = 1e10;
+
+ mface = mdb->cagedm->getTessFaceArray(mdb->cagedm);
+ totface = mdb->cagedm->getNumTessFaces(mdb->cagedm);
+
+ add_v3_v3v3(end, isec->start, isec->vec);
+
+ for (f = 0; f < totface; f++, mface++) {
+ copy_v3_v3(face[0], mdb->cagecos[mface->v1]);
+ copy_v3_v3(face[1], mdb->cagecos[mface->v2]);
+ copy_v3_v3(face[2], mdb->cagecos[mface->v3]);
+
+ if (mface->v4) {
+ copy_v3_v3(face[3], mdb->cagecos[mface->v4]);
+ hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw);
+
+ if (hit) {
+ normal_tri_v3(nor, face[0], face[1], face[2]);
+ }
+ else {
+ hit = meshdeform_tri_intersect(isec->start, end, face[0], face[2], face[3], co, uvw);
+ normal_tri_v3(nor, face[0], face[2], face[3]);
+ }
+ }
+ else {
+ hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw);
+ normal_tri_v3(nor, face[0], face[1], face[2]);
+ }
+
+ if (hit) {
+ len = len_v3v3(isec->start, co) / len_v3v3(isec->start, end);
+ if (len < isec->labda) {
+ isec->labda = len;
+ isec->face = mface;
+ isec->isect = (dot_v3v3(isec->vec, nor) <= 0.0f);
+ is = 1;
+ }
+ }
}
+
+ return is;
}
static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float *co1, float *co2)
{
MDefBoundIsect *isect;
- BVHTreeRayHit hit;
- MeshDeformIsect isect_mdef;
+ MeshDeformIsect isec;
float (*cagecos)[3];
- void *data[3] = {mdb->cagedm->getTessFaceArray(mdb->cagedm), mdb, &isect_mdef};
- MFace *mface1 = data[0], *mface;
+ MFace *mface;
float vert[4][3], len, end[3];
static float epsilon[3] = {0, 0, 0}; //1e-4, 1e-4, 1e-4};
/* setup isec */
- memset(&isect_mdef, 0, sizeof(isect_mdef));
- isect_mdef.labda = 1e10f;
+ memset(&isec, 0, sizeof(isec));
+ isec.labda = 1e10f;
- add_v3_v3v3(isect_mdef.start, co1, epsilon);
+ add_v3_v3v3(isec.start, co1, epsilon);
add_v3_v3v3(end, co2, epsilon);
- sub_v3_v3v3(isect_mdef.vec, end, isect_mdef.start);
+ sub_v3_v3v3(isec.vec, end, isec.start);
- hit.index = -1;
- hit.dist = FLT_MAX;
- if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec,
- 0.0, &hit, harmonic_ray_callback, data) != -1)
- {
- len= isect_mdef.labda;
- isect_mdef.face = mface = mface1 + hit.index;
+ if (meshdeform_intersect(mdb, &isec)) {
+ len = isec.labda;
+ mface = (MFace *)isec.face;
/* create MDefBoundIsect */
isect = BLI_memarena_alloc(mdb->memarena, sizeof(*isect));
/* compute intersection coordinate */
- isect->co[0] = co1[0] + isect_mdef.vec[0] * len;
- isect->co[1] = co1[1] + isect_mdef.vec[1] * len;
- isect->co[2] = co1[2] + isect_mdef.vec[2] * len;
+ isect->co[0] = co1[0] + isec.vec[0] * len;
+ isect->co[1] = co1[1] + isec.vec[1] * len;
+ isect->co[2] = co1[2] + isec.vec[2] * len;
isect->len = len_v3v3(co1, isect->co);
if (isect->len < MESHDEFORM_LEN_THRESHOLD)
@@ -1278,7 +1276,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
isect->v[3] = mface->v4;
isect->nvert = (mface->v4) ? 4 : 3;
- isect->facing = isect_mdef.isect;
+ isect->facing = isec.isect;
/* compute mean value coordinates for interpolation */
cagecos = mdb->cagecos;
@@ -1768,7 +1766,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_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6);
+
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
@@ -1884,7 +1882,6 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
MEM_freeN(mdb->boundisect);
MEM_freeN(mdb->semibound);
BLI_memarena_free(mdb->memarena);
- free_bvhtree_from_mesh(&mdb->bvhdata);
}
#if 0