35
37
#include "DNA_meshdata_types.h"
39
#include "BLI_utildefines.h"
40
#include "BLI_linklist.h"
37
42
#include "BKE_DerivedMesh.h"
38
#include "BKE_utildefines.h"
43
#include "BKE_tessmesh.h"
40
45
#include "BLI_math.h"
41
46
#include "MEM_guardedalloc.h"
43
48
/* Math stuff for ray casting on mesh faces and for nearest surface */
45
static float ray_tri_intersection(const BVHTreeRay *ray, const float m_dist, const float *v0, const float *v1, const float *v2)
50
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, const float UNUSED(m_dist), const float v0[3], const float v1[3], const float v2[3])
49
if(isect_ray_tri_v3((float*)ray->origin, (float*)ray->direction, (float*)v0, (float*)v1, (float*)v2, &dist, NULL))
54
if (isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON))
55
static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float *v0, const float *v1, const float *v2)
60
static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float v0[3], const float v1[3], const float v2[3])
60
65
float plane_normal[3], hit_point[3];
62
normal_tri_v3( plane_normal,(float*)v0, (float*)v1, (float*)v2);
67
normal_tri_v3(plane_normal, v0, v1, v2);
64
VECADDFAC( p1, ray->origin, ray->direction, m_dist);
65
if(isect_sweeping_sphere_tri_v3((float*)ray->origin, p1, radius, (float*)v0, (float*)v1, (float*)v2, &idist, hit_point))
69
madd_v3_v3v3fl(p1, ray->origin, ray->direction, m_dist);
70
if (isect_sweeping_sphere_tri_v3(ray->origin, p1, radius, v0, v1, v2, &idist, hit_point)) {
67
71
return idist * m_dist;
197
else { /* Region 0 */
213
198
// Minimum at interior lv
215
if(fabs(Det) > FLT_EPSILON)
200
if (fabsf(Det) > FLT_EPSILON)
216
201
invDet = 1.0f / Det;
221
206
sqrDist = S * ( A00 * S + A01 * T + 2.0f * B0) +
222
T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
207
T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
227
211
float tmp0, tmp1, numer, denom;
229
if ( S < 0.0f ) // Region 2
213
if (S < 0.0f) { /* Region 2 */
235
217
numer = tmp1 - tmp0;
236
218
denom = A00 - 2.0f * A01 + A11;
237
if ( numer >= denom )
219
if ( numer >= denom ) {
241
222
sqrDist = A00 + 2.0f * B0 + C;
246
if(fabs(denom) > FLT_EPSILON)
226
if (fabsf(denom) > FLT_EPSILON)
247
227
S = numer / denom;
251
231
sqrDist = S * ( A00 * S + A01 * T + 2.0f * B0 ) +
252
T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
232
T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
238
if ( tmp1 <= 0.0f ) {
262
240
sqrDist = A11 + 2.0f * B1 + C;
265
else if ( B1 >= 0.0f )
243
else if (B1 >= 0.0f) {
273
if(fabs(A11) > FLT_EPSILON)
249
if (fabsf(A11) > FLT_EPSILON)
452
if(data->sphere_radius == 0.0f)
453
dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
414
if (data->sphere_radius == 0.0f)
415
dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
455
417
dist = sphereray_tri_intersection(ray, data->sphere_radius, hit->dist, t0, t1, t2);
457
if(dist >= 0 && dist < hit->dist)
419
if (dist >= 0 && dist < hit->dist) {
459
420
hit->index = index;
460
421
hit->dist = dist;
461
VECADDFAC(hit->co, ray->origin, ray->direction, dist);
422
madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
463
424
normal_tri_v3( hit->no,t0, t1, t2);
483
444
t0 = vert[ edge->v1 ].co;
484
445
t1 = vert[ edge->v2 ].co;
486
// NOTE: casts to "float*" here are due to co being "const float*"
487
closest_to_line_segment_v3(nearest_tmp, (float*)co, t0, t1);
488
dist = len_v3v3(nearest_tmp, (float*)co);
490
if(dist < nearest->dist)
447
closest_to_line_segment_v3(nearest_tmp, co, t0, t1);
448
dist = len_squared_v3v3(nearest_tmp, co);
450
if (dist < nearest->dist) {
492
451
nearest->index = index;
493
452
nearest->dist = dist;
494
VECCOPY(nearest->co, nearest_tmp);
453
copy_v3_v3(nearest->co, nearest_tmp);
495
454
sub_v3_v3v3(nearest->no, t0, t1);
496
455
normalize_v3(nearest->no);
564
519
BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_FACES);
570
int numFaces= mesh->getNumFaces(mesh);
571
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
572
MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
574
if(vert != NULL && face != NULL)
524
int numFaces= mesh->getNumTessFaces(mesh);
526
/* BMESH specific check that we have tessfaces,
527
* we _could_ tessellate here but rather not - campbell
529
* this assert checks we have tessfaces,
530
* if not caller should use DM_ensure_tessface() */
531
BLI_assert(!(numFaces == 0 && mesh->getNumPolys(mesh) != 0));
576
534
/* Create a bvh-tree of the given target */
577
535
tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis);
580
for(i = 0; i < numFaces; i++)
583
VECCOPY(co[0], vert[ face[i].v1 ].co);
584
VECCOPY(co[1], vert[ face[i].v2 ].co);
585
VECCOPY(co[2], vert[ face[i].v3 ].co);
587
VECCOPY(co[3], vert[ face[i].v4 ].co);
589
BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
537
BMEditMesh *em= data->em_evil;
539
/* data->em_evil is only set for snapping, and only for the mesh of the object
540
* which is currently open in edit mode. When set, the bvhtree should not contain
541
* faces that will interfere with snapping (e.g. faces that are hidden/selected
542
* or faces that have selected verts).*/
544
/* XXX, for snap only, em & dm are assumed to be aligned, since dm is the em's cage */
546
/* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
547
* and/or selected. Even if the faces themselves are not selected for the snapped
548
* transform, having a vertex selected means the face (and thus it's tessellated
549
* triangles) will be moving and will not be a good snap targets.*/
550
for (i = 0; i < em->tottri; i++) {
551
BMLoop **tri = em->looptris[i];
557
/* Each loop of the triangle points back to the BMFace it was tessellated from.
558
* All three should point to the same face, so just use the face from the first
562
/* If the looptris is ordered such that all triangles tessellated from a single
563
* faces are consecutive elements in the array, then we could speed up the tests
564
* below by using the insert value from the previous iteration.*/
566
/*Start with the assumption the triangle should be included for snapping.*/
569
if (BM_elem_flag_test(f, BM_ELEM_SELECT) || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
570
/* Don't insert triangles tessellated from faces that are hidden
575
BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
576
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
577
/* Don't insert triangles tessellated from faces that have
578
* any selected verts.*/
585
/* No reason found to block hit-testing the triangle for snap,
586
* so insert it now.*/
588
copy_v3_v3(co[0], tri[0]->v->co);
589
copy_v3_v3(co[1], tri[1]->v->co);
590
copy_v3_v3(co[2], tri[2]->v->co);
592
BLI_bvhtree_insert(tree, i, co[0], 3);
597
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
598
MFace *face = mesh->getTessFaceDataArray(mesh, CD_MFACE);
600
if (vert != NULL && face != NULL) {
601
for (i = 0; i < numFaces; i++) {
603
copy_v3_v3(co[0], vert[ face[i].v1 ].co);
604
copy_v3_v3(co[1], vert[ face[i].v2 ].co);
605
copy_v3_v3(co[2], vert[ face[i].v3 ].co);
607
copy_v3_v3(co[3], vert[ face[i].v4 ].co);
609
BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
591
613
BLI_bvhtree_balance(tree);
629
649
BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_EDGES);
635
655
int numEdges= mesh->getNumEdges(mesh);
636
656
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
637
657
MEdge *edge = mesh->getEdgeDataArray(mesh, CD_MEDGE);
639
if(vert != NULL && edge != NULL)
659
if (vert != NULL && edge != NULL) {
641
660
/* Create a bvh-tree of the given target */
642
661
tree = BLI_bvhtree_new(numEdges, epsilon, tree_type, axis);
645
for(i = 0; i < numEdges; i++)
663
for (i = 0; i < numEdges; i++) {
648
VECCOPY(co[0], vert[ edge[i].v1 ].co);
649
VECCOPY(co[1], vert[ edge[i].v2 ].co);
665
copy_v3_v3(co[0], vert[ edge[i].v1 ].co);
666
copy_v3_v3(co[1], vert[ edge[i].v2 ].co);
651
668
BLI_bvhtree_insert(tree, i, co[0], 2);