[Bf-blender-cvs] [abb58eec539] blender2.8: looptri + bvhtree support for Mesh

Sybren A. Stüvel noreply at git.blender.org
Tue May 8 11:47:55 CEST 2018


Commit: abb58eec5393820ee990926915c176664e205bab
Author: Sybren A. Stüvel
Date:   Tue May 8 10:07:21 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBabb58eec5393820ee990926915c176664e205bab

looptri + bvhtree support for Mesh

===================================================================

M	source/blender/blenkernel/BKE_bvhutils.h
M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/bvhutils.c
A	source/blender/blenkernel/intern/mesh_runtime.c
M	source/blender/makesdna/DNA_mesh_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 1b4bb08756b..1157e20d6ac 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -40,6 +40,7 @@
 
 struct DerivedMesh;
 struct BMEditMesh;
+struct Mesh;
 struct MVert;
 struct MFace;
 
@@ -142,6 +143,8 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(
         const BLI_bitmap *mask, int looptri_num_active,
         float epsilon, int tree_type, int axis, BVHCache **bvhCache);
 
+BVHTree *BKE_bvhtree_from_mesh_looptri(
+        struct BVHTreeFromMesh *data, struct Mesh *mesh, float epsilon, int tree_type, int axis);
 BVHTree *bvhtree_from_mesh_looptri_ex(
         struct BVHTreeFromMesh *data,
         const struct MVert *vert, const bool vert_allocated,
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 485132bfa6d..2adc1dbb6e3 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -182,7 +182,11 @@ int  BKE_mesh_mselect_find(struct Mesh *me, int index, int type);
 int  BKE_mesh_mselect_active_get(struct Mesh *me, int type);
 void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type);
 
+/* *** mesh_runtime.c *** */
 
+void BKE_mesh_runtime_recalc_looptri(struct Mesh *mesh);
+int BKE_mesh_get_looptri_num(struct Mesh *mesh);
+const struct MLoopTri *BKE_mesh_get_looptri_array(struct Mesh *mesh);
 
 /* *** mesh_evaluate.c *** */
 
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 9e241b7fa81..83241d3c4c7 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -143,6 +143,7 @@ set(SRC
 	intern/mesh_mapping.c
 	intern/mesh_merge.c
 	intern/mesh_remap.c
+	intern/mesh_runtime.c
 	intern/mesh_tangent.c
 	intern/mesh_validate.c
 	intern/modifier.c
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 0240bb4b624..00aa89b3776 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -34,6 +34,7 @@
 #include <math.h>
 #include <assert.h>
 
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "BLI_utildefines.h"
@@ -43,6 +44,7 @@
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_editmesh.h"
+#include "BKE_mesh.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -1161,6 +1163,70 @@ BVHTree *bvhtree_from_mesh_get(
 	return tree;
 }
 
