diff options
-rw-r--r-- | source/blender/blenkernel/BKE_shrinkwrap.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_remap.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/shrinkwrap.c | 14 | ||||
-rw-r--r-- | source/blender/editors/armature/meshlaplacian.c | 83 |
5 files changed, 28 insertions, 91 deletions
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index d2ab4f3164c..31b4b5cecc5 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -90,7 +90,7 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object * (where each tree was built on its own coords space) */ bool BKE_shrinkwrap_project_normal( - char options, const float vert[3], const float dir[3], + char options, const float vert[3], const float dir[3], const float ray_radius, const struct SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b192cb7cef2..c2c72e290eb 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3485,15 +3485,15 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph), bConstrai break; } - bvhtree_from_mesh_looptri(&treeData, target, scon->dist, 4, 6); + bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 4); if (treeData.tree == NULL) { fail = true; break; } - - if (BKE_shrinkwrap_project_normal(0, co, no, &transform, treeData.tree, &hit, - treeData.raycast_callback, &treeData) == false) + treeData.sphere_radius = scon->dist; + if (BKE_shrinkwrap_project_normal(0, co, no, treeData.sphere_radius, &transform, treeData.tree, + &hit, treeData.raycast_callback, &treeData) == false) { fail = true; break; diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 8dc812463db..84994e80784 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -543,15 +543,13 @@ void BKE_mesh_remap_calc_verts_from_dm( float *weights = MEM_mallocN(sizeof(*weights) * tmp_buff_size, __func__); dm_src->getVertCos(dm_src, vcos_src); - if (mode & MREMAP_USE_NORPROJ) { - bvhtree_from_mesh_looptri( - &treedata, dm_src, ray_radius, 2, 6); - } - else { - bvhtree_from_mesh_get(&treedata, dm_src, BVHTREE_FROM_LOOPTRI, 2); - } + + bvhtree_from_mesh_get(&treedata, dm_src, BVHTREE_FROM_LOOPTRI, 2); if (mode == MREMAP_MODE_VERT_POLYINTERP_VNORPROJ) { + if (mode & MREMAP_USE_NORPROJ) { + treedata.sphere_radius = ray_radius; + } for (i = 0; i < numverts_dst; i++) { copy_v3_v3(tmp_co, verts_dst[i].co); normal_short_to_float_v3(tmp_no, verts_dst[i].no); diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index ced836181a5..bf22b106cf8 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -191,8 +191,8 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) * MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored) */ bool BKE_shrinkwrap_project_normal( - char options, const float vert[3], - const float dir[3], const SpaceTransform *transf, + char options, const float vert[3], const float dir[3], + const float ray_radius, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata) { @@ -229,7 +229,7 @@ bool BKE_shrinkwrap_project_normal( hit_tmp.index = -1; - BLI_bvhtree_ray_cast(tree, co, no, 0.0f, &hit_tmp, callback, userdata); + BLI_bvhtree_ray_cast(tree, co, no, ray_radius, &hit_tmp, callback, userdata); if (hit_tmp.index != -1) { /* invert the normal first so face culling works on rotated objects */ @@ -322,13 +322,13 @@ static void shrinkwrap_calc_normal_projection_cb_ex( if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) { if (aux_tree) { BKE_shrinkwrap_project_normal( - 0, tmp_co, tmp_no, + 0, tmp_co, tmp_no, 0.0, local2aux, aux_tree, hit, aux_callback, auxData); } BKE_shrinkwrap_project_normal( - calc->smd->shrinkOpts, tmp_co, tmp_no, + calc->smd->shrinkOpts, tmp_co, tmp_no, 0.0, &calc->local2target, targ_tree, hit, targ_callback, treeData); } @@ -340,13 +340,13 @@ static void shrinkwrap_calc_normal_projection_cb_ex( if (aux_tree) { BKE_shrinkwrap_project_normal( - 0, tmp_co, inv_no, + 0, tmp_co, inv_no, 0.0, local2aux, aux_tree, hit, aux_callback, auxData); } BKE_shrinkwrap_project_normal( - calc->smd->shrinkOpts, tmp_co, inv_no, + calc->smd->shrinkOpts, tmp_co, inv_no, 0.0, &calc->local2target, targ_tree, hit, targ_callback, treeData); } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index ea7a35a4b0e..eaae7dacbba 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -879,69 +879,6 @@ typedef struct MeshDeformIsect { /* ray intersection */ -/* 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]) -{ - float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; - float det, inv_det, u, v, dir[3], isectdir[3]; - - sub_v3_v3v3(dir, end, orig); - - /* find vectors for two edges sharing vert0 */ - sub_v3_v3v3(edge1, vert1, vert0); - sub_v3_v3v3(edge2, vert2, vert0); - - /* begin calculating determinant - also used to calculate U parameter */ - cross_v3_v3v3(pvec, dir, edge2); - - /* if determinant is near zero, ray lies in plane of triangle */ - det = dot_v3v3(edge1, pvec); - - if (UNLIKELY(det == 0.0f)) { - return 0; - } - - inv_det = 1.0f / det; - - /* calculate distance from vert0 to ray origin */ - sub_v3_v3v3(tvec, orig, vert0); - - /* calculate U parameter and test bounds */ - u = dot_v3v3(tvec, pvec) * inv_det; - if (u < -EPSILON || u > 1.0f + EPSILON) - return 0; - - /* prepare to test V parameter */ - cross_v3_v3v3(qvec, tvec, edge1); - - /* calculate V parameter and test bounds */ - v = dot_v3v3(dir, qvec) * inv_det; - 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]; - - r_uvw[0] = 1.0f - u - v; - r_uvw[1] = u; - r_uvw[2] = v; - - /* check if it is within the length of the line segment */ - sub_v3_v3v3(isectdir, r_isectco, orig); - - if (dot_v3v3(dir, isectdir) < -EPSILON) - return 0; - - if (dot_v3v3(dir, dir) + EPSILON < dot_v3v3(isectdir, isectdir)) - return 0; - - return 1; -} - struct MeshRayCallbackData { MeshDeformBind *mdb; MeshDeformIsect *isec; @@ -955,7 +892,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r const MLoopTri *looptri = mdb->cagedm_cache.looptri, *lt; const float (*poly_nors)[3] = mdb->cagedm_cache.poly_nors; MeshDeformIsect *isec = data->isec; - float no[3], co[3], end[3], uvw[3], dist; + float no[3], co[3], dist; float *face[3]; lt = &looptri[index]; @@ -963,11 +900,12 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r face[0] = mdb->cagecos[mloop[lt->tri[0]].v]; face[1] = mdb->cagecos[mloop[lt->tri[1]].v]; face[2] = mdb->cagecos[mloop[lt->tri[2]].v]; - - add_v3_v3v3(end, isec->start, isec->vec); - - if (!meshdeform_tri_intersect(ray->origin, end, UNPACK3(face), co, uvw)) + + if (!isect_ray_tri_watertight_v3( + ray->origin, ray->isect_precalc, UNPACK3(face), &dist, NULL)) + { return; + } if (poly_nors) { copy_v3_v3(no, poly_nors[lt->poly]); @@ -976,7 +914,8 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r normal_tri_v3(no, UNPACK3(face)); } - dist = len_v3v3(ray->origin, co) / isec->vec_length; + madd_v3_v3v3fl(co, ray->origin, ray->direction, dist); + dist /= isec->vec_length; if (dist < hit->dist) { hit->index = index; hit->dist = dist; @@ -1012,8 +951,8 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const hit.index = -1; hit.dist = BVH_RAYCAST_DIST_MAX; - if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, vec_normal, - 0.0, &hit, harmonic_ray_callback, &data) != -1) + 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]; @@ -1508,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_looptri(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6); + mdb->bvhtree = bvhtree_from_mesh_get(&mdb->bvhdata, mdb->cagedm, BVHTREE_FROM_LOOPTRI, 4); mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside"); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) |