From 54ae189d869a4b02578c115d60ef052dc037b76f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 4 Jan 2023 23:56:20 -0500 Subject: [PATCH 01/25] Start moving ME_SMOOTH flag to generic "sharp_face" attribute --- intern/cycles/blender/mesh.cpp | 30 ++++++++++++++-- .../startup/bl_ui/properties_data_mesh.py | 2 +- source/blender/blenkernel/BKE_mesh_tangent.h | 1 + source/blender/blenkernel/BKE_shrinkwrap.h | 1 + .../intern/curve_to_mesh_convert.cc | 1 - .../intern/geometry_component_mesh.cc | 35 +++++++----------- .../blenkernel/intern/mball_tessellate.cc | 1 - source/blender/blenkernel/intern/mesh.cc | 15 ++++---- .../blender/blenkernel/intern/mesh_convert.cc | 12 ++++--- .../blender/blenkernel/intern/mesh_tangent.cc | 7 +++- .../blender/blenkernel/intern/shrinkwrap.cc | 4 ++- .../draw_cache_extract_mesh_render_data.cc | 3 ++ .../intern/draw_cache_impl_subdivision.cc | 4 +-- .../intern/mesh_extractors/extract_mesh.hh | 1 + .../mesh_extractors/extract_mesh_vbo_lnor.cc | 12 +++---- source/blender/editors/mesh/mesh_data.cc | 28 ++++++++++----- .../blender/editors/object/object_remesh.cc | 8 +++-- .../editors/sculpt_paint/paint_image_proj.cc | 5 ++- .../blender_interface/BlenderFileLoader.cpp | 9 +++-- .../geometry/intern/realize_instances.cc | 1 - .../io/alembic/intern/abc_reader_mesh.cc | 1 - .../blender/io/collada/GeometryExporter.cpp | 7 +++- .../blender/io/usd/intern/usd_reader_mesh.cc | 1 - .../blender/io/usd/intern/usd_writer_mesh.cc | 5 ++- .../wavefront_obj/exporter/obj_export_mesh.cc | 8 +++-- .../wavefront_obj/exporter/obj_export_mesh.hh | 3 ++ .../wavefront_obj/importer/obj_import_mesh.cc | 11 +++--- source/blender/makesdna/DNA_meshdata_types.h | 2 +- source/blender/makesrna/intern/rna_mesh.c | 36 +++++++++++++++++-- source/blender/modifiers/intern/MOD_ocean.c | 2 -- source/blender/modifiers/intern/MOD_remesh.c | 10 +----- source/blender/modifiers/intern/MOD_screw.cc | 5 ++- .../nodes/node_geo_input_shade_smooth.cc | 4 +-- .../nodes/node_geo_set_shade_smooth.cc | 15 ++++---- 34 files changed, 190 insertions(+), 100 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 736b80bacd6..234488794ed 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -895,6 +895,23 @@ static std::optional find_material_index_attribute(BL::Mesh b_ return std::nullopt; } +static std::optional find_sharp_face_attribute(BL::Mesh b_mesh) +{ + for (BL::Attribute &b_attribute : b_mesh.attributes) { + if (b_attribute.domain() != BL::Attribute::domain_FACE) { + continue; + } + if (b_attribute.data_type() != BL::Attribute::data_type_BOOLEAN) { + continue; + } + if (b_attribute.name() != "sharp_face") { + continue; + } + return BL::BoolAttribute{b_attribute}; + } + return std::nullopt; +} + static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, @@ -986,6 +1003,15 @@ static void create_mesh(Scene *scene, return 0; }; + std::optional sharp_faces = find_sharp_face_attribute(b_mesh); + auto get_face_sharp = [&](const int poly_index) -> bool { + if (sharp_faces) { + return sharp_faces->data[poly_index].value(); + } + return 0; + }; + + /* create faces */ const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); if (!subdivision) { @@ -995,7 +1021,7 @@ static void create_mesh(Scene *scene, int3 vi = get_int3(t.vertices()); int shader = get_material_index(poly_index); - bool smooth = (b_poly.flag & ME_SMOOTH) || use_loop_normals; + bool smooth = !get_face_sharp(poly_index) || use_loop_normals; if (use_loop_normals) { BL::Array loop_normals = t.split_normals(); @@ -1021,7 +1047,7 @@ static void create_mesh(Scene *scene, const MPoly &b_poly = polys[i]; int n = b_poly.totloop; int shader = get_material_index(i); - bool smooth = (b_poly.flag & ME_SMOOTH) || use_loop_normals; + bool smooth = !get_face_sharp(poly_index) || use_loop_normals; vi.resize(n); for (int i = 0; i < n; i++) { diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index e390b9cb6d4..44bb932e5f2 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -605,7 +605,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): colliding_names = [] for collection in ( # Built-in names. - {"position": None, "shade_smooth": None, "normal": None, "crease": None}, + {"position": None, "normal": None, "crease": None}, mesh.attributes, mesh.uv_layers, None if ob is None else ob.vertex_groups, diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h index b018ab978b2..3428e383917 100644 --- a/source/blender/blenkernel/BKE_mesh_tangent.h +++ b/source/blender/blenkernel/BKE_mesh_tangent.h @@ -47,6 +47,7 @@ void BKE_mesh_calc_loop_tangent_ex(const struct MVert *mvert, const struct MLoop *mloop, const struct MLoopTri *looptri, uint looptri_len, + const bool *sharp_faces, struct CustomData *loopdata, bool calc_active_tangent, diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index b13a1cbd034..5394d7e043a 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -76,6 +76,7 @@ typedef struct ShrinkwrapTreeData { const struct MPoly *polys; const float (*vert_normals)[3]; const float (*poly_normals)[3]; + const bool *sharp_faces; const float (*clnors)[3]; ShrinkwrapBoundaryData *boundary; } ShrinkwrapTreeData; diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index e5cafd405df..0c9757232a0 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -112,7 +112,6 @@ static void fill_mesh_topology(const int vert_offset, MPoly &poly = polys[ring_poly_offset + i_profile]; poly.loopstart = ring_segment_loop_offset; poly.totloop = 4; - poly.flag = ME_SMOOTH; MLoop &loop_a = loops[ring_segment_loop_offset]; loop_a.v = ring_vert_offset + i_profile; diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index b9702466d17..510a927e6e6 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -922,16 +922,6 @@ static void tag_component_positions_changed(void *owner) } } -static bool get_shade_smooth(const MPoly &mpoly) -{ - return mpoly.flag & ME_SMOOTH; -} - -static void set_shade_smooth(MPoly &mpoly, bool value) -{ - SET_FLAG_FROM_TEST(mpoly.flag, value, ME_SMOOTH); -} - static float2 get_loop_uv(const MLoopUV &uv) { return float2(uv.uv); @@ -1284,18 +1274,17 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() nullptr, AttributeValidator{&material_index_clamp}); - static BuiltinCustomDataLayerProvider shade_smooth( - "shade_smooth", - ATTR_DOMAIN_FACE, - CD_PROP_BOOL, - CD_MPOLY, - BuiltinAttributeProvider::NonCreatable, - BuiltinAttributeProvider::Writable, - BuiltinAttributeProvider::NonDeletable, - face_access, - make_derived_read_attribute, - make_derived_write_attribute, - nullptr); + static BuiltinCustomDataLayerProvider sharp_face("sharp_face", + ATTR_DOMAIN_FACE, + CD_PROP_BOOL, + CD_PROP_BOOL, + BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, + BuiltinAttributeProvider::Deletable, + face_access, + make_array_read_attribute, + make_array_write_attribute, + nullptr); static BuiltinCustomDataLayerProvider crease( "crease", @@ -1325,7 +1314,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() static CustomDataAttributeProvider face_custom_data(ATTR_DOMAIN_FACE, face_access); return ComponentAttributeProviders( - {&position, &id, &material_index, &shade_smooth, &normal, &crease}, + {&position, &id, &material_index, &sharp_face, &normal, &crease}, {&uvs, &corner_custom_data, &vertex_groups, diff --git a/source/blender/blenkernel/intern/mball_tessellate.cc b/source/blender/blenkernel/intern/mball_tessellate.cc index c2322da19cb..414b2e32ed0 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.cc +++ b/source/blender/blenkernel/intern/mball_tessellate.cc @@ -1483,7 +1483,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) const int count = indices[2] != indices[3] ? 4 : 3; mpoly[i].loopstart = loop_offset; mpoly[i].totloop = count; - mpoly[i].flag = ME_SMOOTH; mloop[loop_offset].v = uint32_t(indices[0]); mloop[loop_offset + 1].v = uint32_t(indices[1]); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index a7f1eb1df00..0468ec53a9e 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1464,16 +1464,17 @@ void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len) void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth) { - MutableSpan polys = me->polys_for_write(); + using namespace blender; + using namespace blender::bke; + MutableAttributeAccessor attributes = me->attributes_for_write(); if (use_smooth) { - for (MPoly &poly : polys) { - poly.flag |= ME_SMOOTH; - } + attributes.remove("sharp_face"); } else { - for (MPoly &poly : polys) { - poly.flag &= ~ME_SMOOTH; - } + SpanAttributeWriter sharp_faces = attributes.lookup_or_add_for_write_only_span( + "sharp_face", ATTR_DOMAIN_FACE); + sharp_faces.span.fill(true); + sharp_faces.finish(); } } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index c59210d9d47..0276daff228 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -198,6 +198,9 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_only_span( "material_index", ATTR_DOMAIN_FACE); + SpanAttributeWriter sharp_faces = attributes.lookup_or_add_for_write_span( + "sharp_face", ATTR_DOMAIN_FACE); + MLoopUV *mloopuv = static_cast(CustomData_add_layer_named( &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, DATA_("UVMap"))); @@ -283,8 +286,8 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } } - if (is_smooth) { - polys[dst_poly].flag |= ME_SMOOTH; + if (!is_smooth) { + sharp_faces.span[dst_poly] = true; } dst_poly++; dst_loop += 3; @@ -368,8 +371,8 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } } - if (is_smooth) { - polys[dst_poly].flag |= ME_SMOOTH; + if (!is_smooth) { + sharp_faces.span[dst_poly] = true; } dst_poly++; dst_loop += 4; @@ -388,6 +391,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } material_indices.finish(); + sharp_faces.finish(); return mesh; } diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 8534a68cca4..dfeb5929901 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -237,7 +237,7 @@ struct SGLSLMeshToTangent { if (precomputedLoopNormals) { return mikk::float3(precomputedLoopNormals[loop_index]); } - if ((mpoly[lt->poly].flag & ME_SMOOTH) == 0) { /* flat */ + if (sharp_faces && sharp_faces[lt->poly]) { /* flat */ if (precomputedFaceNormals) { return mikk::float3(precomputedFaceNormals[lt->poly]); } @@ -279,6 +279,7 @@ struct SGLSLMeshToTangent { const MPoly *mpoly; /* indices */ const MLoop *mloop; /* indices */ const MVert *mvert; /* vertex coordinates */ + const bool *sharp_faces; const float (*vert_normals)[3]; const float (*orco)[3]; float (*tangent)[4]; /* destination */ @@ -391,6 +392,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert, const MLoop *mloop, const MLoopTri *looptri, const uint looptri_len, + const bool *sharp_faces, CustomData *loopdata, bool calc_active_tangent, @@ -495,6 +497,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert, mesh2tangent->mpoly = mpoly; mesh2tangent->mloop = mloop; mesh2tangent->looptri = looptri; + mesh2tangent->sharp_faces = sharp_faces; /* NOTE: we assume we do have tessellated loop normals at this point * (in case it is object-enabled), have to check this is valid. */ mesh2tangent->precomputedLoopNormals = loop_normals; @@ -579,6 +582,8 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, BKE_mesh_loops(me_eval), BKE_mesh_runtime_looptri_ensure(me_eval), uint(BKE_mesh_runtime_looptri_len(me_eval)), + static_cast( + CustomData_get_layer_named(&me_eval->pdata, CD_PROP_BOOL, "sharp_face")), &me_eval->ldata, calc_active_tangent, tangent_names, diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index d196f044c58..8dc7e73b8c1 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -116,6 +116,8 @@ bool BKE_shrinkwrap_init_tree( data->mesh = mesh; data->polys = BKE_mesh_polys(mesh); data->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); + data->sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_face")); if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) { data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2); @@ -1175,7 +1177,7 @@ void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree, const float(*vert_normals)[3] = tree->vert_normals; /* Interpolate smooth normals if enabled. */ - if ((tree->polys[tri->poly].flag & ME_SMOOTH) != 0) { + if (!(tree->sharp_faces && tree->sharp_faces[tri->poly])) { const uint32_t vert_indices[3] = {treeData->loop[tri->tri[0]].v, treeData->loop[tri->tri[1]].v, treeData->loop[tri->tri[2]].v}; 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 ba117a75be6..fdc30508183 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 @@ -567,6 +567,9 @@ MeshRenderData *mesh_render_data_create(Object *object, CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".select_edge")); mr->select_poly = static_cast( CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".select_poly")); + + mr->sharp_faces = static_cast( + CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, "sharp_face")); } else { /* #BMesh */ diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index a225c931a14..47bcf8faa17 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -756,7 +756,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData * const Span polys = mesh->polys(); for (const int i : polys.index_range()) { uint32_t flag = 0; - if ((polys[i].flag & ME_SMOOTH) != 0) { + if (!(mr->sharp_faces && mr->sharp_faces[i])) { flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH; } if (mr->select_poly && mr->select_poly[i]) { @@ -785,7 +785,7 @@ 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 ((polys[i].flag & ME_SMOOTH) != 0) { + if ((mr->sharp_faces && mr->sharp_faces[i])) { flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH; } flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index c6230e2695e..648d63fc835 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -91,6 +91,7 @@ struct MeshRenderData { const bool *select_vert; const bool *select_edge; const bool *select_poly; + const bool *sharp_faces; float (*loop_normals)[3]; int *lverts, *ledges; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc index ff0d502ea1e..2a21effd40d 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc @@ -72,11 +72,11 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr, if (mr->loop_normals) { *lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[ml_index]); } - else if (mp->flag & ME_SMOOTH) { - *lnor_data = GPU_normal_convert_i10_v3(mr->vert_normals[ml->v]); + else if (mr->sharp_faces && mr->sharp_faces[mp_index]) { + *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[mp_index]); } else { - *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[mp_index]); + *lnor_data = GPU_normal_convert_i10_v3(mr->vert_normals[ml->v]); } /* Flag for paint mode overlay. @@ -197,11 +197,11 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr, if (mr->loop_normals) { normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[ml_index]); } - else if (mp->flag & ME_SMOOTH) { - normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[ml->v]); + else if (mr->sharp_faces && mr->sharp_faces[mp_index]) { + normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[mp_index]); } else { - normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[mp_index]); + normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[ml->v]); } /* Flag for paint mode overlay. diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index a2310dddc61..1933a1d1373 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -1463,16 +1463,28 @@ void ED_mesh_split_faces(Mesh *mesh) polys.size(), split_angle); - threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { - for (const int poly_i : range) { - const MPoly &poly = polys[poly_i]; - if (!(poly.flag & ME_SMOOTH)) { - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - edges[loop.e].flag |= ME_SHARP; - } + const bke::AttributeAccessor attributes = mesh->attributes(); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); + if (const std::optional value = sharp_faces.get_if_single()) { + if (value) { + for (MEdge &edge : edges) { + edge.flag |= ME_SHARP; } } - }); + } + else { + threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { + for (const int poly_i : range) { + const MPoly &poly = polys[poly_i]; + if (sharp_faces[poly_i]) { + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + edges[loop.e].flag |= ME_SHARP; + } + } + } + }); + } Vector split_indices; const IndexMask split_mask = index_mask_ops::find_indices_based_on_predicate( diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index db2769aac00..04cd6ec4212 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -25,6 +25,7 @@ #include "BLT_translation.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_global.h" @@ -117,6 +118,7 @@ static bool object_remesh_poll(bContext *C) static int voxel_remesh_exec(bContext *C, wmOperator *op) { + using namespace blender; Object *ob = CTX_data_active_object(C); Mesh *mesh = static_cast(ob->data); @@ -131,8 +133,10 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) } /* Output mesh will be all smooth or all flat shading. */ - const Span polys = mesh->polys(); - const bool smooth_normals = polys.first().flag & ME_SMOOTH; + const bke::AttributeAccessor attributes = mesh->attributes(); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); + const bool smooth_normals = !sharp_faces[0]; float isovalue = 0.0f; if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) { diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 61aa984c1af..222989efc72 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -418,6 +418,7 @@ struct ProjPaintState { const MPoly *mpoly_eval; const bool *select_poly_eval; const int *material_indices; + const bool *sharp_faces_eval; const MLoop *mloop_eval; const MLoopTri *mlooptri_eval; @@ -1730,7 +1731,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, const MPoly *mp = &ps->mpoly_eval[lt->poly]; float no[3], angle_cos; - if (mp->flag & ME_SMOOTH) { + if (!(ps->sharp_faces_eval && ps->sharp_faces_eval[lt->poly])) { const float *no1, *no2, *no3; no1 = ps->vert_normals[lt_vtri[0]]; no2 = ps->vert_normals[lt_vtri[1]]; @@ -4083,6 +4084,8 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p } ps->mloop_eval = BKE_mesh_loops(ps->me_eval); ps->mpoly_eval = BKE_mesh_polys(ps->me_eval); + ps->sharp_faces_eval = static_cast( + CustomData_get_layer_named(&ps->me_eval->pdata, CD_PROP_BOOL, "sharp_face")); ps->select_poly_eval = (const bool *)CustomData_get_layer_named( &ps->me_eval->pdata, CD_PROP_BOOL, ".select_poly"); ps->material_indices = (const int *)CustomData_get_layer_named( diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 53c2b1d235b..b2df04e8181 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -399,6 +399,7 @@ static bool testEdgeMark(Mesh *me, const FreestyleEdge *fed, const MLoopTri *lt, void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) { + using namespace blender; char *name = ob->id.name + 2; const Span mesh_verts = me->verts(); @@ -507,14 +508,16 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) FrsMaterial tmpMat; - const blender::VArray material_indices = me->attributes().lookup_or_default( + const bke::AttributeAccessor attributes = me->attributes(); + const VArray material_indices = attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); // We parse the vlak nodes again and import meshes while applying the clipping // by the near and far view planes. for (int a = 0; a < tottri; a++) { const MLoopTri *lt = &mlooptri[a]; - const MPoly *mp = &mesh_polys[lt->poly]; Material *mat = BKE_object_material_get(ob, material_indices[lt->poly] + 1); copy_v3_v3(v1, mesh_verts[mesh_loops[lt->tri[0]].v].co); @@ -529,7 +532,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) v2[2] += _z_offset; v3[2] += _z_offset; - if (_smooth && (mp->flag & ME_SMOOTH) && lnors) { + if (_smooth && (!sharp_faces[lt->poly]) && lnors) { copy_v3_v3(n1, lnors[lt->tri[0]]); copy_v3_v3(n2, lnors[lt->tri[1]]); copy_v3_v3(n3, lnors[lt->tri[2]]); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 57a4ae70b5f..7f2ef62a4d7 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -833,7 +833,6 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate( src_component_types, GEO_COMPONENT_TYPE_MESH, true, attributes_to_propagate); attributes_to_propagate.remove("position"); attributes_to_propagate.remove("normal"); - attributes_to_propagate.remove("shade_smooth"); r_create_id = attributes_to_propagate.pop_try("id").has_value(); r_create_material_index = attributes_to_propagate.pop_try("material_index").has_value(); OrderedAttributes ordered_attributes; diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index f632891dfda..e5873908746 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -205,7 +205,6 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) /* Polygons are always assumed to be smooth-shaded. If the Alembic mesh should be flat-shaded, * this is encoded in custom loop normals. See T71246. */ - poly.flag |= ME_SMOOTH; /* NOTE: Alembic data is stored in the reverse order. */ rev_loop_index = loop_index + (face_size - 1); diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 5ede22163fc..68f9d059844 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -614,6 +614,7 @@ void GeometryExporter::create_normals(std::vector &normals, std::vector &polygons_normals, Mesh *me) { + using namespace blender; std::map shared_normal_indices; int last_normal_index = -1; @@ -624,6 +625,10 @@ void GeometryExporter::create_normals(std::vector &normals, const float(*lnors)[3] = nullptr; bool use_custom_normals = false; + const bke::AttributeAccessor attributes = me->attributes(); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); + BKE_mesh_calc_normals_split(me); if (CustomData_has_layer(&me->ldata, CD_NORMAL)) { lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL); @@ -632,7 +637,7 @@ void GeometryExporter::create_normals(std::vector &normals, for (const int poly_index : polys.index_range()) { const MPoly *mpoly = &polys[poly_index]; - bool use_vertex_normals = use_custom_normals || mpoly->flag & ME_SMOOTH; + bool use_vertex_normals = use_custom_normals || !sharp_faces[poly_index]; if (!use_vertex_normals) { /* For flat faces use face normal as vertex normal: */ diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 52cd3b32b49..df66cf29743 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -325,7 +325,6 @@ void USDMeshReader::read_mpolys(Mesh *mesh) /* Polygons are always assumed to be smooth-shaded. If the mesh should be flat-shaded, * this is encoded in custom loop normals. */ - poly.flag |= ME_SMOOTH; if (is_left_handed_) { int loop_end_index = loop_index + (face_size - 1); diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index e7d79e888e4..8de1d4b9450 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -413,12 +413,15 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_ } else { /* Compute the loop normals based on the 'smooth' flag. */ + bke::AttributeAccessor attributes = mesh->attributes(); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); const float(*face_normals)[3] = BKE_mesh_poly_normals_ensure(mesh); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - if ((poly.flag & ME_SMOOTH) == 0) { + if (sharp_faces[i]) { /* Flat shaded, use common normal for all verts. */ pxr::GfVec3f pxr_normal(face_normals[i]); for (int loop_idx = 0; loop_idx < poly.totloop; ++loop_idx) { diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index e0a5811ae76..040fb52ce7c 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -44,6 +44,8 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj mesh_edges_ = export_mesh_->edges(); mesh_polys_ = export_mesh_->polys(); mesh_loops_ = export_mesh_->loops(); + sharp_faces_ = export_mesh_->attributes().lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); } else { /* Curves and NURBS surfaces need a new mesh when they're @@ -76,6 +78,8 @@ void OBJMesh::set_mesh(Mesh *mesh) mesh_edges_ = mesh->edges(); mesh_polys_ = mesh->polys(); mesh_loops_ = mesh->loops(); + sharp_faces_ = export_mesh_->attributes().lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); } void OBJMesh::clear() @@ -243,7 +247,7 @@ const Material *OBJMesh::get_object_material(const int16_t mat_nr) const bool OBJMesh::is_ith_poly_smooth(const int poly_index) const { - return mesh_polys_[poly_index].flag & ME_SMOOTH; + return !sharp_faces_[poly_index]; } const char *OBJMesh::get_object_name() const @@ -392,7 +396,7 @@ void OBJMesh::store_normal_coords_and_indices() CustomData_get_layer(&export_mesh_->ldata, CD_NORMAL)); for (int poly_index = 0; poly_index < export_mesh_->totpoly; ++poly_index) { const MPoly &mpoly = mesh_polys_[poly_index]; - bool need_per_loop_normals = lnors != nullptr || (mpoly.flag & ME_SMOOTH); + bool need_per_loop_normals = lnors != nullptr || !(sharp_faces_[poly_index]); if (need_per_loop_normals) { for (int loop_of_poly = 0; loop_of_poly < mpoly.totloop; ++loop_of_poly) { float3 loop_normal; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh index 9869469e616..73377cda4bd 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -11,6 +11,7 @@ #include "BLI_math_vec_types.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" +#include "BLI_virtual_array.hh" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -41,6 +42,8 @@ class OBJMesh : NonCopyable { Span mesh_polys_; Span mesh_loops_; + VArray sharp_faces_; + /** * Final transform of an object obtained from export settings (up_axis, forward_axis) and the * object's world transform matrix. diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 42293a9b992..58ab85589fd 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -183,9 +183,11 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter material_indices = - mesh->attributes_for_write().lookup_or_add_for_write_only_span("material_index", - ATTR_DOMAIN_FACE); + attributes.lookup_or_add_for_write_only_span("material_index", ATTR_DOMAIN_FACE); + bke::SpanAttributeWriter sharp_faces = attributes.lookup_or_add_for_write_span( + "sharp_face", ATTR_DOMAIN_FACE); const int64_t tot_face_elems{mesh->totpoly}; int tot_loop_idx = 0; @@ -201,8 +203,8 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) MPoly &mpoly = polys[poly_idx]; mpoly.totloop = curr_face.corner_count_; mpoly.loopstart = tot_loop_idx; - if (curr_face.shaded_smooth) { - mpoly.flag |= ME_SMOOTH; + if (!curr_face.shaded_smooth) { + sharp_faces.span[poly_idx] = true; } material_indices.span[poly_idx] = curr_face.material_index; /* Importing obj files without any materials would result in negative indices, which is not @@ -228,6 +230,7 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) } material_indices.finish(); + sharp_faces.finish(); } void MeshFromGeometry::create_vertex_groups(Object *obj) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 96c543d3db5..078ec24271c 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -98,8 +98,8 @@ typedef struct MPoly { /** #MPoly.flag */ enum { - ME_SMOOTH = (1 << 0), #ifdef DNA_DEPRECATED_ALLOW + ME_SMOOTH = (1 << 0), /** Deprecated selection status. Now stored in ".select_poly" attribute. */ ME_FACE_SEL = (1 << 1), #endif diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 7351ca1d8ca..20675417401 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -649,6 +649,32 @@ static void rna_MeshPolygon_hide_set(PointerRNA *ptr, bool value) hide_poly[index] = value; } +static bool rna_MeshPolygon_use_smooth_get(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + const bool *sharp_faces = (const bool *)CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face"); + const int index = rna_MeshPolygon_index_get(ptr); + return sharp_faces == NULL ? false : sharp_faces[index]; +} + +static void rna_MeshPolygon_use_smooth_set(PointerRNA *ptr, bool value) +{ + Mesh *mesh = rna_mesh(ptr); + bool *sharp_faces = (bool *)CustomData_duplicate_referenced_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face", mesh->totpoly); + if (!sharp_faces) { + if (value) { + /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */ + return; + } + sharp_faces = (bool *)CustomData_add_layer_named( + &mesh->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totpoly, "sharp_face"); + } + const int index = rna_MeshPolygon_index_get(ptr); + sharp_faces[index] = !value; +} + static bool rna_MeshPolygon_select_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); @@ -1510,10 +1536,15 @@ static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr) static bool rna_MeshLoopTriangle_use_smooth_get(PointerRNA *ptr) { + const bool *sharp_faces = (const bool *)CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face"); + if (!sharp_faces) { + return true; + } const Mesh *me = rna_mesh(ptr); const MLoopTri *ltri = (MLoopTri *)ptr->data; const MPoly *polys = BKE_mesh_polys(me); - return polys[ltri->poly].flag & ME_SMOOTH; + return sharp_faces[ltri->poly]; } /* path construction */ @@ -2561,8 +2592,9 @@ static void rna_def_mpolygon(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SMOOTH); RNA_def_property_ui_text(prop, "Smooth", ""); + RNA_def_property_boolean_funcs( + prop, "rna_MeshPolygon_use_smooth_get", "rna_MeshPolygon_use_smooth_set"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index bee1bd7795a..7aab94d2f4c 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -206,8 +206,6 @@ static void generate_ocean_geometry_polys(void *__restrict userdata, mp->loopstart = fi * 4; mp->totloop = 4; - - mp->flag |= ME_SMOOTH; } } diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index d6241fcb290..957ea34c514 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -198,15 +198,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) MEM_freeN(output); } - if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) { - MPoly *mpoly = BKE_mesh_polys_for_write(result); - int i, totpoly = result->totpoly; - - /* Apply smooth shading to output faces */ - for (i = 0; i < totpoly; i++) { - mpoly[i].flag |= ME_SMOOTH; - } - } + BKE_mesh_smooth_flag_set(result, (rmd->flag & MOD_REMESH_SMOOTH_SHADING)); BKE_mesh_copy_parameters_for_eval(result, mesh); BKE_mesh_calc_edges(result, true, false); diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 5d9e6a84422..1540bef90a8 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -247,8 +247,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ScrewVertConnect *vc, *vc_tmp, *vert_connect = nullptr; - const char mpoly_flag = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) ? ME_SMOOTH : 0; - /* don't do anything? */ if (!totvert) { return BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); @@ -890,7 +888,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * else { origindex[mpoly_index] = ORIGINDEX_NONE; dst_material_index[mpoly_index] = mat_nr; - mp_new->flag = mpoly_flag; } mp_new->loopstart = mpoly_index * 4; mp_new->totloop = 4; @@ -1034,6 +1031,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ltmd->merge_dist); } + BKE_mesh_smooth_flag_set(result, ltmd->flag & MOD_SCREW_SMOOTH_SHADING); + return result; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc index 54279719bd4..dd54bf1136e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc @@ -11,8 +11,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_geo_exec(GeoNodeExecParams params) { - Field shade_smooth_field = AttributeFieldInput::Create("shade_smooth"); - params.set_output("Smooth", std::move(shade_smooth_field)); + Field shade_smooth_field = AttributeFieldInput::Create("sharp_face"); + params.set_output("Smooth", fn::invert_boolean_field(shade_smooth_field)); } } // namespace blender::nodes::node_geo_input_shade_smooth_cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc index 7dd721288ac..cab21db2493 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc @@ -16,34 +16,35 @@ static void node_declare(NodeDeclarationBuilder &b) static void set_smooth(Mesh &mesh, const Field &selection_field, - const Field &shade_field) + const Field &sharp_field) { if (mesh.totpoly == 0) { return; } MutableAttributeAccessor attributes = mesh.attributes_for_write(); - AttributeWriter smooth = attributes.lookup_or_add_for_write("shade_smooth", - ATTR_DOMAIN_FACE); + AttributeWriter sharp_faces = attributes.lookup_or_add_for_write("sharp_face", + ATTR_DOMAIN_FACE); bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; fn::FieldEvaluator evaluator{field_context, mesh.totpoly}; evaluator.set_selection(selection_field); - evaluator.add_with_destination(shade_field, smooth.varray); + evaluator.add_with_destination(sharp_field, sharp_faces.varray); evaluator.evaluate(); - smooth.finish(); + sharp_faces.finish(); } static void node_geo_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input("Geometry"); Field selection_field = params.extract_input>("Selection"); - Field shade_field = params.extract_input>("Shade Smooth"); + Field smooth_field = params.extract_input>("Shade Smooth"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (Mesh *mesh = geometry_set.get_mesh_for_write()) { - set_smooth(*mesh, selection_field, shade_field); + /* TODO: Do this with nodes instead. */ + set_smooth(*mesh, selection_field, fn::invert_boolean_field(smooth_field)); } }); params.set_output("Geometry", std::move(geometry_set)); -- 2.30.2 From 9bfd8525fcadf62880a5f39ae87ffe8bbf7129dc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 11:32:05 -0500 Subject: [PATCH 02/25] More progress --- source/blender/blenkernel/BKE_DerivedMesh.h | 2 +- source/blender/blenkernel/BKE_mesh.h | 7 ++++ .../blenkernel/intern/data_transfer.cc | 38 ++++++++--------- .../blender/blenkernel/intern/mesh_normals.cc | 23 +++++++++-- source/blender/blenkernel/intern/pbvh.c | 41 +++++++++++++------ source/blender/bmesh/intern/bmesh_construct.c | 10 ----- source/blender/bmesh/intern/bmesh_construct.h | 2 - .../bmesh/intern/bmesh_mesh_convert.cc | 28 +++++++++++-- source/blender/draw/intern/draw_pbvh.cc | 13 ++++-- .../intern/lineart/lineart_cpu.cc | 10 ++++- .../io/alembic/exporter/abc_writer_mesh.cc | 12 ++++-- source/blender/render/intern/bake.cc | 7 +++- source/blender/render/intern/multires_bake.cc | 7 +++- 13 files changed, 136 insertions(+), 64 deletions(-) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index cb9c4256e33..8b60fa7ee7a 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -75,7 +75,7 @@ struct Scene; /* keep in sync with MFace/MPoly types */ typedef struct DMFlagMat { short mat_nr; - char flag; + bool sharp; } DMFlagMat; typedef enum DerivedMeshType { diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 066d302fdd1..0727cb71b85 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -475,6 +475,8 @@ void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh); * * Used when defining an empty custom loop normals data layer, * to keep same shading as with auto-smooth! + * + * \param sharp_faces: Optional array used to mark specific faces as sharp. */ void BKE_edges_sharp_from_angle_set(struct MEdge *medges, int numEdges, @@ -482,6 +484,7 @@ void BKE_edges_sharp_from_angle_set(struct MEdge *medges, int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, int numPolys, float split_angle); @@ -596,6 +599,7 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, * (splitting edges). * * \param loop_to_poly_map: Optional pre-created map from loops to their polygon. + * \param sharp_faces: Optional array used to mark specific faces as sharp. */ void BKE_mesh_normals_loop_split(const struct MVert *mverts, const float (*vert_normals)[3], @@ -607,6 +611,7 @@ void BKE_mesh_normals_loop_split(const struct MVert *mverts, int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, int numPolys, bool use_split_normals, float split_angle, @@ -624,6 +629,7 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, int numPolys, short (*r_clnors_data)[2]); void BKE_mesh_normals_loop_custom_from_verts_set(const struct MVert *mverts, @@ -636,6 +642,7 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const struct MVert *mverts, int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, int numPolys, short (*r_clnors_data)[2]); diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 4220d106095..0bf66fdcead 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -297,6 +297,8 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, num_loops_dst, polys_dst, BKE_mesh_poly_normals_ensure(me_dst), + static_cast(CustomData_get_layer_named( + &me_dst->pdata, CD_PROP_BOOL, "sharp_face")), num_polys_dst, use_split_nors_dst, split_angle_dst, @@ -352,6 +354,8 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, num_loops_dst, polys_dst, poly_nors_dst, + static_cast(CustomData_get_layer_named( + &me_dst->pdata, CD_PROP_BOOL, "sharp_face")), num_polys_dst, custom_nors_dst); } @@ -1056,26 +1060,20 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, return true; } if (r_map && cddata_type == CD_FAKE_SHARP) { - const size_t elem_size = sizeof(*((MPoly *)nullptr)); - const size_t data_size = sizeof(((MPoly *)nullptr)->flag); - const size_t data_offset = offsetof(MPoly, flag); - const uint64_t data_flag = ME_SMOOTH; - - data_transfer_layersmapping_add_item(r_map, - cddata_type, - mix_mode, - mix_factor, - mix_weights, - BKE_mesh_polys(me_src), - BKE_mesh_polys_for_write(me_dst), - me_src->totpoly, - me_dst->totpoly, - elem_size, - data_size, - data_offset, - data_flag, - nullptr, - interp_data); + if (!CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face")) { + CustomData_add_layer_named( + &me_dst->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me_dst->totpoly, "sharp_face"); + } + data_transfer_layersmapping_add_item_cd( + r_map, + CD_PROP_BOOL, + mix_mode, + mix_factor, + mix_weights, + CustomData_get_layer_named(&me_src->pdata, CD_PROP_BOOL, "sharp_face"), + CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face"), + interp, + interp_data); return true; } diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 7d486a99406..f0bd91a5044 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -838,6 +838,7 @@ static void mesh_edges_sharp_tag(const Span edges, const Span loops, const Span loop_to_poly_map, const Span poly_normals, + const Span sharp_faces, const bool check_angle, const float split_angle, MutableSpan edge_to_loops, @@ -845,6 +846,9 @@ static void mesh_edges_sharp_tag(const Span edges, { using namespace blender; const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f; + auto face_is_smooth = [&](const int poly_i) { + return sharp_faces.is_empty() || !sharp_faces[poly_i]; + }; for (const int poly_i : polys.index_range()) { const MPoly &poly = polys[poly_i]; @@ -859,7 +863,7 @@ static void mesh_edges_sharp_tag(const Span edges, /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */ e2l[0] = loop_index; /* We have to check this here too, else we might miss some flat faces!!! */ - e2l[1] = (poly.flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID; + e2l[1] = (face_is_smooth(poly_i)) ? INDEX_UNSET : INDEX_INVALID; } else if (e2l[1] == INDEX_UNSET) { const bool is_angle_sharp = (check_angle && @@ -871,7 +875,7 @@ static void mesh_edges_sharp_tag(const Span edges, * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the * same vertex, or angle between both its polys' normals is above split_angle value. */ - if (!(poly.flag & ME_SMOOTH) || (edges[edge_i].flag & ME_SHARP) || + if (!face_is_smooth(poly_i) || (edges[edge_i].flag & ME_SHARP) || vert_i == loops[e2l[0]].v || is_angle_sharp) { /* NOTE: we are sure that loop != 0 here ;). */ e2l[1] = INDEX_INVALID; @@ -907,6 +911,7 @@ void BKE_edges_sharp_from_angle_set(MEdge *medges, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, const int numPolys, const float split_angle) { @@ -930,6 +935,7 @@ void BKE_edges_sharp_from_angle_set(MEdge *medges, {mloops, numLoops}, loop_to_poly, {reinterpret_cast(poly_normals), numPolys}, + Span(sharp_faces, sharp_faces ? numPolys : 0), true, split_angle, edge_to_loops, @@ -1501,6 +1507,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, const int numPolys, const bool use_split_normals, const float split_angle, @@ -1527,7 +1534,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, const MPoly *mp = &mpolys[mp_index]; int ml_index = mp->loopstart; const int ml_index_end = ml_index + mp->totloop; - const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0); + const bool is_poly_flat = sharp_faces && sharp_faces[mp_index]; for (; ml_index < ml_index_end; ml_index++) { if (is_poly_flat) { @@ -1619,6 +1626,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, loops, loop_to_poly, {reinterpret_cast(poly_normals), numPolys}, + Span(sharp_faces, sharp_faces ? numPolys : 0), check_angle, split_angle, edge_to_loops, @@ -1668,6 +1676,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, const int numPolys, short (*r_clnors_data)[2], const bool use_vertices) @@ -1704,6 +1713,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, numLoops, mpolys, poly_normals, + sharp_faces, numPolys, use_split_normals, split_angle, @@ -1831,6 +1841,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, numLoops, mpolys, poly_normals, + sharp_faces, numPolys, use_split_normals, split_angle, @@ -1908,6 +1919,7 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, const int numPolys, short (*r_clnors_data)[2]) { @@ -1921,6 +1933,7 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, numLoops, mpolys, poly_normals, + sharp_faces, numPolys, r_clnors_data, false); @@ -1936,6 +1949,7 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], + const bool *sharp_faces, const int numPolys, short (*r_clnors_data)[2]) { @@ -1949,6 +1963,7 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts, numLoops, mpolys, poly_normals, + sharp_faces, numPolys, r_clnors_data, true); @@ -1982,6 +1997,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), + static_cast(CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face")), polys.size(), clnors, use_vertices); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index a6a362b1daf..127edfa342e 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -152,14 +152,22 @@ static void update_node_vb(PBVH *pbvh, PBVHNode *node) // BB_expand(&node->vb, co); //} -static bool face_materials_match(const PBVH *pbvh, const int a, const int b) +static bool face_materials_match(const PBVH *pbvh, + const bool *sharp_faces, + const int a, + const int b) { if (pbvh->material_indices) { if (pbvh->material_indices[a] != pbvh->material_indices[b]) { return false; } } - return (pbvh->mpoly[a].flag & ME_SMOOTH) == (pbvh->mpoly[b].flag & ME_SMOOTH); + if (sharp_faces) { + if (sharp_faces[a] != sharp_faces[b]) { + return false; + } + } + return true; } static bool grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2) @@ -230,7 +238,7 @@ static int partition_indices_grids(int *prim_indices, } /* Returns the index of the first element on the right of the partition */ -static int partition_indices_material(PBVH *pbvh, int lo, int hi) +static int partition_indices_material(PBVH *pbvh, const bool *sharp_faces, int lo, int hi) { const MLoopTri *looptri = pbvh->looptri; const DMFlagMat *flagmats = pbvh->grid_flag_mats; @@ -240,10 +248,10 @@ static int partition_indices_material(PBVH *pbvh, int lo, int hi) for (;;) { if (pbvh->looptri) { const int first = looptri[pbvh->prim_indices[lo]].poly; - for (; face_materials_match(pbvh, first, looptri[indices[i]].poly); i++) { + for (; face_materials_match(pbvh, sharp_faces, first, looptri[indices[i]].poly); i++) { /* pass */ } - for (; !face_materials_match(pbvh, first, looptri[indices[j]].poly); j--) { + for (; !face_materials_match(pbvh, sharp_faces, first, looptri[indices[j]].poly); j--) { /* pass */ } } @@ -449,7 +457,7 @@ static void build_leaf(PBVH *pbvh, int node_index, BBC *prim_bbc, int offset, in /* Return zero if all primitives in the node can be drawn with the * same material (including flat/smooth shading), non-zero otherwise */ -static bool leaf_needs_material_split(PBVH *pbvh, int offset, int count) +static bool leaf_needs_material_split(PBVH *pbvh, const bool *sharp_faces, int offset, int count) { if (count <= 1) { return false; @@ -459,7 +467,7 @@ static bool leaf_needs_material_split(PBVH *pbvh, int offset, int count) const MLoopTri *first = &pbvh->looptri[pbvh->prim_indices[offset]]; for (int i = offset + count - 1; i > offset; i--) { int prim = pbvh->prim_indices[i]; - if (!face_materials_match(pbvh, first->poly, pbvh->looptri[prim].poly)) { + if (!face_materials_match(pbvh, sharp_faces, first->poly, pbvh->looptri[prim].poly)) { return true; } } @@ -538,6 +546,7 @@ static void test_face_boundaries(PBVH *pbvh) */ static void build_sub(PBVH *pbvh, + const bool *sharp_faces, int node_index, BB *cb, BBC *prim_bbc, @@ -556,7 +565,7 @@ static void build_sub(PBVH *pbvh, /* Decide whether this is a leaf or not */ const bool below_leaf_limit = count <= pbvh->leaf_limit || depth == STACK_FIXED_DEPTH - 1; if (below_leaf_limit) { - if (!leaf_needs_material_split(pbvh, offset, count)) { + if (!leaf_needs_material_split(pbvh, sharp_faces, offset, count)) { build_leaf(pbvh, node_index, prim_bbc, offset, count); if (node_index == 0) { @@ -609,11 +618,12 @@ static void build_sub(PBVH *pbvh, } else { /* Partition primitives by material */ - end = partition_indices_material(pbvh, offset, offset + count - 1); + end = partition_indices_material(pbvh, sharp_faces, offset, offset + count - 1); } /* Build children */ build_sub(pbvh, + sharp_faces, pbvh->nodes[node_index].children_offset, NULL, prim_bbc, @@ -622,6 +632,7 @@ static void build_sub(PBVH *pbvh, prim_scratch, depth + 1); build_sub(pbvh, + sharp_faces, pbvh->nodes[node_index].children_offset + 1, NULL, prim_bbc, @@ -635,7 +646,7 @@ static void build_sub(PBVH *pbvh, } } -static void pbvh_build(PBVH *pbvh, BB *cb, BBC *prim_bbc, int totprim) +static void pbvh_build(PBVH *pbvh, const bool *sharp_faces, BB *cb, BBC *prim_bbc, int totprim) { if (totprim != pbvh->totprim) { pbvh->totprim = totprim; @@ -657,7 +668,7 @@ static void pbvh_build(PBVH *pbvh, BB *cb, BBC *prim_bbc, int totprim) } pbvh->totnode = 1; - build_sub(pbvh, 0, cb, prim_bbc, 0, totprim, NULL, 0); + build_sub(pbvh, sharp_faces, 0, cb, prim_bbc, 0, totprim, NULL, 0); } static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) @@ -876,7 +887,9 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, } if (looptri_num) { - pbvh_build(pbvh, &cb, prim_bbc, looptri_num); + const bool *sharp_faces = (const bool *)CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face"); + pbvh_build(pbvh, sharp_faces, &cb, prim_bbc, looptri_num); #ifdef TEST_PBVH_FACE_SPLIT test_face_boundaries(pbvh); @@ -964,7 +977,9 @@ void BKE_pbvh_build_grids(PBVH *pbvh, } if (totgrid) { - pbvh_build(pbvh, &cb, prim_bbc, totgrid); + const bool *sharp_faces = (const bool *)CustomData_get_layer_named( + &me->pdata, CD_PROP_BOOL, "sharp_face"); + pbvh_build(pbvh, sharp_faces, &cb, prim_bbc, totgrid); #ifdef TEST_PBVH_FACE_SPLIT test_face_boundaries(pbvh); diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 90609121963..01e5417cf3b 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -721,10 +721,6 @@ char BM_edge_flag_from_mflag(const short mflag) return (((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | ((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0)); } -char BM_face_flag_from_mflag(const char mflag) -{ - return ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0); -} short BM_edge_flag_to_mflag(BMEdge *e) { @@ -733,9 +729,3 @@ short BM_edge_flag_to_mflag(BMEdge *e) return (((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0)); } -char BM_face_flag_to_mflag(BMFace *f) -{ - const char hflag = f->head.hflag; - - return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0); -} diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 635198b9346..1a74d492a8d 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -170,10 +170,8 @@ void BM_mesh_copy_init_customdata_all_layers(BMesh *bm_dst, const struct BMAllocTemplate *allocsize); BMesh *BM_mesh_copy(BMesh *bm_old); -char BM_face_flag_from_mflag(char mflag); char BM_edge_flag_from_mflag(short mflag); /* ME -> BM */ -char BM_face_flag_to_mflag(BMFace *f); short BM_edge_flag_to_mflag(BMEdge *e); #ifdef __cplusplus diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 0ee1d546ddc..6f5d79237bd 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -302,6 +302,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar &me->pdata, CD_PROP_BOOL, ".hide_poly"); const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); + const bool *sharp_faces = (const bool *)CustomData_get_layer_named( + &me->pdata, CD_PROP_BOOL, "sharp_face"); Span mvert = me->verts(); Array vtable(me->totvert); @@ -396,10 +398,12 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_elem_index_set(f, bm->totface - 1); /* set_ok */ /* Transfer flag. */ - f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag); if (hide_poly && hide_poly[i]) { BM_elem_flag_enable(f, BM_ELEM_HIDDEN); } + if (!(sharp_faces && sharp_faces[i])) { + BM_elem_flag_enable(f, BM_ELEM_SMOOTH); + } if (select_poly && select_poly[i]) { BM_face_select_set(bm, f, true); } @@ -978,6 +982,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh bool need_hide_edge = false; bool need_hide_poly = false; bool need_material_index = false; + bool need_sharp_face = false; i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -1033,7 +1038,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (f->mat_nr != 0) { need_material_index = true; } - mpoly[i].flag = BM_face_flag_to_mflag(f); + if (!BM_elem_flag_test(f, BM_ELEM_SMOOTH)) { + need_sharp_face = true; + } if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { need_hide_poly = true; } @@ -1073,6 +1080,13 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh ATTR_DOMAIN_FACE, [&](const int i) { return int(BM_face_at_index(bm, i)->mat_nr); }); } + if (need_sharp_face) { + BM_mesh_elem_table_ensure(bm, BM_FACE); + write_fn_to_attribute( + me->attributes_for_write(), "sharp_face", ATTR_DOMAIN_FACE, [&](const int i) { + return !BM_elem_flag_test(BM_face_at_index(bm, i), BM_ELEM_SMOOTH); + }); + } /* Patch hook indices and vertex parents. */ if (params->calc_object_remap && (ototvert > 0)) { @@ -1296,6 +1310,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * j = 0; bke::SpanAttributeWriter material_index_attribute; + bke::SpanAttributeWriter sharp_face_attribute; bke::SpanAttributeWriter hide_poly_attribute; bke::SpanAttributeWriter select_poly_attribute; BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { @@ -1306,7 +1321,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * BM_elem_index_set(efa, i); /* set_inline */ mp->totloop = efa->len; - mp->flag = BM_face_flag_to_mflag(efa); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (!hide_poly_attribute) { hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_span(".hide_poly", @@ -1328,7 +1342,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * material_index_attribute = mesh_attributes.lookup_or_add_for_write_span( "material_index", ATTR_DOMAIN_FACE); } - material_index_attribute.span[i] = efa->mat_nr; + } + if (!BM_elem_flag_test(efa, BM_ELEM_SMOOTH)) { + if (!sharp_face_attribute) { + sharp_face_attribute = mesh_attributes.lookup_or_add_for_write_span( + "sharp_face", ATTR_DOMAIN_FACE); + } + sharp_face_attribute.span[i] = true; } l_iter = l_first = BM_FACE_FIRST_LOOP(efa); diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 8ba827b266c..309dcbce04c 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -336,16 +336,17 @@ struct PBVHBatches { float fno[3]; short no[3]; int last_poly = -1; - bool smooth = false; + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(args->pdata, CD_PROP_BOOL, "sharp_face")); foreach_faces([&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri *tri) { - const MPoly *mp = args->mpoly + tri->poly; - + bool smooth = false; if (tri->poly != last_poly) { last_poly = tri->poly; - if (!(mp->flag & ME_SMOOTH)) { + if (sharp_faces && sharp_faces[tri->poly]) { smooth = true; + const MPoly *mp = args->mpoly + tri->poly; BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->mvert, fno); normal_float_to_short_v3(no, fno); } @@ -371,6 +372,8 @@ struct PBVHBatches { { uint vert_per_grid = square_i(args->ccg_key.grid_size - 1) * 4; uint vert_count = args->totprim * vert_per_grid; + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(args->pdata, CD_PROP_BOOL, "sharp_face")); int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf); void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf); @@ -1066,6 +1069,8 @@ struct PBVHBatches { { int *mat_index = static_cast( CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index")); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(args->pdata, CD_PROP_BOOL, "sharp_face")); if (mat_index && args->totprim) { int poly_index = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg, args->grid_indices[0]); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 1ae91ab29c2..4c9cb3c0ec2 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -17,6 +17,7 @@ #include "PIL_time.h" +#include "BKE_attribute.hh" #include "BKE_camera.h" #include "BKE_collection.h" #include "BKE_customdata.h" @@ -1474,6 +1475,7 @@ struct EdgeFeatData { Object *ob_eval; /* For evaluated materials. */ const MLoopTri *mlooptri; const int *material_indices; + blender::VArray sharp_faces; blender::Span edges; blender::Span loops; blender::Span polys; @@ -1645,8 +1647,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, if (ld->conf.use_crease) { bool do_crease = true; if (!ld->conf.force_crease && !e_feat_data->use_auto_smooth && - (e_feat_data->polys[mlooptri[f1].poly].flag & ME_SMOOTH) && - (e_feat_data->polys[mlooptri[f2].poly].flag & ME_SMOOTH)) { + (!e_feat_data->sharp_faces[mlooptri[f1].poly]) && + (!e_feat_data->sharp_faces[mlooptri[f2].poly])) { do_crease = false; } if (do_crease && (dot_v3v3_db(tri1->gn, tri2->gn) < e_feat_data->crease_threshold)) { @@ -1936,6 +1938,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); const int tot_tri = BKE_mesh_runtime_looptri_len(me); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); @@ -2075,6 +2080,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_data.ob_eval = ob_info->original_ob_eval; edge_feat_data.mlooptri = mlooptri; edge_feat_data.material_indices = material_indices; + edge_feat_data.sharp_faces = sharp_faces; edge_feat_data.edges = me->edges(); edge_feat_data.polys = me->polys(); edge_feat_data.loops = me->loops(); diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index 084d26198bc..ff2ba045047 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -449,7 +449,15 @@ static void get_topology(struct Mesh *mesh, { const Span polys = mesh->polys(); const Span loops = mesh->loops(); - r_has_flat_shaded_poly = false; + const bke::AttributeAccessor attributes = mesh->attributes(); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); + for (const int i : sharp_faces.index_range()) { + if (sharp_faces[i]) { + r_has_flat_shaded_poly = true; + break; + } + } poly_verts.clear(); loop_counts.clear(); @@ -461,8 +469,6 @@ static void get_topology(struct Mesh *mesh, const MPoly &poly = polys[i]; loop_counts.push_back(poly.totloop); - r_has_flat_shaded_poly |= (poly.flag & ME_SMOOTH) == 0; - const MLoop *loop = &loops[poly.loopstart + (poly.totloop - 1)]; for (int j = 0; j < poly.totloop; j++, loop--) { diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index e88dbcc3778..89050aa677c 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -56,6 +56,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_attribute.hh" #include "BKE_bvhutils.h" #include "BKE_customdata.h" #include "BKE_image.h" @@ -450,6 +451,7 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, */ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval) { + using namespace blender; int i; const int tottri = poly_to_tri_count(me->totpoly, me->totloop); @@ -463,6 +465,9 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval const MVert *verts = BKE_mesh_verts(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); looptri = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); triangles = static_cast(MEM_callocN(sizeof(TriTessFace) * tottri, __func__)); @@ -505,7 +510,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval triangles[i].vert_normals[0] = vert_normals[loops[lt->tri[0]].v]; triangles[i].vert_normals[1] = vert_normals[loops[lt->tri[1]].v]; triangles[i].vert_normals[2] = vert_normals[loops[lt->tri[2]].v]; - triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0; + triangles[i].is_smooth = !sharp_faces[lt->poly]; if (tangent) { triangles[i].tspace[0] = &tspace[lt->tri[0]]; diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 4ef71dc39a3..adc7a42b252 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -64,6 +64,7 @@ struct MResolvePixelData { const float (*vert_normals)[3]; MPoly *mpoly; const int *material_indices; + const bool *sharp_faces; MLoop *mloop; MLoopUV *mloopuv; float uv_offset[2]; @@ -114,7 +115,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, { const int poly_index = data->mlooptri[tri_num].poly; const MPoly *mp = &data->mpoly[poly_index]; - const bool smoothnormal = (mp->flag & ME_SMOOTH) != 0; + const bool smoothnormal = !(data->sharp_faces && data->sharp_faces[poly_index]); if (smoothnormal) { const int vi = data->mloop[data->mlooptri[tri_num].tri[vert_index]].v; @@ -509,6 +510,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, dm->getLoopArray(dm), dm->getLoopTriArray(dm), dm->getNumLoopTri(dm), + static_cast( + CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face")), &dm->loopData, true, nullptr, @@ -555,6 +558,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, handle->data.mpoly = mpoly; handle->data.material_indices = static_cast( CustomData_get_layer_named(&dm->polyData, CD_PROP_INT32, "material_index")); + handle->data.sharp_faces = static_cast( + CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face")); handle->data.mvert = mvert; handle->data.vert_normals = vert_normals; handle->data.mloopuv = mloopuv; -- 2.30.2 From 1442711908f0e34d96fe5801823dda898f68398e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 12:50:46 -0500 Subject: [PATCH 03/25] Branch compiling --- intern/cycles/blender/mesh.cpp | 8 +- .../blenkernel/BKE_mesh_legacy_convert.h | 3 + source/blender/blenkernel/BKE_mesh_mapping.h | 1 + source/blender/blenkernel/intern/fluid.c | 11 --- source/blender/blenkernel/intern/key.cc | 2 + source/blender/blenkernel/intern/mesh.cc | 3 + .../blenkernel/intern/mesh_boolean_convert.cc | 5 -- .../blenkernel/intern/mesh_legacy_convert.cc | 84 ++++++++++++++++--- .../blender/blenkernel/intern/mesh_mapping.cc | 30 ++++--- .../blender/blenkernel/intern/mesh_mirror.cc | 2 + .../blender/blenkernel/intern/mesh_remap.cc | 2 + source/blender/blenkernel/intern/pbvh.c | 2 +- .../blenkernel/intern/subdiv_ccg_material.c | 9 +- .../blender/blenkernel/intern/subsurf_ccg.c | 7 +- .../blenloader/intern/versioning_400.cc | 1 + .../draw_cache_extract_mesh_render_data.cc | 1 + source/blender/draw/intern/draw_pbvh.cc | 8 +- .../mesh_extractors/extract_mesh_vbo_tan.cc | 1 + source/blender/editors/mesh/mesh_data.cc | 4 + .../editors/sculpt_paint/paint_image_proj.cc | 1 - source/blender/io/collada/MeshImporter.cpp | 14 +++- .../wavefront_obj/exporter/obj_export_mesh.cc | 19 +++-- source/blender/makesdna/DNA_meshdata_types.h | 7 +- .../blender/makesdna/intern/dna_rename_defs.h | 1 + source/blender/makesrna/intern/rna_mesh.c | 5 +- source/blender/makesrna/intern/rna_mesh_api.c | 18 ++-- .../modifiers/intern/MOD_normal_edit.cc | 6 ++ .../modifiers/intern/MOD_solidify_extrude.c | 1 - .../intern/MOD_solidify_nonmanifold.c | 3 - .../modifiers/intern/MOD_weighted_normal.cc | 8 ++ .../geometry/nodes/node_geo_extrude_mesh.cc | 1 - 31 files changed, 176 insertions(+), 92 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 234488794ed..aaf89e4218f 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -895,7 +895,7 @@ static std::optional find_material_index_attribute(BL::Mesh b_ return std::nullopt; } -static std::optional find_sharp_face_attribute(BL::Mesh b_mesh) +static std::optional find_sharp_face_attribute(BL::Mesh b_mesh) { for (BL::Attribute &b_attribute : b_mesh.attributes) { if (b_attribute.domain() != BL::Attribute::domain_FACE) { @@ -1011,13 +1011,10 @@ static void create_mesh(Scene *scene, return 0; }; - /* create faces */ - const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); if (!subdivision) { for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) { const int poly_index = t.polygon_index(); - const MPoly &b_poly = polys[poly_index]; int3 vi = get_int3(t.vertices()); int shader = get_material_index(poly_index); @@ -1041,13 +1038,14 @@ static void create_mesh(Scene *scene, else { vector vi; + const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); const MLoop *loops = static_cast(b_mesh.loops[0].ptr.data); for (int i = 0; i < numfaces; i++) { const MPoly &b_poly = polys[i]; int n = b_poly.totloop; int shader = get_material_index(i); - bool smooth = !get_face_sharp(poly_index) || use_loop_normals; + bool smooth = !get_face_sharp(i) || use_loop_normals; vi.resize(n); for (int i = 0; i < n; i++) { diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index 65804e9ac24..6e7a5833281 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -24,6 +24,9 @@ struct MFace; #ifdef __cplusplus +void BKE_mesh_sharp_faces_to_flags(struct Mesh *mesh); +void BKE_mesh_sharp_faces_from_flags(struct Mesh *mesh); + /** * Move face sets to the legacy type from a generic type. */ diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index b49d61ac0a8..48b38537959 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -322,6 +322,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(struct MVert *verts, int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge, int totedge, const struct MPoly *mpoly, + const bool *sharp_faces, int totpoly, const struct MLoop *mloop, int totloop, diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index c72f498cd5a..e76a6eb8de0 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -3212,18 +3212,8 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, float size[3]; float cell_size_scaled[3]; - /* Assign material + flags to new mesh. - * If there are no faces in original mesh, keep materials and flags unchanged. */ - MPoly *mpoly; - MPoly mp_example = {0}; - mpoly = BKE_mesh_polys_for_write(orgmesh); - if (mpoly) { - mp_example = *mpoly; - } - const int *orig_material_indices = BKE_mesh_material_indices(orgmesh); const short mp_mat_nr = orig_material_indices ? orig_material_indices[0] : 0; - const char mp_flag = mp_example.flag; int i; int num_verts, num_faces; @@ -3339,7 +3329,6 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, for (i = 0; i < num_faces; i++, mpolys++, mloops += 3) { /* Initialize from existing face. */ material_indices[i] = mp_mat_nr; - mpolys->flag = mp_flag; mpolys->loopstart = i * 3; mpolys->totloop = 3; diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index b19ad6a3e97..00903854ce0 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2298,6 +2298,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, mesh->totloop, polys, poly_normals, + static_cast(CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face")), mesh->totpoly, (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 0468ec53a9e..31dff924f2e 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -254,6 +254,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address BKE_mesh_legacy_convert_hide_layers_to_flags(mesh); BKE_mesh_legacy_convert_selection_layers_to_flags(mesh); BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh); + BKE_mesh_sharp_faces_to_flags(mesh); BKE_mesh_legacy_bevel_weight_from_layers(mesh); BKE_mesh_legacy_face_set_from_generic(mesh, poly_layers); BKE_mesh_legacy_edge_crease_from_layers(mesh); @@ -1850,6 +1851,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), + static_cast(CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face")), polys.size(), use_split_normals, split_angle, diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 3d98fc7c958..836aa3c5498 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -402,15 +402,12 @@ static void copy_vert_attributes(Mesh *dest_mesh, /* Similar to copy_vert_attributes but for poly attributes. */ static void copy_poly_attributes(Mesh *dest_mesh, - MPoly *mp, - const MPoly *orig_mp, const Mesh *orig_me, int mp_index, int index_in_orig_me, Span material_remap, MutableSpan dst_material_indices) { - mp->flag = orig_mp->flag; CustomData *target_cd = &dest_mesh->pdata; const CustomData *source_cd = &orig_me->pdata; for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) { @@ -760,8 +757,6 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) } copy_poly_attributes(result, - mp, - orig_mp, orig_me, fi, index_in_orig_me, diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 7d4f0f8f7f8..b7c34436d79 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -440,6 +440,12 @@ static void convert_mfaces_to_mpolys(ID *id, material_indices = static_cast(CustomData_add_layer_named( pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, totpoly, "material_index")); } + bool *sharp_faces = static_cast( + CustomData_get_layer_named(pdata, CD_PROP_BOOL, "sharp_face")); + if (sharp_faces == nullptr) { + sharp_faces = static_cast(CustomData_add_layer_named( + pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, totpoly, "sharp_face")); + } numTex = CustomData_number_of_layers(fdata, CD_MTFACE); numCol = CustomData_number_of_layers(fdata, CD_MCOL); @@ -484,7 +490,7 @@ static void convert_mfaces_to_mpolys(ID *id, mp->totloop = mf->v4 ? 4 : 3; material_indices[i] = mf->mat_nr; - mp->flag = mf->flag; + sharp_faces[i] = (mf->flag & ME_SMOOTH) == 0; #define ML(v1, v2) \ { \ @@ -966,6 +972,8 @@ static int mesh_tessface_calc(Mesh &mesh, mloop = (const MLoop *)CustomData_get_layer(ldata, CD_MLOOP); const int *material_indices = static_cast( CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(pdata, CD_PROP_BOOL, "sharp_face")); /* Allocate the length of `totfaces`, avoid many small reallocation's, * if all faces are triangles it will be correct, `quads == 2x` allocations. */ @@ -1005,7 +1013,7 @@ static int mesh_tessface_calc(Mesh &mesh, lidx[2] = l3; \ lidx[3] = 0; \ mf->mat_nr = material_indices ? material_indices[poly_index] : 0; \ - mf->flag = mp->flag; \ + mf->flag = (sharp_faces && sharp_faces[poly_index]) ? 0 : ME_SMOOTH; \ mf->edcode = 0; \ (void)0 @@ -1028,7 +1036,7 @@ static int mesh_tessface_calc(Mesh &mesh, lidx[2] = l3; \ lidx[3] = l4; \ mf->mat_nr = material_indices ? material_indices[poly_index] : 0; \ - mf->flag = mp->flag; \ + mf->flag = (sharp_faces && sharp_faces[poly_index]) ? 0 : ME_SMOOTH; \ mf->edcode = TESSFACE_IS_QUAD; \ (void)0 @@ -1114,7 +1122,6 @@ static int mesh_tessface_calc(Mesh &mesh, lidx[3] = 0; mf->mat_nr = material_indices ? material_indices[poly_index] : 0; - mf->flag = mp->flag; mf->edcode = 0; mface_index++; @@ -1205,6 +1212,57 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Sharp Edge Conversion + * \{ */ + +void BKE_mesh_sharp_faces_to_flags(Mesh *mesh) +{ + using namespace blender; + MutableSpan polys = mesh->polys_for_write(); + if (const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"))) { + threading::parallel_for(polys.index_range(), 4096, [&](const IndexRange range) { + for (const int i : range) { + SET_FLAG_FROM_TEST(polys[i].flag_legacy, !sharp_faces[i], ME_SMOOTH); + } + }); + } + else { + for (const int i : polys.index_range()) { + polys[i].flag_legacy |= ME_SMOOTH; + } + } +} + +void BKE_mesh_sharp_faces_from_flags(Mesh *mesh) +{ + using namespace blender; + using namespace blender::bke; + const Span polys = mesh->polys(); + MutableAttributeAccessor attributes = mesh->attributes_for_write(); + if (attributes.contains("sharp_face")) { + return; + } + if (std::any_of(polys.begin(), polys.end(), [](const MPoly &poly) { + return !(poly.flag_legacy & ME_SMOOTH); + })) { + SpanAttributeWriter sharp_faces = attributes.lookup_or_add_for_write_only_span( + "sharp_face", ATTR_DOMAIN_FACE); + threading::parallel_for(polys.index_range(), 4096, [&](const IndexRange range) { + for (const int i : range) { + sharp_faces.span[i] = !(polys[i].flag_legacy & ME_SMOOTH); + } + }); + sharp_faces.finish(); + } + else { + attributes.remove("sharp_face"); + } +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Face Set Conversion * \{ */ @@ -1367,7 +1425,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh) ".hide_poly", ATTR_DOMAIN_FACE, false); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - SET_FLAG_FROM_TEST(polys[i].flag, hide_poly[i], ME_HIDE); + SET_FLAG_FROM_TEST(polys[i].flag_legacy, hide_poly[i], ME_HIDE); } }); } @@ -1406,13 +1464,14 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) } const Span polys = mesh->polys(); - if (std::any_of( - polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_HIDE; })) { + if (std::any_of(polys.begin(), polys.end(), [](const MPoly &poly) { + return poly.flag_legacy & ME_HIDE; + })) { SpanAttributeWriter hide_poly = attributes.lookup_or_add_for_write_only_span( ".hide_poly", ATTR_DOMAIN_FACE); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - hide_poly.span[i] = polys[i].flag & ME_HIDE; + hide_poly.span[i] = polys[i].flag_legacy & ME_HIDE; } }); hide_poly.finish(); @@ -1494,7 +1553,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh) ".select_poly", ATTR_DOMAIN_FACE, false); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - SET_FLAG_FROM_TEST(polys[i].flag, select_poly[i], ME_FACE_SEL); + SET_FLAG_FROM_TEST(polys[i].flag_legacy, select_poly[i], ME_FACE_SEL); } }); } @@ -1533,13 +1592,14 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) } const Span polys = mesh->polys(); - if (std::any_of( - polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_FACE_SEL; })) { + if (std::any_of(polys.begin(), polys.end(), [](const MPoly &poly) { + return poly.flag_legacy & ME_FACE_SEL; + })) { SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_only_span( ".select_poly", ATTR_DOMAIN_FACE); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - select_poly.span[i] = (polys[i].flag & ME_FACE_SEL) != 0; + select_poly.span[i] = (polys[i].flag_legacy & ME_FACE_SEL) != 0; } }); select_poly.finish(); diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index cdd7fd4895d..03f98ccdc7c 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -630,17 +630,18 @@ Vector> build_edge_to_loop_map_resizable(const Span loops, co /** * Callback deciding whether the given poly/loop/edge define an island boundary or not. */ -using MeshRemap_CheckIslandBoundary = bool (*)(const MPoly *mpoly, +using MeshRemap_CheckIslandBoundary = bool (*)(const int poly_index, + const bool *sharp_faces, const MLoop *mloop, const MEdge *medge, const int edge_user_count, - const MPoly *mpoly_array, const MeshElemMap *edge_poly_map, void *user_data); static void poly_edge_loop_islands_calc(const MEdge *medge, const int totedge, const MPoly *mpoly, + const bool *sharp_faces, const int totpoly, const MLoop *mloop, const int totloop, @@ -735,7 +736,8 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, const MeshElemMap *map_ele = &edge_poly_map[me_idx]; const int *p = map_ele->indices; int i = map_ele->count; - if (!edge_boundary_check(mp, ml, me, i, mpoly, map_ele, edge_boundary_check_data)) { + if (!edge_boundary_check( + poly, sharp_faces, ml, me, i, map_ele, edge_boundary_check_data)) { for (; i--; p++) { /* if we meet other non initialized its a bug */ BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id)); @@ -833,22 +835,23 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, } } -static bool poly_is_island_boundary_smooth_cb(const MPoly *mp, +static bool poly_is_island_boundary_smooth_cb(const int poly_index, + const bool *sharp_faces, const MLoop * /*ml*/, const MEdge *me, const int edge_user_count, - const MPoly *mpoly_array, const MeshElemMap *edge_poly_map, void * /*user_data*/) { + auto poly_is_smooth = [&](const int i) { return !(sharp_faces && sharp_faces[i]); }; + /* Edge is sharp if one of its polys is flat, or edge itself is sharp, * or edge is not used by exactly two polygons. */ - if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (edge_user_count == 2)) { + if ((poly_is_smooth(poly_index)) && !(me->flag & ME_SHARP) && (edge_user_count == 2)) { /* In that case, edge appears to be smooth, but we need to check its other poly too. */ - const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ? - &mpoly_array[edge_poly_map->indices[1]] : - &mpoly_array[edge_poly_map->indices[0]]; - return (mp_other->flag & ME_SMOOTH) == 0; + const int mp_other = (poly_index == edge_poly_map->indices[0]) ? edge_poly_map->indices[1] : + edge_poly_map->indices[0]; + return !poly_is_smooth(mp_other); } return true; } @@ -856,6 +859,7 @@ static bool poly_is_island_boundary_smooth_cb(const MPoly *mp, int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge, const MPoly *mpoly, + const bool *sharp_faces, const int totpoly, const MLoop *mloop, const int totloop, @@ -867,6 +871,7 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, poly_edge_loop_islands_calc(medge, totedge, mpoly, + sharp_faces, totpoly, mloop, totloop, @@ -1009,11 +1014,11 @@ struct MeshCheckIslandBoundaryUv { const MeshElemMap *edge_loop_map; }; -static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/, +static bool mesh_check_island_boundary_uv(const int /*poly_index*/, + const bool * /*sharp_faces*/, const MLoop *ml, const MEdge *me, const int /*edge_user_count*/, - const MPoly * /*mpoly_array*/, const MeshElemMap * /*edge_poly_map*/, void *user_data) { @@ -1109,6 +1114,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/, poly_edge_loop_islands_calc(edges, totedge, polys, + nullptr, totpoly, loops, totloop, diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 7d875ba799b..da166b719f7 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -414,6 +414,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, totloop, BKE_mesh_polys(result), BKE_mesh_poly_normals_ensure(result), + static_cast(CustomData_get_layer_named( + &result->pdata, CD_PROP_BOOL, "sharp_face")), totpoly, true, mesh->smoothresh, diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index f66570bdcc7..6c387abe5f7 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -1377,6 +1377,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, numloops_dst, polys_dst, poly_nors_dst, + static_cast(CustomData_get_layer_named( + &mesh_dst->pdata, CD_PROP_BOOL, "sharp_face")), numpolys_dst, use_split_nors_dst, split_angle_dst, diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 127edfa342e..f2c97e65cfb 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -172,7 +172,7 @@ static bool face_materials_match(const PBVH *pbvh, static bool grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2) { - return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) && (f1->mat_nr == f2->mat_nr)); + return (f1->sharp == f2->sharp) && (f1->mat_nr == f2->mat_nr); } /* Adapted from BLI_kdopbvh.c */ diff --git a/source/blender/blenkernel/intern/subdiv_ccg_material.c b/source/blender/blenkernel/intern/subdiv_ccg_material.c index 891e1d1b630..d10b162f426 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_material.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_material.c @@ -15,7 +15,7 @@ typedef struct CCGMaterialFromMeshData { const Mesh *mesh; - const MPoly *polys; + const bool *sharp_faces; const int *material_indices; } CCGMaterialFromMeshData; @@ -24,9 +24,8 @@ static DMFlagMat subdiv_ccg_material_flags_eval( { CCGMaterialFromMeshData *data = (CCGMaterialFromMeshData *)material_flags_evaluator->user_data; BLI_assert(coarse_face_index < data->mesh->totpoly); - const MPoly *poly = &data->polys[coarse_face_index]; DMFlagMat material_flags; - material_flags.flag = poly->flag; + material_flags.sharp = data->sharp_faces && data->sharp_faces[coarse_face_index]; material_flags.mat_nr = data->material_indices ? data->material_indices[coarse_face_index] : 0; return material_flags; } @@ -45,7 +44,9 @@ void BKE_subdiv_ccg_material_flags_init_from_mesh( data->mesh = mesh; data->material_indices = (const int *)CustomData_get_layer_named( &mesh->pdata, CD_PROP_INT32, "material_index"); - data->polys = BKE_mesh_polys(mesh); + data->sharp_faces = (const bool *)CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face"); + material_flags_evaluator->eval_material_flags = subdiv_ccg_material_flags_eval; material_flags_evaluator->free = subdiv_ccg_material_flags_free; material_flags_evaluator->user_data = data; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index bfb1f781a70..42d75e0816e 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1122,20 +1122,17 @@ static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly) int gridSize = ccgSubSurf_getGridSize(ss); /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */ int i = 0, k = 0; - DMFlagMat *faceFlags = ccgdm->faceFlags; totface = ccgSubSurf_getNumFaces(ss); for (index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH; for (S = 0; S < numVerts; S++) { for (y = 0; y < gridSize - 1; y++) { for (x = 0; x < gridSize - 1; x++) { MPoly *mp = &mpoly[i]; - mp->flag = flag; mp->loopstart = k; mp->totloop = 4; @@ -1599,9 +1596,9 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, medge = dm->getEdgeArray(dm); - const MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); const int *material_indices = CustomData_get_layer_named( &dm->polyData, CD_MPOLY, "material_index"); + const bool *sharp_faces = CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face"); const int *base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); int *vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); @@ -1629,7 +1626,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, ccgdm->faceMap[index].startEdge = edgeNum; ccgdm->faceMap[index].startFace = faceNum; - faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0; + faceFlags->sharp = sharp_faces ? sharp_faces[origIndex] : false; faceFlags->mat_nr = material_indices ? material_indices[origIndex] : 0; faceFlags++; diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 583e885a487..146653fb4fd 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -30,6 +30,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) BKE_mesh_legacy_convert_flags_to_selection_layers(&mesh); BKE_mesh_legacy_convert_flags_to_hide_layers(&mesh); BKE_mesh_legacy_convert_mpoly_to_material_indices(&mesh); + BKE_mesh_sharp_faces_from_flags(&mesh); BKE_mesh_legacy_bevel_weight_to_layers(&mesh); BKE_mesh_legacy_face_set_to_generic(&mesh); BKE_mesh_legacy_edge_crease_to_layers(&mesh); 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 fdc30508183..d36b573ae78 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 @@ -378,6 +378,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ mr->loop_len, mr->mpoly, mr->poly_normals, + mr->sharp_faces, mr->poly_len, is_auto_smooth, split_angle, diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 309dcbce04c..d9005da4291 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -372,8 +372,6 @@ struct PBVHBatches { { uint vert_per_grid = square_i(args->ccg_key.grid_size - 1) * 4; uint vert_count = args->totprim * vert_per_grid; - const bool *sharp_faces = static_cast( - CustomData_get_layer_named(args->pdata, CD_PROP_BOOL, "sharp_face")); int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf); void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf); @@ -412,7 +410,7 @@ struct PBVHBatches { foreach_grids([&](int /*x*/, int /*y*/, int grid_index, CCGElem *elems[4], int /*i*/) { float3 no(0.0f, 0.0f, 0.0f); - const bool smooth = args->grid_flag_mats[grid_index].flag & ME_SMOOTH; + const bool smooth = !args->grid_flag_mats[grid_index].sharp; if (smooth) { no = CCG_elem_no(&args->ccg_key, elems[0]); @@ -1069,8 +1067,6 @@ struct PBVHBatches { { int *mat_index = static_cast( CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index")); - const bool *sharp_faces = static_cast( - CustomData_get_layer_named(args->pdata, CD_PROP_BOOL, "sharp_face")); if (mat_index && args->totprim) { int poly_index = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg, args->grid_indices[0]); @@ -1092,7 +1088,7 @@ struct PBVHBatches { for (int i : IndexRange(args->totprim)) { int grid_index = args->grid_indices[i]; - bool smooth = args->grid_flag_mats[grid_index].flag & ME_SMOOTH; + bool smooth = !args->grid_flag_mats[grid_index].sharp; BLI_bitmap *gh = args->grid_hidden[grid_index]; for (int y = 0; y < gridsize - 1; y += skip) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc index 5df881251c1..e446872683c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc @@ -120,6 +120,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, mr->mloop, mr->mlooptri, mr->tri_len, + mr->sharp_faces, cd_ldata, calc_active_tangent, r_tangent_names, diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 1933a1d1373..00c870f08fd 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -791,6 +791,8 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(me), + static_cast(CustomData_get_layer_named( + &me->pdata, CD_PROP_BOOL, "sharp_face")), polys.size(), me->smoothresh); } @@ -1460,6 +1462,8 @@ void ED_mesh_split_faces(Mesh *mesh) loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), + static_cast(CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face")), polys.size(), split_angle); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 222989efc72..a701dde9c68 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -1728,7 +1728,6 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, if (ps->do_mask_normal) { const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)}; - const MPoly *mp = &ps->mpoly_eval[lt->poly]; float no[3], angle_cos; if (!(ps->sharp_faces_eval && ps->sharp_faces_eval[lt->poly])) { diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 436d919f8d5..d6a1b009ca7 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -623,6 +623,12 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, MaterialIdPrimitiveArrayMap mat_prim_map; int *material_indices = BKE_mesh_material_indices_for_write(me); + bool *sharp_faces = (bool *)CustomData_duplicate_referenced_layer_named( + &me->pdata, CD_PROP_BOOL, "material_index", me->totpoly); + if (sharp_faces) { + sharp_faces = (bool *)CustomData_add_layer_named( + &me->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totpoly, "sharp_face"); + } COLLADAFW::MeshPrimitiveArray &prim_arr = collada_mesh->getMeshPrimitives(); COLLADAFW::MeshVertexData &nor = collada_mesh->getNormals(); @@ -665,13 +671,14 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */ /* The same for vertices normals. */ uint vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]}; - if (!is_flat_face(vertex_normal_indices, nor, 3)) { - mpoly->flag |= ME_SMOOTH; + if (is_flat_face(vertex_normal_indices, nor, 3)) { + *sharp_faces = true; } normal_indices++; } mpoly++; + sharp_faces++; if (material_indices) { material_indices++; } @@ -738,7 +745,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, /* If it turns out that we have complete custom normals for each MPoly * and we want to use custom normals, this will be overridden. */ if (!is_flat_face(normal_indices, nor, vcount)) { - mpoly->flag |= ME_SMOOTH; + *sharp_faces = true; } if (use_custom_normals) { @@ -775,6 +782,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, } mpoly++; + sharp_faces++; if (material_indices) { material_indices++; } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index 040fb52ce7c..ad2cbb112b3 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -196,14 +196,17 @@ void OBJMesh::ensure_mesh_normals() const void OBJMesh::calc_smooth_groups(const bool use_bitflags) { - poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.data(), - mesh_edges_.size(), - mesh_polys_.data(), - mesh_polys_.size(), - mesh_loops_.data(), - mesh_loops_.size(), - &tot_smooth_groups_, - use_bitflags); + poly_smooth_groups_ = BKE_mesh_calc_smoothgroups( + mesh_edges_.data(), + mesh_edges_.size(), + mesh_polys_.data(), + static_cast( + CustomData_get_layer_named(&export_mesh_->pdata, CD_PROP_BOOL, "sharp_face")), + mesh_polys_.size(), + mesh_loops_.data(), + mesh_loops_.size(), + &tot_smooth_groups_, + use_bitflags); } void OBJMesh::calc_poly_order() diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 078ec24271c..8a30a876867 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -93,19 +93,20 @@ typedef struct MPoly { int totloop; /** Deprecated material index. Now stored in the "material_index" attribute, but kept for IO. */ short mat_nr_legacy; - char flag, _pad; + char flag_legacy, _pad; } MPoly; /** #MPoly.flag */ -enum { #ifdef DNA_DEPRECATED_ALLOW +enum { + /** Deprecated smooth shading status. Now stored reversed in "sharp_face" attribute. */ ME_SMOOTH = (1 << 0), /** Deprecated selection status. Now stored in ".select_poly" attribute. */ ME_FACE_SEL = (1 << 1), -#endif /** Deprecated hide status. Now stored in ".hide_poly" attribute. */ /* ME_HIDE = (1 << 4), */ }; +#endif /** * Mesh Face Corners. diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index b2bf0aead90..6c19c24ad26 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -108,6 +108,7 @@ DNA_STRUCT_RENAME_ELEM(Object_Runtime, crazyspace_num_verts, crazyspace_verts_nu DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy) DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy) DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy) +DNA_STRUCT_RENAME_ELEM(MPoly, flag, flag_legacy) DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy) DNA_STRUCT_RENAME_ELEM(MVert, flag, flag_legacy) DNA_STRUCT_RENAME_ELEM(ParticleSettings, child_nbr, child_percent) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 20675417401..625abb1caaf 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1536,14 +1536,13 @@ static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr) static bool rna_MeshLoopTriangle_use_smooth_get(PointerRNA *ptr) { + const Mesh *me = rna_mesh(ptr); const bool *sharp_faces = (const bool *)CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face"); + &me->pdata, CD_PROP_BOOL, "sharp_face"); if (!sharp_faces) { return true; } - const Mesh *me = rna_mesh(ptr); const MLoopTri *ltri = (MLoopTri *)ptr->data; - const MPoly *polys = BKE_mesh_polys(me); return sharp_faces[ltri->poly]; } diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 0675c39299e..ecacae5e7c8 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -91,14 +91,16 @@ static void rna_Mesh_calc_smooth_groups( Mesh *mesh, bool use_bitflags, int *r_poly_group_len, int **r_poly_group, int *r_group_total) { *r_poly_group_len = mesh->totpoly; - *r_poly_group = BKE_mesh_calc_smoothgroups(BKE_mesh_edges(mesh), - mesh->totedge, - BKE_mesh_polys(mesh), - mesh->totpoly, - BKE_mesh_loops(mesh), - mesh->totloop, - r_group_total, - use_bitflags); + *r_poly_group = BKE_mesh_calc_smoothgroups( + BKE_mesh_edges(mesh), + mesh->totedge, + BKE_mesh_polys(mesh), + (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"), + mesh->totpoly, + BKE_mesh_loops(mesh), + mesh->totloop, + r_group_total, + use_bitflags); } static void rna_Mesh_normals_split_custom_do(Mesh *mesh, diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index cc25f032228..64a2f87d6e6 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -339,6 +339,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, loops_num, mpoly, poly_normals, + static_cast(CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face")), polys_num, clnors); @@ -455,6 +457,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, loops_num, mpoly, poly_normals, + static_cast(CustomData_get_layer_named( + &mesh->pdata, CD_PROP_BOOL, "sharp_face")), polys_num, clnors); @@ -559,6 +563,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, loops_num, polys, poly_normals, + static_cast(CustomData_get_layer_named( + &result->pdata, CD_PROP_BOOL, "sharp_face")), polys_num, true, result->smoothresh, diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 08e9569bd95..612c84d72bd 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -1081,7 +1081,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex CustomData_copy_data( &mesh->pdata, &result->pdata, (int)pidx, (int)((polys_num * stride) + i), 1); mp->loopstart = (int)(j + (loops_num * stride)); - mp->flag = mpoly[pidx].flag; /* notice we use 'mp->totloop' which is later overwritten, * we could lookup the original face but there's no point since this is a copy diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 9d0b5c30b5e..9ff44cfbbeb 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -2300,7 +2300,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, dst_material_index[poly_index] = most_mat_nr + (g->is_orig_closed || !do_rim ? 0 : mat_ofs_rim); CLAMP(dst_material_index[poly_index], 0, mat_nr_max); - mpoly[poly_index].flag = orig_mpoly[most_mat_nr_face].flag; poly_index++; for (uint k = 0; g2->valid && k < j; g2++) { @@ -2376,7 +2375,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, dst_material_index[poly_index] = (src_material_index ? src_material_index[orig_face_index] : 0) + mat_ofs_rim; CLAMP(dst_material_index[poly_index], 0, mat_nr_max); - mpoly[poly_index].flag = face->flag; poly_index++; int loop1 = -1; @@ -2569,7 +2567,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, 0) + (fr->reversed != do_flip ? mat_ofs : 0); CLAMP(dst_material_index[poly_index], 0, mat_nr_max); - mpoly[poly_index].flag = fr->face->flag; if (fr->reversed != do_flip) { for (int l = (int)k - 1; l >= 0; l--) { if (shell_defgrp_index != -1) { diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index a7278d13093..f89cced0188 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -84,6 +84,7 @@ struct WeightedNormalData { const MPoly *mpoly; const float (*poly_normals)[3]; + const bool *sharp_faces; const int *poly_strength; const MDeformVert *dvert; @@ -233,6 +234,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, + wn_data->sharp_faces, polys_num, true, split_angle, @@ -365,6 +367,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, + wn_data->sharp_faces, polys_num, clnors); } @@ -396,6 +399,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, + wn_data->sharp_faces, polys_num, clnors); @@ -415,6 +419,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, + wn_data->sharp_faces, polys_num, true, split_angle, @@ -439,6 +444,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, + wn_data->sharp_faces, polys_num, clnors); } @@ -642,6 +648,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * wn_data.mpoly = mpoly; wn_data.poly_normals = BKE_mesh_poly_normals_ensure(mesh); + wn_data.sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); wn_data.poly_strength = static_cast(CustomData_get_layer_named( &result->pdata, CD_PROP_INT32, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index a36413e49b2..17173cd84da 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -163,7 +163,6 @@ static MPoly new_poly(const int loopstart, const int totloop) MPoly poly; poly.loopstart = loopstart; poly.totloop = totloop; - poly.flag = 0; return poly; } -- 2.30.2 From 4c30b950b66a26bf00f29affcd73c62ea56a3072 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 14:43:55 -0500 Subject: [PATCH 04/25] Remove attribute in set shade smooth node --- .../nodes/node_geo_set_shade_smooth.cc | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc index cab21db2493..b2171677538 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc @@ -14,6 +14,30 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Geometry")).propagate_all(); } +/** + * When the `sharp_face` attribute doesn't exist, all faces are considered smooth. If all faces + * are selected and the sharp value is a constant false value, we can remove the attribute instead, + * as an optimization to avoid propagating and storing it in the future. + */ +static bool try_removing_sharp_attribute(Mesh &mesh, + const Field &selection_field, + const Field &sharp_field) +{ + if (selection_field.node().depends_on_input() || sharp_field.node().depends_on_input()) { + return false; + } + const bool selection = fn::evaluate_constant_field(selection_field); + if (!selection) { + return true; + } + const bool sharp = fn::evaluate_constant_field(sharp_field); + if (sharp) { + return false; + } + mesh.attributes_for_write().remove("sharp_face"); + return true; +} + static void set_smooth(Mesh &mesh, const Field &selection_field, const Field &sharp_field) @@ -22,6 +46,10 @@ static void set_smooth(Mesh &mesh, return; } + if (try_removing_sharp_attribute(mesh, selection_field, sharp_field)) { + return; + } + MutableAttributeAccessor attributes = mesh.attributes_for_write(); AttributeWriter sharp_faces = attributes.lookup_or_add_for_write("sharp_face", ATTR_DOMAIN_FACE); @@ -43,7 +71,6 @@ static void node_geo_exec(GeoNodeExecParams params) geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (Mesh *mesh = geometry_set.get_mesh_for_write()) { - /* TODO: Do this with nodes instead. */ set_smooth(*mesh, selection_field, fn::invert_boolean_field(smooth_field)); } }); -- 2.30.2 From cfa65938604957694de2723b558011810f6eab3b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 14:46:40 -0500 Subject: [PATCH 05/25] Don't move sharp face attribute to BMesh --- source/blender/blenkernel/intern/customdata.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 60d38895a89..60ddb146d57 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2378,7 +2378,8 @@ static bool attribute_stored_in_bmesh_flag(const StringRef name) ".select_vert", ".select_edge", ".select_poly", - "material_index"); + "material_index", + "sharp_face"); } CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src, -- 2.30.2 From 6a596e03faf20653639c917de99b69c02ea47edc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 14:46:50 -0500 Subject: [PATCH 06/25] Fix Mesh BMesh conversion --- .../blender/bmesh/intern/bmesh_mesh_convert.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 6f5d79237bd..f0381385cd4 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1082,7 +1082,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh } if (need_sharp_face) { BM_mesh_elem_table_ensure(bm, BM_FACE); - write_fn_to_attribute( + write_fn_to_attribute( me->attributes_for_write(), "sharp_face", ATTR_DOMAIN_FACE, [&](const int i) { return !BM_elem_flag_test(BM_face_at_index(bm, i), BM_ELEM_SMOOTH); }); @@ -1321,6 +1321,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * BM_elem_index_set(efa, i); /* set_inline */ mp->totloop = efa->len; + if (!BM_elem_flag_test(efa, BM_ELEM_SMOOTH)) { + if (!sharp_face_attribute) { + sharp_face_attribute = mesh_attributes.lookup_or_add_for_write_span( + "sharp_face", ATTR_DOMAIN_FACE); + } + sharp_face_attribute.span[i] = true; + } if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (!hide_poly_attribute) { hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_span(".hide_poly", @@ -1342,13 +1349,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * material_index_attribute = mesh_attributes.lookup_or_add_for_write_span( "material_index", ATTR_DOMAIN_FACE); } - } - if (!BM_elem_flag_test(efa, BM_ELEM_SMOOTH)) { - if (!sharp_face_attribute) { - sharp_face_attribute = mesh_attributes.lookup_or_add_for_write_span( - "sharp_face", ATTR_DOMAIN_FACE); - } - sharp_face_attribute.span[i] = true; + material_index_attribute.span[i] = efa->mat_nr; } l_iter = l_first = BM_FACE_FIRST_LOOP(efa); @@ -1370,6 +1371,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * assert_bmesh_has_no_mesh_only_attributes(*bm); material_index_attribute.finish(); + sharp_face_attribute.finish(); hide_vert_attribute.finish(); hide_edge_attribute.finish(); hide_poly_attribute.finish(); -- 2.30.2 From ad44bfbb6de98972e307f2b749acb33f81e34e7d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 14:47:17 -0500 Subject: [PATCH 07/25] Set sharp flag in many places to keep default behavior unchanged --- source/blender/blenkernel/intern/volume_to_mesh.cc | 1 + source/blender/editors/object/object_remesh.cc | 8 ++------ source/blender/geometry/intern/mesh_primitive_cuboid.cc | 1 + source/blender/modifiers/intern/MOD_volume_to_mesh.cc | 4 +--- .../blender/nodes/geometry/nodes/node_geo_convex_hull.cc | 2 ++ .../blender/nodes/geometry/nodes/node_geo_curve_fill.cc | 1 + source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc | 1 + .../geometry/nodes/node_geo_mesh_primitive_circle.cc | 1 + .../nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc | 1 + .../nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc | 1 + .../geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc | 1 + .../nodes/geometry/nodes/node_geo_volume_to_mesh.cc | 1 + 12 files changed, 14 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index f3bb8726b4f..90797a68a57 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -183,6 +183,7 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid, mesh->loops_for_write()); BKE_mesh_calc_edges(mesh, false, false); + BKE_mesh_smooth_flag_set(mesh, false); return mesh; } diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index 04cd6ec4212..ff239ce3069 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -179,9 +179,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob); - if (smooth_normals) { - BKE_mesh_smooth_flag_set(static_cast(ob->data), true); - } + BKE_mesh_smooth_flag_set(static_cast(ob->data), smooth_normals); if (ob->mode == OB_MODE_SCULPT) { ED_sculpt_undo_geometry_end(ob); @@ -903,9 +901,7 @@ static void quadriflow_start_job(void *customdata, bool *stop, bool *do_update, BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob); - if (qj->smooth_normals) { - BKE_mesh_smooth_flag_set(static_cast(ob->data), true); - } + BKE_mesh_smooth_flag_set(static_cast(ob->data), qj->smooth_normals); if (ob->mode == OB_MODE_SCULPT) { ED_sculpt_undo_geometry_end(ob); diff --git a/source/blender/geometry/intern/mesh_primitive_cuboid.cc b/source/blender/geometry/intern/mesh_primitive_cuboid.cc index a014c488a3b..d74c76e1b1d 100644 --- a/source/blender/geometry/intern/mesh_primitive_cuboid.cc +++ b/source/blender/geometry/intern/mesh_primitive_cuboid.cc @@ -408,6 +408,7 @@ Mesh *create_cuboid_mesh(const float3 &size, MutableSpan verts = mesh->verts_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + BKE_mesh_smooth_flag_set(mesh, false); calculate_verts(config, verts); diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc index 2a8883dc2eb..08833e1cac1 100644 --- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc +++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc @@ -183,9 +183,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } BKE_mesh_copy_parameters_for_eval(mesh, input_mesh); - if (vmmd->flag & VOLUME_TO_MESH_USE_SMOOTH_SHADE) { - BKE_mesh_smooth_flag_set(mesh, true); - } + BKE_mesh_smooth_flag_set(mesh, vmmd->flag & VOLUME_TO_MESH_USE_SMOOTH_SHADE); return mesh; #else UNUSED_VARS(md); diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 825913fb985..f445a76308a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -45,6 +45,8 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) BKE_id_material_eval_ensure_default_slot(&result->id); } + BKE_mesh_smooth_flag_set(result, false); + /* Copy vertices. */ MutableSpan dst_verts = result->verts_for_write(); for (const int i : IndexRange(verts_num)) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index a14661b4a50..25c03204d60 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -105,6 +105,7 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result &result) /* The delaunay triangulation doesn't seem to return all of the necessary edges, even in * triangulation mode. */ BKE_mesh_calc_edges(mesh, true, false); + BKE_mesh_smooth_flag_set(mesh, false); return mesh; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index b076f0b7261..d06683dd7e3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -886,6 +886,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, } Mesh *mesh_out = BKE_mesh_new_nomain( vertex_positions.size(), new_edges.size(), 0, loops.size(), loop_lengths.size()); + BKE_mesh_smooth_flag_set(mesh_out, false); transfer_attributes(vertex_types, keep_boundaries, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index fca2f0b7313..c96f7e8523c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -109,6 +109,7 @@ static Mesh *create_circle_mesh(const float radius, circle_corner_total(fill_type, verts_num), circle_face_total(fill_type, verts_num)); BKE_id_material_eval_ensure_default_slot(&mesh->id); + BKE_mesh_smooth_flag_set(mesh, false); MutableSpan verts = mesh->verts_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 9e92527f393..f2b664323ef 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -690,6 +690,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, Mesh *mesh = BKE_mesh_new_nomain( config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces); + BKE_mesh_smooth_flag_set(mesh, false); BKE_id_material_eval_ensure_default_slot(&mesh->id); MutableSpan verts = mesh->verts_for_write(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index b05a6d8019e..b35f910fab4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -54,6 +54,7 @@ Mesh *create_grid_mesh(const int verts_x, 0, edges_x * edges_y * 4, edges_x * edges_y); + BKE_mesh_smooth_flag_set(mesh, false); MutableSpan verts = mesh->verts_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index ff40a970785..e2863e6ae74 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -315,6 +315,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, 0, sphere_corner_total(segments, rings), sphere_face_total(segments, rings)); + BKE_mesh_smooth_flag_set(mesh, false); BKE_id_material_eval_ensure_default_slot(&mesh->id); MutableSpan verts = mesh->verts_for_write(); MutableSpan edges = mesh->edges_for_write(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc index c076a6c08f3..9584f683ec6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc @@ -141,6 +141,7 @@ static Mesh *create_mesh_from_volume_grids(Span gri } BKE_mesh_calc_edges(mesh, false, false); + BKE_mesh_smooth_flag_set(mesh, false); return mesh; } -- 2.30.2 From bbff1aaed1a2515c617ba2bf0020728a5085ce1e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 5 Jan 2023 15:48:12 -0500 Subject: [PATCH 08/25] Keep existing behavior in curve to mesh node --- .../intern/curve_to_mesh_convert.cc | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index e3b94b8ec95..7f464090d96 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -647,6 +647,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { fill_mesh_topology(info.vert_range.start(), @@ -663,6 +664,23 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, polys); }); + if (fill_caps) { + /* TODO: This is used to keep the tests passing after refactoring mesh shade smooth flags. It + * can be removed if the tests are updated and the final shading results will be the same. */ + SpanAttributeWriter sharp_faces = mesh_attributes.lookup_or_add_for_write_span( + "sharp_face", ATTR_DOMAIN_FACE); + foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { + const bool has_caps = fill_caps && !info.main_cyclic && info.profile_cyclic; + if (has_caps) { + const int poly_num = info.main_segment_num * info.profile_segment_num; + const int cap_poly_offset = info.poly_range.start() + poly_num; + sharp_faces.span[cap_poly_offset] = true; + sharp_faces.span[cap_poly_offset + 1] = true; + } + }); + sharp_faces.finish(); + } + const Span main_positions = main.evaluated_positions(); const Span tangents = main.evaluated_tangents(); const Span normals = main.evaluated_normals(); @@ -714,8 +732,6 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, Set main_attributes_set; - MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); - main_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { if (!should_add_attribute_to_mesh( main_attributes, mesh_attributes, id, meta_data, propagation_info)) { -- 2.30.2 From b9e67ee1d6ffac24dcb1a3091fb45c092ec18775 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 16:34:49 -0500 Subject: [PATCH 09/25] Cleanup: Rearrange arguments --- source/blender/blenkernel/BKE_mesh.h | 2 +- source/blender/blenkernel/intern/data_transfer.cc | 5 +++-- source/blender/blenkernel/intern/key.cc | 5 +++-- source/blender/blenkernel/intern/mesh.cc | 6 +++--- source/blender/blenkernel/intern/mesh_mirror.cc | 5 +++-- source/blender/blenkernel/intern/mesh_normals.cc | 6 +++--- source/blender/blenkernel/intern/mesh_remap.cc | 5 +++-- .../draw/intern/draw_cache_extract_mesh_render_data.cc | 2 +- source/blender/modifiers/intern/MOD_normal_edit.cc | 6 +++--- source/blender/modifiers/intern/MOD_weighted_normal.cc | 4 ++-- 10 files changed, 25 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index f705248e52e..d96db499892 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -609,11 +609,11 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], - const bool *sharp_faces, int numPolys, bool use_split_normals, float split_angle, const bool *sharp_edges, + const bool *sharp_faces, const int *loop_to_poly_map, MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2]); diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 17da2eb8596..f6f405f7be7 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -290,6 +290,8 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, if (dirty_nors_dst || do_loop_nors_dst) { const bool *sharp_edges = static_cast( CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_split(positions_dst, BKE_mesh_vertex_normals_ensure(me_dst), num_verts_dst, @@ -300,12 +302,11 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, num_loops_dst, polys_dst, BKE_mesh_poly_normals_ensure(me_dst), - static_cast(CustomData_get_layer_named( - &me_dst->pdata, CD_PROP_BOOL, "sharp_face")), num_polys_dst, use_split_nors_dst, split_angle_dst, sharp_edges, + sharp_faces, nullptr, nullptr, custom_nors_dst); diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index fdea39fef67..3f17416e1e6 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2276,6 +2276,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); /* May be nullptr. */ const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_split(positions, vert_normals, mesh->totvert, @@ -2286,12 +2288,11 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, mesh->totloop, polys, poly_normals, - static_cast(CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face")), mesh->totpoly, (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, sharp_edges, + sharp_faces, nullptr, nullptr, clnors); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 8277fa13b81..b0fbfbf1a5e 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1844,7 +1844,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, short(*clnors)[2] = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); - + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); const Span positions = mesh->vert_positions(); const Span edges = mesh->edges(); const Span polys = mesh->polys(); @@ -1860,12 +1861,11 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), - static_cast(CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face")), polys.size(), use_split_normals, split_angle, sharp_edges, + sharp_faces, nullptr, r_lnors_spacearr, clnors); diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index da03fbc4266..8c5903da999 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -410,6 +410,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&result->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result), BKE_mesh_vertex_normals_ensure(result), result->totvert, @@ -420,12 +422,11 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, totloop, BKE_mesh_polys(result), BKE_mesh_poly_normals_ensure(result), - static_cast(CustomData_get_layer_named( - &result->pdata, CD_PROP_BOOL, "sharp_face")), totpoly, true, mesh->smoothresh, sharp_edges, + sharp_faces, nullptr, &lnors_spacearr, clnors); diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index b1463204ce8..726437400e8 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -1451,11 +1451,11 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], - const bool *sharp_faces, const int numPolys, const bool use_split_normals, const float split_angle, const bool *sharp_edges, + const bool *sharp_faces, const int *loop_to_poly_map, MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2]) @@ -1659,11 +1659,11 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], numLoops, mpolys, poly_normals, - sharp_faces, numPolys, use_split_normals, split_angle, sharp_edges.data(), + sharp_faces, loop_to_poly.data(), &lnors_spacearr, nullptr); @@ -1788,11 +1788,11 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], numLoops, mpolys, poly_normals, - sharp_faces, numPolys, use_split_normals, split_angle, sharp_edges.data(), + sharp_faces, loop_to_poly.data(), &lnors_spacearr, nullptr); diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index c761f8284c3..08918a26b57 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -1370,6 +1370,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, if (dirty_nors_dst || do_loop_nors_dst) { const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mesh_dst->edata, CD_PROP_BOOL, "sharp_edge")); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh_dst->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_split(vert_positions_dst, BKE_mesh_vertex_normals_ensure(mesh_dst), numverts_dst, @@ -1380,12 +1382,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, numloops_dst, polys_dst, poly_nors_dst, - static_cast(CustomData_get_layer_named( - &mesh_dst->pdata, CD_PROP_BOOL, "sharp_face")), numpolys_dst, use_split_nors_dst, split_angle_dst, sharp_edges, + sharp_faces, nullptr, nullptr, custom_nors_dst); 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 2c9b927a06e..16a70d889b4 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 @@ -380,11 +380,11 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ mr->loop_len, mr->mpoly, mr->poly_normals, - mr->sharp_faces, mr->poly_len, is_auto_smooth, split_angle, sharp_edges, + mr->sharp_faces, nullptr, nullptr, clnors); diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index cb188f72c55..8ec68021069 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -563,7 +563,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num)); loop_normals = static_cast( MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__)); - + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&result->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_split(positions, vert_normals, verts_num, @@ -574,12 +575,11 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, loops_num, polys, poly_normals, - static_cast(CustomData_get_layer_named( - &result->pdata, CD_PROP_BOOL, "sharp_face")), polys_num, true, result->smoothresh, sharp_edges.span.data(), + sharp_faces, nullptr, nullptr, clnors); diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 6d5e9d7070e..efbe251d19f 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -236,11 +236,11 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, - wn_data->sharp_faces, polys_num, true, split_angle, wn_data->sharp_edges, + wn_data->sharp_faces, loop_to_poly.data(), &lnors_spacearr, has_clnors ? clnors : nullptr); @@ -424,11 +424,11 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loops_num, mpoly, poly_normals, - wn_data->sharp_faces, polys_num, true, split_angle, wn_data->sharp_edges, + wn_data->sharp_faces, loop_to_poly.data(), nullptr, has_clnors ? clnors : nullptr); -- 2.30.2 From 79e600f75e06971682c5e7bd7444a07d3718e7c0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 16:35:15 -0500 Subject: [PATCH 10/25] Cleanup: Rename functions --- source/blender/blenkernel/BKE_mesh_legacy_convert.h | 4 ++-- source/blender/blenkernel/intern/mesh.cc | 2 +- source/blender/blenkernel/intern/mesh_legacy_convert.cc | 4 ++-- source/blender/blenloader/intern/versioning_400.cc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index d0747a07efe..a92d69d4be6 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -95,8 +95,8 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh); void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh); void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh); -void BKE_mesh_sharp_faces_to_flags(struct Mesh *mesh); -void BKE_mesh_sharp_faces_from_flags(struct Mesh *mesh); +void BKE_mesh_legacy_sharp_faces_to_flags(struct Mesh *mesh); +void BKE_mesh_legacy_sharp_faces_from_flags(struct Mesh *mesh); void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh); void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index b0fbfbf1a5e..c1f9bba7659 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -269,7 +269,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address BKE_mesh_legacy_convert_hide_layers_to_flags(mesh); BKE_mesh_legacy_convert_selection_layers_to_flags(mesh); BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh); - BKE_mesh_sharp_faces_to_flags(mesh); + BKE_mesh_legacy_sharp_faces_to_flags(mesh); BKE_mesh_legacy_bevel_weight_from_layers(mesh); BKE_mesh_legacy_face_set_from_generic(mesh, poly_layers); BKE_mesh_legacy_edge_crease_from_layers(mesh); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index f17a02b92ab..0bc28698aee 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1225,7 +1225,7 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh) /** \name Sharp Edge Conversion * \{ */ -void BKE_mesh_sharp_faces_to_flags(Mesh *mesh) +void BKE_mesh_legacy_sharp_faces_to_flags(Mesh *mesh) { using namespace blender; MutableSpan polys = mesh->polys_for_write(); @@ -1244,7 +1244,7 @@ void BKE_mesh_sharp_faces_to_flags(Mesh *mesh) } } -void BKE_mesh_sharp_faces_from_flags(Mesh *mesh) +void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh) { using namespace blender; using namespace blender::bke; diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 93d66c6f4e2..da3a0018d24 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -31,7 +31,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) BKE_mesh_legacy_convert_flags_to_hide_layers(&mesh); BKE_mesh_legacy_convert_uvs_to_generic(&mesh); BKE_mesh_legacy_convert_mpoly_to_material_indices(&mesh); - BKE_mesh_sharp_faces_from_flags(&mesh); + BKE_mesh_legacy_sharp_faces_from_flags(&mesh); BKE_mesh_legacy_bevel_weight_to_layers(&mesh); BKE_mesh_legacy_sharp_edges_from_flags(&mesh); BKE_mesh_legacy_face_set_to_generic(&mesh); -- 2.30.2 From 6b32a9a956d5e0f9e64d65be834f45220839fb56 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 16:38:41 -0500 Subject: [PATCH 11/25] Cleanup: Rearrange arguments --- source/blender/blenkernel/BKE_mesh_mapping.h | 2 +- .../blender/blenkernel/intern/mesh_legacy_convert.cc | 2 +- source/blender/blenkernel/intern/mesh_mapping.cc | 2 +- source/blender/editors/mesh/mesh_data.cc | 10 ++++++---- .../io/wavefront_obj/exporter/obj_export_mesh.cc | 2 +- source/blender/makesrna/intern/rna_mesh_api.c | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index 6e415e03f95..c8561372e30 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -319,11 +319,11 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge, int totedge, const struct MPoly *mpoly, - const bool *sharp_faces, int totpoly, const struct MLoop *mloop, int totloop, const bool *sharp_edges, + const bool *sharp_faces, int *r_totgroup, bool use_bitflags); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 0bc28698aee..7083c9880de 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -450,7 +450,7 @@ static void convert_mfaces_to_mpolys(ID *id, } bool *sharp_faces = static_cast( CustomData_get_layer_named(pdata, CD_PROP_BOOL, "sharp_face")); - if (sharp_faces == nullptr) { + if (!sharp_faces) { sharp_faces = static_cast(CustomData_add_layer_named( pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, totpoly, "sharp_face")); } diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 4460465a50b..76534a9de2b 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -871,11 +871,11 @@ static bool poly_is_island_boundary_smooth_cb(const int poly_index, int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge, const MPoly *mpoly, - const bool *sharp_faces, const int totpoly, const MLoop *mloop, const int totloop, const bool *sharp_edges, + const bool *sharp_faces, int *r_totgroup, const bool use_bitflags) { diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 835fa5f6c1e..e2cb1286356 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -868,13 +868,14 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator bke::MutableAttributeAccessor attributes = me->attributes_for_write(); bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", ATTR_DOMAIN_EDGE); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, "sharp_face")); BKE_edges_sharp_from_angle_set(me->totedge, loops.data(), loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(me), - static_cast(CustomData_get_layer_named( - &me->pdata, CD_PROP_BOOL, "sharp_face")), + sharp_faces, polys.size(), me->smoothresh, sharp_edges.span.data()); @@ -1542,13 +1543,14 @@ void ED_mesh_split_faces(Mesh *mesh) const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); Array sharp_edges(mesh->totedge, false); + const bool *sharp_faces_ptr = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); BKE_edges_sharp_from_angle_set(mesh->totedge, loops.data(), loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), - static_cast(CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face")), + sharp_faces_ptr, polys.size(), split_angle, sharp_edges.data()); diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index 97d8276071e..76732ce8326 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -203,11 +203,11 @@ void OBJMesh::calc_smooth_groups(const bool use_bitflags) poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.data(), mesh_edges_.size(), mesh_polys_.data(), - sharp_faces, mesh_polys_.size(), mesh_loops_.data(), mesh_loops_.size(), sharp_edges, + sharp_faces, &tot_smooth_groups_, use_bitflags); } diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index c5bb1841189..12138705641 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -99,10 +99,10 @@ static void rna_Mesh_calc_smooth_groups( mesh->totedge, BKE_mesh_polys(mesh), mesh->totpoly, - sharp_faces, BKE_mesh_loops(mesh), mesh->totloop, sharp_edges, + sharp_faces, r_group_total, use_bitflags); } -- 2.30.2 From 4ed7b4338da93fe594cec04dd7740c91f1f8dee5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 21 Jan 2023 16:06:07 -0600 Subject: [PATCH 12/25] Fix build errors after merge --- source/blender/blenkernel/intern/curve_to_mesh_convert.cc | 2 -- source/blender/blenkernel/intern/data_transfer.cc | 3 ++- source/blender/blenkernel/intern/mesh_legacy_convert.cc | 2 +- source/blender/blenkernel/intern/subsurf_ccg.cc | 1 - source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc | 1 - source/blender/makesrna/intern/rna_mesh.c | 2 +- 6 files changed, 4 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 390f047c838..40eacdca168 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -738,8 +738,6 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, positions.slice(info.vert_range)); }); - MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); - SpanAttributeWriter sharp_edges; write_sharp_bezier_edges(curves_info, offsets, mesh_attributes, sharp_edges); if (fill_caps) { diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index cb9e82c7f62..6e8dbb4919c 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -1043,7 +1043,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_factor, mix_weights, CustomData_get_layer_named(&me_src->pdata, CD_PROP_BOOL, "sharp_face"), - CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face"), + CustomData_get_layer_named_for_write( + &me_dst->pdata, CD_PROP_BOOL, "sharp_face", num_elem_dst), interp, interp_data); return true; diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index a404820c283..0e97b334aec 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -454,7 +454,7 @@ static void convert_mfaces_to_mpolys(ID *id, pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, totpoly, "material_index")); } bool *sharp_faces = static_cast( - CustomData_get_layer_named(pdata, CD_PROP_BOOL, "sharp_face")); + CustomData_get_layer_named_for_write(pdata, CD_PROP_BOOL, "sharp_face", totpoly)); if (!sharp_faces) { sharp_faces = static_cast(CustomData_add_layer_named( pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, totpoly, "sharp_face")); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index a4e043556b4..3e91b7e962e 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -1565,7 +1565,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, medge = dm->getEdgeArray(dm); - const MPoly *mpoly = static_cast(CustomData_get_layer(&dm->polyData, CD_MPOLY)); const int *material_indices = static_cast( CustomData_get_layer_named(&dm->polyData, CD_MPOLY, "material_index")); const bool *sharp_faces = static_cast( diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index c191a079c8a..2e79450710c 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -2073,7 +2073,6 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_settings.userdata_chunk_size = sizeof(EdgeFeatReduceData); edge_feat_settings.func_reduce = feat_data_sum_reduce; - const bke::AttributeAccessor attributes = me->attributes(); const VArray sharp_edges = attributes.lookup_or_default( "sharp_edge", ATTR_DOMAIN_EDGE, false); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index f0f9fc9f9bf..c4baf1104e6 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -671,7 +671,7 @@ static bool rna_MeshPolygon_use_smooth_get(PointerRNA *ptr) static void rna_MeshPolygon_use_smooth_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *sharp_faces = (bool *)CustomData_duplicate_referenced_layer_named( + bool *sharp_faces = (bool *)CustomData_get_layer_named_for_write( &mesh->pdata, CD_PROP_BOOL, "sharp_face", mesh->totpoly); if (!sharp_faces) { if (value) { -- 2.30.2 From 61de7565de49b63432047ce6363471c6ac642258 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 22 Jan 2023 10:16:41 -0600 Subject: [PATCH 13/25] Various fixes and cleanups --- intern/cycles/blender/mesh.cpp | 2 +- source/blender/blenkernel/BKE_mesh.h | 4 +-- source/blender/blenkernel/intern/fluid.cc | 4 +++ .../blender/blenkernel/intern/mesh_convert.cc | 16 ++++++---- .../blenkernel/intern/mesh_legacy_convert.cc | 2 +- .../blender/blenkernel/intern/mesh_normals.cc | 12 +++---- .../blender/blenkernel/intern/mesh_tangent.cc | 9 +++--- .../bmesh/intern/bmesh_mesh_convert.cc | 20 ++++++------ .../intern/draw_cache_impl_subdivision.cc | 2 +- source/blender/editors/mesh/mesh_data.cc | 32 +++++++------------ .../intern/lineart/lineart_cpu.cc | 10 +++--- source/blender/io/collada/MeshImporter.cpp | 18 ++++------- .../wavefront_obj/exporter/obj_export_mesh.hh | 1 - .../wavefront_obj/importer/obj_import_mesh.cc | 4 +-- source/blender/makesrna/intern/rna_mesh.c | 6 ++-- .../modifiers/intern/MOD_normal_edit.cc | 12 +++---- source/blender/modifiers/intern/MOD_remesh.cc | 2 +- .../geometry/nodes/node_geo_convex_hull.cc | 1 - .../nodes/node_geo_mesh_primitive_circle.cc | 2 +- .../nodes/node_geo_mesh_primitive_cone.cc | 2 +- .../nodes/node_geo_mesh_primitive_grid.cc | 2 +- .../node_geo_mesh_primitive_uv_sphere.cc | 2 +- .../nodes/node_geo_set_shade_smooth.cc | 13 ++++---- 23 files changed, 83 insertions(+), 95 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index e242a184f2f..847c7358f7a 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -1005,7 +1005,7 @@ static void create_mesh(Scene *scene, if (sharp_faces) { return sharp_faces->data[poly_index].value(); } - return 0; + return false; }; /* create faces */ diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 11f22fd9e2a..28ae1d82aa4 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -473,7 +473,7 @@ void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh); * Used when defining an empty custom loop normals data layer, * to keep same shading as with auto-smooth! * - * \param sharp_faces: Optional array used to mark specific faces as sharp. + * \param sharp_faces: Optional array used to mark specific faces for sharp shading. */ void BKE_edges_sharp_from_angle_set(int numEdges, const struct MLoop *mloops, @@ -596,7 +596,7 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, * (splitting edges). * * \param loop_to_poly_map: Optional pre-created map from loops to their polygon. - * \param sharp_faces: Optional array used to mark specific faces as sharp. + * \param sharp_faces: Optional array used to mark specific faces for sharp shading. * \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on * each side of the edge. */ diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 81e7840e91c..e467d3ef6c9 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -3246,6 +3246,10 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, mpolys = BKE_mesh_polys_for_write(me); mloops = BKE_mesh_loops_for_write(me); + const bool is_sharp = orgmesh->attributes().lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false)[0]; + BKE_mesh_smooth_flag_set(me, !is_sharp); + /* Get size (dimension) but considering scaling. */ copy_v3_v3(cell_size_scaled, fds->cell_size); mul_v3_v3(cell_size_scaled, ob->scale); diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 0d3cce58736..9ac2da547ca 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -286,9 +286,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } } - if (!is_smooth) { - sharp_faces.span[dst_poly] = true; - } + sharp_faces.span[dst_poly] = !is_smooth; dst_poly++; dst_loop += 3; index += 3; @@ -371,9 +369,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } } - if (!is_smooth) { - sharp_faces.span[dst_poly] = true; - } + sharp_faces.span[dst_poly] = !is_smooth; dst_poly++; dst_loop += 4; @@ -390,6 +386,14 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba make_edges_mdata_extend(*mesh); } + int sharp_faces_count = 0; + for (const bool value : sharp_faces.span) { + if (value) { + sharp_faces_count++; + } + } + std::cout << "Number of sharp faces: " << sharp_faces_count << '\n'; + material_indices.finish(); sharp_faces.finish(); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 0e97b334aec..d5da9fbfdd2 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1855,7 +1855,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) ".select_poly", ATTR_DOMAIN_FACE); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - select_poly.span[i] = (polys[i].flag_legacy & ME_FACE_SEL) != 0; + select_poly.span[i] = polys[i].flag_legacy & ME_FACE_SEL; } }); select_poly.finish(); diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 8a939de01ac..077e5bad42c 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -802,7 +802,7 @@ static void mesh_edges_sharp_tag(const Span polys, { using namespace blender; const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f; - auto face_is_smooth = [&](const int poly_i) { + auto poly_is_smooth = [&](const int poly_i) { return sharp_faces.is_empty() || !sharp_faces[poly_i]; }; @@ -819,7 +819,7 @@ static void mesh_edges_sharp_tag(const Span polys, /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */ e2l[0] = loop_index; /* We have to check this here too, else we might miss some flat faces!!! */ - e2l[1] = (face_is_smooth(poly_i)) ? INDEX_UNSET : INDEX_INVALID; + e2l[1] = (poly_is_smooth(poly_i)) ? INDEX_UNSET : INDEX_INVALID; } else if (e2l[1] == INDEX_UNSET) { const bool is_angle_sharp = (check_angle && @@ -831,7 +831,7 @@ static void mesh_edges_sharp_tag(const Span polys, * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the * same vertex, or angle between both its polys' normals is above split_angle value. */ - if (!face_is_smooth(poly_i) || (!sharp_edges.is_empty() && sharp_edges[edge_i]) || + if (!poly_is_smooth(poly_i) || (!sharp_edges.is_empty() && sharp_edges[edge_i]) || vert_i == loops[e2l[0]].v || is_angle_sharp) { /* NOTE: we are sure that loop != 0 here ;). */ e2l[1] = INDEX_INVALID; @@ -1944,7 +1944,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", ATTR_DOMAIN_EDGE); - + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); mesh_normals_loop_custom_set(reinterpret_cast(positions.data()), BKE_mesh_vertex_normals_ensure(mesh), positions.size(), @@ -1955,8 +1956,7 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), - static_cast(CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face")), + sharp_faces, polys.size(), sharp_edges.span, clnors, diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index f8992262add..39188238640 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -278,15 +278,14 @@ struct SGLSLMeshToTangent { const float (*precomputedFaceNormals)[3]; const float (*precomputedLoopNormals)[3]; const MLoopTri *looptri; - const float2 *mloopuv; /* texture coordinates */ - const MPoly *mpoly; /* indices */ - const MLoop *mloop; /* indices */ - const MVert *mvert; /* vertex coordinates */ - const bool *sharp_faces; + const float2 *mloopuv; /* texture coordinates */ + const MPoly *mpoly; /* indices */ + const MLoop *mloop; /* indices */ const float (*positions)[3]; /* vertex coordinates */ const float (*vert_normals)[3]; const float (*orco)[3]; float (*tangent)[4]; /* destination */ + const bool *sharp_faces; int numTessFaces; #ifdef USE_LOOPTRI_DETECT_QUADS diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 49f2cc35878..40021a4e0ab 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -437,12 +437,12 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_elem_index_set(f, bm->totface - 1); /* set_ok */ /* Transfer flag. */ - if (hide_poly && hide_poly[i]) { - BM_elem_flag_enable(f, BM_ELEM_HIDDEN); - } if (!(sharp_faces && sharp_faces[i])) { BM_elem_flag_enable(f, BM_ELEM_SMOOTH); } + if (hide_poly && hide_poly[i]) { + BM_elem_flag_enable(f, BM_ELEM_HIDDEN); + } if (select_poly && select_poly[i]) { BM_face_select_set(bm, f, true); } @@ -1174,13 +1174,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh ATTR_DOMAIN_FACE, [&](const int i) { return int(BM_face_at_index(bm, i)->mat_nr); }); } - if (need_sharp_face) { - BM_mesh_elem_table_ensure(bm, BM_FACE); - write_fn_to_attribute( - me->attributes_for_write(), "sharp_face", ATTR_DOMAIN_FACE, [&](const int i) { - return !BM_elem_flag_test(BM_face_at_index(bm, i), BM_ELEM_SMOOTH); - }); - } if (need_sharp_edge) { BM_mesh_elem_table_ensure(bm, BM_EDGE); write_fn_to_attribute( @@ -1188,6 +1181,13 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh return !BM_elem_flag_test(BM_edge_at_index(bm, i), BM_ELEM_SMOOTH); }); } + if (need_sharp_face) { + BM_mesh_elem_table_ensure(bm, BM_FACE); + write_fn_to_attribute( + me->attributes_for_write(), "sharp_face", ATTR_DOMAIN_FACE, [&](const int i) { + return !BM_elem_flag_test(BM_face_at_index(bm, i), BM_ELEM_SMOOTH); + }); + } /* Patch hook indices and vertex parents. */ if (params->calc_object_remap && (ototvert > 0)) { diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 3f9647e634a..8eaf0962712 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -785,7 +785,7 @@ 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->sharp_faces && mr->sharp_faces[i])) { flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH; } flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET); diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index f22274eaf72..018feecf610 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -1542,40 +1542,30 @@ void ED_mesh_split_faces(Mesh *mesh) const Span polys = mesh->polys(); const Span loops = mesh->loops(); const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); Array sharp_edges(mesh->totedge, false); - const bool *sharp_faces_ptr = static_cast( - CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); BKE_edges_sharp_from_angle_set(mesh->totedge, loops.data(), loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), - sharp_faces_ptr, + sharp_faces, polys.size(), split_angle, sharp_edges.data()); - const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray sharp_faces = attributes.lookup_or_default( - "sharp_face", ATTR_DOMAIN_FACE, false); - if (const std::optional value = sharp_faces.get_if_single()) { - if (value) { - sharp_edges.fill(true); - } - } - else { - threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { - for (const int poly_i : range) { - const MPoly &poly = polys[poly_i]; - if (sharp_faces[poly_i]) { - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - sharp_edges[loop.e] = true; - } + threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { + for (const int poly_i : range) { + const MPoly &poly = polys[poly_i]; + if (sharp_faces && sharp_faces[poly_i]) { + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + sharp_edges[loop.e] = true; } } - }); - } + } + }); Vector split_indices; const IndexMask split_mask = index_mask_ops::find_indices_from_virtual_array( diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 2e79450710c..b68265168e6 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -1474,12 +1474,12 @@ struct EdgeFeatData { Object *ob_eval; /* For evaluated materials. */ const MLoopTri *mlooptri; const int *material_indices; - blender::VArray sharp_faces; blender::Span edges; blender::Span loops; blender::Span polys; LineartTriangle *tri_array; blender::VArray sharp_edges; + blender::VArray sharp_faces; LineartVert *v_array; float crease_threshold; bool use_auto_smooth; @@ -1937,9 +1937,6 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); const int tot_tri = BKE_mesh_runtime_looptri_len(me); - const bke::AttributeAccessor attributes = me->attributes(); - const VArray sharp_faces = attributes.lookup_or_default( - "sharp_face", ATTR_DOMAIN_FACE, false); const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); @@ -2073,8 +2070,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_settings.userdata_chunk_size = sizeof(EdgeFeatReduceData); edge_feat_settings.func_reduce = feat_data_sum_reduce; + const bke::AttributeAccessor attributes = me->attributes(); const VArray sharp_edges = attributes.lookup_or_default( "sharp_edge", ATTR_DOMAIN_EDGE, false); + const VArray sharp_faces = attributes.lookup_or_default( + "sharp_face", ATTR_DOMAIN_FACE, false); EdgeFeatData edge_feat_data = {nullptr}; edge_feat_data.ld = la_data; @@ -2082,11 +2082,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_data.ob_eval = ob_info->original_ob_eval; edge_feat_data.mlooptri = mlooptri; edge_feat_data.material_indices = material_indices; - edge_feat_data.sharp_faces = sharp_faces; edge_feat_data.edges = me->edges(); edge_feat_data.polys = me->polys(); edge_feat_data.loops = me->loops(); edge_feat_data.sharp_edges = sharp_edges; + edge_feat_data.sharp_faces = sharp_faces; edge_feat_data.edge_nabr = lineart_build_edge_neighbor(me, total_edges); edge_feat_data.tri_array = la_tri_arr; edge_feat_data.v_array = la_v_arr; diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 5531e62de6c..1b1b05aac09 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -625,11 +625,11 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, MaterialIdPrimitiveArrayMap mat_prim_map; int *material_indices = BKE_mesh_material_indices_for_write(me); - bool *sharp_faces = (bool *)CustomData_get_layer_named_for_write( - &me->pdata, CD_PROP_BOOL, "sharp_face", me->totpoly); - if (sharp_faces) { - sharp_faces = (bool *)CustomData_add_layer_named( - &me->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totpoly, "sharp_face"); + bool *sharp_faces = static_cast( + CustomData_get_layer_named_for_write(&me->pdata, CD_PROP_BOOL, "sharp_face", me->totpoly)); + if (!sharp_faces) { + sharp_faces = static_cast(CustomData_add_layer_named( + &me->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totpoly, "sharp_face")); } COLLADAFW::MeshPrimitiveArray &prim_arr = collada_mesh->getMeshPrimitives(); @@ -673,9 +673,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */ /* The same for vertices normals. */ uint vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]}; - if (is_flat_face(vertex_normal_indices, nor, 3)) { - *sharp_faces = true; - } + *sharp_faces = is_flat_face(vertex_normal_indices, nor, 3); normal_indices++; } @@ -746,9 +744,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, if (mp_has_normals) { /* If it turns out that we have complete custom normals for each MPoly * and we want to use custom normals, this will be overridden. */ - if (!is_flat_face(normal_indices, nor, vcount)) { - *sharp_faces = true; - } + *sharp_faces = is_flat_face(normal_indices, nor, vcount); if (use_custom_normals) { /* Store the custom normals for later application. */ diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh index 3c0c123cb68..21d212f5575 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -41,7 +41,6 @@ class OBJMesh : NonCopyable { Span mesh_edges_; Span mesh_polys_; Span mesh_loops_; - VArray sharp_faces_; /** diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 7a91f530ce9..6adff42192f 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -203,9 +203,7 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) MPoly &mpoly = polys[poly_idx]; mpoly.totloop = curr_face.corner_count_; mpoly.loopstart = tot_loop_idx; - if (!curr_face.shaded_smooth) { - sharp_faces.span[poly_idx] = true; - } + sharp_faces.span[poly_idx] = !curr_face.shaded_smooth; material_indices.span[poly_idx] = curr_face.material_index; /* Importing obj files without any materials would result in negative indices, which is not * supported. */ diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index c4baf1104e6..f73f40d34ee 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -674,8 +674,8 @@ static void rna_MeshPolygon_use_smooth_set(PointerRNA *ptr, bool value) bool *sharp_faces = (bool *)CustomData_get_layer_named_for_write( &mesh->pdata, CD_PROP_BOOL, "sharp_face", mesh->totpoly); if (!sharp_faces) { - if (value) { - /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */ + if (!value) { + /* Skip adding layer if the value is the same as the default. */ return; } sharp_faces = (bool *)CustomData_add_layer_named( @@ -2855,9 +2855,9 @@ static void rna_def_mpolygon(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_ui_text(prop, "Smooth", ""); RNA_def_property_boolean_funcs( prop, "rna_MeshPolygon_use_smooth_get", "rna_MeshPolygon_use_smooth_set"); + RNA_def_property_ui_text(prop, "Smooth", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 9b373bbe121..28e9b3aefb7 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -336,7 +336,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, /* We need to recompute vertex normals! */ BKE_mesh_normals_tag_dirty(mesh); } - + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_custom_set(vert_positions, BKE_mesh_vertex_normals_ensure(mesh), verts_num, @@ -347,8 +348,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, loops_num, mpoly, poly_normals, - static_cast(CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face")), + sharp_faces, polys_num, sharp_edges, clnors); @@ -460,7 +460,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, polys_num)) { BKE_mesh_normals_tag_dirty(mesh); } - + const bool *sharp_faces = static_cast( + CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); BKE_mesh_normals_loop_custom_set(positions, BKE_mesh_vertex_normals_ensure(mesh), verts_num, @@ -471,8 +472,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, loops_num, mpoly, poly_normals, - static_cast(CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, "sharp_face")), + sharp_faces, polys_num, sharp_edges, clnors); diff --git a/source/blender/modifiers/intern/MOD_remesh.cc b/source/blender/modifiers/intern/MOD_remesh.cc index 6e84ecbb9f0..8d0025628ab 100644 --- a/source/blender/modifiers/intern/MOD_remesh.cc +++ b/source/blender/modifiers/intern/MOD_remesh.cc @@ -197,7 +197,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, M MEM_freeN(output); } - BKE_mesh_smooth_flag_set(result, (rmd->flag & MOD_REMESH_SMOOTH_SHADING)); + BKE_mesh_smooth_flag_set(result, rmd->flag & MOD_REMESH_SMOOTH_SHADING); BKE_mesh_copy_parameters_for_eval(result, mesh); BKE_mesh_calc_edges(result, true, false); diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 5b40d27ddd4..624abf91424 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -44,7 +44,6 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) result = BKE_mesh_new_nomain(verts_num, edges_num, 0, loops_num, faces_num); BKE_id_material_eval_ensure_default_slot(&result->id); } - BKE_mesh_smooth_flag_set(result, false); /* Copy vertices. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index 687a9641c28..cac823a3878 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -109,11 +109,11 @@ static Mesh *create_circle_mesh(const float radius, circle_corner_total(fill_type, verts_num), circle_face_total(fill_type, verts_num)); BKE_id_material_eval_ensure_default_slot(&mesh->id); - BKE_mesh_smooth_flag_set(mesh, false); MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + BKE_mesh_smooth_flag_set(mesh, false); /* Assign vertex coordinates. */ const float angle_delta = 2.0f * (M_PI / float(verts_num)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 267b34b7163..137f1ae34b8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -690,13 +690,13 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, Mesh *mesh = BKE_mesh_new_nomain( config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces); - BKE_mesh_smooth_flag_set(mesh, false); BKE_id_material_eval_ensure_default_slot(&mesh->id); MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + BKE_mesh_smooth_flag_set(mesh, false); calculate_cone_verts(config, positions); calculate_cone_edges(config, edges); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index 62fe35108f8..21c794b7b38 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -54,11 +54,11 @@ Mesh *create_grid_mesh(const int verts_x, 0, edges_x * edges_y * 4, edges_x * edges_y); - BKE_mesh_smooth_flag_set(mesh, false); MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + BKE_mesh_smooth_flag_set(mesh, false); { const float dx = edges_x == 0 ? 0.0f : size_x / edges_x; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index 54c8ec8e2cf..c722108c3d8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -315,12 +315,12 @@ static Mesh *create_uv_sphere_mesh(const float radius, 0, sphere_corner_total(segments, rings), sphere_face_total(segments, rings)); - BKE_mesh_smooth_flag_set(mesh, false); BKE_id_material_eval_ensure_default_slot(&mesh->id); MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); + BKE_mesh_smooth_flag_set(mesh, false); threading::parallel_invoke( 1024 < segments * rings, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc index b2171677538..af80cf75e2e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc @@ -16,8 +16,8 @@ static void node_declare(NodeDeclarationBuilder &b) /** * When the `sharp_face` attribute doesn't exist, all faces are considered smooth. If all faces - * are selected and the sharp value is a constant false value, we can remove the attribute instead, - * as an optimization to avoid propagating and storing it in the future. + * are selected and the sharp value is a constant false value, we can remove the attribute instead + * as an optimization to avoid storing it and propagating it in the future. */ static bool try_removing_sharp_attribute(Mesh &mesh, const Field &selection_field, @@ -38,14 +38,13 @@ static bool try_removing_sharp_attribute(Mesh &mesh, return true; } -static void set_smooth(Mesh &mesh, - const Field &selection_field, - const Field &sharp_field) +static void set_sharp_faces(Mesh &mesh, + const Field &selection_field, + const Field &sharp_field) { if (mesh.totpoly == 0) { return; } - if (try_removing_sharp_attribute(mesh, selection_field, sharp_field)) { return; } @@ -71,7 +70,7 @@ static void node_geo_exec(GeoNodeExecParams params) geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (Mesh *mesh = geometry_set.get_mesh_for_write()) { - set_smooth(*mesh, selection_field, fn::invert_boolean_field(smooth_field)); + set_sharp_faces(*mesh, selection_field, fn::invert_boolean_field(smooth_field)); } }); params.set_output("Geometry", std::move(geometry_set)); -- 2.30.2 From d8abf380e072b946bd280e2321bd13f2b691bae5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 22 Jan 2023 11:11:33 -0600 Subject: [PATCH 14/25] Fix "use smooth" RNA access --- source/blender/makesrna/intern/rna_mesh.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index f73f40d34ee..d4a0df75269 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -665,7 +665,7 @@ static bool rna_MeshPolygon_use_smooth_get(PointerRNA *ptr) const bool *sharp_faces = (const bool *)CustomData_get_layer_named( &mesh->pdata, CD_PROP_BOOL, "sharp_face"); const int index = rna_MeshPolygon_index_get(ptr); - return sharp_faces == NULL ? false : sharp_faces[index]; + return !(sharp_faces && sharp_faces[index]); } static void rna_MeshPolygon_use_smooth_set(PointerRNA *ptr, bool value) @@ -1688,13 +1688,10 @@ static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr) static bool rna_MeshLoopTriangle_use_smooth_get(PointerRNA *ptr) { const Mesh *me = rna_mesh(ptr); + const MLoopTri *ltri = (MLoopTri *)ptr->data; const bool *sharp_faces = (const bool *)CustomData_get_layer_named( &me->pdata, CD_PROP_BOOL, "sharp_face"); - if (!sharp_faces) { - return true; - } - const MLoopTri *ltri = (MLoopTri *)ptr->data; - return sharp_faces[ltri->poly]; + return !(sharp_faces && sharp_faces[ltri->poly]); } /* path construction */ -- 2.30.2 From bd4c68658f214db9f157562a66e9c9e6764170fc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 22 Jan 2023 11:29:33 -0600 Subject: [PATCH 15/25] Fix screw modifier --- source/blender/blenkernel/intern/mesh_convert.cc | 8 -------- source/blender/modifiers/intern/MOD_screw.cc | 12 ++++++++++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 9ac2da547ca..ad8e4ec976a 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -386,14 +386,6 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba make_edges_mdata_extend(*mesh); } - int sharp_faces_count = 0; - for (const bool value : sharp_faces.span) { - if (value) { - sharp_faces_count++; - } - } - std::cout << "Number of sharp faces: " << sharp_faces_count << '\n'; - material_indices.finish(); sharp_faces.finish(); diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 76d611c1147..ec615c7883b 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -21,6 +21,7 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_lib_query.h" #include "BKE_mesh.h" @@ -179,6 +180,7 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) { + using namespace blender; const Mesh *mesh = meshData; Mesh *result; ScrewModifierData *ltmd = (ScrewModifierData *)md; @@ -245,6 +247,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ScrewVertConnect *vc, *vc_tmp, *vert_connect = nullptr; + const bool use_flat_shading = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) == 0; + /* don't do anything? */ if (!totvert) { return BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); @@ -387,6 +391,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEdge *medge_new = BKE_mesh_edges_for_write(result); MPoly *mpoly_new = BKE_mesh_polys_for_write(result); MLoop *mloop_new = BKE_mesh_loops_for_write(result); + bke::MutableAttributeAccessor attributes = result->attributes_for_write(); + bke::SpanAttributeWriter sharp_faces = attributes.lookup_or_add_for_write_span( + "sharp_face", ATTR_DOMAIN_FACE); if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) { CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, int(maxPolys)); @@ -863,6 +870,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * else { origindex[mpoly_index] = ORIGINDEX_NONE; dst_material_index[mpoly_index] = mat_nr; + sharp_faces.span[i] = use_flat_shading; } mp_new->loopstart = mpoly_index * 4; mp_new->totloop = 4; @@ -988,6 +996,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } #endif + sharp_faces.finish(); + if (edge_poly_map) { MEM_freeN(edge_poly_map); } @@ -1006,8 +1016,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ltmd->merge_dist); } - BKE_mesh_smooth_flag_set(result, ltmd->flag & MOD_SCREW_SMOOTH_SHADING); - return result; } -- 2.30.2 From 21fb2ebd0e6826555db73844e85611cc65eef873 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 10:30:46 -0600 Subject: [PATCH 16/25] Progress in versioning code --- .../blenloader/intern/versioning_300.cc | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 4c45e1433ab..16d9836a24a 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -14,6 +14,7 @@ #include "BLI_listbase.h" #include "BLI_math_vector.h" +#include "BLI_multi_value_map.hh" #include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_string_utils.h" @@ -919,6 +920,121 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree) } } +static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) +{ + using namespace blender; + Vector new_nodes; + LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) { + if (node->idname != StringRef("GeometryNodeExtrudeMesh")) { + continue; + } + const NodeGeometryExtrudeMesh &storage = *static_cast( + node->storage); + if (storage.mode != GEO_NODE_EXTRUDE_MESH_EDGES) { + continue; + } + bNodeSocket *geometry_in_socket = nodeFindSocket(node, SOCK_IN, "Geometry"); + bNodeSocket *geometry_out_socket = nodeFindSocket(node, SOCK_OUT, "Geometry"); + + Map in_links_per_socket; + MultiValueMap out_links_per_socket; + LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + in_links_per_socket.add(link->tosock, link); + out_links_per_socket.add(link->fromsock, link); + } + + bNodeLink *geometry_in_link = in_links_per_socket.lookup_default(geometry_in_socket, nullptr); + Span geometry_out_links = out_links_per_socket.lookup(geometry_in_socket); + if (!geometry_in_link || geometry_out_links.is_empty()) { + continue; + } + + const bool versioning_already_done = [&]() { + if (geometry_in_link->fromnode->idname != StringRef("GeometryNodeAttributeCapture")) { + return false; + } + bNode *capture_node = geometry_in_link->fromnode; + const NodeGeometryAttributeCapture &capture_storage = + *static_cast(capture_node->storage); + if (capture_storage.data_type != CD_PROP_BOOL || + capture_storage.domain != ATTR_DOMAIN_FACE) { + return false; + } + bNodeSocket *capture_in_socket = nodeFindSocket(capture_node, SOCK_IN, "Value_003"); + bNodeLink *link = in_links_per_socket.lookup_default(capture_in_socket, nullptr); + if (!link || link->fromnode->idname != StringRef("GeometryNodeInputShadeSmooth")) { + return false; + } + return true; + }(); + if (versioning_already_done) { + continue; + } + + bNode *capture_node = nullptr; + + if (!capture_node) { + capture_node = nodeAddNode(nullptr, &ntree, "GeometryNodeAttributeCapture"); + new_nodes.append(capture_node); + NodeGeometryAttributeCapture &capture_storage = *static_cast( + capture_node->storage); + capture_storage.data_type = CD_PROP_BOOL; + capture_storage.domain = ATTR_DOMAIN_FACE; + bNodeSocket *capture_out_socket = nodeFindSocket(capture_node, SOCK_OUT, "Attribute_003"); + bNode *is_smooth_node = nodeAddNode(nullptr, &ntree, "GeometryNodeInputShadeSmooth"); + nodeAddLink(&ntree, + is_smooth_node, + nodeFindSocket(is_smooth_node, SOCK_OUT, "Smooth"), + capture_node, + nodeFindSocket(capture_node, SOCK_IN, "Value_003")); + nodeAddLink(&ntree, + capture_node, + nodeFindSocket(capture_node, SOCK_OUT, "Geometry"), + capture_node, + geometry_in_socket); + geometry_in_link->tonode = capture_node; + geometry_in_link->tosock = nodeFindSocket(capture_node, SOCK_IN, "Geometry"); + } + + bNodeSocket *capture_out_socket = nodeFindSocket(capture_node, SOCK_OUT, "Attribute_003"); + + bNode *set_smooth_node = nullptr; + if (geometry_out_links.size() == 1) { + bNodeLink *link = geometry_out_links.first(); + if (link->tonode->idname == StringRef("GeometryNodeSetShadeSmooth")) { + } + } + + for (bNodeLink *link : geometry_out_links) { + if (link->tonode->idname == StringRef("GeometryNodeSetShadeSmooth")) { + set_smooth_nodes.append(link->tonode); + continue; + } + bNode *set_node = nodeAddNode(nullptr, &ntree, "GeometryNodeSetShadeSmooth"); + nodeAddLink(&ntree, ) + } + + for (bNode *set_smooth_node : set_smooth_nodes) { + bNodeSocket *in_socket = nodeFindSocket(set_smooth_node, SOCK_IN, "Shade Smooth"); + if (bNodeLink *link = in_links_per_socket.lookup_default(in_socket, nullptr)) { + if (link->fromnode == capture_smooth_node) { + continue; + } + } + nodeAddLink(&ntree, capture_smooth_node, capture_out_socket, set_smooth_node, in_socket); + } + } + + /* Move nodes to the front so that they are drawn behind existing nodes. */ + for (bNode *node : new_nodes) { + BLI_remlink(&ntree.nodes, node); + BLI_addhead(&ntree.nodes, node); + } + if (!new_nodes.is_empty()) { + nodeRebuildIDVector(&ntree); + } +} + void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/) { if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) { @@ -3912,5 +4028,10 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { + if (ntree->type == NTREE_GEOMETRY) { + version_geometry_nodes_extrude_smooth_propagation(*ntree); + } + } } } -- 2.30.2 From dcb60e2e0d759803b3f71b5d715518145fba08f4 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 15:52:27 -0600 Subject: [PATCH 17/25] More progress on versioning --- .../blenloader/intern/versioning_300.cc | 110 ++++++++++-------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 16d9836a24a..aac9b3c3435 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -961,8 +961,27 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) return false; } bNodeSocket *capture_in_socket = nodeFindSocket(capture_node, SOCK_IN, "Value_003"); - bNodeLink *link = in_links_per_socket.lookup_default(capture_in_socket, nullptr); - if (!link || link->fromnode->idname != StringRef("GeometryNodeInputShadeSmooth")) { + bNodeLink *capture_in_link = in_links_per_socket.lookup_default(capture_in_socket, nullptr); + if (!capture_in_link) { + return false; + } + if (capture_in_link->fromnode->idname != StringRef("GeometryNodeInputShadeSmooth")) { + return false; + } + if (geometry_out_links.size() != 1) { + return false; + } + bNodeLink *geometry_out_link = geometry_out_links.first(); + if (geometry_out_link->tonode->idname != StringRef("GeometryNodeSetShadeSmooth")) { + return false; + } + bNode *set_smooth_node = geometry_out_link->tonode; + bNodeSocket *smooth_in_socket = nodeFindSocket(set_smooth_node, SOCK_IN, "Shade Smooth"); + bNodeLink *connecting_link = in_links_per_socket.lookup_default(smooth_in_socket, nullptr); + if (!connecting_link) { + return false; + } + if (connecting_link->fromnode != capture_node) { return false; } return true; @@ -971,58 +990,51 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) continue; } - bNode *capture_node = nullptr; + bNode *capture_node = nodeAddNode(nullptr, &ntree, "GeometryNodeAttributeCapture"); + capture_node->parent = node->parent; + capture_node->locx = node->locx - 25; + capture_node->locx = node->locy; + new_nodes.append(capture_node); + static_cast(capture_node->storage)->data_type = CD_PROP_BOOL; + static_cast(capture_node->storage)->domain = ATTR_DOMAIN_FACE; - if (!capture_node) { - capture_node = nodeAddNode(nullptr, &ntree, "GeometryNodeAttributeCapture"); - new_nodes.append(capture_node); - NodeGeometryAttributeCapture &capture_storage = *static_cast( - capture_node->storage); - capture_storage.data_type = CD_PROP_BOOL; - capture_storage.domain = ATTR_DOMAIN_FACE; - bNodeSocket *capture_out_socket = nodeFindSocket(capture_node, SOCK_OUT, "Attribute_003"); - bNode *is_smooth_node = nodeAddNode(nullptr, &ntree, "GeometryNodeInputShadeSmooth"); - nodeAddLink(&ntree, - is_smooth_node, - nodeFindSocket(is_smooth_node, SOCK_OUT, "Smooth"), - capture_node, - nodeFindSocket(capture_node, SOCK_IN, "Value_003")); - nodeAddLink(&ntree, - capture_node, - nodeFindSocket(capture_node, SOCK_OUT, "Geometry"), - capture_node, - geometry_in_socket); - geometry_in_link->tonode = capture_node; - geometry_in_link->tosock = nodeFindSocket(capture_node, SOCK_IN, "Geometry"); - } + bNode *is_smooth_node = nodeAddNode(nullptr, &ntree, "GeometryNodeInputShadeSmooth"); + is_smooth_node->parent = node->parent; + capture_node->locx = capture_node->locx - 25; + capture_node->locx = capture_node->locy; + nodeAddLink(&ntree, + is_smooth_node, + nodeFindSocket(is_smooth_node, SOCK_OUT, "Smooth"), + capture_node, + nodeFindSocket(capture_node, SOCK_IN, "Value_003")); + nodeAddLink(&ntree, + capture_node, + nodeFindSocket(capture_node, SOCK_OUT, "Geometry"), + capture_node, + geometry_in_socket); + geometry_in_link->tonode = capture_node; + geometry_in_link->tosock = nodeFindSocket(capture_node, SOCK_IN, "Geometry"); - bNodeSocket *capture_out_socket = nodeFindSocket(capture_node, SOCK_OUT, "Attribute_003"); - - bNode *set_smooth_node = nullptr; - if (geometry_out_links.size() == 1) { - bNodeLink *link = geometry_out_links.first(); - if (link->tonode->idname == StringRef("GeometryNodeSetShadeSmooth")) { - } - } + bNode *set_smooth_node = nodeAddNode(nullptr, &ntree, "GeometryNodeSetShadeSmooth"); + set_smooth_node->parent = node->parent; + set_smooth_node->locx = node->locx + 25; + set_smooth_node->locx = node->locy; + nodeAddLink(&ntree, + node, + geometry_out_socket, + set_smooth_node, + nodeFindSocket(set_smooth_node, SOCK_IN, "Geometry")); + bNodeSocket *smooth_geometry_out = nodeFindSocket(set_smooth_node, SOCK_OUT, "Geometry"); for (bNodeLink *link : geometry_out_links) { - if (link->tonode->idname == StringRef("GeometryNodeSetShadeSmooth")) { - set_smooth_nodes.append(link->tonode); - continue; - } - bNode *set_node = nodeAddNode(nullptr, &ntree, "GeometryNodeSetShadeSmooth"); - nodeAddLink(&ntree, ) - } - - for (bNode *set_smooth_node : set_smooth_nodes) { - bNodeSocket *in_socket = nodeFindSocket(set_smooth_node, SOCK_IN, "Shade Smooth"); - if (bNodeLink *link = in_links_per_socket.lookup_default(in_socket, nullptr)) { - if (link->fromnode == capture_smooth_node) { - continue; - } - } - nodeAddLink(&ntree, capture_smooth_node, capture_out_socket, set_smooth_node, in_socket); + link->fromnode = set_smooth_node; + link->fromsock = smooth_geometry_out; } + nodeAddLink(&ntree, + capture_node, + nodeFindSocket(capture_node, SOCK_OUT, "Attribute_003"), + set_smooth_node, + nodeFindSocket(set_smooth_node, SOCK_IN, "Shade Smooth")); } /* Move nodes to the front so that they are drawn behind existing nodes. */ -- 2.30.2 From 163edf3cafa9bf123eb95950cf8c9917a880d45f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 16:21:11 -0600 Subject: [PATCH 18/25] Fixes for versioning --- .../blenloader/intern/versioning_300.cc | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index aac9b3c3435..04ea85bfaac 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -928,13 +928,12 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) if (node->idname != StringRef("GeometryNodeExtrudeMesh")) { continue; } - const NodeGeometryExtrudeMesh &storage = *static_cast( - node->storage); - if (storage.mode != GEO_NODE_EXTRUDE_MESH_EDGES) { + if (static_cast(node->storage)->mode != + GEO_NODE_EXTRUDE_MESH_EDGES) { continue; } - bNodeSocket *geometry_in_socket = nodeFindSocket(node, SOCK_IN, "Geometry"); - bNodeSocket *geometry_out_socket = nodeFindSocket(node, SOCK_OUT, "Geometry"); + bNodeSocket *geometry_in_socket = nodeFindSocket(node, SOCK_IN, "Mesh"); + bNodeSocket *geometry_out_socket = nodeFindSocket(node, SOCK_OUT, "Mesh"); Map in_links_per_socket; MultiValueMap out_links_per_socket; @@ -944,13 +943,13 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) } bNodeLink *geometry_in_link = in_links_per_socket.lookup_default(geometry_in_socket, nullptr); - Span geometry_out_links = out_links_per_socket.lookup(geometry_in_socket); + Span geometry_out_links = out_links_per_socket.lookup(geometry_out_socket); if (!geometry_in_link || geometry_out_links.is_empty()) { continue; } const bool versioning_already_done = [&]() { - if (geometry_in_link->fromnode->idname != StringRef("GeometryNodeAttributeCapture")) { + if (geometry_in_link->fromnode->idname != StringRef("GeometryNodeCaptureAttribute")) { return false; } bNode *capture_node = geometry_in_link->fromnode; @@ -990,18 +989,19 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) continue; } - bNode *capture_node = nodeAddNode(nullptr, &ntree, "GeometryNodeAttributeCapture"); + bNode *capture_node = nodeAddNode(nullptr, &ntree, "GeometryNodeCaptureAttribute"); capture_node->parent = node->parent; capture_node->locx = node->locx - 25; - capture_node->locx = node->locy; + capture_node->locy = node->locy; new_nodes.append(capture_node); static_cast(capture_node->storage)->data_type = CD_PROP_BOOL; static_cast(capture_node->storage)->domain = ATTR_DOMAIN_FACE; bNode *is_smooth_node = nodeAddNode(nullptr, &ntree, "GeometryNodeInputShadeSmooth"); is_smooth_node->parent = node->parent; - capture_node->locx = capture_node->locx - 25; - capture_node->locx = capture_node->locy; + is_smooth_node->locx = capture_node->locx - 25; + is_smooth_node->locy = capture_node->locy; + new_nodes.append(is_smooth_node); nodeAddLink(&ntree, is_smooth_node, nodeFindSocket(is_smooth_node, SOCK_OUT, "Smooth"), @@ -1018,7 +1018,8 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) bNode *set_smooth_node = nodeAddNode(nullptr, &ntree, "GeometryNodeSetShadeSmooth"); set_smooth_node->parent = node->parent; set_smooth_node->locx = node->locx + 25; - set_smooth_node->locx = node->locy; + set_smooth_node->locy = node->locy; + new_nodes.append(set_smooth_node); nodeAddLink(&ntree, node, geometry_out_socket, -- 2.30.2 From aa35e2b4b95442cfe4874a29408dcabf48951784 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 18:04:30 -0600 Subject: [PATCH 19/25] Cleanup --- source/blender/blenkernel/intern/subdiv_ccg_material.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenkernel/intern/subdiv_ccg_material.cc b/source/blender/blenkernel/intern/subdiv_ccg_material.cc index 424a11f0941..a690da515ed 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_material.cc +++ b/source/blender/blenkernel/intern/subdiv_ccg_material.cc @@ -46,7 +46,6 @@ void BKE_subdiv_ccg_material_flags_init_from_mesh( &mesh->pdata, CD_PROP_INT32, "material_index"); data->sharp_faces = (const bool *)CustomData_get_layer_named( &mesh->pdata, CD_PROP_BOOL, "sharp_face"); - material_flags_evaluator->eval_material_flags = subdiv_ccg_material_flags_eval; material_flags_evaluator->free = subdiv_ccg_material_flags_free; material_flags_evaluator->user_data = data; -- 2.30.2 From 2c97f1529476b70730472997ac66a33295d3938c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 18:27:53 -0600 Subject: [PATCH 20/25] Fix fluid.cc build error --- source/blender/blenkernel/intern/fluid.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 95636d40d32..a314a5c0886 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -23,7 +23,7 @@ #include "DNA_object_types.h" #include "DNA_rigidbody_types.h" -#include "BKE_attribute.h" +#include "BKE_attribute.hh" #include "BKE_effect.h" #include "BKE_fluid.h" #include "BKE_global.h" -- 2.30.2 From 2c5ac4c09dd7609143d9238648f2baf049b8e033 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 3 Feb 2023 22:08:37 -0500 Subject: [PATCH 21/25] Fix BMesh to Mesh conversion --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 33f11286de3..97b33a72d77 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1358,8 +1358,8 @@ static void bm_face_loop_table_build(BMesh &bm, MutableSpan loop_table, bool &need_select_poly, bool &need_hide_poly, - bool &need_material_index, - bool &need_sharp_face) + bool &need_sharp_face, + bool &need_material_index) { char hflag = 0; BMIter iter; @@ -1370,6 +1370,7 @@ static void bm_face_loop_table_build(BMesh &bm, BM_elem_index_set(face, face_i); /* set_inline */ face_table[face_i] = face; hflag |= face->head.hflag; + need_sharp_face |= (face->head.hflag & BM_ELEM_SMOOTH) == 0; need_material_index |= face->mat_nr != 0; BMLoop *loop = BM_FACE_FIRST_LOOP(face); @@ -1382,7 +1383,6 @@ static void bm_face_loop_table_build(BMesh &bm, } need_select_poly = (hflag & BM_ELEM_SELECT) != 0; need_hide_poly = (hflag & BM_ELEM_HIDDEN) != 0; - need_sharp_face = (hflag & BM_ELEM_SMOOTH); } static void bm_to_mesh_verts(const BMesh &bm, @@ -1585,8 +1585,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * loop_table, need_select_poly, need_hide_poly, - need_material_index, - need_sharp_face); + need_sharp_face, + need_material_index); }); bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE | BM_LOOP); -- 2.30.2 From 038c12c48887b985274184f0a7e3e2a7673b803a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 10 Feb 2023 13:59:08 -0500 Subject: [PATCH 22/25] Fix bad update to calc mesh smooth groups --- source/blender/blenkernel/intern/mesh_mapping.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 38d870e0297..771e0048182 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -853,6 +853,8 @@ int *BKE_mesh_calc_smoothgroups(const int totedge, { int *poly_groups = nullptr; + auto poly_is_smooth = [&](const int i) { return !(sharp_faces && sharp_faces[i]); }; + auto poly_is_island_boundary_smooth = [&](const int poly_index, const int /*loop_index*/, const int edge_index, @@ -860,13 +862,13 @@ int *BKE_mesh_calc_smoothgroups(const int totedge, const MeshElemMap &edge_poly_map_elem) { /* Edge is sharp if one of its polys is flat, or edge itself is sharp, * or edge is not used by exactly two polygons. */ - if (!(sharp_faces && sharp_faces[poly_index]) && !(sharp_edges && sharp_edges[edge_index]) && + if ((poly_is_smooth(poly_index)) && !(sharp_edges && sharp_edges[edge_index]) && (edge_user_count == 2)) { /* In that case, edge appears to be smooth, but we need to check its other poly too. */ const int other_poly_index = (poly_index == edge_poly_map_elem.indices[0]) ? edge_poly_map_elem.indices[1] : edge_poly_map_elem.indices[0]; - return !(sharp_faces && sharp_faces[other_poly_index]); + return !poly_is_smooth(other_poly_index); } return true; }; -- 2.30.2 From 53ad429fd39ee5cd672c979d0d01dc0d3a1bebe2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 21 Feb 2023 22:45:41 -0500 Subject: [PATCH 23/25] Convert newly added USDShapeReader --- source/blender/io/usd/intern/usd_reader_shape.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/io/usd/intern/usd_reader_shape.cc b/source/blender/io/usd/intern/usd_reader_shape.cc index a1082e8d734..5dec502f252 100644 --- a/source/blender/io/usd/intern/usd_reader_shape.cc +++ b/source/blender/io/usd/intern/usd_reader_shape.cc @@ -144,7 +144,8 @@ Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh, MutableSpan polys = active_mesh->polys_for_write(); MutableSpan loops = active_mesh->loops_for_write(); - const char should_smooth = prim_.IsA() ? 0 : ME_SMOOTH; + /* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */ + BKE_mesh_smooth_flag_set(active_mesh, !prim_.IsA()); int loop_index = 0; for (int i = 0; i < face_counts.size(); i++) { @@ -154,9 +155,6 @@ Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh, poly.loopstart = loop_index; poly.totloop = face_size; - /* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */ - poly.flag |= should_smooth; - for (int f = 0; f < face_size; ++f, ++loop_index) { loops[loop_index].v = face_indices[loop_index]; } -- 2.30.2 From 7a2b072bcae8b82ca692c47e1dfd5e0dd63ce857 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 8 Mar 2023 08:23:45 -0500 Subject: [PATCH 24/25] Add default sharp faces for PLY import --- source/blender/io/ply/importer/ply_import_mesh.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/io/ply/importer/ply_import_mesh.cc b/source/blender/io/ply/importer/ply_import_mesh.cc index b281af75d3d..49a99e458e1 100644 --- a/source/blender/io/ply/importer/ply_import_mesh.cc +++ b/source/blender/io/ply/importer/ply_import_mesh.cc @@ -121,6 +121,8 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams ¶ } } + BKE_mesh_smooth_flag_set(mesh, false); + return mesh; } } // namespace blender::io::ply -- 2.30.2 From 97a29e77a0f8676941918897781f66f9f9c4c95c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 8 Mar 2023 08:26:11 -0500 Subject: [PATCH 25/25] Add comment --- source/blender/blenloader/intern/versioning_300.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 34858ae248f..45c5b40486d 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -941,6 +941,11 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree) } } +/** + * When extruding from loose edges, the extrude geometry node used to create flat faces due to the + * default of the old "shade_smooth" attribute. Since the "false" value has changed with the + * "sharp_face" attribute, add nodes to propagate the new attribute in its inverted "smooth" form. + */ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree) { using namespace blender; -- 2.30.2