|
|
|
|
@@ -10,7 +10,7 @@
|
|
|
|
|
* \see bmesh_mesh_tessellate.c for the #BMesh equivalent of this file.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <climits>
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
@@ -120,13 +120,14 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
|
|
|
|
|
const uint totfilltri = mp_totloop - 2;
|
|
|
|
|
|
|
|
|
|
MemArena *pf_arena = *pf_arena_p;
|
|
|
|
|
if (UNLIKELY(pf_arena == NULL)) {
|
|
|
|
|
if (UNLIKELY(pf_arena == nullptr)) {
|
|
|
|
|
pf_arena = *pf_arena_p = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint(*tris)[3] = tris = BLI_memarena_alloc(pf_arena, sizeof(*tris) * (size_t)totfilltri);
|
|
|
|
|
float(*projverts)[2] = projverts = BLI_memarena_alloc(
|
|
|
|
|
pf_arena, sizeof(*projverts) * (size_t)mp_totloop);
|
|
|
|
|
uint(*tris)[3] = static_cast<uint(*)[3]>(
|
|
|
|
|
BLI_memarena_alloc(pf_arena, sizeof(*tris) * (size_t)totfilltri));
|
|
|
|
|
float(*projverts)[2] = static_cast<float(*)[2]>(
|
|
|
|
|
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * (size_t)mp_totloop));
|
|
|
|
|
|
|
|
|
|
ml = mloop + mp_loopstart;
|
|
|
|
|
for (uint j = 0; j < mp_totloop; j++, ml++) {
|
|
|
|
|
@@ -157,7 +158,7 @@ static void mesh_calc_tessellation_for_face(const MLoop *mloop,
|
|
|
|
|
MemArena **pf_arena_p)
|
|
|
|
|
{
|
|
|
|
|
mesh_calc_tessellation_for_face_impl(
|
|
|
|
|
mloop, mpoly, mvert, poly_index, mlt, pf_arena_p, false, NULL);
|
|
|
|
|
mloop, mpoly, mvert, poly_index, mlt, pf_arena_p, false, nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_calc_tessellation_for_face_with_normal(const MLoop *mloop,
|
|
|
|
|
@@ -180,11 +181,11 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
|
|
|
|
|
MLoopTri *mlooptri,
|
|
|
|
|
const float (*poly_normals)[3])
|
|
|
|
|
{
|
|
|
|
|
MemArena *pf_arena = NULL;
|
|
|
|
|
MemArena *pf_arena = nullptr;
|
|
|
|
|
const MPoly *mp = mpoly;
|
|
|
|
|
uint tri_index = 0;
|
|
|
|
|
|
|
|
|
|
if (poly_normals != NULL) {
|
|
|
|
|
if (poly_normals != nullptr) {
|
|
|
|
|
for (uint poly_index = 0; poly_index < (uint)totpoly; poly_index++, mp++) {
|
|
|
|
|
mesh_calc_tessellation_for_face_with_normal(mloop,
|
|
|
|
|
mpoly,
|
|
|
|
|
@@ -206,7 +207,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
|
|
|
|
|
|
|
|
|
|
if (pf_arena) {
|
|
|
|
|
BLI_memarena_free(pf_arena);
|
|
|
|
|
pf_arena = NULL;
|
|
|
|
|
pf_arena = nullptr;
|
|
|
|
|
}
|
|
|
|
|
BLI_assert(tri_index == (uint)poly_to_tri_count(totpoly, totloop));
|
|
|
|
|
UNUSED_VARS_NDEBUG(totloop);
|
|
|
|
|
@@ -232,8 +233,8 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata,
|
|
|
|
|
const int index,
|
|
|
|
|
const TaskParallelTLS *__restrict tls)
|
|
|
|
|
{
|
|
|
|
|
const struct TessellationUserData *data = userdata;
|
|
|
|
|
struct TessellationUserTLS *tls_data = tls->userdata_chunk;
|
|
|
|
|
const TessellationUserData *data = static_cast<const TessellationUserData *>(userdata);
|
|
|
|
|
TessellationUserTLS *tls_data = static_cast<TessellationUserTLS *>(tls->userdata_chunk);
|
|
|
|
|
const int tri_index = poly_to_tri_count(index, data->mpoly[index].loopstart);
|
|
|
|
|
mesh_calc_tessellation_for_face_impl(data->mloop,
|
|
|
|
|
data->mpoly,
|
|
|
|
|
@@ -242,15 +243,15 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata,
|
|
|
|
|
&data->mlooptri[tri_index],
|
|
|
|
|
&tls_data->pf_arena,
|
|
|
|
|
false,
|
|
|
|
|
NULL);
|
|
|
|
|
nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict userdata,
|
|
|
|
|
const int index,
|
|
|
|
|
const TaskParallelTLS *__restrict tls)
|
|
|
|
|
{
|
|
|
|
|
const struct TessellationUserData *data = userdata;
|
|
|
|
|
struct TessellationUserTLS *tls_data = tls->userdata_chunk;
|
|
|
|
|
const TessellationUserData *data = static_cast<const TessellationUserData *>(userdata);
|
|
|
|
|
TessellationUserTLS *tls_data = static_cast<TessellationUserTLS *>(tls->userdata_chunk);
|
|
|
|
|
const int tri_index = poly_to_tri_count(index, data->mpoly[index].loopstart);
|
|
|
|
|
mesh_calc_tessellation_for_face_impl(data->mloop,
|
|
|
|
|
data->mpoly,
|
|
|
|
|
@@ -265,7 +266,7 @@ static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict user
|
|
|
|
|
static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict UNUSED(userdata),
|
|
|
|
|
void *__restrict tls_v)
|
|
|
|
|
{
|
|
|
|
|
struct TessellationUserTLS *tls_data = tls_v;
|
|
|
|
|
TessellationUserTLS *tls_data = static_cast<TessellationUserTLS *>(tls_v);
|
|
|
|
|
if (tls_data->pf_arena) {
|
|
|
|
|
BLI_memarena_free(tls_data->pf_arena);
|
|
|
|
|
}
|
|
|
|
|
@@ -279,15 +280,14 @@ static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop,
|
|
|
|
|
MLoopTri *mlooptri,
|
|
|
|
|
const float (*poly_normals)[3])
|
|
|
|
|
{
|
|
|
|
|
struct TessellationUserTLS tls_data_dummy = {NULL};
|
|
|
|
|
struct TessellationUserTLS tls_data_dummy = {nullptr};
|
|
|
|
|
|
|
|
|
|
struct TessellationUserData data = {
|
|
|
|
|
.mloop = mloop,
|
|
|
|
|
.mpoly = mpoly,
|
|
|
|
|
.mvert = mvert,
|
|
|
|
|
.mlooptri = mlooptri,
|
|
|
|
|
.poly_normals = poly_normals,
|
|
|
|
|
};
|
|
|
|
|
struct TessellationUserData data {};
|
|
|
|
|
data.mloop = mloop;
|
|
|
|
|
data.mpoly = mpoly;
|
|
|
|
|
data.mvert = mvert;
|
|
|
|
|
data.mlooptri = mlooptri;
|
|
|
|
|
data.poly_normals = poly_normals;
|
|
|
|
|
|
|
|
|
|
TaskParallelSettings settings;
|
|
|
|
|
BLI_parallel_range_settings_defaults(&settings);
|
|
|
|
|
@@ -313,10 +313,10 @@ void BKE_mesh_recalc_looptri(const MLoop *mloop,
|
|
|
|
|
MLoopTri *mlooptri)
|
|
|
|
|
{
|
|
|
|
|
if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
|
|
|
|
|
mesh_recalc_looptri__single_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, NULL);
|
|
|
|
|
mesh_recalc_looptri__single_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, nullptr);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mesh_recalc_looptri__multi_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, NULL);
|
|
|
|
|
mesh_recalc_looptri__multi_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, nullptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -328,7 +328,7 @@ void BKE_mesh_recalc_looptri_with_normals(const MLoop *mloop,
|
|
|
|
|
MLoopTri *mlooptri,
|
|
|
|
|
const float (*poly_normals)[3])
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(poly_normals != NULL);
|
|
|
|
|
BLI_assert(poly_normals != nullptr);
|
|
|
|
|
if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
|
|
|
|
|
mesh_recalc_looptri__single_threaded(
|
|
|
|
|
mloop, mpoly, mvert, totloop, totpoly, mlooptri, poly_normals);
|