+/* This is a Mesh-specific copy of bvhtree_from_mesh_looptri() */
+/**
+ * Builds a bvh tree where nodes are the looptri faces of the given mesh.
+ *
+ * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces
+ */
+BVHTree *BKE_bvhtree_from_mesh_looptri(
+        BVHTreeFromMesh *data, Mesh *mesh,
+        float epsilon, int tree_type, int axis)
+{
+	BVHTree *tree;
+	MVert *mvert = NULL;
+	MLoop *mloop = NULL;
+	const MLoopTri *looptri = NULL;
+
+	BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+	tree = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_LOOPTRI);
+	BLI_rw_mutex_unlock(&cache_rwlock);
+
+	mvert = mesh->mvert;
+	mloop = mesh->mloop;
+	looptri = BKE_mesh_get_looptri_array(mesh);
+
+	/* Not in cache */
+	if (tree == NULL) {
+		BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+		tree = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_LOOPTRI);
+		if (tree == NULL) {
+			int looptri_num = BKE_mesh_get_looptri_num(mesh);
+
+			/* this assert checks we have looptris,
+			 * if not caller should use DM_ensure_looptri() */
+			BLI_assert(!(looptri_num == 0 && mesh->totpoly != 0));
+
+			tree = bvhtree_from_mesh_looptri_create_tree(
+			        epsilon, tree_type, axis,
+			        mvert, mloop, looptri, looptri_num, NULL, -1);
+			if (tree) {
+				/* Save on cache for later use */
+				/* printf("BVHTree built and saved on cache\n"); */
+				bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_LOOPTRI);
+			}
+		}
+		BLI_rw_mutex_unlock(&cache_rwlock);
+	}
+	else {
+		/* printf("BVHTree is already build, using cached tree\n"); */
+	}
+
+	if (tree) {
+		/* Setup BVHTreeFromMesh */
+		bvhtree_from_mesh_looptri_setup_data(
+		        data, tree, true,
+		        mvert, false,
+		        mloop, false,
+		        looptri, false);
+	}
+	else {
+		memset(data, 0, sizeof(*data));
+	}
+
+	return tree;
+}
+
 /** \} */
 
 
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
new file mode 100644
index 00000000000..02caf454b7e
--- /dev/null
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -0,0 +1,130 @@
+/*
+ * ***** 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,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/mesh_runtime.c
+ *  \ingroup bke
+ */
+
+#include "atomic_ops.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_math_geom.h"
+#include "BLI_threads.h"
+
+#include "BKE_mesh.h"
+
+
+static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
+
+
+/* This is a ported copy of DM_ensure_looptri_data(dm) */
+/**
+ * Ensure the array is large enough
+ *
+ * /note This function must always be thread-protected by caller. It should only be used by internal code.
+ */
+static void mesh_ensure_looptri_data(Mesh *mesh)
+{
+	const unsigned int totpoly = mesh->totpoly;
+	const int looptris_num = poly_to_tri_count(totpoly, mesh->totloop);
+
+	BLI_assert(mesh->runtime.looptris.array_wip == NULL);
+
+	SWAP(MLoopTri *, mesh->runtime.looptris.array, mesh->runtime.looptris.array_wip);
+
+	if ((looptris_num > mesh->runtime.looptris.num_alloc) ||
+	    (looptris_num < mesh->runtime.looptris.num_alloc * 2) ||
+	    (totpoly == 0))
+	{
+		MEM_SAFE_FREE(mesh->runtime.looptris.array_wip);
+		mesh->runtime.looptris.num_alloc = 0;
+		mesh->runtime.looptris.num = 0;
+	}
+
+	if (totpoly) {
+		if (mesh->runtime.looptris.array_wip == NULL) {
+			mesh->runtime.looptris.array_wip = MEM_malloc_arrayN(looptris_num, sizeof(*mesh->runtime.looptris.array_wip), __func__);
+			mesh->runtime.looptris.num_alloc = looptris_num;
+		}
+
+		mesh->runtime.looptris.num = looptris_num;
+	}
+}
+
+/* This is a ported copy of CDDM_recalc_looptri(dm). */
+void BKE_mesh_runtime_recalc_looptri(Mesh *mesh)
+{
+	mesh_ensure_looptri_data(mesh);
+	BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != NULL);
+
+	BKE_mesh_recalc_looptri(
+	        mesh->mloop, mesh->mpoly,
+	        mesh->mvert,
+	        mesh->totloop, mesh->totpoly,
+	        mesh->runtime.looptris.array_wip);
+
+	BLI_assert(mesh->runtime.looptris.array == NULL);
+	atomic_cas_ptr((void **)&mesh->runtime.looptris.array, mesh->runtime.looptris.array, mesh->runtime.looptris.array_wip);
+	mesh->runtime.looptris.array_wip = NULL;
+}
+
+/* This is a ported copy of dm_getNumLoopTri(dm). */
+int BKE_mesh_get_looptri_num(Mesh *mesh)
+{
+	const int numlooptris = poly_to_tri_count(mesh->totpoly, mesh->totloop);
+	BLI_assert(ELEM(mesh->runtime.looptris.num, 0, numlooptris));
+	return numlooptris;
+}
+
+/* This is a ported copy of dm_getLoopTriArray(dm). */
+const MLoopTri *BKE_mesh_get_looptri_array(Mesh *mesh)
+{
+	MLoopTri *looptri;
+
+	BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_READ);
+	looptri = mesh->runtime.looptris.array;
+	BLI_rw_mutex_unlock(&loops_cache_lock);
+
+	if (looptri != NULL) {
+		BLI_assert(BKE_mesh_get_looptri_num(mesh) == mesh->runtime.looptris.num);
+	}
+	else {
+		BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_WRITE);
+		/* We need to ensure array is still NULL inside mutex-protected code, some other thread might have already
+		 * recomputed those looptris. */
+		if (mesh->runtime.looptris.array == NULL) {
+			BKE_mesh_runtime_recalc_looptri(mesh);
+		}
+		looptri = mesh->runtime.looptris.array;
+		BLI_rw_mutex_unlock(&loops_cache_lock);
+	}
+	return looptri;
+}
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index d951f67a7c4..af81ac8423b 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -39,11 +39,13 @@
 struct AnimData;
 struct Ipo;
 struct Key;
+struct LinkNode;
 struct MCol;
 struct MEdge;
 struct MFace;
 struct MLoop;
 struct MLoopCol;
+struct MLoopTri;
 struct MLoopUV;
 struct MPoly;
 struct MTexPoly;
@@ -65,6 +67,18 @@ typedef struct EditMeshData {
 	const float (*polyCos)[3];
 } EditMeshData;
 
+
+/**
+ * \warning Typical access is done via #BKE_mesh_get_looptri_array, #BKE_mesh_get_looptri_num.
+ */
+struct LooptrisData {
+	/* WARNING! swapping between array (ready-to-be-used data) and array_wip (where data is actually computed)
+	 *          shall always be protected by same lock as one used for looptris computing. */
+	struct MLoopTri *array, *array_wip;
+	int num;
+	int num_alloc;
+};
+
 /* not saved in file! */
 typedef struct MeshRuntime {
 	struct EditMeshData *edit_data;
@@ -74,6 +88,11 @@ typedef struct MeshRuntime {
 	int64_t cd_dirty_edge;
 	int64_t cd_dirty_loop;
 	int64_t cd_dirty_poly;
+
+	struct LooptrisData looptris;
+
+	/** 'BVHCache', for 'BKE_bvhutil.c' */
+	struct LinkNode *bvh_cache;
 } MeshRuntime;
 
 typedef struct Mesh {



More information about the Bf-blender-cvs mailing list