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:
authorHans Goudey <h.goudey@me.com>2022-11-12 07:56:44 +0300
committerHans Goudey <h.goudey@me.com>2022-11-12 08:27:36 +0300
commit1a8516163fa921e857b17ff152cc5264ab42b898 (patch)
treecaa9e4e6a661b959a2728328d3837c4c1aa2502d
parentd63ada602d37e5bf0f4f4c7984c538fcfed5bf39 (diff)
Cleanup: Simplify handling of loop to poly map in normal calculation
A Loop to poly map was passed as an optional output to the loop normal calculation. That meant it was often recalculated more than necessary. Instead, treat it as an optional argument. This also helps relieve unnecessary responsibilities from the already-complicated loop normal calculation code.
-rw-r--r--source/blender/blenkernel/BKE_mesh.h6
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c4
-rw-r--r--source/blender/blenkernel/intern/key.c4
-rw-r--r--source/blender/blenkernel/intern/mesh.cc4
-rw-r--r--source/blender/blenkernel/intern/mesh_mirror.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_normals.cc55
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c4
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc4
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.cc4
-rw-r--r--source/blender/modifiers/intern/MOD_weighted_normal.cc35
10 files changed, 61 insertions, 63 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index bb0b4467bd2..b1488c93ba6 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -621,6 +621,8 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space,
* Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry
* (splitting edges).
+ *
+ * \param loop_to_poly_map: Optional pre-created map from loops to their polygon.
*/
void BKE_mesh_normals_loop_split(const struct MVert *mverts,
const float (*vert_normals)[3],
@@ -635,9 +637,9 @@ void BKE_mesh_normals_loop_split(const struct MVert *mverts,
int numPolys,
bool use_split_normals,
float split_angle,
+ const int *loop_to_poly_map,
MLoopNorSpaceArray *r_lnors_spacearr,
- short (*clnors_data)[2],
- int *r_loop_to_poly);
+ short (*clnors_data)[2]);
void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts,
const float (*vert_normals)[3],
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index e6afca11b40..7b81f74206d 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -300,8 +300,8 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
use_split_nors_dst,
split_angle_dst,
NULL,
- custom_nors_dst,
- NULL);
+ NULL,
+ custom_nors_dst);
}
}
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 2ba81c54872..53147c94f43 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -2296,8 +2296,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
(mesh->flag & ME_AUTOSMOOTH) != 0,
mesh->smoothresh,
NULL,
- clnors,
- NULL);
+ NULL,
+ clnors);
}
if (free_vert_normals) {
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 2d613f24a0a..b8658139161 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -1829,9 +1829,9 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
polys.size(),
use_split_normals,
split_angle,
+ nullptr,
r_lnors_spacearr,
- clnors,
- nullptr);
+ clnors);
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
}
diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c
index ce3fc5d99c8..9f00d8860b8 100644
--- a/source/blender/blenkernel/intern/mesh_mirror.c
+++ b/source/blender/blenkernel/intern/mesh_mirror.c
@@ -418,9 +418,9 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
totpoly,
true,
mesh->smoothresh,
+ NULL,
&lnors_spacearr,
- clnors,
- NULL);
+ clnors);
/* mirroring has to account for loops being reversed in polys in second half */
MPoly *result_polys = BKE_mesh_polys_for_write(result);
diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc
index 510301b7192..404357bda8d 100644
--- a/source/blender/blenkernel/intern/mesh_normals.cc
+++ b/source/blender/blenkernel/intern/mesh_normals.cc
@@ -33,6 +33,7 @@
#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "atomic_ops.h"
@@ -816,7 +817,7 @@ struct LoopSplitTaskDataCommon {
Span<MLoop> loops;
Span<MPoly> polys;
int (*edge_to_loops)[2];
- MutableSpan<int> loop_to_poly;
+ Span<int> loop_to_poly;
Span<float3> polynors;
Span<float3> vert_normals;
};
@@ -834,12 +835,12 @@ static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data,
MutableSpan<MEdge> edges = data->edges;
const Span<MPoly> polys = data->polys;
const Span<MLoop> loops = data->loops;
+ const Span<int> loop_to_poly = data->loop_to_poly;
MutableSpan<float3> loopnors = data->loopnors; /* NOTE: loopnors may be empty here. */
const Span<float3> polynors = data->polynors;
int(*edge_to_loops)[2] = data->edge_to_loops;
- MutableSpan<int> loop_to_poly = data->loop_to_poly;
BitVector sharp_edges;
if (do_sharp_edges_tag) {
@@ -859,8 +860,6 @@ static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data,
for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) {
e2l = edge_to_loops[ml_curr->e];
- loop_to_poly[ml_curr_index] = mp_index;
-
/* Pre-populate all loop normals as if their verts were all-smooth,
* this way we don't have to compute those later!
*/
@@ -935,6 +934,8 @@ void BKE_edges_sharp_from_angle_set(const MVert *mverts,
const int numPolys,
const float split_angle)
{
+ using namespace blender;
+ using namespace blender::bke;
if (split_angle >= float(M_PI)) {
/* Nothing to do! */
return;
@@ -945,7 +946,8 @@ void BKE_edges_sharp_from_angle_set(const MVert *mverts,
size_t(numEdges), sizeof(*edge_to_loops), __func__);
/* Simple mapping from a loop to its polygon index. */
- int *loop_to_poly = (int *)MEM_malloc_arrayN(size_t(numLoops), sizeof(*loop_to_poly), __func__);
+ const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map({mpolys, numPolys},
+ numLoops);
LoopSplitTaskDataCommon common_data = {};
common_data.verts = {mverts, numVerts};
@@ -953,13 +955,12 @@ void BKE_edges_sharp_from_angle_set(const MVert *mverts,
common_data.polys = {mpolys, numPolys};
common_data.loops = {mloops, numLoops};
common_data.edge_to_loops = edge_to_loops;
- common_data.loop_to_poly = {loop_to_poly, numLoops};
+ common_data.loop_to_poly = loop_to_poly;
common_data.polynors = {reinterpret_cast<const float3 *>(polynors), numPolys};
mesh_edges_sharp_tag(&common_data, true, split_angle, true);
MEM_freeN(edge_to_loops);
- MEM_freeN(loop_to_poly);
}
static void loop_manifold_fan_around_vert_next(const Span<MLoop> loops,
@@ -1564,10 +1565,12 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
const int numPolys,
const bool use_split_normals,
const float split_angle,
+ const int *loop_to_poly_map,
MLoopNorSpaceArray *r_lnors_spacearr,
- short (*clnors_data)[2],
- int *r_loop_to_poly)
+ short (*clnors_data)[2])
{
+ using namespace blender;
+ using namespace blender::bke;
/* For now this is not supported.
* If we do not use split normals, we do not generate anything fancy! */
BLI_assert(use_split_normals || !(r_lnors_spacearr));
@@ -1588,9 +1591,6 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
for (; ml_index < ml_index_end; ml_index++) {
- if (r_loop_to_poly) {
- r_loop_to_poly[ml_index] = mp_index;
- }
if (is_poly_flat) {
copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
}
@@ -1620,9 +1620,15 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
size_t(numEdges), sizeof(*edge_to_loops), __func__);
/* Simple mapping from a loop to its polygon index. */
- int *loop_to_poly = r_loop_to_poly ? r_loop_to_poly :
- (int *)MEM_malloc_arrayN(
- size_t(numLoops), sizeof(*loop_to_poly), __func__);
+ Span<int> loop_to_poly;
+ Array<int> local_loop_to_poly_map;
+ if (loop_to_poly_map) {
+ loop_to_poly = {loop_to_poly_map, numLoops};
+ }
+ else {
+ local_loop_to_poly_map = mesh_topology::build_loop_to_poly_map({mpolys, numPolys}, numLoops);
+ loop_to_poly = local_loop_to_poly_map;
+ }
/* When using custom loop normals, disable the angle feature! */
const bool check_angle = (split_angle < float(M_PI)) && (clnors_data == nullptr);
@@ -1651,7 +1657,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
common_data.polys = {mpolys, numPolys};
common_data.loops = {mloops, numLoops};
common_data.edge_to_loops = edge_to_loops;
- common_data.loop_to_poly = {loop_to_poly, numLoops};
+ common_data.loop_to_poly = loop_to_poly;
common_data.polynors = {reinterpret_cast<const float3 *>(polynors), numPolys};
common_data.vert_normals = {reinterpret_cast<const float3 *>(vert_normals), numVerts};
@@ -1673,9 +1679,6 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
}
MEM_freeN(edge_to_loops);
- if (!r_loop_to_poly) {
- MEM_freeN(loop_to_poly);
- }
if (r_lnors_spacearr) {
if (r_lnors_spacearr == &_lnors_spacearr) {
@@ -1711,6 +1714,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
short (*r_clnors_data)[2],
const bool use_vertices)
{
+ using namespace blender;
+ using namespace blender::bke;
/* We *may* make that poor #BKE_mesh_normals_loop_split() even more complex by making it handling
* that feature too, would probably be more efficient in absolute.
* However, this function *is not* performance-critical, since it is mostly expected to be called
@@ -1720,7 +1725,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
MLoopNorSpaceArray lnors_spacearr = {nullptr};
BitVector<> done_loops(numLoops, false);
float(*lnors)[3] = (float(*)[3])MEM_calloc_arrayN(size_t(numLoops), sizeof(*lnors), __func__);
- int *loop_to_poly = (int *)MEM_malloc_arrayN(size_t(numLoops), sizeof(int), __func__);
+ const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map({mpolys, numPolys},
+ numLoops);
/* In this case we always consider split nors as ON,
* and do not want to use angle to define smooth fans! */
const bool use_split_normals = true;
@@ -1742,9 +1748,9 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
numPolys,
use_split_normals,
split_angle,
+ loop_to_poly.data(),
&lnors_spacearr,
- nullptr,
- loop_to_poly);
+ nullptr);
/* Set all given zero vectors to their default value. */
if (use_vertices) {
@@ -1865,9 +1871,9 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
numPolys,
use_split_normals,
split_angle,
+ loop_to_poly.data(),
&lnors_spacearr,
- nullptr,
- loop_to_poly);
+ nullptr);
}
else {
done_loops.fill(true);
@@ -1929,7 +1935,6 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
}
MEM_freeN(lnors);
- MEM_freeN(loop_to_poly);
BKE_lnor_spacearr_free(&lnors_spacearr);
}
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 90798ea593d..d96cd54e198 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1372,8 +1372,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
use_split_nors_dst,
split_angle_dst,
NULL,
- custom_nors_dst,
- NULL);
+ NULL,
+ custom_nors_dst);
}
}
if (need_pnors_src || need_lnors_src) {
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
index f606701ed09..1f5157e6b8b 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
@@ -376,8 +376,8 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
is_auto_smooth,
split_angle,
nullptr,
- clnors,
- nullptr);
+ nullptr,
+ clnors);
}
}
else {
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc
index 7d422826cf8..29404fb044a 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.cc
+++ b/source/blender/modifiers/intern/MOD_normal_edit.cc
@@ -563,8 +563,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
true,
result->smoothresh,
nullptr,
- clnors,
- nullptr);
+ nullptr,
+ clnors);
}
if (clnors == nullptr) {
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc
index 1ebd5423d39..9d2460be2be 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.cc
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc
@@ -23,6 +23,7 @@
#include "BKE_deform.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "BKE_screen.h"
#include "UI_interface.h"
@@ -76,6 +77,7 @@ struct WeightedNormalData {
MEdge *medge;
const MLoop *mloop;
+ blender::Span<int> loop_to_poly;
short (*clnors)[2];
bool has_clnors; /* True if clnors already existed, false if we had to create them. */
float split_angle;
@@ -97,8 +99,6 @@ struct WeightedNormalData {
WeightedNormalDataAggregateItem *items_data;
ModePair *mode_pair;
-
- int *loop_to_poly;
};
/**
@@ -181,6 +181,7 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd,
static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
WeightedNormalData *wn_data)
{
+ using namespace blender;
const int verts_num = wn_data->verts_num;
const int edges_num = wn_data->edges_num;
const int loops_num = wn_data->loops_num;
@@ -191,7 +192,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
const MLoop *mloop = wn_data->mloop;
short(*clnors)[2] = wn_data->clnors;
- int *loop_to_poly = wn_data->loop_to_poly;
+ const Span<int> loop_to_poly = wn_data->loop_to_poly;
const MPoly *mpoly = wn_data->mpoly;
const float(*polynors)[3] = wn_data->polynors;
@@ -235,9 +236,9 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
polys_num,
true,
split_angle,
+ loop_to_poly.data(),
&lnors_spacearr,
- has_clnors ? clnors : nullptr,
- loop_to_poly);
+ has_clnors ? clnors : nullptr);
items_num = lnors_spacearr.spaces_num;
items_data = static_cast<WeightedNormalDataAggregateItem *>(
@@ -315,8 +316,6 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
break;
case MOD_WEIGHTEDNORMAL_MODE_ANGLE:
case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
- BLI_assert(loop_to_poly != nullptr);
-
for (int i = 0; i < loops_num; i++) {
const int ml_index = mode_pair[i].index;
const float ml_val = mode_pair[i].val;
@@ -419,9 +418,9 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
polys_num,
true,
split_angle,
+ loop_to_poly.data(),
nullptr,
- has_clnors ? clnors : nullptr,
- loop_to_poly);
+ has_clnors ? clnors : nullptr);
for (int ml_index = 0; ml_index < loops_num; ml_index++) {
const int item_index = mloop[ml_index].v;
@@ -489,9 +488,6 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData
const MPoly *mp;
int mp_index;
- int *loop_to_poly = static_cast<int *>(
- MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_to_poly), __func__));
-
ModePair *corner_angle = static_cast<ModePair *>(
MEM_malloc_arrayN(size_t(loops_num), sizeof(*corner_angle), __func__));
@@ -508,15 +504,12 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData
ml_index++, c_angl++, angl++) {
c_angl->val = float(M_PI) - *angl;
c_angl->index = ml_index;
-
- loop_to_poly[ml_index] = mp_index;
}
MEM_freeN(index_angle);
}
qsort(corner_angle, loops_num, sizeof(*corner_angle), modepair_cmp_by_val_inverse);
- wn_data->loop_to_poly = loop_to_poly;
wn_data->mode_pair = corner_angle;
apply_weights_vertex_normal(wnmd, wn_data);
}
@@ -533,9 +526,6 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD
const MPoly *mp;
int mp_index;
- int *loop_to_poly = static_cast<int *>(
- MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_to_poly), __func__));
-
ModePair *combined = static_cast<ModePair *>(
MEM_malloc_arrayN(size_t(loops_num), sizeof(*combined), __func__));
@@ -554,21 +544,19 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD
/* In this case val is product of corner angle and face area. */
cmbnd->val = (float(M_PI) - *angl) * face_area;
cmbnd->index = ml_index;
-
- loop_to_poly[ml_index] = mp_index;
}
MEM_freeN(index_angle);
}
qsort(combined, loops_num, sizeof(*combined), modepair_cmp_by_val_inverse);
- wn_data->loop_to_poly = loop_to_poly;
wn_data->mode_pair = combined;
apply_weights_vertex_normal(wnmd, wn_data);
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
+ using namespace blender;
WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
Object *ob = ctx->object;
@@ -633,6 +621,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
int defgrp_index;
MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index);
+ const Array<int> loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(result->polys(),
+ result->totloop);
+
WeightedNormalData wn_data{};
wn_data.verts_num = verts_num;
wn_data.edges_num = edges_num;
@@ -644,6 +635,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
wn_data.medge = medge;
wn_data.mloop = mloop;
+ wn_data.loop_to_poly = loop_to_poly_map;
wn_data.clnors = clnors;
wn_data.has_clnors = has_clnors;
wn_data.split_angle = split_angle;
@@ -672,7 +664,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
break;
}
- MEM_SAFE_FREE(wn_data.loop_to_poly);
MEM_SAFE_FREE(wn_data.mode_pair);
MEM_SAFE_FREE(wn_data.items_data);