| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-01-07 19:18:31 +00:00
										 |  |  |  * Contributor(s): Andr Pinto. | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-02-27 20:40:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/blenkernel/intern/bvhutils.c
 | 
					
						
							|  |  |  |  *  \ingroup bke | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 10:07:21 +02:00
										 |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2011-10-22 01:53:35 +00:00
										 |  |  | #include "BLI_linklist.h"
 | 
					
						
							| 
									
										
										
										
											2013-01-24 21:57:13 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | #include "BLI_threads.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-15 13:38:10 +11:00
										 |  |  | #include "BKE_bvhutils.h"
 | 
					
						
							| 
									
										
										
										
											2013-04-13 20:31:52 +00:00
										 |  |  | #include "BKE_editmesh.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-08 10:07:21 +02:00
										 |  |  | #include "BKE_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-05 15:59:53 +02:00
										 |  |  | #include "BKE_mesh_runtime.h"
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | static ThreadRWMutex cache_rwlock = BLI_RWLOCK_INITIALIZER; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Local Callbacks
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | /* Math stuff for ray casting on mesh faces and for nearest surface */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | 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]) | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float dist; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-21 17:46:23 +10:00
										 |  |  | #ifdef USE_KDOPBVH_WATERTIGHT
 | 
					
						
							|  |  |  | 	if (isect_ray_tri_watertight_v3(ray->origin, ray->isect_precalc, v0, v1, v2, &dist, NULL)) | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	if (isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON)) | 
					
						
							| 
									
										
										
										
											2015-08-21 17:46:23 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 		return dist; | 
					
						
							| 
									
										
										
										
											2015-08-21 17:46:23 +10:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return FLT_MAX; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-29 21:14:16 +10:00
										 |  |  | float bvhtree_sphereray_tri_intersection( | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  |         const BVHTreeRay *ray, float radius, const float m_dist, | 
					
						
							|  |  |  |         const float v0[3], const float v1[3], const float v2[3]) | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 	float idist; | 
					
						
							|  |  |  | 	float p1[3]; | 
					
						
							| 
									
										
										
										
											2014-12-27 16:36:31 +11:00
										 |  |  | 	float hit_point[3]; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 	madd_v3_v3v3fl(p1, ray->origin, ray->direction, m_dist); | 
					
						
							| 
									
										
										
										
											2012-03-07 04:53:43 +00:00
										 |  |  | 	if (isect_sweeping_sphere_tri_v3(ray->origin, p1, radius, v0, v1, v2, &idist, hit_point)) { | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 		return idist * m_dist; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return FLT_MAX; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2013-10-05 14:19:39 +00:00
										 |  |  |  * BVH from meshes callbacks | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /* Callback to bvh tree nearest point. The tree must have been built using bvhtree_from_mesh_faces.
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  |  * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | static void mesh_faces_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | 	const MVert *vert = data->vert; | 
					
						
							|  |  |  | 	const MFace *face = data->face + index; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 00:20:13 +10:00
										 |  |  | 	const float *t0, *t1, *t2, *t3; | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	t0 = vert[face->v1].co; | 
					
						
							|  |  |  | 	t1 = vert[face->v2].co; | 
					
						
							|  |  |  | 	t2 = vert[face->v3].co; | 
					
						
							|  |  |  | 	t3 = face->v4 ? vert[face->v4].co : NULL; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 		float nearest_tmp[3], dist_sq; | 
					
						
							| 
									
										
										
										
											2014-08-19 17:41:55 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); | 
					
						
							|  |  |  | 		dist_sq = len_squared_v3v3(co, nearest_tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 		if (dist_sq < nearest->dist_sq) { | 
					
						
							| 
									
										
										
										
											2008-08-13 19:22:35 +00:00
										 |  |  | 			nearest->index = index; | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 			nearest->dist_sq = dist_sq; | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 			copy_v3_v3(nearest->co, nearest_tmp); | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 			normal_tri_v3(nearest->no, t0, t1, t2); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		t1 = t2; | 
					
						
							|  |  |  | 		t2 = t3; | 
					
						
							|  |  |  | 		t3 = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	} while (t2); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-23 13:09:14 +10:00
										 |  |  | /* copy of function above */ | 
					
						
							|  |  |  | static void mesh_looptri_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; | 
					
						
							|  |  |  | 	const MVert *vert = data->vert; | 
					
						
							|  |  |  | 	const MLoopTri *lt = &data->looptri[index]; | 
					
						
							|  |  |  | 	const float *vtri_co[3] = { | 
					
						
							|  |  |  | 	    vert[data->loop[lt->tri[0]].v].co, | 
					
						
							|  |  |  | 	    vert[data->loop[lt->tri[1]].v].co, | 
					
						
							|  |  |  | 	    vert[data->loop[lt->tri[2]].v].co, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	float nearest_tmp[3], dist_sq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	closest_on_tri_to_point_v3(nearest_tmp, co, UNPACK3(vtri_co)); | 
					
						
							|  |  |  | 	dist_sq = len_squared_v3v3(co, nearest_tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (dist_sq < nearest->dist_sq) { | 
					
						
							|  |  |  | 		nearest->index = index; | 
					
						
							|  |  |  | 		nearest->dist_sq = dist_sq; | 
					
						
							|  |  |  | 		copy_v3_v3(nearest->co, nearest_tmp); | 
					
						
							|  |  |  | 		normal_tri_v3(nearest->no, UNPACK3(vtri_co)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | /* copy of function above (warning, should de-duplicate with editmesh_bvh.c) */ | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | static void editmesh_looptri_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	const BVHTreeFromEditMesh *data = userdata; | 
					
						
							|  |  |  | 	BMEditMesh *em = data->em; | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 	const BMLoop **ltri = (const BMLoop **)em->looptris[index]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 00:20:13 +10:00
										 |  |  | 	const float *t0, *t1, *t2; | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 	t0 = ltri[0]->v->co; | 
					
						
							|  |  |  | 	t1 = ltri[1]->v->co; | 
					
						
							|  |  |  | 	t2 = ltri[2]->v->co; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 		float nearest_tmp[3], dist_sq; | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-19 17:41:55 +10:00
										 |  |  | 		closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); | 
					
						
							|  |  |  | 		dist_sq = len_squared_v3v3(co, nearest_tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 		if (dist_sq < nearest->dist_sq) { | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 			nearest->index = index; | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 			nearest->dist_sq = dist_sq; | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 			copy_v3_v3(nearest->co, nearest_tmp); | 
					
						
							|  |  |  | 			normal_tri_v3(nearest->no, t0, t1, t2); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_faces.
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  |  * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | 	const MVert *vert = data->vert; | 
					
						
							|  |  |  | 	const MFace *face = &data->face[index]; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 00:20:13 +10:00
										 |  |  | 	const float *t0, *t1, *t2, *t3; | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 	t0 = vert[face->v1].co; | 
					
						
							|  |  |  | 	t1 = vert[face->v2].co; | 
					
						
							|  |  |  | 	t2 = vert[face->v3].co; | 
					
						
							|  |  |  | 	t3 = face->v4 ? vert[face->v4].co : NULL; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 		float dist; | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 		if (ray->radius == 0.0f) | 
					
						
							| 
									
										
										
										
											2011-10-28 14:46:09 +00:00
										 |  |  | 			dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 			dist = bvhtree_sphereray_tri_intersection(ray, ray->radius, hit->dist, t0, t1, t2); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-07 04:53:43 +00:00
										 |  |  | 		if (dist >= 0 && dist < hit->dist) { | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 			hit->index = index; | 
					
						
							|  |  |  | 			hit->dist = dist; | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 			madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 			normal_tri_v3(hit->no, t0, t1, t2); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		t1 = t2; | 
					
						
							|  |  |  | 		t2 = t3; | 
					
						
							|  |  |  | 		t3 = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	} while (t2); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-23 13:09:14 +10:00
										 |  |  | /* copy of function above */ | 
					
						
							|  |  |  | static void mesh_looptri_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; | 
					
						
							|  |  |  | 	const MVert *vert = data->vert; | 
					
						
							|  |  |  | 	const MLoopTri *lt = &data->looptri[index]; | 
					
						
							|  |  |  | 	const float *vtri_co[3] = { | 
					
						
							|  |  |  | 	    vert[data->loop[lt->tri[0]].v].co, | 
					
						
							|  |  |  | 	    vert[data->loop[lt->tri[1]].v].co, | 
					
						
							|  |  |  | 	    vert[data->loop[lt->tri[2]].v].co, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	float dist; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 	if (ray->radius == 0.0f) | 
					
						
							| 
									
										
										
										
											2015-07-23 13:09:14 +10:00
										 |  |  | 		dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(vtri_co)); | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 		dist = bvhtree_sphereray_tri_intersection(ray, ray->radius, hit->dist, UNPACK3(vtri_co)); | 
					
						
							| 
									
										
										
										
											2015-07-23 13:09:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (dist >= 0 && dist < hit->dist) { | 
					
						
							|  |  |  | 		hit->index = index; | 
					
						
							|  |  |  | 		hit->dist = dist; | 
					
						
							|  |  |  | 		madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		normal_tri_v3(hit->no, UNPACK3(vtri_co)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | /* copy of function above (warning, should de-duplicate with editmesh_bvh.c) */ | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | static void editmesh_looptri_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	const BVHTreeFromEditMesh *data = (BVHTreeFromEditMesh *)userdata; | 
					
						
							|  |  |  | 	BMEditMesh *em = data->em; | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 	const BMLoop **ltri = (const BMLoop **)em->looptris[index]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 00:20:13 +10:00
										 |  |  | 	const float *t0, *t1, *t2; | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 	t0 = ltri[0]->v->co; | 
					
						
							|  |  |  | 	t1 = ltri[1]->v->co; | 
					
						
							|  |  |  | 	t2 = ltri[2]->v->co; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		float dist; | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 		if (ray->radius == 0.0f) | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 			dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 			dist = bvhtree_sphereray_tri_intersection(ray, ray->radius, hit->dist, t0, t1, t2); | 
					
						
							| 
									
										
										
										
											2013-04-23 23:57:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (dist >= 0 && dist < hit->dist) { | 
					
						
							|  |  |  | 			hit->index = index; | 
					
						
							|  |  |  | 			hit->dist = dist; | 
					
						
							|  |  |  | 			madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			normal_tri_v3(hit->no, t0, t1, t2); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /* Callback to bvh tree nearest point. The tree must have been built using bvhtree_from_mesh_edges.
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  |  * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | static void mesh_edges_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | 	const MVert *vert = data->vert; | 
					
						
							|  |  |  | 	const MEdge *edge = data->edge + index; | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 	float nearest_tmp[3], dist_sq; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 00:20:13 +10:00
										 |  |  | 	const float *t0, *t1; | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | 	t0 = vert[edge->v1].co; | 
					
						
							|  |  |  | 	t1 = vert[edge->v2].co; | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	closest_to_line_segment_v3(nearest_tmp, co, t0, t1); | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 	dist_sq = len_squared_v3v3(nearest_tmp, co); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 	if (dist_sq < nearest->dist_sq) { | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		nearest->index = index; | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 		nearest->dist_sq = dist_sq; | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 		copy_v3_v3(nearest->co, nearest_tmp); | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 		sub_v3_v3v3(nearest->no, t0, t1); | 
					
						
							|  |  |  | 		normalize_v3(nearest->no); | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /* Helper, does all the point-spherecast work actually. */ | 
					
						
							|  |  |  | static void mesh_verts_spherecast_do( | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 	float dist; | 
					
						
							|  |  |  | 	const float *r1; | 
					
						
							|  |  |  | 	float r2[3], i1[3]; | 
					
						
							|  |  |  | 	r1 = ray->origin; | 
					
						
							|  |  |  | 	add_v3_v3v3(r2, r1, ray->direction); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	closest_to_line_segment_v3(i1, v, r1, r2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* No hit if closest point is 'behind' the origin of the ray, or too far away from it. */ | 
					
						
							|  |  |  | 	if ((dot_v3v3v3(r1, i1, r2) >= 0.0f) && ((dist = len_v3v3(r1, i1)) < hit->dist)) { | 
					
						
							|  |  |  | 		hit->index = index; | 
					
						
							|  |  |  | 		hit->dist = dist; | 
					
						
							|  |  |  | 		copy_v3_v3(hit->co, i1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | static void editmesh_verts_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const BVHTreeFromEditMesh *data = userdata; | 
					
						
							|  |  |  | 	BMVert *eve = BM_vert_at_index(data->em->bm, index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mesh_verts_spherecast_do(index, eve->co, ray, hit); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_verts.
 | 
					
						
							|  |  |  |  * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | 
					
						
							|  |  |  | static void mesh_verts_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | 	const float *v = data->vert[index].co; | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	mesh_verts_spherecast_do(index, v, ray, hit); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_edges.
 | 
					
						
							|  |  |  |  * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | 
					
						
							|  |  |  | static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | 	const MVert *vert = data->vert; | 
					
						
							|  |  |  | 	const MEdge *edge = &data->edge[index]; | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 	const float radius_sq = SQUARE(ray->radius); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 	float dist; | 
					
						
							|  |  |  | 	const float *v1, *v2, *r1; | 
					
						
							|  |  |  | 	float r2[3], i1[3], i2[3]; | 
					
						
							|  |  |  | 	v1 = vert[edge->v1].co; | 
					
						
							|  |  |  | 	v2 = vert[edge->v2].co; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* In case we get a zero-length edge, handle it as a point! */ | 
					
						
							|  |  |  | 	if (equals_v3v3(v1, v2)) { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		mesh_verts_spherecast_do(index, v1, ray, hit); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 	r1 = ray->origin; | 
					
						
							|  |  |  | 	add_v3_v3v3(r2, r1, ray->direction); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 	if (isect_line_line_v3(v1, v2, r1, r2, i1, i2)) { | 
					
						
							|  |  |  | 		/* No hit if intersection point is 'behind' the origin of the ray, or too far away from it. */ | 
					
						
							|  |  |  | 		if ((dot_v3v3v3(r1, i2, r2) >= 0.0f) && ((dist = len_v3v3(r1, i2)) < hit->dist)) { | 
					
						
							|  |  |  | 			const float e_fac = line_point_factor_v3(i1, v1, v2); | 
					
						
							|  |  |  | 			if (e_fac < 0.0f) { | 
					
						
							|  |  |  | 				copy_v3_v3(i1, v1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (e_fac > 1.0f) { | 
					
						
							|  |  |  | 				copy_v3_v3(i1, v2); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* Ensure ray is really close enough from edge! */ | 
					
						
							|  |  |  | 			if (len_squared_v3v3(i1, i2) <= radius_sq) { | 
					
						
							|  |  |  | 				hit->index = index; | 
					
						
							|  |  |  | 				hit->dist = dist; | 
					
						
							|  |  |  | 				copy_v3_v3(hit->co, i2); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * BVH builders | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \name Vertex Builder
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2017-02-04 19:06:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | static BVHTree *bvhtree_from_editmesh_verts_create_tree( | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  |         float epsilon, int tree_type, int axis, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         BMEditMesh *em, const int verts_num, | 
					
						
							|  |  |  |         const BLI_bitmap *verts_mask, int verts_num_active) | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	BM_mesh_elem_table_ensure(em->bm, BM_VERT); | 
					
						
							| 
									
										
										
										
											2016-05-06 06:10:37 +10:00
										 |  |  | 	if (verts_mask) { | 
					
						
							| 
									
										
										
										
											2016-05-14 04:05:18 +10:00
										 |  |  | 		BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num)); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-06 06:10:37 +10:00
										 |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		verts_num_active = verts_num; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (tree) { | 
					
						
							| 
									
										
										
										
											2017-02-04 19:01:29 -03:00
										 |  |  | 		for (int i = 0; i < verts_num; i++) { | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 			if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 			BMVert *eve = BM_vert_at_index(em->bm, i); | 
					
						
							|  |  |  | 			BLI_bvhtree_insert(tree, i, eve->co, 1); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  | 		BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		BLI_bvhtree_balance(tree); | 
					
						
							| 
									
										
										
										
											2016-01-25 18:18:42 +11:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static BVHTree *bvhtree_from_mesh_verts_create_tree( | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis, | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const int verts_num, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         const BLI_bitmap *verts_mask, int verts_num_active) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 	BVHTree *tree = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	if (verts_mask) { | 
					
						
							|  |  |  | 		BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		verts_num_active = verts_num; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 	if (verts_num_active) { | 
					
						
							|  |  |  | 		tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 		if (tree) { | 
					
						
							|  |  |  | 			for (int i = 0; i < verts_num; i++) { | 
					
						
							|  |  |  | 				if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				BLI_bvhtree_insert(tree, i, vert[i].co, 1); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 			BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); | 
					
						
							|  |  |  | 			BLI_bvhtree_balance(tree); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | static void bvhtree_from_mesh_verts_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  |         BVHTreeFromMesh *data, BVHTree *tree, const bool is_cached, | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const bool vert_allocated) | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | 	memset(data, 0, sizeof(*data)); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->tree = tree; | 
					
						
							|  |  |  | 	data->cached = is_cached; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	/* a NULL nearest callback works fine
 | 
					
						
							|  |  |  | 	 * remember the min distance to point is the same as the min distance to BV of point */ | 
					
						
							|  |  |  | 	data->nearest_callback = NULL; | 
					
						
							|  |  |  | 	data->raycast_callback = mesh_verts_spherecast; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->vert = vert; | 
					
						
							|  |  |  | 	data->vert_allocated = vert_allocated; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | /* Builds a bvh tree where nodes are the vertices of the given em */ | 
					
						
							|  |  |  | BVHTree *bvhtree_from_editmesh_verts_ex( | 
					
						
							|  |  |  |         BVHTreeFromEditMesh *data, BMEditMesh *em, | 
					
						
							|  |  |  |         const BLI_bitmap *verts_mask, int verts_num_active, | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BVHTree *tree = bvhtree_from_editmesh_verts_create_tree( | 
					
						
							|  |  |  | 	        epsilon, tree_type, axis, | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	        em, em->bm->totvert, verts_mask, verts_num_active); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (tree) { | 
					
						
							|  |  |  | 		memset(data, 0, sizeof(*data)); | 
					
						
							|  |  |  | 		data->tree = tree; | 
					
						
							|  |  |  | 		data->em = em; | 
					
						
							|  |  |  | 		data->nearest_callback = NULL; | 
					
						
							|  |  |  | 		data->raycast_callback = editmesh_verts_spherecast; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | BVHTree *bvhtree_from_editmesh_verts( | 
					
						
							|  |  |  |         BVHTreeFromEditMesh *data, BMEditMesh *em, | 
					
						
							| 
									
										
										
										
											2018-07-23 11:04:58 -03:00
										 |  |  |         float epsilon, int tree_type, int axis, BVHCache **bvh_cache) | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-23 11:04:58 -03:00
										 |  |  | 	if (bvh_cache) { | 
					
						
							|  |  |  | 		BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); | 
					
						
							|  |  |  | 		data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree); | 
					
						
							|  |  |  | 		BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (data->cached == false) { | 
					
						
							|  |  |  | 			BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							|  |  |  | 			data->cached = bvhcache_find( | 
					
						
							|  |  |  | 			        *bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree); | 
					
						
							|  |  |  | 			if (data->cached == false) { | 
					
						
							|  |  |  | 				data->tree = bvhtree_from_editmesh_verts_ex( | 
					
						
							|  |  |  | 				        data, em, | 
					
						
							|  |  |  | 				        NULL, -1, | 
					
						
							|  |  |  | 				        epsilon, tree_type, axis); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Save on cache for later use */ | 
					
						
							|  |  |  | 				/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							|  |  |  | 				bvhcache_insert( | 
					
						
							|  |  |  | 				        bvh_cache, data->tree, BVHTREE_FROM_EM_VERTS); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		data->tree = bvhtree_from_editmesh_verts_ex( | 
					
						
							|  |  |  | 		        data, em, | 
					
						
							|  |  |  | 		        NULL, -1, | 
					
						
							|  |  |  | 		        epsilon, tree_type, axis); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return data->tree; | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Builds a bvh tree where nodes are the given vertices (note: does not copy given mverts!). | 
					
						
							|  |  |  |  * \param vert_allocated if true, vert freeing will be done when freeing data. | 
					
						
							| 
									
										
										
										
											2016-06-27 13:20:56 +10:00
										 |  |  |  * \param verts_mask if not null, true elements give which vert to add to BVH tree. | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |  * \param verts_num_active if >= 0, number of active verts to add to BVH tree (else will be computed from mask). | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | BVHTree *bvhtree_from_mesh_verts_ex( | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         BVHTreeFromMesh *data, const MVert *vert, const int verts_num, const bool vert_allocated, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         const BLI_bitmap *verts_mask, int verts_num_active, | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	BVHTree *tree = bvhtree_from_mesh_verts_create_tree( | 
					
						
							|  |  |  | 	        epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 	/* Setup BVHTreeFromMesh */ | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	bvhtree_from_mesh_verts_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 	        data, tree, false, vert, vert_allocated); | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	return tree; | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \name Edge Builder
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | static BVHTree *bvhtree_from_editmesh_edges_create_tree( | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis, | 
					
						
							|  |  |  |         BMEditMesh *em, const int edges_num, | 
					
						
							|  |  |  |         const BLI_bitmap *edges_mask, int edges_num_active) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BM_mesh_elem_table_ensure(em->bm, BM_EDGE); | 
					
						
							|  |  |  | 	if (edges_mask) { | 
					
						
							|  |  |  | 		BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges_num)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		edges_num_active = edges_num; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis); | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (tree) { | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 		int i; | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | 		BMIter iter; | 
					
						
							|  |  |  | 		BMEdge *eed; | 
					
						
							|  |  |  | 		BM_ITER_MESH_INDEX (eed, &iter, em->bm, BM_EDGES_OF_MESH, i) { | 
					
						
							|  |  |  | 			if (edges_mask && !BLI_BITMAP_TEST_BOOL(edges_mask, i)) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			float co[2][3]; | 
					
						
							|  |  |  | 			copy_v3_v3(co[0], eed->v1->co); | 
					
						
							|  |  |  | 			copy_v3_v3(co[1], eed->v2->co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BLI_bvhtree_insert(tree, i, co[0], 2); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  | 		BLI_assert(BLI_bvhtree_get_len(tree) == edges_num_active); | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | 		BLI_bvhtree_balance(tree); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | static BVHTree *bvhtree_from_mesh_edges_create_tree( | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const MEdge *edge, const int edge_num, | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  |         const BLI_bitmap *edges_mask, int edges_num_active, | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 	BVHTree *tree = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	if (edges_mask) { | 
					
						
							|  |  |  | 		BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edge_num)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		edges_num_active = edge_num; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 	if (edges_num_active) { | 
					
						
							|  |  |  | 		/* Create a bvh-tree of the given target */ | 
					
						
							|  |  |  | 		tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis); | 
					
						
							|  |  |  | 		if (tree) { | 
					
						
							|  |  |  | 			for (int i = 0; i < edge_num; i++) { | 
					
						
							|  |  |  | 				if (edges_mask && !BLI_BITMAP_TEST_BOOL(edges_mask, i)) { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				float co[2][3]; | 
					
						
							|  |  |  | 				copy_v3_v3(co[0], vert[edge[i].v1].co); | 
					
						
							|  |  |  | 				copy_v3_v3(co[1], vert[edge[i].v2].co); | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 				BLI_bvhtree_insert(tree, i, co[0], 2); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			BLI_bvhtree_balance(tree); | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bvhtree_from_mesh_edges_setup_data( | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         BVHTreeFromMesh *data, BVHTree *tree, | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  |         const bool is_cached, | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const bool vert_allocated, | 
					
						
							|  |  |  |         const MEdge *edge, const bool edge_allocated) | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	memset(data, 0, sizeof(*data)); | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	data->tree = tree; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->cached = is_cached; | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->nearest_callback = mesh_edges_nearest_point; | 
					
						
							|  |  |  | 	data->raycast_callback = mesh_edges_spherecast; | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->vert = vert; | 
					
						
							|  |  |  | 	data->vert_allocated = vert_allocated; | 
					
						
							|  |  |  | 	data->edge = edge; | 
					
						
							|  |  |  | 	data->edge_allocated = edge_allocated; | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | /* Builds a bvh tree where nodes are the edges of the given em */ | 
					
						
							|  |  |  | BVHTree *bvhtree_from_editmesh_edges_ex( | 
					
						
							|  |  |  |         BVHTreeFromEditMesh *data, BMEditMesh *em, | 
					
						
							|  |  |  |         const BLI_bitmap *edges_mask, int edges_num_active, | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int edge_num = em->bm->totedge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BVHTree *tree = bvhtree_from_editmesh_edges_create_tree( | 
					
						
							|  |  |  | 	        epsilon, tree_type, axis, | 
					
						
							|  |  |  | 	        em, edge_num, edges_mask, edges_num_active); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (tree) { | 
					
						
							|  |  |  | 		memset(data, 0, sizeof(*data)); | 
					
						
							|  |  |  | 		data->tree = tree; | 
					
						
							|  |  |  | 		data->em = em; | 
					
						
							|  |  |  | 		data->nearest_callback = NULL;  /* TODO */ | 
					
						
							|  |  |  | 		data->raycast_callback = NULL;  /* TODO */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | BVHTree *bvhtree_from_editmesh_edges( | 
					
						
							|  |  |  |         BVHTreeFromEditMesh *data, BMEditMesh *em, | 
					
						
							| 
									
										
										
										
											2018-07-23 11:04:58 -03:00
										 |  |  |         float epsilon, int tree_type, int axis, BVHCache **bvh_cache) | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-23 11:04:58 -03:00
										 |  |  | 	if (bvh_cache) { | 
					
						
							|  |  |  | 		BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); | 
					
						
							|  |  |  | 		data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree); | 
					
						
							|  |  |  | 		BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (data->cached == false) { | 
					
						
							|  |  |  | 			BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							|  |  |  | 			data->cached = bvhcache_find( | 
					
						
							|  |  |  | 			        *bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree); | 
					
						
							|  |  |  | 			if (data->cached == false) { | 
					
						
							|  |  |  | 				data->tree = bvhtree_from_editmesh_edges_ex( | 
					
						
							|  |  |  | 				        data, em, | 
					
						
							|  |  |  | 				        NULL, -1, | 
					
						
							|  |  |  | 				        epsilon, tree_type, axis); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Save on cache for later use */ | 
					
						
							|  |  |  | 				/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							|  |  |  | 				bvhcache_insert( | 
					
						
							|  |  |  | 				        bvh_cache, data->tree, BVHTREE_FROM_EM_EDGES); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		data->tree = bvhtree_from_editmesh_edges_ex( | 
					
						
							|  |  |  | 		        data, em, | 
					
						
							|  |  |  | 		        NULL, -1, | 
					
						
							|  |  |  | 		        epsilon, tree_type, axis); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return data->tree; | 
					
						
							| 
									
										
										
										
											2016-06-30 15:43:47 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Builds a bvh tree where nodes are the given edges . | 
					
						
							|  |  |  |  * \param vert/edge_allocated if true, elem freeing will be done when freeing data. | 
					
						
							|  |  |  |  * \param edges_mask if not null, true elements give which vert to add to BVH tree. | 
					
						
							|  |  |  |  * \param edges_num_active if >= 0, number of active edges to add to BVH tree (else will be computed from mask). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | BVHTree *bvhtree_from_mesh_edges_ex( | 
					
						
							|  |  |  |         BVHTreeFromMesh *data, | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const bool vert_allocated, | 
					
						
							|  |  |  |         const MEdge *edge, const int edges_num, const bool edge_allocated, | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  |         const BLI_bitmap *edges_mask, int edges_num_active, | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BVHTree *tree = bvhtree_from_mesh_edges_create_tree( | 
					
						
							|  |  |  | 	        vert, edge, edges_num, edges_mask, edges_num_active, | 
					
						
							|  |  |  | 	        epsilon, tree_type, axis); | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 14:11:06 -03:00
										 |  |  | 	/* Setup BVHTreeFromMesh */ | 
					
						
							|  |  |  | 	bvhtree_from_mesh_edges_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 	        data, tree, false, vert, vert_allocated, edge, edge_allocated); | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	return tree; | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \name Tessellated Face Builder
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static BVHTree *bvhtree_from_mesh_faces_create_tree( | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis, | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const MFace *face, const int faces_num, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         const BLI_bitmap *faces_mask, int faces_num_active) | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	BVHTree *tree = NULL; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	if (faces_num) { | 
					
						
							| 
									
										
										
										
											2016-05-06 06:10:37 +10:00
										 |  |  | 		if (faces_mask) { | 
					
						
							| 
									
										
										
										
											2016-05-14 04:05:18 +10:00
										 |  |  | 			BLI_assert(IN_RANGE_INCL(faces_num_active, 0, faces_num)); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-05-06 06:10:37 +10:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 			faces_num_active = faces_num; | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Create a bvh-tree of the given target */ | 
					
						
							|  |  |  | 		/* printf("%s: building BVH, total=%d\n", __func__, numFaces); */ | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		tree = BLI_bvhtree_new(faces_num_active, epsilon, tree_type, axis); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 		if (tree) { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 			if (vert && face) { | 
					
						
							|  |  |  | 				for (i = 0; i < faces_num; i++) { | 
					
						
							|  |  |  | 					float co[4][3]; | 
					
						
							|  |  |  | 					if (faces_mask && !BLI_BITMAP_TEST_BOOL(faces_mask, i)) { | 
					
						
							|  |  |  | 						continue; | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 					copy_v3_v3(co[0], vert[face[i].v1].co); | 
					
						
							|  |  |  | 					copy_v3_v3(co[1], vert[face[i].v2].co); | 
					
						
							|  |  |  | 					copy_v3_v3(co[2], vert[face[i].v3].co); | 
					
						
							|  |  |  | 					if (face[i].v4) | 
					
						
							|  |  |  | 						copy_v3_v3(co[3], vert[face[i].v4].co); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 					BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  | 			BLI_assert(BLI_bvhtree_get_len(tree) == faces_num_active); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 			BLI_bvhtree_balance(tree); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | static void bvhtree_from_mesh_faces_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  |         BVHTreeFromMesh *data, BVHTree *tree, const bool is_cached, | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         const MVert *vert, const bool vert_allocated, | 
					
						
							|  |  |  |         const MFace *face, const bool face_allocated) | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	memset(data, 0, sizeof(*data)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->tree = tree; | 
					
						
							|  |  |  | 	data->cached = is_cached; | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->nearest_callback = mesh_faces_nearest_point; | 
					
						
							|  |  |  | 	data->raycast_callback = mesh_faces_spherecast; | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->vert = vert; | 
					
						
							|  |  |  | 	data->vert_allocated = vert_allocated; | 
					
						
							|  |  |  | 	data->face = face; | 
					
						
							|  |  |  | 	data->face_allocated = face_allocated; | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Builds a bvh tree where nodes are the given tessellated faces (note: does not copy given mfaces!). | 
					
						
							| 
									
										
										
										
											2017-06-19 09:33:23 +10:00
										 |  |  |  * \param vert_allocated: if true, vert freeing will be done when freeing data. | 
					
						
							|  |  |  |  * \param face_allocated: if true, face freeing will be done when freeing data. | 
					
						
							| 
									
										
										
										
											2016-06-27 13:20:56 +10:00
										 |  |  |  * \param faces_mask: if not null, true elements give which faces to add to BVH tree. | 
					
						
							| 
									
										
										
										
											2017-06-19 09:33:23 +10:00
										 |  |  |  * \param faces_num_active: if >= 0, number of active faces to add to BVH tree (else will be computed from mask). | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | BVHTree *bvhtree_from_mesh_faces_ex( | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  |         BVHTreeFromMesh *data, const MVert *vert, const bool vert_allocated, | 
					
						
							|  |  |  |         const MFace *face, const int numFaces, const bool face_allocated, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         const BLI_bitmap *faces_mask, int faces_num_active, | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-07-22 17:39:33 +10:00
										 |  |  | 	BVHTree *tree = bvhtree_from_mesh_faces_create_tree( | 
					
						
							| 
									
										
										
										
											2015-10-09 11:04:24 +11:00
										 |  |  | 	        epsilon, tree_type, axis, | 
					
						
							|  |  |  | 	        vert, face, numFaces, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	        faces_mask, faces_num_active); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup BVHTreeFromMesh */ | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	bvhtree_from_mesh_faces_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 	        data, tree, false, vert, vert_allocated, face, face_allocated); | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	return tree; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \name LoopTri Face Builder
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | static BVHTree *bvhtree_from_editmesh_looptri_create_tree( | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  |         float epsilon, int tree_type, int axis, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         BMEditMesh *em, const int looptri_num, | 
					
						
							|  |  |  |         const BLI_bitmap *looptri_mask, int looptri_num_active) | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	BVHTree *tree = NULL; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-23 15:17:26 +10:00
										 |  |  | 	if (looptri_num) { | 
					
						
							| 
									
										
										
										
											2016-05-06 06:27:42 +10:00
										 |  |  | 		if (looptri_mask) { | 
					
						
							| 
									
										
										
										
											2016-05-14 04:05:18 +10:00
										 |  |  | 			BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num)); | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-05-06 06:27:42 +10:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-07-23 15:17:26 +10:00
										 |  |  | 			looptri_num_active = looptri_num; | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Create a bvh-tree of the given target */ | 
					
						
							|  |  |  | 		/* printf("%s: building BVH, total=%d\n", __func__, numFaces); */ | 
					
						
							| 
									
										
										
										
											2015-07-23 15:17:26 +10:00
										 |  |  | 		tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis); | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 		if (tree) { | 
					
						
							|  |  |  | 			if (em) { | 
					
						
							|  |  |  | 				const struct BMLoop *(*looptris)[3] = (void *)em->looptris; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
 | 
					
						
							|  |  |  | 				 * and/or selected. Even if the faces themselves are not selected for the snapped | 
					
						
							|  |  |  | 				 * transform, having a vertex selected means the face (and thus it's tessellated | 
					
						
							|  |  |  | 				 * triangles) will be moving and will not be a good snap targets. */ | 
					
						
							| 
									
										
										
										
											2015-07-23 15:17:26 +10:00
										 |  |  | 				for (i = 0; i < looptri_num; i++) { | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 					const BMLoop **ltri = looptris[i]; | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 					bool insert = looptri_mask ? BLI_BITMAP_TEST_BOOL(looptri_mask, i) : true; | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if (insert) { | 
					
						
							|  |  |  | 						/* No reason found to block hit-testing the triangle for snap, so insert it now.*/ | 
					
						
							|  |  |  | 						float co[3][3]; | 
					
						
							|  |  |  | 						copy_v3_v3(co[0], ltri[0]->v->co); | 
					
						
							|  |  |  | 						copy_v3_v3(co[1], ltri[1]->v->co); | 
					
						
							|  |  |  | 						copy_v3_v3(co[2], ltri[2]->v->co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						BLI_bvhtree_insert(tree, i, co[0], 3); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  | 			BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 			BLI_bvhtree_balance(tree); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | static BVHTree *bvhtree_from_mesh_looptri_create_tree( | 
					
						
							|  |  |  |         float epsilon, int tree_type, int axis, | 
					
						
							|  |  |  |         const MVert *vert, const MLoop *mloop, const MLoopTri *looptri, const int looptri_num, | 
					
						
							|  |  |  |         const BLI_bitmap *looptri_mask, int looptri_num_active) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BVHTree *tree = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 	if (looptri_mask) { | 
					
						
							|  |  |  | 		BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		looptri_num_active = looptri_num; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 	if (looptri_num_active) { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		/* Create a bvh-tree of the given target */ | 
					
						
							|  |  |  | 		/* printf("%s: building BVH, total=%d\n", __func__, numFaces); */ | 
					
						
							|  |  |  | 		tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis); | 
					
						
							|  |  |  | 		if (tree) { | 
					
						
							|  |  |  | 			if (vert && looptri) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:31:26 -03:00
										 |  |  | 				for (int i = 0; i < looptri_num; i++) { | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 					float co[3][3]; | 
					
						
							|  |  |  | 					if (looptri_mask && !BLI_BITMAP_TEST_BOOL(looptri_mask, i)) { | 
					
						
							|  |  |  | 						continue; | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					copy_v3_v3(co[0], vert[mloop[looptri[i].tri[0]].v].co); | 
					
						
							|  |  |  | 					copy_v3_v3(co[1], vert[mloop[looptri[i].tri[1]].v].co); | 
					
						
							|  |  |  | 					copy_v3_v3(co[2], vert[mloop[looptri[i].tri[2]].v].co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					BLI_bvhtree_insert(tree, i, co[0], 3); | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  | 			BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 			BLI_bvhtree_balance(tree); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bvhtree_from_mesh_looptri_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  |         BVHTreeFromMesh *data, BVHTree *tree, const bool is_cached, | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  |         const MVert *vert, const bool vert_allocated, | 
					
						
							|  |  |  |         const MLoop *mloop, const bool loop_allocated, | 
					
						
							|  |  |  |         const MLoopTri *looptri, const bool looptri_allocated) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	memset(data, 0, sizeof(*data)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->tree = tree; | 
					
						
							|  |  |  | 	data->cached = is_cached; | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->nearest_callback = mesh_looptri_nearest_point; | 
					
						
							|  |  |  | 	data->raycast_callback = mesh_looptri_spherecast; | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	data->vert = vert; | 
					
						
							|  |  |  | 	data->vert_allocated = vert_allocated; | 
					
						
							|  |  |  | 	data->loop = mloop; | 
					
						
							|  |  |  | 	data->loop_allocated = loop_allocated; | 
					
						
							|  |  |  | 	data->looptri = looptri; | 
					
						
							|  |  |  | 	data->looptri_allocated = looptri_allocated; | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Builds a bvh tree where nodes are the looptri faces of the given bm | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | BVHTree *bvhtree_from_editmesh_looptri_ex( | 
					
						
							|  |  |  |         BVHTreeFromEditMesh *data, BMEditMesh *em, | 
					
						
							|  |  |  |         const BLI_bitmap *looptri_mask, int looptri_num_active, | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  |         float epsilon, int tree_type, int axis, BVHCache **bvhCache) | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* BMESH specific check that we have tessfaces,
 | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 	 * we _could_ tessellate here but rather not - campbell */ | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 	BVHTree *tree = NULL; | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 	if (bvhCache) { | 
					
						
							|  |  |  | 		BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 		bool in_cache = bvhcache_find(*bvhCache, BVHTREE_FROM_EM_LOOPTRI, &tree); | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 		BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 		if (in_cache == false) { | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 			BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 			in_cache = bvhcache_find(*bvhCache, BVHTREE_FROM_EM_LOOPTRI, &tree); | 
					
						
							|  |  |  | 			if (in_cache == false) { | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 				tree = bvhtree_from_editmesh_looptri_create_tree( | 
					
						
							|  |  |  | 				        epsilon, tree_type, axis, | 
					
						
							|  |  |  | 				        em, em->tottri, looptri_mask, looptri_num_active); | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* Save on cache for later use */ | 
					
						
							|  |  |  | 				/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							|  |  |  | 				bvhcache_insert(bvhCache, tree, BVHTREE_FROM_EM_LOOPTRI); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		tree = bvhtree_from_editmesh_looptri_create_tree( | 
					
						
							|  |  |  | 		        epsilon, tree_type, axis, | 
					
						
							|  |  |  | 		        em, em->tottri, looptri_mask, looptri_num_active); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (tree) { | 
					
						
							|  |  |  | 		data->tree = tree; | 
					
						
							|  |  |  | 		data->nearest_callback = editmesh_looptri_nearest_point; | 
					
						
							|  |  |  | 		data->raycast_callback = editmesh_looptri_spherecast; | 
					
						
							|  |  |  | 		data->em = em; | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 		data->cached = bvhCache != NULL; | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | BVHTree *bvhtree_from_editmesh_looptri( | 
					
						
							|  |  |  |         BVHTreeFromEditMesh *data, BMEditMesh *em, | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  |         float epsilon, int tree_type, int axis, BVHCache **bvhCache) | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	return bvhtree_from_editmesh_looptri_ex( | 
					
						
							|  |  |  | 	        data, em, NULL, -1, | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 	        epsilon, tree_type, axis, bvhCache); | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Builds a bvh tree where nodes are the looptri faces of the given dm | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-05-04 11:15:21 -03:00
										 |  |  |  * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces_ex | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  |  */ | 
					
						
							|  |  |  | BVHTree *bvhtree_from_mesh_looptri_ex( | 
					
						
							|  |  |  |         BVHTreeFromMesh *data, | 
					
						
							|  |  |  |         const struct MVert *vert, const bool vert_allocated, | 
					
						
							|  |  |  |         const struct MLoop *mloop, const bool loop_allocated, | 
					
						
							|  |  |  |         const struct MLoopTri *looptri, const int looptri_num, const bool looptri_allocated, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  |         const BLI_bitmap *looptri_mask, int looptri_num_active, | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  |         float epsilon, int tree_type, int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BVHTree *tree = bvhtree_from_mesh_looptri_create_tree( | 
					
						
							| 
									
										
										
										
											2015-10-09 11:04:24 +11:00
										 |  |  | 	        epsilon, tree_type, axis, | 
					
						
							|  |  |  | 	        vert, mloop, looptri, looptri_num, | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 	        looptri_mask, looptri_num_active); | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup BVHTreeFromMesh */ | 
					
						
							|  |  |  | 	bvhtree_from_mesh_looptri_setup_data( | 
					
						
							| 
									
										
										
										
											2018-05-04 11:57:01 -03:00
										 |  |  | 	        data, tree, false, | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | 	        vert, vert_allocated, | 
					
						
							|  |  |  | 	        mloop, loop_allocated, | 
					
						
							|  |  |  | 	        looptri, looptri_allocated); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	return tree; | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | static BLI_bitmap *loose_verts_map_get( | 
					
						
							|  |  |  |         const MEdge *medge, int edges_num, | 
					
						
							| 
									
										
										
										
											2018-05-10 19:08:53 +02:00
										 |  |  |         const MVert *UNUSED(mvert), int verts_num, | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  |         int *r_loose_vert_num) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BLI_bitmap *loose_verts_mask = BLI_BITMAP_NEW(verts_num, __func__); | 
					
						
							|  |  |  | 	BLI_BITMAP_SET_ALL(loose_verts_mask, true, verts_num); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const MEdge *e = medge; | 
					
						
							|  |  |  | 	int num_linked_verts = 0; | 
					
						
							|  |  |  | 	for (;edges_num--; e++) { | 
					
						
							|  |  |  | 		if (BLI_BITMAP_TEST(loose_verts_mask, e->v1)) { | 
					
						
							|  |  |  | 			BLI_BITMAP_DISABLE(loose_verts_mask, e->v1); | 
					
						
							|  |  |  | 			num_linked_verts++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (BLI_BITMAP_TEST(loose_verts_mask, e->v2)) { | 
					
						
							|  |  |  | 			BLI_BITMAP_DISABLE(loose_verts_mask, e->v2); | 
					
						
							|  |  |  | 			num_linked_verts++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*r_loose_vert_num = verts_num - num_linked_verts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return loose_verts_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static BLI_bitmap *loose_edges_map_get( | 
					
						
							|  |  |  |         const MEdge *medge, const int edges_len, | 
					
						
							| 
									
										
										
										
											2018-05-10 16:32:13 -03:00
										 |  |  |         int *r_loose_edge_len) | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	BLI_bitmap *loose_edges_mask = BLI_BITMAP_NEW(edges_len, __func__); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int loose_edges_len = 0; | 
					
						
							|  |  |  | 	const MEdge *e = medge; | 
					
						
							|  |  |  | 	for (int i = 0; i < edges_len; i++, e++) { | 
					
						
							|  |  |  | 		if (e->flag & ME_LOOSEEDGE) { | 
					
						
							|  |  |  | 			BLI_BITMAP_ENABLE(loose_edges_mask, i); | 
					
						
							|  |  |  | 			loose_edges_len++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BLI_BITMAP_DISABLE(loose_edges_mask, i); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*r_loose_edge_len = loose_edges_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return loose_edges_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Builds or queries a bvhcache for the cache bvhtree of the request type. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | BVHTree *BKE_bvhtree_from_mesh_get( | 
					
						
							|  |  |  |         struct BVHTreeFromMesh *data, struct Mesh *mesh, | 
					
						
							|  |  |  |         const int type, const int tree_type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 	struct BVHTreeFromMesh data_cp = {0}; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 	data_cp.cached = bvhcache_find(mesh->runtime.bvh_cache, type, &data_cp.tree); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 	BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 	if (data_cp.cached && data_cp.tree == NULL) { | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 		memset(data, 0, sizeof(*data)); | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 		return data_cp.tree; | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 	switch (type) { | 
					
						
							|  |  |  | 		case BVHTREE_FROM_VERTS: | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 		case BVHTREE_FROM_LOOSEVERTS: | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.raycast_callback = mesh_verts_spherecast; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.vert = mesh->mvert; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 				data_cp.cached = bvhcache_find( | 
					
						
							|  |  |  | 				        mesh->runtime.bvh_cache, type, &data_cp.tree); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					BLI_bitmap *loose_verts_mask = NULL; | 
					
						
							|  |  |  | 					int loose_vert_len = -1; | 
					
						
							|  |  |  | 					int verts_len = mesh->totvert; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (type == BVHTREE_FROM_LOOSEVERTS) { | 
					
						
							|  |  |  | 						loose_verts_mask = loose_verts_map_get( | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 						        mesh->medge, mesh->totedge, data_cp.vert, | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 						        verts_len, &loose_vert_len); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					data_cp.tree = bvhtree_from_mesh_verts_create_tree( | 
					
						
							|  |  |  | 					        0.0, tree_type, 6, data_cp.vert, verts_len, | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					        loose_verts_mask, loose_vert_len); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					if (loose_verts_mask != NULL) { | 
					
						
							|  |  |  | 						MEM_freeN(loose_verts_mask); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 					/* Save on cache for later use */ | 
					
						
							|  |  |  | 					/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					bvhcache_insert(&mesh->runtime.bvh_cache, data_cp.tree, type); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case BVHTREE_FROM_EDGES: | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 		case BVHTREE_FROM_LOOSEEDGES: | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.nearest_callback = mesh_edges_nearest_point; | 
					
						
							|  |  |  | 			data_cp.raycast_callback = mesh_edges_spherecast; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.vert = mesh->mvert; | 
					
						
							|  |  |  | 			data_cp.edge = mesh->medge; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 				data_cp.cached = bvhcache_find(mesh->runtime.bvh_cache, type, &data_cp.tree); | 
					
						
							|  |  |  | 				if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					BLI_bitmap *loose_edges_mask = NULL; | 
					
						
							|  |  |  | 					int loose_edges_len = -1; | 
					
						
							|  |  |  | 					int edges_len = mesh->totedge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (type == BVHTREE_FROM_LOOSEEDGES) { | 
					
						
							|  |  |  | 						loose_edges_mask = loose_edges_map_get( | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 						        data_cp.edge, edges_len, &loose_edges_len); | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					data_cp.tree = bvhtree_from_mesh_edges_create_tree( | 
					
						
							|  |  |  | 					        data_cp.vert, data_cp.edge, edges_len, | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					        loose_edges_mask, loose_edges_len, 0.0, tree_type, 6); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 13:35:48 -03:00
										 |  |  | 					if (loose_edges_mask != NULL) { | 
					
						
							|  |  |  | 						MEM_freeN(loose_edges_mask); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 					/* Save on cache for later use */ | 
					
						
							|  |  |  | 					/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					bvhcache_insert(&mesh->runtime.bvh_cache, data_cp.tree, type); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case BVHTREE_FROM_FACES: | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.nearest_callback = mesh_faces_nearest_point; | 
					
						
							|  |  |  | 			data_cp.raycast_callback = mesh_faces_spherecast; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.vert = mesh->mvert; | 
					
						
							|  |  |  | 			data_cp.face = mesh->mface; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 				data_cp.cached = bvhcache_find( | 
					
						
							|  |  |  | 				        mesh->runtime.bvh_cache, BVHTREE_FROM_FACES, &data_cp.tree); | 
					
						
							|  |  |  | 				if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 					int num_faces = mesh->totface; | 
					
						
							|  |  |  | 					BLI_assert(!(num_faces == 0 && mesh->totpoly != 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					data_cp.tree = bvhtree_from_mesh_faces_create_tree( | 
					
						
							|  |  |  | 					        0.0, tree_type, 6, data_cp.vert, | 
					
						
							|  |  |  | 					        data_cp.face, num_faces, NULL, -1); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 					/* Save on cache for later use */ | 
					
						
							|  |  |  | 					/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					bvhcache_insert( | 
					
						
							|  |  |  | 					        &mesh->runtime.bvh_cache, data_cp.tree, BVHTREE_FROM_FACES); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case BVHTREE_FROM_LOOPTRI: | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.nearest_callback = mesh_looptri_nearest_point; | 
					
						
							|  |  |  | 			data_cp.raycast_callback = mesh_looptri_spherecast; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.vert = mesh->mvert; | 
					
						
							|  |  |  | 			data_cp.loop = mesh->mloop; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* TODO: store looptris somewhere? */ | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			data_cp.looptri = BKE_mesh_runtime_looptri_ensure(mesh); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 			if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 				data_cp.cached = bvhcache_find( | 
					
						
							|  |  |  | 				        mesh->runtime.bvh_cache, BVHTREE_FROM_LOOPTRI, &data_cp.tree); | 
					
						
							|  |  |  | 				if (data_cp.cached == false) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 					int looptri_num = BKE_mesh_runtime_looptri_len(mesh); | 
					
						
							|  |  |  | 					/* this assert checks we have looptris,
 | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  | 					 * if not caller should use DM_ensure_looptri() */ | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 					BLI_assert(!(looptri_num == 0 && mesh->totpoly != 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					data_cp.tree = bvhtree_from_mesh_looptri_create_tree( | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 					        0.0, tree_type, 6, | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					        data_cp.vert, data_cp.loop, | 
					
						
							|  |  |  | 					        data_cp.looptri, looptri_num, NULL, -1); | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					/* Save on cache for later use */ | 
					
						
							|  |  |  | 					/* printf("BVHTree built and saved on cache\n"); */ | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 					bvhcache_insert( | 
					
						
							|  |  |  | 					        &mesh->runtime.bvh_cache, data_cp.tree, BVHTREE_FROM_LOOPTRI); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				BLI_rw_mutex_unlock(&cache_rwlock); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2018-07-23 11:04:58 -03:00
										 |  |  | 		case BVHTREE_FROM_EM_VERTS: | 
					
						
							|  |  |  | 		case BVHTREE_FROM_EM_EDGES: | 
					
						
							|  |  |  | 		case BVHTREE_FROM_EM_LOOPTRI: | 
					
						
							|  |  |  | 			BLI_assert(false); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 	if (data_cp.tree != NULL) { | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 		if (BLI_bvhtree_get_tree_type(data_cp.tree) != tree_type) { | 
					
						
							|  |  |  | 			printf("tree_type %d obtained instead of %d\n", | 
					
						
							|  |  |  | 			       BLI_bvhtree_get_tree_type(data_cp.tree), tree_type); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 		data_cp.cached = true; | 
					
						
							|  |  |  | 		memcpy(data, &data_cp, sizeof(*data)); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 		free_bvhtree_from_mesh(&data_cp); | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | 		memset(data, 0, sizeof(*data)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 15:26:33 -03:00
										 |  |  | 	return data_cp.tree; | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:55:46 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | /* Frees data allocated by a call to bvhtree_from_editmesh_*. */ | 
					
						
							|  |  |  | void free_bvhtree_from_editmesh(struct BVHTreeFromEditMesh *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (data->tree) { | 
					
						
							| 
									
										
										
										
											2016-06-29 19:31:57 +10:00
										 |  |  | 		if (!data->cached) { | 
					
						
							|  |  |  | 			BLI_bvhtree_free(data->tree); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-05-06 04:49:21 +10:00
										 |  |  | 		memset(data, 0, sizeof(*data)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* Frees data allocated by a call to bvhtree_from_mesh_*. */ | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	if (data->tree && !data->cached) { | 
					
						
							|  |  |  | 		BLI_bvhtree_free(data->tree); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-10 17:21:39 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	if (data->vert_allocated) { | 
					
						
							|  |  |  | 		MEM_freeN((void *)data->vert); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-16 22:55:01 -03:00
										 |  |  | 	if (data->edge_allocated) { | 
					
						
							|  |  |  | 		MEM_freeN((void *)data->edge); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (data->face_allocated) { | 
					
						
							|  |  |  | 		MEM_freeN((void *)data->face); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (data->loop_allocated) { | 
					
						
							|  |  |  | 		MEM_freeN((void *)data->loop); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (data->looptri_allocated) { | 
					
						
							|  |  |  | 		MEM_freeN((void *)data->looptri); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(data, 0, sizeof(*data)); | 
					
						
							| 
									
										
										
										
											2008-08-11 13:29:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \name BVHCache
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2015-01-09 12:25:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 17:22:54 +00:00
										 |  |  | typedef struct BVHCacheItem { | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | 	int type; | 
					
						
							|  |  |  | 	BVHTree *tree; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } BVHCacheItem; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Queries a bvhcache for the cache bvhtree of the request type | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | bool bvhcache_find(const BVHCache *cache, int type, BVHTree **r_tree) | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | 	while (cache) { | 
					
						
							|  |  |  | 		const BVHCacheItem *item = cache->link; | 
					
						
							|  |  |  | 		if (item->type == type) { | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 			*r_tree = item->tree; | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		cache = cache->next; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 01:39:33 +10:00
										 |  |  | bool bvhcache_has_tree(const BVHCache *cache, const BVHTree *tree) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	while (cache) { | 
					
						
							|  |  |  | 		const BVHCacheItem *item = cache->link; | 
					
						
							|  |  |  | 		if (item->tree == tree) { | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cache = cache->next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Inserts a BVHTree of the given type under the cache | 
					
						
							|  |  |  |  * After that the caller no longer needs to worry when to free the BVHTree | 
					
						
							|  |  |  |  * as that will be done when the cache is freed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A call to this assumes that there was no previous cached tree of the given type | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void bvhcache_insert(BVHCache **cache_p, BVHTree *tree, int type) | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BVHCacheItem *item = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 19:43:36 -03:00
										 |  |  | 	assert(bvhcache_find(*cache_p, type, &(BVHTree *){0}) == false); | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	item = MEM_mallocN(sizeof(BVHCacheItem), "BVHCacheItem"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	item->type = type; | 
					
						
							|  |  |  | 	item->tree = tree; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | 	BLI_linklist_prepend(cache_p, item); | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-05-08 20:00:51 -03:00
										 |  |  |  * frees a bvhcache | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | static void bvhcacheitem_free(void *_item) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BVHCacheItem *item = (BVHCacheItem *)_item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_bvhtree_free(item->tree); | 
					
						
							|  |  |  | 	MEM_freeN(item); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | void bvhcache_free(BVHCache **cache_p) | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-12 01:37:01 +10:00
										 |  |  | 	BLI_linklist_free(*cache_p, (LinkNodeFreeFP)bvhcacheitem_free); | 
					
						
							|  |  |  | 	*cache_p = NULL; | 
					
						
							| 
									
										
										
										
											2009-05-23 03:24:15 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 20:35:33 +10:00
										 |  |  | /** \} */ |