Mesh: Reduce custom normal calculation memory usage #107592
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue