forked from blender/blender
main sync #3
@ -19,6 +19,7 @@
|
|||||||
# include "BLI_math_vector_types.hh"
|
# include "BLI_math_vector_types.hh"
|
||||||
# include "BLI_shared_cache.hh"
|
# include "BLI_shared_cache.hh"
|
||||||
# include "BLI_span.hh"
|
# include "BLI_span.hh"
|
||||||
|
# include "BLI_vector.hh"
|
||||||
|
|
||||||
# include "DNA_customdata_types.h"
|
# include "DNA_customdata_types.h"
|
||||||
# include "DNA_meshdata_types.h"
|
# include "DNA_meshdata_types.h"
|
||||||
@ -158,8 +159,8 @@ struct MeshRuntime {
|
|||||||
*/
|
*/
|
||||||
bool vert_normals_dirty = true;
|
bool vert_normals_dirty = true;
|
||||||
bool poly_normals_dirty = true;
|
bool poly_normals_dirty = true;
|
||||||
float (*vert_normals)[3] = nullptr;
|
mutable Vector<float3> vert_normals;
|
||||||
float (*poly_normals)[3] = nullptr;
|
mutable Vector<float3> poly_normals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cache of data about the loose edges. Can be shared with other data-blocks with unchanged
|
* A cache of data about the loose edges. Can be shared with other data-blocks with unchanged
|
||||||
|
@ -102,38 +102,26 @@ static void add_v3_v3_atomic(float r[3], const float a[3])
|
|||||||
|
|
||||||
float (*BKE_mesh_vert_normals_for_write(Mesh *mesh))[3]
|
float (*BKE_mesh_vert_normals_for_write(Mesh *mesh))[3]
|
||||||
{
|
{
|
||||||
if (mesh->runtime->vert_normals == nullptr) {
|
mesh->runtime->vert_normals.reinitialize(mesh->totvert);
|
||||||
mesh->runtime->vert_normals = (float(*)[3])MEM_malloc_arrayN(
|
return reinterpret_cast<float(*)[3]>(mesh->runtime->vert_normals.data());
|
||||||
mesh->totvert, sizeof(float[3]), __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
BLI_assert(MEM_allocN_len(mesh->runtime->vert_normals) >= sizeof(float[3]) * mesh->totvert);
|
|
||||||
|
|
||||||
return mesh->runtime->vert_normals;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
|
float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
|
||||||
{
|
{
|
||||||
if (mesh->runtime->poly_normals == nullptr) {
|
mesh->runtime->poly_normals.reinitialize(mesh->totpoly);
|
||||||
mesh->runtime->poly_normals = (float(*)[3])MEM_malloc_arrayN(
|
return reinterpret_cast<float(*)[3]>(mesh->runtime->poly_normals.data());
|
||||||
mesh->totpoly, sizeof(float[3]), __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
BLI_assert(MEM_allocN_len(mesh->runtime->poly_normals) >= sizeof(float[3]) * mesh->totpoly);
|
|
||||||
|
|
||||||
return mesh->runtime->poly_normals;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_mesh_vert_normals_clear_dirty(Mesh *mesh)
|
void BKE_mesh_vert_normals_clear_dirty(Mesh *mesh)
|
||||||
{
|
{
|
||||||
mesh->runtime->vert_normals_dirty = false;
|
mesh->runtime->vert_normals_dirty = false;
|
||||||
BLI_assert(mesh->runtime->vert_normals || mesh->totvert == 0);
|
BLI_assert(mesh->runtime->vert_normals.size() == mesh->totvert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
|
void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
|
||||||
{
|
{
|
||||||
mesh->runtime->poly_normals_dirty = false;
|
mesh->runtime->poly_normals_dirty = false;
|
||||||
BLI_assert(mesh->runtime->poly_normals || mesh->totpoly == 0);
|
BLI_assert(mesh->runtime->poly_normals.size() == mesh->totpoly);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BKE_mesh_vert_normals_are_dirty(const Mesh *mesh)
|
bool BKE_mesh_vert_normals_are_dirty(const Mesh *mesh)
|
||||||
@ -341,9 +329,9 @@ void normals_calc_poly_vert(const Span<float3> positions,
|
|||||||
|
|
||||||
const float (*BKE_mesh_vert_normals_ensure(const Mesh *mesh))[3]
|
const float (*BKE_mesh_vert_normals_ensure(const Mesh *mesh))[3]
|
||||||
{
|
{
|
||||||
if (!BKE_mesh_vert_normals_are_dirty(mesh)) {
|
if (!mesh->runtime->vert_normals_dirty) {
|
||||||
BLI_assert(mesh->runtime->vert_normals != nullptr || mesh->totvert == 0);
|
BLI_assert(mesh->runtime->vert_normals.size() == mesh->totvert);
|
||||||
return mesh->runtime->vert_normals;
|
return reinterpret_cast<const float(*)[3]>(mesh->runtime->vert_normals.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->totvert == 0) {
|
if (mesh->totvert == 0) {
|
||||||
@ -351,42 +339,34 @@ const float (*BKE_mesh_vert_normals_ensure(const Mesh *mesh))[3]
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock{mesh->runtime->normals_mutex};
|
std::lock_guard lock{mesh->runtime->normals_mutex};
|
||||||
if (!BKE_mesh_vert_normals_are_dirty(mesh)) {
|
if (!mesh->runtime->vert_normals_dirty) {
|
||||||
BLI_assert(mesh->runtime->vert_normals != nullptr);
|
BLI_assert(mesh->runtime->vert_normals.size() == mesh->totvert);
|
||||||
return mesh->runtime->vert_normals;
|
return reinterpret_cast<const float(*)[3]>(mesh->runtime->vert_normals.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
float(*vert_normals)[3];
|
|
||||||
float(*poly_normals)[3];
|
|
||||||
|
|
||||||
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
|
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
|
||||||
blender::threading::isolate_task([&]() {
|
blender::threading::isolate_task([&]() {
|
||||||
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
|
const Span<float3> positions = mesh->vert_positions();
|
||||||
const Span<float3> positions = mesh_mutable.vert_positions();
|
const Span<MPoly> polys = mesh->polys();
|
||||||
const Span<MPoly> polys = mesh_mutable.polys();
|
const Span<MLoop> loops = mesh->loops();
|
||||||
const Span<MLoop> loops = mesh_mutable.loops();
|
|
||||||
|
|
||||||
vert_normals = BKE_mesh_vert_normals_for_write(&mesh_mutable);
|
mesh->runtime->vert_normals.reinitialize(positions.size());
|
||||||
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
|
mesh->runtime->poly_normals.reinitialize(polys.size());
|
||||||
blender::bke::mesh::normals_calc_poly_vert(
|
blender::bke::mesh::normals_calc_poly_vert(
|
||||||
positions,
|
positions, polys, loops, mesh->runtime->poly_normals, mesh->runtime->vert_normals);
|
||||||
polys,
|
|
||||||
loops,
|
|
||||||
{reinterpret_cast<float3 *>(poly_normals), mesh->totpoly},
|
|
||||||
{reinterpret_cast<float3 *>(vert_normals), mesh->totvert});
|
|
||||||
|
|
||||||
BKE_mesh_vert_normals_clear_dirty(&mesh_mutable);
|
mesh->runtime->vert_normals_dirty = false;
|
||||||
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
|
mesh->runtime->poly_normals_dirty = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return vert_normals;
|
return reinterpret_cast<const float(*)[3]>(mesh->runtime->vert_normals.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
|
const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
|
||||||
{
|
{
|
||||||
if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
|
if (!mesh->runtime->poly_normals_dirty) {
|
||||||
BLI_assert(mesh->runtime->poly_normals != nullptr || mesh->totpoly == 0);
|
BLI_assert(mesh->runtime->poly_normals.size() == mesh->totpoly);
|
||||||
return mesh->runtime->poly_normals;
|
return reinterpret_cast<const float(*)[3]>(mesh->runtime->poly_normals.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->totpoly == 0) {
|
if (mesh->totpoly == 0) {
|
||||||
@ -394,28 +374,24 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock{mesh->runtime->normals_mutex};
|
std::lock_guard lock{mesh->runtime->normals_mutex};
|
||||||
if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
|
if (!mesh->runtime->poly_normals_dirty) {
|
||||||
BLI_assert(mesh->runtime->poly_normals != nullptr);
|
BLI_assert(mesh->runtime->poly_normals.size() == mesh->totpoly);
|
||||||
return mesh->runtime->poly_normals;
|
return reinterpret_cast<const float(*)[3]>(mesh->runtime->poly_normals.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
float(*poly_normals)[3];
|
|
||||||
|
|
||||||
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
|
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
|
||||||
blender::threading::isolate_task([&]() {
|
blender::threading::isolate_task([&]() {
|
||||||
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
|
const Span<float3> positions = mesh->vert_positions();
|
||||||
const Span<float3> positions = mesh_mutable.vert_positions();
|
const Span<MPoly> polys = mesh->polys();
|
||||||
const Span<MPoly> polys = mesh_mutable.polys();
|
const Span<MLoop> loops = mesh->loops();
|
||||||
const Span<MLoop> loops = mesh_mutable.loops();
|
|
||||||
|
|
||||||
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
|
mesh->runtime->poly_normals.reinitialize(polys.size());
|
||||||
blender::bke::mesh::normals_calc_polys(
|
blender::bke::mesh::normals_calc_polys(positions, polys, loops, mesh->runtime->poly_normals);
|
||||||
positions, polys, loops, {reinterpret_cast<float3 *>(poly_normals), mesh->totpoly});
|
|
||||||
|
|
||||||
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
|
mesh->runtime->poly_normals_dirty = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return poly_normals;
|
return reinterpret_cast<const float(*)[3]>(mesh->runtime->poly_normals.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
|
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
|
||||||
|
@ -78,10 +78,10 @@ static void free_bvh_cache(MeshRuntime &mesh_runtime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_normals(MeshRuntime &mesh_runtime)
|
static void reset_normals(MeshRuntime &mesh_runtime)
|
||||||
{
|
{
|
||||||
MEM_SAFE_FREE(mesh_runtime.vert_normals);
|
mesh_runtime.vert_normals.clear_and_shrink();
|
||||||
MEM_SAFE_FREE(mesh_runtime.poly_normals);
|
mesh_runtime.poly_normals.clear_and_shrink();
|
||||||
mesh_runtime.vert_normals_dirty = true;
|
mesh_runtime.vert_normals_dirty = true;
|
||||||
mesh_runtime.poly_normals_dirty = true;
|
mesh_runtime.poly_normals_dirty = true;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,6 @@ MeshRuntime::~MeshRuntime()
|
|||||||
free_bvh_cache(*this);
|
free_bvh_cache(*this);
|
||||||
free_edit_data(*this);
|
free_edit_data(*this);
|
||||||
free_batch_cache(*this);
|
free_batch_cache(*this);
|
||||||
free_normals(*this);
|
|
||||||
if (this->shrinkwrap_data) {
|
if (this->shrinkwrap_data) {
|
||||||
BKE_shrinkwrap_boundary_data_free(this->shrinkwrap_data);
|
BKE_shrinkwrap_boundary_data_free(this->shrinkwrap_data);
|
||||||
}
|
}
|
||||||
@ -216,7 +215,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
|
|||||||
{
|
{
|
||||||
/* Tagging shared caches dirty will free the allocated data if there is only one user. */
|
/* Tagging shared caches dirty will free the allocated data if there is only one user. */
|
||||||
free_bvh_cache(*mesh->runtime);
|
free_bvh_cache(*mesh->runtime);
|
||||||
free_normals(*mesh->runtime);
|
reset_normals(*mesh->runtime);
|
||||||
free_subdiv_ccg(*mesh->runtime);
|
free_subdiv_ccg(*mesh->runtime);
|
||||||
mesh->runtime->bounds_cache.tag_dirty();
|
mesh->runtime->bounds_cache.tag_dirty();
|
||||||
mesh->runtime->loose_edges_cache.tag_dirty();
|
mesh->runtime->loose_edges_cache.tag_dirty();
|
||||||
@ -234,7 +233,7 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh)
|
|||||||
* Face normals didn't change either, but tag those anyway, since there is no API function to
|
* Face normals didn't change either, but tag those anyway, since there is no API function to
|
||||||
* only tag vertex normals dirty. */
|
* only tag vertex normals dirty. */
|
||||||
free_bvh_cache(*mesh->runtime);
|
free_bvh_cache(*mesh->runtime);
|
||||||
free_normals(*mesh->runtime);
|
reset_normals(*mesh->runtime);
|
||||||
free_subdiv_ccg(*mesh->runtime);
|
free_subdiv_ccg(*mesh->runtime);
|
||||||
mesh->runtime->loose_edges_cache.tag_dirty();
|
mesh->runtime->loose_edges_cache.tag_dirty();
|
||||||
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
|
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
|
||||||
|
@ -1114,13 +1114,6 @@ bool BKE_mesh_is_valid(Mesh *me)
|
|||||||
do_fixes,
|
do_fixes,
|
||||||
&changed);
|
&changed);
|
||||||
|
|
||||||
if (!me->runtime->vert_normals_dirty) {
|
|
||||||
BLI_assert(me->runtime->vert_normals || me->totvert == 0);
|
|
||||||
}
|
|
||||||
if (!me->runtime->poly_normals_dirty) {
|
|
||||||
BLI_assert(me->runtime->poly_normals || me->totpoly == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BLI_assert(changed == false);
|
BLI_assert(changed == false);
|
||||||
|
|
||||||
return is_valid;
|
return is_valid;
|
||||||
|
Loading…
Reference in New Issue
Block a user