diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-05-08 11:07:21 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-05-08 12:36:48 +0300 |
commit | abb58eec5393820ee990926915c176664e205bab (patch) | |
tree | a9555705ae68ac6c2f9d9f22b60215003504769a /source/blender/blenkernel/intern/mesh_runtime.c | |
parent | d915aa57f8ecc0f6fee7334f140f5bbf7c913f6f (diff) |
looptri + bvhtree support for Mesh
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_runtime.c')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_runtime.c | 130 |
1 files changed, 130 insertions, 0 deletions
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; +} |