diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-02-25 23:36:09 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-02-25 23:36:09 +0300 |
commit | bdf4e1596d4560c0bb1d79cd5344b3e6524e1037 (patch) | |
tree | cb0387c797007ee4adff5deab45e582e64ce6109 /source | |
parent | 1a8db5b717299eee1a6e9726c9de0abe5c169253 (diff) | |
parent | c8b4e0c0b5f874906d746637c5a006d990b72e49 (diff) |
Merge remote-tracking branch 'origin/blender-v3.1-release'
Diffstat (limited to 'source')
11 files changed, 158 insertions, 68 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index a9ab5b91e1a..40e8ee2f999 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -24,18 +24,30 @@ void BKE_subsurf_modifier_subdiv_settings_init(struct SubdivSettings *settings, const struct SubsurfModifierData *smd, bool use_render_params); +bool BKE_subsurf_modifier_use_custom_loop_normals(const struct SubsurfModifierData *smd, + const struct Mesh *mesh); + +/** + * Return true if GPU subdivision evaluation is disabled by force due to incompatible mesh or + * modifier settings. This will only return true if GPU subdivision is enabled in the preferences + * and supported by the GPU. It is mainly useful for showing UI messages. + */ +bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh( + const struct SubsurfModifierData *smd, const struct Mesh *mesh); /** * \param skip_check_is_last: When true, we assume that the modifier passed is the last enabled * modifier in the stack. */ bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const struct Scene *scene, const struct Object *ob, + const struct Mesh *mesh, const struct SubsurfModifierData *smd, int required_mode, bool skip_check_is_last); bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Scene *scene, const struct Object *ob, + const struct Mesh *mesh, int required_mode); extern void (*BKE_subsurf_modifier_free_gpu_cache_cb)(struct Subdiv *subdiv); diff --git a/source/blender/blenkernel/intern/subdiv_modifier.c b/source/blender/blenkernel/intern/subdiv_modifier.c index dd35388f230..48b3bb2acef 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.c +++ b/source/blender/blenkernel/intern/subdiv_modifier.c @@ -54,23 +54,20 @@ static ModifierData *modifier_get_last_enabled_for_mode(const Scene *scene, return md; } -bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const Scene *scene, - const Object *ob, - const SubsurfModifierData *smd, - int required_mode, - bool skip_check_is_last) +bool BKE_subsurf_modifier_use_custom_loop_normals(const SubsurfModifierData *smd, const Mesh *mesh) { - if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) { - return false; - } + return (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && (mesh->flag & ME_AUTOSMOOTH) && + CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); +} - if (!skip_check_is_last) { - ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode); - if (md != (const ModifierData *)smd) { - return false; - } - } +bool subsurf_modifier_use_autosmooth_or_split_normals(const SubsurfModifierData *smd, + const Mesh *mesh) +{ + return (mesh->flag & ME_AUTOSMOOTH) || BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh); +} +static bool is_subdivision_evaluation_possible_on_gpu(void) +{ /* Only OpenGL is supported for OpenSubdiv evaluation for now. */ if (GPU_backend_get_type() != GPU_BACKEND_OPENGL) { return false; @@ -88,8 +85,52 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const Scene *scene, return true; } +bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfModifierData *smd, + const Mesh *mesh) +{ + if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) { + /* GPU subdivision is explicitely disabled, so we don't force it. */ + return false; + } + + if (!is_subdivision_evaluation_possible_on_gpu()) { + /* The GPU type is not compatible with the subdivision. */ + return false; + } + + return subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh); +} + +bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const Scene *scene, + const Object *ob, + const Mesh *mesh, + const SubsurfModifierData *smd, + int required_mode, + bool skip_check_is_last) +{ + if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) { + return false; + } + + /* Deactivate GPU subdivision if autosmooth or custom split normals are used as those are + * complicated to support on GPU, and should really be separate workflows. */ + if (subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh)) { + return false; + } + + if (!skip_check_is_last) { + ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode); + if (md != (const ModifierData *)smd) { + return false; + } + } + + return is_subdivision_evaluation_possible_on_gpu(); +} + bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene, const Object *ob, + const Mesh *mesh, int required_mode) { ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode); @@ -103,7 +144,7 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene, } return BKE_subsurf_modifier_can_do_gpu_subdiv_ex( - scene, ob, (SubsurfModifierData *)md, required_mode, true); + scene, ob, mesh, (SubsurfModifierData *)md, required_mode, true); } void (*BKE_subsurf_modifier_free_gpu_cache_cb)(Subdiv *subdiv) = NULL; diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 8833a354c21..e9f1012f930 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1712,7 +1712,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, const int required_mode = BKE_subsurf_modifier_eval_required_mode(DRW_state_is_scene_render(), is_editmode); - const bool do_subdivision = BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ob, required_mode); + const bool do_subdivision = BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ob, me, required_mode); MeshBufferList *mbuflist = &cache->final.buff; diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 831b0327d6f..9bdd1f0482f 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -67,7 +67,6 @@ enum { SHADER_BUFFER_NORMALS_ACCUMULATE, SHADER_BUFFER_NORMALS_FINALIZE, SHADER_PATCH_EVALUATION, - SHADER_PATCH_EVALUATION_LIMIT_NORMALS, SHADER_PATCH_EVALUATION_FVAR, SHADER_PATCH_EVALUATION_FACE_DOTS, SHADER_COMP_CUSTOM_DATA_INTERP_1D, @@ -107,7 +106,6 @@ static const char *get_shader_code(int shader_type) return datatoc_common_subdiv_normals_finalize_comp_glsl; } case SHADER_PATCH_EVALUATION: - case SHADER_PATCH_EVALUATION_LIMIT_NORMALS: case SHADER_PATCH_EVALUATION_FVAR: case SHADER_PATCH_EVALUATION_FACE_DOTS: { return datatoc_common_subdiv_patch_evaluation_comp_glsl; @@ -159,9 +157,6 @@ static const char *get_shader_name(int shader_type) case SHADER_PATCH_EVALUATION: { return "subdiv patch evaluation"; } - case SHADER_PATCH_EVALUATION_LIMIT_NORMALS: { - return "subdiv patch evaluation limit normals"; - } case SHADER_PATCH_EVALUATION_FVAR: { return "subdiv patch evaluation face-varying"; } @@ -199,13 +194,7 @@ static GPUShader *get_patch_evaluation_shader(int shader_type) const char *compute_code = get_shader_code(shader_type); const char *defines = nullptr; - if (shader_type == SHADER_PATCH_EVALUATION_LIMIT_NORMALS) { - defines = - "#define OSD_PATCH_BASIS_GLSL\n" - "#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n" - "#define LIMIT_NORMALS\n"; - } - else if (shader_type == SHADER_PATCH_EVALUATION_FVAR) { + if (shader_type == SHADER_PATCH_EVALUATION_FVAR) { defines = "#define OSD_PATCH_BASIS_GLSL\n" "#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n" @@ -246,7 +235,6 @@ static GPUShader *get_subdiv_shader(int shader_type, const char *defines) { if (ELEM(shader_type, SHADER_PATCH_EVALUATION, - SHADER_PATCH_EVALUATION_LIMIT_NORMALS, SHADER_PATCH_EVALUATION_FVAR, SHADER_PATCH_EVALUATION_FACE_DOTS)) { return get_patch_evaluation_shader(shader_type); @@ -1194,9 +1182,7 @@ static void drw_subdiv_compute_dispatch(const DRWSubdivCache *cache, GPU_compute_dispatch(shader, dispatch_rx, dispatch_ry, 1); } -void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, - GPUVertBuf *pos_nor, - const bool do_limit_normals) +void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, GPUVertBuf *pos_nor) { Subdiv *subdiv = cache->subdiv; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; @@ -1221,8 +1207,7 @@ void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, get_patch_param_format()); evaluator->wrapPatchParamBuffer(evaluator, &patch_param_buffer_interface); - GPUShader *shader = get_patch_evaluation_shader( - do_limit_normals ? SHADER_PATCH_EVALUATION_LIMIT_NORMALS : SHADER_PATCH_EVALUATION); + GPUShader *shader = get_patch_evaluation_shader(SHADER_PATCH_EVALUATION); GPU_shader_bind(shader); GPU_vertbuf_bind_as_ssbo(src_buffer, 0); @@ -1394,6 +1379,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache, GPUVertBuf *pos_nor, GPUVertBuf *face_adjacency_offsets, GPUVertBuf *face_adjacency_lists, + GPUVertBuf *vertex_loop_map, GPUVertBuf *vertex_normals) { GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_ACCUMULATE, nullptr); @@ -1404,6 +1390,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache, GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); GPU_vertbuf_bind_as_ssbo(face_adjacency_offsets, binding_point++); GPU_vertbuf_bind_as_ssbo(face_adjacency_lists, binding_point++); + GPU_vertbuf_bind_as_ssbo(vertex_loop_map, binding_point++); GPU_vertbuf_bind_as_ssbo(vertex_normals, binding_point++); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_verts); @@ -1851,8 +1838,6 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene, draw_cache->subdiv = subdiv; draw_cache->optimal_display = optimal_display; draw_cache->num_subdiv_triangles = tris_count_from_number_of_loops(draw_cache->num_subdiv_loops); - /* We can only evaluate limit normals if the patches are adaptive. */ - draw_cache->do_limit_normals = settings.is_adaptive; draw_cache->use_custom_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && (mesh_eval->flag & ME_AUTOSMOOTH) && diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h index 6714ba571e5..862b296626f 100644 --- a/source/blender/draw/intern/draw_subdivision.h +++ b/source/blender/draw/intern/draw_subdivision.h @@ -51,7 +51,6 @@ typedef struct DRWSubdivCache { struct BMesh *bm; struct Subdiv *subdiv; bool optimal_display; - bool do_limit_normals; bool use_custom_loop_normals; /* Coordinates used to evaluate patches for UVs, positions, and normals. */ @@ -165,6 +164,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache, struct GPUVertBuf *pos_nor, struct GPUVertBuf *face_adjacency_offsets, struct GPUVertBuf *face_adjacency_lists, + struct GPUVertBuf *vertex_loop_map, struct GPUVertBuf *vertex_normals); void draw_subdiv_finalize_normals(const DRWSubdivCache *cache, @@ -176,9 +176,7 @@ void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache, GPUVertBuf *src_custom_normals, GPUVertBuf *pos_nor); -void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, - struct GPUVertBuf *pos_nor, - bool do_limit_normals); +void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, struct GPUVertBuf *pos_nor); void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache, struct GPUVertBuf *src_data, diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index bd7f1ba0128..c0e2c30e862 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -217,14 +217,12 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, void *UNUSED(data)) { GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer); - const bool do_limit_normals = subdiv_cache->do_limit_normals && - !subdiv_cache->use_custom_loop_normals; /* Initialize the vertex buffer, it was already allocated. */ GPU_vertbuf_init_build_on_device( vbo, get_pos_nor_format(), subdiv_cache->num_subdiv_loops + mr->loop_loose_len); - draw_subdiv_extract_pos_nor(subdiv_cache, vbo, do_limit_normals); + draw_subdiv_extract_pos_nor(subdiv_cache, vbo); if (subdiv_cache->use_custom_loop_normals) { Mesh *coarse_mesh = subdiv_cache->mesh; @@ -250,7 +248,7 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, GPU_vertbuf_discard(src_custom_normals); GPU_vertbuf_discard(dst_custom_normals); } - else if (!do_limit_normals) { + else { /* We cannot evaluate vertex normals using the limit surface, so compute them manually. */ GPUVertBuf *subdiv_loop_subdiv_vert_index = draw_subdiv_build_origindex_buffer( subdiv_cache->subdiv_loop_subdiv_vert_index, subdiv_cache->num_subdiv_loops); @@ -263,6 +261,7 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, vbo, subdiv_cache->subdiv_vertex_face_adjacency_offsets, subdiv_cache->subdiv_vertex_face_adjacency, + subdiv_loop_subdiv_vert_index, vertex_normals); draw_subdiv_finalize_normals(subdiv_cache, vertex_normals, subdiv_loop_subdiv_vert_index, vbo); diff --git a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl index e6538d80111..5d71c5e4bb8 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl @@ -140,6 +140,13 @@ void set_vertex_nor(inout PosNorLoop vertex_data, vec3 nor) set_vertex_nor(vertex_data, nor, 0); } +void add_newell_cross_v3_v3v3(inout vec3 n, vec3 v_prev, vec3 v_curr) +{ + n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]); + n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]); + n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); +} + #define ORIGINDEX_NONE -1 #ifdef SUBDIV_POLYGON_OFFSET diff --git a/source/blender/draw/intern/shaders/common_subdiv_normals_accumulate_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_normals_accumulate_comp.glsl index 575090472b1..a6d6c205615 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_normals_accumulate_comp.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_normals_accumulate_comp.glsl @@ -16,11 +16,33 @@ layout(std430, binding = 2) readonly buffer faceAdjacencyLists uint face_adjacency_lists[]; }; -layout(std430, binding = 3) writeonly buffer vertexNormals +layout(std430, binding = 3) readonly buffer vertexLoopMap +{ + uint vert_loop_map[]; +}; + +layout(std430, binding = 4) writeonly buffer vertexNormals { vec3 normals[]; }; +void find_prev_and_next_vertex_on_face( + uint face_index, uint vertex_index, out uint curr, out uint next, out uint prev) +{ + uint start_loop_index = face_index * 4; + + for (uint i = 0; i < 4; i++) { + uint subdiv_vert_index = vert_loop_map[start_loop_index + i]; + + if (subdiv_vert_index == vertex_index) { + curr = i; + next = (i + 1) % 4; + prev = (i + 4 - 1) % 4; + break; + } + } +} + void main() { uint vertex_index = get_global_invocation_index(); @@ -39,18 +61,37 @@ void main() uint adjacent_face = face_adjacency_lists[first_adjacent_face_offset + i]; uint start_loop_index = adjacent_face * 4; - /* Compute face normal. */ - vec3 adjacent_verts[3]; - for (uint j = 0; j < 3; j++) { - adjacent_verts[j] = get_vertex_pos(pos_nor[start_loop_index + j]); + /* Compute the face normal using Newell's method. */ + vec3 verts[4]; + for (uint j = 0; j < 4; j++) { + verts[j] = get_vertex_pos(pos_nor[start_loop_index + j]); } - vec3 face_normal = normalize( - cross(adjacent_verts[1] - adjacent_verts[0], adjacent_verts[2] - adjacent_verts[0])); - accumulated_normal += face_normal; + vec3 face_normal = vec3(0.0); + add_newell_cross_v3_v3v3(face_normal, verts[0], verts[1]); + add_newell_cross_v3_v3v3(face_normal, verts[1], verts[2]); + add_newell_cross_v3_v3v3(face_normal, verts[2], verts[3]); + add_newell_cross_v3_v3v3(face_normal, verts[3], verts[0]); + + /* Accumulate angle weighted normal. */ + uint curr_vert = 0; + uint next_vert = 0; + uint prev_vert = 0; + find_prev_and_next_vertex_on_face( + adjacent_face, vertex_index, curr_vert, next_vert, prev_vert); + + vec3 curr_co = verts[curr_vert]; + vec3 prev_co = verts[next_vert]; + vec3 next_co = verts[prev_vert]; + + vec3 edvec_prev = normalize(prev_co - curr_co); + vec3 edvec_next = normalize(curr_co - next_co); + + float fac = acos(-dot(edvec_prev, edvec_next)); + + accumulated_normal += face_normal * fac; } - float weight = 1.0 / float(number_of_adjacent_faces); vec3 normal = normalize(accumulated_normal); normals[vertex_index] = normal; } diff --git a/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl index 5dd7decf663..26410eb2d7f 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl @@ -394,12 +394,8 @@ void main() evaluate_patches_limits(patch_co.patch_index, uv.x, uv.y, pos, du, dv); -# if defined(LIMIT_NORMALS) - vec3 nor = normalize(cross(du, dv)); -# else /* This will be computed later. */ vec3 nor = vec3(0.0); -# endif int origindex = input_vert_origindex[loop_index]; uint flag = 0; diff --git a/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl index 41a8df3cf82..8b4a5dd14f3 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl @@ -38,13 +38,18 @@ void main() } } else { - /* Face is flat shaded, compute flat face normal from an inscribed triangle. */ - vec3 verts[3]; - for (int i = 0; i < 3; i++) { - verts[i] = get_vertex_pos(pos_nor[start_loop_index + i]); - } - - vec3 face_normal = normalize(cross(verts[1] - verts[0], verts[2] - verts[0])); + vec3 v0 = get_vertex_pos(pos_nor[start_loop_index + 0]); + vec3 v1 = get_vertex_pos(pos_nor[start_loop_index + 1]); + vec3 v2 = get_vertex_pos(pos_nor[start_loop_index + 2]); + vec3 v3 = get_vertex_pos(pos_nor[start_loop_index + 3]); + + vec3 face_normal = vec3(0.0); + add_newell_cross_v3_v3v3(face_normal, v0, v1); + add_newell_cross_v3_v3v3(face_normal, v1, v2); + add_newell_cross_v3_v3v3(face_normal, v2, v3); + add_newell_cross_v3_v3v3(face_normal, v3, v0); + + face_normal = normalize(face_normal); for (int i = 0; i < 4; i++) { output_lnor[start_loop_index + i] = face_normal; } diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index cad36959f2b..b791e28d15b 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -234,7 +234,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * assigned at this stage of modifier stack evaluation. */ const bool is_editmode = (mesh->edit_mesh != NULL); const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode); - if (BKE_subsurf_modifier_can_do_gpu_subdiv_ex(scene, ctx->object, smd, required_mode, false)) { + if (BKE_subsurf_modifier_can_do_gpu_subdiv_ex( + scene, ctx->object, mesh, smd, required_mode, false)) { subdiv_cache_cpu_evaluation_settings(ctx, mesh, smd); return result; } @@ -246,9 +247,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Happens on bad topology, but also on empty input mesh. */ return result; } - const bool use_clnors = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && - (mesh->flag & ME_AUTOSMOOTH) && - CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh); if (use_clnors) { /* If custom normals are present and the option is turned on calculate the split * normals and clear flag so the normals get interpolated to the result mesh. */ @@ -412,6 +411,13 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(layout, ptr, "show_only_control_edges", 0, NULL, ICON_NONE); + SubsurfModifierData *smd = ptr->data; + Object *ob = ob_ptr.data; + Mesh *mesh = ob->data; + if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) { + uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", ICON_INFO); + } + modifier_panel_end(layout, ptr); } |