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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h3
-rw-r--r--source/blender/blenkernel/BKE_mesh.h4
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c66
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c130
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h19
6 files changed, 223 insertions, 0 deletions
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 {