Mesh: Reduce custom normal calculation memory usage #107592

Merged
Hans Goudey merged 32 commits from HooglyBoogly/blender:corner-normals-refactor-storage into main 2023-05-10 14:41:16 +02:00
2 changed files with 37 additions and 39 deletions
Showing only changes of commit 39ba2bc5d9 - Show all commits

View File

@ -908,7 +908,8 @@ static void lnor_space_for_single_fan(LoopSplitTaskDataCommon *common_data,
const Span<int> corner_edges = common_data->corner_edges;
const Span<short2> clnors_data = common_data->clnors_data;
float vec_curr[3], vec_prev[3];
float3 vec_curr;
float3 vec_prev;
const int poly_index = loop_to_poly[ml_curr_index];
const int ml_prev_index = mesh::poly_corner_prev(polys[poly_index], ml_curr_index);
@ -968,11 +969,13 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
/* `ml_curr_index` would be mlfan_prev if we needed that one. */
const int2 &edge_orig = edges[corner_edges[ml_curr_index]];
float vec_curr[3], vec_prev[3], vec_org[3];
float3 vec_curr;
float3 vec_prev;
float3 vec_org;
float3 lnor(0.0f);
/* We validate clnors data on the fly - cheapest way to do! */
int clnors_avg[2] = {0, 0};
int2 clnors_avg(0);
short2 *clnor_ref = nullptr;
int clnors_count = 0;
bool clnors_invalid = false;
@ -1023,7 +1026,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
/* Calculate angle between the two poly edges incident on this vertex. */
const float fac = saacos(dot_v3v3(vec_curr, vec_prev));
/* Accumulate */
madd_v3_v3fl(lnor, poly_normals[mpfan_curr_index], fac);
lnor += poly_normals[mpfan_curr_index] * fac;
if (!clnors_data.is_empty()) {
/* Accumulate all clnors, if they are not all equal we have to fix that! */
@ -1052,11 +1055,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
if (IS_EDGE_SHARP(edge_to_loops[corner_edges[mlfan_curr_index]]) || (edge == edge_orig)) {
/* Current edge is sharp and we have finished with this fan of faces around this vert,
* or this vert is smooth, and we have completed a full turn around it. */
// printf("FAN: Finished!\n");
break;
}
copy_v3_v3(vec_prev, vec_curr);
vec_prev = vec_curr;
/* Find next loop of the smooth fan. */
loop_manifold_fan_around_vert_next(corner_verts,
@ -1069,36 +1071,32 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
&mpfan_curr_index);
}
{
float lnor_len = normalize_v3(lnor);
float length;
lnor = math::normalize_and_get_length(lnor, length);
/* If we are generating lnor spacearr, we can now define the one for this fan,
* and optionally compute final lnor from custom data too!
*/
if (lnors_spacearr) {
fan_space_add_corners(*lnors_spacearr, processed_corners, space_index);
if (UNLIKELY(lnor_len == 0.0f)) {
/* Use vertex normal as fallback! */
copy_v3_v3(lnor, loop_normals[mlfan_vert_index]);
lnor_len = 1.0f;
}
/* If we are generating lnor spacearr, we can now define the one for this fan,
* and optionally compute final lnor from custom data too!
*/
if (lnors_spacearr) {
fan_space_add_corners(*lnors_spacearr, processed_corners, space_index);
if (UNLIKELY(length == 0.0f)) {
/* Use vertex normal as fallback! */
copy_v3_v3(lnor, loop_normals[mlfan_vert_index]);
length = 1.0f;
}
NormalFanSpace *lnor_space = &lnors_spacearr->spaces[space_index];
normal_fan_space_define(lnor_space, lnor, vec_org, vec_curr, *edge_vectors);
lnor_space->corners = std::move(processed_corners);
edge_vectors->clear();
NormalFanSpace *lnor_space = &lnors_spacearr->spaces[space_index];
normal_fan_space_define(lnor_space, lnor, vec_org, vec_curr, *edge_vectors);
lnor_space->corners = std::move(processed_corners);
edge_vectors->clear();
if (!clnors_data.is_empty()) {
if (clnors_invalid) {
clnors_avg[0] /= clnors_count;
clnors_avg[1] /= clnors_count;
/* Fix/update all clnors of this fan with computed average value. */
if (G.debug & G_DEBUG) {
printf("Invalid clnors in this fan!\n");
}
clnors_data.fill_indices(processed_corners.as_span(),
short2(clnors_avg[0], clnors_avg[1]));
// print_v2("new clnors", clnors_avg);
if (!clnors_data.is_empty()) {
if (clnors_invalid) {
clnors_avg[0] /= clnors_count;
clnors_avg[1] /= clnors_count;
/* Fix/update all clnors of this fan with computed average value. */
if (G.debug & G_DEBUG) {
printf("Invalid clnors in this fan!\n");
}
/* Extra bonus: since small-stack is local to this function,
* no more need to empty it at all cost! */
@ -1106,12 +1104,12 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
fan_space_custom_data_to_normal(lnor_space, lnor, *clnor_ref, lnor);
}
}
}
/* In case we get a zero normal here, just use vertex normal already set! */
if (LIKELY(lnor_len != 0.0f)) {
/* Copy back the final computed normal into all related loop-normals. */
loop_normals.fill_indices(processed_corners.as_span(), lnor);
}
/* In case we get a zero normal here, just use vertex normal already set! */
if (LIKELY(length != 0.0f)) {
/* Copy back the final computed normal into all related loop-normals. */
loop_normals.fill_indices(processed_corners.as_span(), lnor);
}
}

View File

@ -1687,7 +1687,7 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
*/
gpencil_brush_grab_stroke_init(gso, gps_active);
changed |= gpencil_sculpt_brush_do_stroke(
gso, gps_active, bound_mat, gpencil_brush_grab_store_points);
gso, gps, bound_mat, gpencil_brush_grab_store_points);
}
else {
/* Apply effect to the stored points */