Fix: Mesh draw normals extraction ignores sharp_edge with no sharp_face

See c4446d7924

When the "fully flat" state comes from "sharp_edge" and "sharp_face"
doesn't exist, we need to check for that for every face when extracting
normals. Eventually these loops should be unrolled so we don't have a
function call per face. That would remove the cost of this check.
This commit is contained in:
Hans Goudey
2023-12-12 12:44:54 -05:00
parent a6838c8a12
commit 5875349390
4 changed files with 17 additions and 5 deletions

View File

@@ -409,12 +409,13 @@ void mesh_render_data_update_normals(MeshRenderData &mr, const eMRDataType data_
{
if (mr.extract_type != MR_EXTRACT_BMESH) {
/* Mesh */
mr.normals_domain = mr.mesh->normals_domain();
mr.vert_normals = mr.mesh->vert_normals();
if (data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR | MR_DATA_TAN_LOOP_NOR)) {
mr.face_normals = mr.mesh->face_normals();
}
if (((data_flag & MR_DATA_LOOP_NOR) &&
mr.mesh->normals_domain() == blender::bke::MeshNormalDomain::Corner) ||
mr.normals_domain == blender::bke::MeshNormalDomain::Corner) ||
(data_flag & MR_DATA_TAN_LOOP_NOR))
{
mr.loop_normals = mr.mesh->corner_normals();

View File

@@ -756,7 +756,9 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData &
const blender::OffsetIndices faces = mesh->faces();
for (const int i : faces.index_range()) {
uint32_t flag = 0;
if (!(mr.sharp_faces && mr.sharp_faces[i])) {
if (!(mr.normals_domain == blender::bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[i])))
{
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
if (mr.select_poly && mr.select_poly[i]) {
@@ -785,7 +787,9 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
/* Selection and hiding from bmesh. */
uint32_t flag = (f) ? compute_coarse_face_flag_bm(f, mr.efa_act) : 0;
/* Smooth from mesh. */
if (!(mr.sharp_faces && mr.sharp_faces[i])) {
if (!(mr.normals_domain == blender::bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[i])))
{
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
flags_data[i] = uint(faces[i].start()) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);

View File

@@ -90,9 +90,12 @@ struct MeshRenderData {
blender::Span<MLoopTri> looptris;
blender::Span<int> looptri_faces;
const int *material_indices;
blender::bke::MeshNormalDomain normals_domain;
blender::Span<blender::float3> vert_normals;
blender::Span<blender::float3> face_normals;
blender::Span<blender::float3> loop_normals;
const bool *hide_vert;
const bool *hide_edge;
const bool *hide_poly;

View File

@@ -68,7 +68,9 @@ static void extract_lnor_iter_face_mesh(const MeshRenderData &mr, const int face
if (!mr.loop_normals.is_empty()) {
*lnor_data = GPU_normal_convert_i10_v3(mr.loop_normals[ml_index]);
}
else if (mr.sharp_faces && mr.sharp_faces[face_index]) {
else if (mr.normals_domain == bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[face_index]))
{
*lnor_data = GPU_normal_convert_i10_v3(mr.face_normals[face_index]);
}
else {
@@ -189,7 +191,9 @@ static void extract_lnor_hq_iter_face_mesh(const MeshRenderData &mr,
if (!mr.loop_normals.is_empty()) {
normal_float_to_short_v3(&lnor_data->x, mr.loop_normals[ml_index]);
}
else if (mr.sharp_faces && mr.sharp_faces[face_index]) {
else if (mr.normals_domain == bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[face_index]))
{
normal_float_to_short_v3(&lnor_data->x, mr.face_normals[face_index]);
}
else {