From 16fbadde363c8074ec725fa1e1079add096bd741 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 20 Mar 2023 15:55:13 +0100 Subject: [PATCH] Mesh: Replace MLoop struct with generic attributes Implements #102359. Split the `MLoop` struct into two separate integer arrays called `corner_verts` and `corner_edges`, referring to the vertex each corner is attached to and the next edge around the face at each corner. These arrays can be sliced to give access to the edges or vertices in a face. Then they are often referred to as "poly_verts" or "poly_edges". The main benefits are halving the necessary memory bandwidth when only one array is used and simplifications from using regular integer indices instead of a special-purpose struct. The commit also starts a renaming from "loop" to "corner" in mesh code. Like the other mesh struct of array refactors, forward compatibility is kept by writing files with the older format. This will be done until 4.0 to ease the transition process. Looking at a small portion of the patch should give a good impression for the rest of the changes. I tried to make the changes as small as possible so it's easy to tell the correctness from the diff. Though I found Blender developers have been very inventive over the last decade when finding different ways to loop over the corners in a face. For performance, nearly every piece of code that deals with `Mesh` is slightly impacted. Any algorithm that is memory bottle-necked should see an improvement. For example, here is a comparison of interpolating a vertex float attribute to face corners (Ryzen 3700x): **Before** (Average: 3.7 ms, Min: 3.4 ms) ``` threading::parallel_for(loops.index_range(), 4096, [&](IndexRange range) { for (const int64_t i : range) { dst[i] = src[loops[i].v]; } }); ``` **After** (Average: 2.9 ms, Min: 2.6 ms) ``` array_utils::gather(src, corner_verts, dst); ``` That's an improvement of 28% to the average timings, and it's also a simplification, since an index-based routine can be used instead. For more examples using the new arrays, see the design task. Pull Request: https://projects.blender.org/blender/blender/pulls/104424 --- intern/cycles/blender/mesh.cpp | 28 +- source/blender/blenkernel/BKE_DerivedMesh.h | 6 +- source/blender/blenkernel/BKE_bvhutils.h | 4 +- source/blender/blenkernel/BKE_deform.h | 5 +- source/blender/blenkernel/BKE_mesh.h | 59 ++-- source/blender/blenkernel/BKE_mesh.hh | 47 +-- .../blenkernel/BKE_mesh_legacy_convert.h | 7 + source/blender/blenkernel/BKE_mesh_mapping.h | 38 +-- source/blender/blenkernel/BKE_mesh_remap.h | 5 +- source/blender/blenkernel/BKE_mesh_runtime.h | 3 +- source/blender/blenkernel/BKE_mesh_sample.hh | 2 +- source/blender/blenkernel/BKE_mesh_tangent.h | 4 +- source/blender/blenkernel/BKE_mesh_types.h | 2 +- source/blender/blenkernel/BKE_multires.h | 1 + source/blender/blenkernel/BKE_paint.h | 3 +- source/blender/blenkernel/BKE_pbvh.h | 9 +- source/blender/blenkernel/BKE_shrinkwrap.h | 1 + source/blender/blenkernel/BKE_subdiv_ccg.h | 5 +- .../blender/blenkernel/BKE_volume_to_mesh.hh | 2 +- .../blender/blenkernel/intern/DerivedMesh.cc | 43 ++- source/blender/blenkernel/intern/bvhutils.cc | 36 +-- .../blenkernel/intern/cdderivedmesh.cc | 24 +- source/blender/blenkernel/intern/cloth.cc | 55 ++-- .../blender/blenkernel/intern/crazyspace.cc | 38 +-- .../intern/curve_to_mesh_convert.cc | 45 +-- .../blender/blenkernel/intern/customdata.cc | 15 +- .../blenkernel/intern/data_transfer.cc | 35 ++- source/blender/blenkernel/intern/deform.cc | 14 +- .../blender/blenkernel/intern/dynamicpaint.cc | 104 +++---- source/blender/blenkernel/intern/effect.c | 8 +- source/blender/blenkernel/intern/fluid.cc | 104 +++---- .../intern/geometry_component_mesh.cc | 169 ++++++----- .../blenkernel/intern/gpencil_geom_legacy.cc | 8 +- source/blender/blenkernel/intern/key.cc | 14 +- .../blenkernel/intern/mball_tessellate.cc | 12 +- source/blender/blenkernel/intern/mesh.cc | 94 +++--- .../blenkernel/intern/mesh_boolean_convert.cc | 56 ++-- .../blenkernel/intern/mesh_calc_edges.cc | 38 ++- .../blender/blenkernel/intern/mesh_convert.cc | 56 ++-- .../blenkernel/intern/mesh_evaluate.cc | 213 +++++++------- source/blender/blenkernel/intern/mesh_fair.cc | 21 +- .../blenkernel/intern/mesh_iterators.cc | 48 ++-- .../blenkernel/intern/mesh_legacy_convert.cc | 118 ++++++-- .../blender/blenkernel/intern/mesh_mapping.cc | 167 ++++++----- .../intern/mesh_merge_customdata.cc | 2 +- .../blender/blenkernel/intern/mesh_mirror.cc | 25 +- .../blender/blenkernel/intern/mesh_normals.cc | 271 ++++++++++-------- .../blender/blenkernel/intern/mesh_remap.cc | 146 +++++----- .../blenkernel/intern/mesh_remesh_voxel.cc | 45 +-- .../blender/blenkernel/intern/mesh_runtime.cc | 30 +- .../blender/blenkernel/intern/mesh_sample.cc | 52 ++-- .../blender/blenkernel/intern/mesh_tangent.cc | 38 +-- .../blenkernel/intern/mesh_tessellate.cc | 93 +++--- .../blenkernel/intern/mesh_validate.cc | 115 ++++---- .../blender/blenkernel/intern/mesh_wrapper.cc | 2 +- source/blender/blenkernel/intern/multires.cc | 3 +- .../blenkernel/intern/multires_reshape.hh | 4 +- .../intern/multires_reshape_apply_base.cc | 19 +- .../intern/multires_reshape_smooth.cc | 11 +- .../intern/multires_reshape_subdivide.cc | 18 +- .../intern/multires_reshape_util.cc | 12 +- .../blenkernel/intern/multires_unsubdivide.cc | 19 +- .../blender/blenkernel/intern/object_dupli.cc | 29 +- source/blender/blenkernel/intern/paint.cc | 30 +- source/blender/blenkernel/intern/pbvh.cc | 55 ++-- .../blender/blenkernel/intern/pbvh_colors.cc | 16 +- .../blender/blenkernel/intern/pbvh_intern.hh | 5 +- .../blender/blenkernel/intern/pbvh_pixels.cc | 8 +- .../blenkernel/intern/pbvh_pixels_copy.cc | 6 +- .../blenkernel/intern/pbvh_uv_islands.cc | 61 ++-- .../blenkernel/intern/pbvh_uv_islands.hh | 4 +- source/blender/blenkernel/intern/rigidbody.c | 16 +- .../blender/blenkernel/intern/shrinkwrap.cc | 35 ++- source/blender/blenkernel/intern/softbody.c | 20 +- .../blender/blenkernel/intern/subdiv_ccg.cc | 23 +- .../intern/subdiv_converter_mesh.cc | 26 +- .../blender/blenkernel/intern/subdiv_eval.cc | 7 +- .../blenkernel/intern/subdiv_foreach.cc | 151 +++++----- .../blender/blenkernel/intern/subdiv_mesh.cc | 91 +++--- .../blender/blenkernel/intern/subsurf_ccg.cc | 121 +++++--- .../blenkernel/intern/volume_to_mesh.cc | 8 +- .../blenloader/intern/versioning_290.cc | 5 +- .../blenloader/intern/versioning_400.cc | 1 + .../bmesh/intern/bmesh_mesh_convert.cc | 43 +-- source/blender/draw/DRW_pbvh.hh | 5 +- .../draw_cache_extract_mesh_render_data.cc | 8 +- source/blender/draw/intern/draw_pbvh.cc | 12 +- .../intern/mesh_extractors/extract_mesh.hh | 3 +- .../extract_mesh_ibo_edituv.cc | 14 +- .../mesh_extractors/extract_mesh_ibo_fdots.cc | 4 +- .../mesh_extractors/extract_mesh_ibo_lines.cc | 14 +- .../extract_mesh_ibo_lines_adjacency.cc | 6 +- .../extract_mesh_ibo_lines_paint_mask.cc | 3 +- .../extract_mesh_ibo_points.cc | 3 +- .../extract_mesh_vbo_attributes.cc | 11 +- .../extract_mesh_vbo_edge_fac.cc | 19 +- .../extract_mesh_vbo_edit_data.cc | 5 +- .../extract_mesh_vbo_edituv_data.cc | 9 +- .../extract_mesh_vbo_edituv_stretch_angle.cc | 8 +- .../extract_mesh_vbo_edituv_stretch_area.cc | 4 +- .../extract_mesh_vbo_fdots_pos.cc | 8 +- .../extract_mesh_vbo_fdots_uv.cc | 4 +- .../mesh_extractors/extract_mesh_vbo_lnor.cc | 12 +- .../extract_mesh_vbo_mesh_analysis.cc | 52 ++-- .../mesh_extractors/extract_mesh_vbo_orco.cc | 4 +- .../extract_mesh_vbo_pos_nor.cc | 25 +- .../extract_mesh_vbo_sculpt_data.cc | 9 +- .../extract_mesh_vbo_select_idx.cc | 8 +- .../mesh_extractors/extract_mesh_vbo_tan.cc | 4 +- .../extract_mesh_vbo_weights.cc | 4 +- .../blender/editors/armature/meshlaplacian.cc | 61 ++-- .../editors/curves/intern/curves_ops.cc | 14 +- source/blender/editors/mesh/editface.cc | 40 +-- source/blender/editors/mesh/mesh_data.cc | 26 +- source/blender/editors/mesh/meshtools.cc | 48 ++-- .../blender/editors/object/object_bake_api.cc | 22 +- .../blender/editors/object/object_remesh.cc | 17 +- .../editors/sculpt_paint/curves_sculpt_add.cc | 15 +- .../sculpt_paint/curves_sculpt_puff.cc | 10 +- .../sculpt_paint/curves_sculpt_slide.cc | 14 +- .../editors/sculpt_paint/paint_image_proj.cc | 45 +-- .../editors/sculpt_paint/paint_mask.cc | 26 +- .../editors/sculpt_paint/paint_utils.c | 4 +- .../editors/sculpt_paint/paint_vertex.cc | 62 ++-- .../sculpt_paint/paint_vertex_weight_ops.cc | 8 +- source/blender/editors/sculpt_paint/sculpt.cc | 16 +- .../editors/sculpt_paint/sculpt_dyntopo.cc | 2 +- .../editors/sculpt_paint/sculpt_expand.cc | 22 +- .../editors/sculpt_paint/sculpt_face_set.cc | 29 +- .../editors/sculpt_paint/sculpt_geodesic.cc | 10 +- .../spreadsheet_data_source_geometry.cc | 9 +- .../editors/space_view3d/drawobject.cc | 10 +- .../transform/transform_snap_object.cc | 47 +-- .../editors/uvedit/uvedit_unwrap_ops.cc | 56 ++-- .../blender_interface/BlenderFileLoader.cpp | 29 +- .../BlenderStrokeRenderer.cpp | 33 ++- .../geometry/intern/add_curves_on_mesh.cc | 8 +- .../geometry/intern/mesh_merge_by_distance.cc | 142 +++++---- .../geometry/intern/mesh_primitive_cuboid.cc | 32 +-- .../geometry/intern/mesh_split_edges.cc | 59 ++-- .../blender/geometry/intern/mesh_to_volume.cc | 13 +- .../geometry/intern/realize_instances.cc | 38 ++- .../intern/lineart/lineart_cpu.cc | 35 ++- .../gpu/intern/gpu_shader_builder_stubs.cc | 8 - .../io/alembic/exporter/abc_writer_mesh.cc | 13 +- .../io/alembic/intern/abc_customdata.cc | 22 +- .../io/alembic/intern/abc_customdata.h | 5 +- .../io/alembic/intern/abc_reader_mesh.cc | 14 +- .../blender/io/collada/GeometryExporter.cpp | 12 +- source/blender/io/collada/MeshImporter.cpp | 28 +- source/blender/io/collada/MeshImporter.h | 2 +- .../ply/exporter/ply_export_load_plydata.cc | 13 +- .../io/ply/importer/ply_import_mesh.cc | 7 +- .../io/stl/importer/stl_import_mesh.cc | 11 +- .../blender/io/usd/intern/usd_reader_mesh.cc | 14 +- .../blender/io/usd/intern/usd_reader_shape.cc | 4 +- .../blender/io/usd/intern/usd_writer_mesh.cc | 12 +- .../exporter/obj_export_file_writer.cc | 2 +- .../wavefront_obj/exporter/obj_export_mesh.cc | 27 +- .../wavefront_obj/exporter/obj_export_mesh.hh | 4 +- .../wavefront_obj/importer/obj_import_mesh.cc | 9 +- .../importer/obj_import_objects.hh | 2 +- .../blender/makesdna/DNA_customdata_types.h | 1 - source/blender/makesdna/DNA_mesh_types.h | 32 ++- source/blender/makesdna/DNA_meshdata_types.h | 68 +++-- source/blender/makesrna/intern/rna_mesh.c | 101 ++++--- source/blender/makesrna/intern/rna_mesh_api.c | 9 +- source/blender/modifiers/intern/MOD_array.cc | 23 +- source/blender/modifiers/intern/MOD_build.cc | 29 +- .../blender/modifiers/intern/MOD_collision.c | 4 +- .../modifiers/intern/MOD_correctivesmooth.cc | 62 ++-- .../blender/modifiers/intern/MOD_displace.cc | 7 +- .../modifiers/intern/MOD_laplaciandeform.cc | 16 +- .../modifiers/intern/MOD_laplaciansmooth.cc | 142 ++++----- source/blender/modifiers/intern/MOD_mask.cc | 105 +++---- .../blender/modifiers/intern/MOD_meshcache.c | 2 +- .../blender/modifiers/intern/MOD_multires.cc | 2 +- .../modifiers/intern/MOD_normal_edit.cc | 98 ++++--- source/blender/modifiers/intern/MOD_ocean.cc | 39 +-- .../modifiers/intern/MOD_particleinstance.cc | 26 +- source/blender/modifiers/intern/MOD_remesh.cc | 11 +- source/blender/modifiers/intern/MOD_screw.cc | 76 ++--- .../modifiers/intern/MOD_solidify_extrude.cc | 155 +++++----- .../intern/MOD_solidify_nonmanifold.cc | 168 +++++------ .../modifiers/intern/MOD_surfacedeform.cc | 86 +++--- source/blender/modifiers/intern/MOD_util.cc | 5 +- .../blender/modifiers/intern/MOD_uvproject.cc | 17 +- source/blender/modifiers/intern/MOD_uvwarp.cc | 19 +- .../modifiers/intern/MOD_weighted_normal.cc | 79 ++--- .../geometry/nodes/node_geo_blur_attribute.cc | 21 +- .../geometry/nodes/node_geo_convex_hull.cc | 21 +- .../geometry/nodes/node_geo_curve_fill.cc | 4 +- .../node_geo_deform_curves_on_surface.cc | 16 +- .../nodes/node_geo_delete_geometry.cc | 128 +++++---- .../node_geo_distribute_points_on_faces.cc | 19 +- .../geometry/nodes/node_geo_dual_mesh.cc | 151 +++++----- .../nodes/node_geo_duplicate_elements.cc | 30 +- .../nodes/node_geo_edges_to_face_groups.cc | 3 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 191 ++++++------ .../geometry/nodes/node_geo_flip_faces.cc | 10 +- .../nodes/node_geo_input_mesh_edge_angle.cc | 32 ++- .../node_geo_input_mesh_edge_neighbors.cc | 6 +- .../nodes/node_geo_input_mesh_face_area.cc | 6 +- .../node_geo_input_mesh_face_is_planar.cc | 11 +- .../node_geo_input_mesh_face_neighbors.cc | 10 +- .../node_geo_input_mesh_vertex_neighbors.cc | 7 +- .../node_geo_mesh_face_group_boundaries.cc | 5 +- .../nodes/node_geo_mesh_primitive_circle.cc | 29 +- .../nodes/node_geo_mesh_primitive_cone.cc | 59 ++-- .../nodes/node_geo_mesh_primitive_grid.cc | 36 +-- .../node_geo_mesh_primitive_uv_sphere.cc | 48 ++-- ...ode_geo_mesh_topology_corners_of_vertex.cc | 12 +- .../node_geo_mesh_topology_edges_of_corner.cc | 17 +- ...node_geo_mesh_topology_vertex_of_corner.cc | 7 +- .../geometry/nodes/node_geo_sample_nearest.cc | 5 +- .../geometry/nodes/node_geo_scale_elements.cc | 33 +-- .../nodes/node_geo_uv_pack_islands.cc | 11 +- .../geometry/nodes/node_geo_uv_unwrap.cc | 13 +- .../geometry/nodes/node_geo_volume_to_mesh.cc | 4 +- .../python/mathutils/mathutils_bvhtree.cc | 10 +- source/blender/render/intern/bake.cc | 24 +- source/blender/render/intern/multires_bake.cc | 58 ++-- .../blender/render/intern/texture_margin.cc | 32 ++- .../render/intern/texture_pointdensity.c | 4 +- 224 files changed, 3934 insertions(+), 3422 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 847c7358f7a..3cd762bbf05 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -818,6 +818,23 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b } } +static std::optional find_corner_vert_attribute(BL::Mesh b_mesh) +{ + for (BL::Attribute &b_attribute : b_mesh.attributes) { + if (b_attribute.domain() != BL::Attribute::domain_CORNER) { + continue; + } + if (b_attribute.data_type() != BL::Attribute::data_type_INT) { + continue; + } + if (b_attribute.name() != ".corner_vert") { + continue; + } + return BL::IntAttribute{b_attribute}; + } + return std::nullopt; +} + /* The Random Per Island attribute is a random float associated with each * connected component (island) of the mesh. The attribute is computed by * first classifying the vertices into different sets using a Disjoint Set @@ -864,11 +881,11 @@ static void attr_create_random_per_island(Scene *scene, else { if (polys_num != 0) { const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); - const MLoop *loops = static_cast(b_mesh.loops[0].ptr.data); + BL::IntAttribute corner_verts = *find_corner_vert_attribute(b_mesh); for (int i = 0; i < polys_num; i++) { const MPoly &b_poly = polys[i]; - const MLoop &b_loop = loops[b_poly.loopstart]; - data[i] = hash_uint_to_float(vertices_sets.find(b_loop.v)); + const int vert = corner_verts.data[b_poly.loopstart].value(); + data[i] = hash_uint_to_float(vertices_sets.find(vert)); } } } @@ -1036,7 +1053,7 @@ static void create_mesh(Scene *scene, vector vi; const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); - const MLoop *loops = static_cast(b_mesh.loops[0].ptr.data); + std::optional corner_verts = find_corner_vert_attribute(b_mesh); for (int i = 0; i < numfaces; i++) { const MPoly &b_poly = polys[i]; @@ -1047,8 +1064,7 @@ static void create_mesh(Scene *scene, vi.resize(n); for (int i = 0; i < n; i++) { /* NOTE: Autosmooth is already taken care about. */ - - vi[i] = loops[b_poly.loopstart + i].v; + vi[i] = corner_verts->data[b_poly.loopstart + i].value(); } /* create subd faces */ diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 8eb57c5509c..72f1171fe08 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -129,7 +129,8 @@ struct DerivedMesh { */ float *(*getVertArray)(DerivedMesh *dm); struct MEdge *(*getEdgeArray)(DerivedMesh *dm); - struct MLoop *(*getLoopArray)(DerivedMesh *dm); + int *(*getCornerVertArray)(DerivedMesh *dm); + int *(*getCornerEdgeArray)(DerivedMesh *dm); struct MPoly *(*getPolyArray)(DerivedMesh *dm); /** Copy all verts/edges/faces from the derived mesh into @@ -137,7 +138,8 @@ struct DerivedMesh { */ void (*copyVertArray)(DerivedMesh *dm, float (*r_positions)[3]); void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge); - void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop); + void (*copyCornerVertArray)(DerivedMesh *dm, int *r_corner_verts); + void (*copyCornerEdgeArray)(DerivedMesh *dm, int *r_corner_edges); void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly); /** Return a pointer to the entire array of vert/edge/face custom data diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index ba13d9d6a6c..53620561ea7 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -61,7 +61,7 @@ typedef struct BVHTreeFromMesh { const float (*vert_positions)[3]; const struct MEdge *edge; const struct MFace *face; - const struct MLoop *loop; + const int *corner_verts; const struct MLoopTri *looptri; /* Private data */ @@ -181,7 +181,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, */ BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data, const float (*vert_positions)[3], - const struct MLoop *mloop, + const int *corner_verts, const struct MLoopTri *looptri, int looptri_num, blender::BitSpan mask, diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index a1ab2e47a55..0fae5823209 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -18,7 +18,6 @@ struct ID; struct ListBase; struct MDeformVert; struct MEdge; -struct MLoop; struct MPoly; struct Object; struct bDeformGroup; @@ -270,14 +269,14 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const struct MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert, int defgroup, int verts_num, - const struct MLoop *loops, + const int *corner_verts, int loops_num, bool invert_vgroup, float *r_weights); void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert, int defgroup, int verts_num, - const struct MLoop *loops, + const int *corner_verts, int loops_num, const struct MPoly *polys, int polys_num, diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 70d6f1a0383..2b28b28d68a 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -33,7 +33,6 @@ struct MDeformVert; struct MDisps; struct MEdge; struct MFace; -struct MLoop; struct MLoopTri; struct MPoly; struct Main; @@ -109,14 +108,14 @@ void BKE_mesh_ensure_default_orig_index_customdata_no_check(struct Mesh *mesh); * Find the index of the loop in 'poly' which references vertex, * returns -1 if not found */ -int poly_find_loop_from_vert(const struct MPoly *poly, const struct MLoop *loopstart, int vert); +int poly_find_loop_from_vert(const struct MPoly *poly, const int *poly_verts, int vert); /** * Fill \a r_adj with the loop indices in \a poly adjacent to the * vertex. Returns the index of the loop matching vertex, or -1 if the * vertex is not in \a poly */ int poly_get_adj_loops_from_vert(const struct MPoly *poly, - const struct MLoop *mloop, + const int *corner_verts, int vert, int r_adj[2]); @@ -129,8 +128,9 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v); * Sets each output array element to the edge index if it is a real edge, or -1. */ void BKE_mesh_looptri_get_real_edges(const struct MEdge *edges, - const struct MLoop *loops, - const struct MLoopTri *looptri, + const int *corner_verts, + const int *corner_edges, + const struct MLoopTri *tri, int r_edges[3]); /** @@ -312,7 +312,7 @@ void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float (*vert_coords)[3] /** * Calculate tessellation into #MLoopTri which exist only for this purpose. */ -void BKE_mesh_recalc_looptri(const struct MLoop *mloop, +void BKE_mesh_recalc_looptri(const int *corner_verts, const struct MPoly *polys, const float (*vert_positions)[3], int totvert, @@ -384,7 +384,7 @@ bool BKE_mesh_vert_normals_are_dirty(const struct Mesh *mesh); */ bool BKE_mesh_poly_normals_are_dirty(const struct Mesh *mesh); -void BKE_mesh_calc_poly_normal(const struct MLoop *poly_loops, +void BKE_mesh_calc_poly_normal(const int *poly_verts, int poly_size, const float (*vert_positions)[3], int verts_num, @@ -430,7 +430,7 @@ enum { * Collection of #MLoopNorSpace basic storage & pre-allocation. */ typedef struct MLoopNorSpaceArray { - MLoopNorSpace **lspacearr; /* MLoop aligned array */ + MLoopNorSpace **lspacearr; /* Face corner aligned array */ struct LinkNode *loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */ char data_type; /* Whether we store loop indices, or pointers to BMLoop. */ @@ -505,7 +505,7 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, * \param r_vert_clnors: The (already allocated) array where to store averaged per-vertex normals. */ void BKE_mesh_normals_loop_to_vertex(int numVerts, - const struct MLoop *mloops, + const int *corner_verts, int numLoops, const float (*clnors)[3], float (*r_vert_clnors)[3]); @@ -546,12 +546,12 @@ void BKE_mesh_set_custom_normals_from_verts(struct Mesh *mesh, float (*r_custom_ /* *** mesh_evaluate.cc *** */ -void BKE_mesh_calc_poly_center(const struct MLoop *poly_loops, +void BKE_mesh_calc_poly_center(const int *poly_verts, int poly_size, const float (*vert_positions)[3], int verts_num, float r_cent[3]); -float BKE_mesh_calc_poly_area(const struct MLoop *poly_loops, +float BKE_mesh_calc_poly_area(const int *poly_verts, int poly_size, const float (*vert_positions)[3], int verts_num); @@ -581,12 +581,12 @@ void BKE_mesh_calc_volume(const float (*vert_positions)[3], int mverts_num, const struct MLoopTri *mlooptri, int looptri_num, - const struct MLoop *mloop, + const int *corner_verts, float *r_volume, float r_center[3]); /** - * Flip a single MLoop's #MDisps structure, + * Flip a single corner's #MDisps structure, * low level function to be called from face-flipping code which re-arranged the mdisps themselves. */ void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip); @@ -600,13 +600,15 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip); * \param ldata: the loops custom data. */ void BKE_mesh_polygon_flip_ex(const struct MPoly *poly, - struct MLoop *mloop, + int *corner_verts, + int *corner_edges, struct CustomData *ldata, float (*lnors)[3], struct MDisps *mdisp, bool use_loop_mdisp_flip); void BKE_mesh_polygon_flip(const struct MPoly *poly, - struct MLoop *mloop, + int *corner_verts, + int *corner_edges, struct CustomData *ldata, int totloop); /** @@ -615,7 +617,8 @@ void BKE_mesh_polygon_flip(const struct MPoly *poly, * \note Invalidates tessellation, caller must handle that. */ void BKE_mesh_polys_flip(const struct MPoly *polys, - struct MLoop *mloop, + int *corner_verts, + int *corner_edges, struct CustomData *ldata, int totpoly); @@ -652,7 +655,7 @@ void BKE_mesh_flush_select_from_verts(struct Mesh *me); */ void BKE_mesh_calc_relative_deform(const struct MPoly *polys, int totpoly, - const struct MLoop *mloop, + const int *corner_verts, int totvert, const float (*vert_cos_src)[3], @@ -702,7 +705,8 @@ bool BKE_mesh_validate_arrays(struct Mesh *me, unsigned int totedge, struct MFace *mfaces, unsigned int totface, - struct MLoop *mloops, + int *corner_verts, + int *corner_edges, unsigned int totloop, struct MPoly *polys, unsigned int totpoly, @@ -819,13 +823,24 @@ BLI_INLINE MPoly *BKE_mesh_polys_for_write(Mesh *mesh) return (MPoly *)CustomData_get_layer_for_write(&mesh->pdata, CD_MPOLY, mesh->totpoly); } -BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh) +BLI_INLINE const int *BKE_mesh_corner_verts(const Mesh *mesh) { - return (const MLoop *)CustomData_get_layer(&mesh->ldata, CD_MLOOP); + return (const int *)CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert"); } -BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh) +BLI_INLINE int *BKE_mesh_corner_verts_for_write(Mesh *mesh) { - return (MLoop *)CustomData_get_layer_for_write(&mesh->ldata, CD_MLOOP, mesh->totloop); + return (int *)CustomData_get_layer_named_for_write( + &mesh->ldata, CD_PROP_INT32, ".corner_vert", mesh->totloop); +} + +BLI_INLINE const int *BKE_mesh_corner_edges(const Mesh *mesh) +{ + return (const int *)CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge"); +} +BLI_INLINE int *BKE_mesh_corner_edges_for_write(Mesh *mesh) +{ + return (int *)CustomData_get_layer_named_for_write( + &mesh->ldata, CD_PROP_INT32, ".corner_edge", mesh->totloop); } BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh) diff --git a/source/blender/blenkernel/BKE_mesh.hh b/source/blender/blenkernel/BKE_mesh.hh index 7035b80dfd6..1ed858cf1aa 100644 --- a/source/blender/blenkernel/BKE_mesh.hh +++ b/source/blender/blenkernel/BKE_mesh.hh @@ -15,14 +15,14 @@ namespace blender::bke::mesh { * \{ */ /** Calculate the up direction for the polygon, depending on its winding direction. */ -float3 poly_normal_calc(Span vert_positions, Span poly_loops); +float3 poly_normal_calc(Span vert_positions, Span poly_verts); /** * Calculate tessellation into #MLoopTri which exist only for this purpose. */ void looptris_calc(Span vert_positions, Span polys, - Span loops, + Span corner_verts, MutableSpan looptris); /** * A version of #looptris_calc which takes pre-calculated polygon normals @@ -33,19 +33,19 @@ void looptris_calc(Span vert_positions, */ void looptris_calc_with_normals(Span vert_positions, Span polys, - Span loops, + Span corner_verts, Span poly_normals, MutableSpan looptris); /** Calculate the average position of the vertices in the polygon. */ -float3 poly_center_calc(Span vert_positions, Span poly_loops); +float3 poly_center_calc(Span vert_positions, Span poly_verts); /** Calculate the surface area of the polygon described by the indexed vertices. */ -float poly_area_calc(Span vert_positions, Span poly_loops); +float poly_area_calc(Span vert_positions, Span poly_verts); /** Calculate the angles at each of the polygons corners. */ void poly_angles_calc(Span vert_positions, - Span poly_loops, + Span poly_verts, MutableSpan angles); /** \} */ @@ -62,7 +62,7 @@ void poly_angles_calc(Span vert_positions, */ void normals_calc_polys(Span vert_positions, Span polys, - Span loops, + Span corner_verts, MutableSpan poly_normals); /** @@ -73,7 +73,7 @@ void normals_calc_polys(Span vert_positions, */ void normals_calc_poly_vert(Span vert_positions, Span polys, - Span loops, + Span corner_verts, MutableSpan poly_normals, MutableSpan vert_normals); @@ -82,14 +82,15 @@ void normals_calc_poly_vert(Span vert_positions, * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry * (splitting edges). * - * \param loop_to_poly_map: Optional pre-created map from loops to their polygon. + * \param loop_to_poly_map: Optional pre-created map from corners to their polygon. * \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on * each side of the edge. */ void normals_calc_loop(Span vert_positions, Span edges, Span polys, - Span loops, + Span corner_verts, + Span corner_edges, Span loop_to_poly_map, Span vert_normals, Span poly_normals, @@ -104,7 +105,8 @@ void normals_calc_loop(Span vert_positions, void normals_loop_custom_set(Span vert_positions, Span edges, Span polys, - Span loops, + Span corner_verts, + Span corner_edges, Span vert_normals, Span poly_normals, const bool *sharp_faces, @@ -115,7 +117,8 @@ void normals_loop_custom_set(Span vert_positions, void normals_loop_custom_set_from_verts(Span vert_positions, Span edges, Span polys, - Span loops, + Span corner_verts, + Span corner_edges, Span vert_normals, Span poly_normals, const bool *sharp_faces, @@ -132,7 +135,8 @@ void normals_loop_custom_set_from_verts(Span vert_positions, * \param sharp_faces: Optional array used to mark specific faces for sharp shading. */ void edges_sharp_from_angle_set(Span polys, - Span loops, + Span corner_verts, + Span corner_edges, Span poly_normals, const bool *sharp_faces, const float split_angle, @@ -174,13 +178,22 @@ inline blender::MutableSpan Mesh::polys_for_write() return {BKE_mesh_polys_for_write(this), this->totpoly}; } -inline blender::Span Mesh::loops() const +inline blender::Span Mesh::corner_verts() const { - return {BKE_mesh_loops(this), this->totloop}; + return {BKE_mesh_corner_verts(this), this->totloop}; } -inline blender::MutableSpan Mesh::loops_for_write() +inline blender::MutableSpan Mesh::corner_verts_for_write() { - return {BKE_mesh_loops_for_write(this), this->totloop}; + return {BKE_mesh_corner_verts_for_write(this), this->totloop}; +} + +inline blender::Span Mesh::corner_edges() const +{ + return {BKE_mesh_corner_edges(this), this->totloop}; +} +inline blender::MutableSpan Mesh::corner_edges_for_write() +{ + return {BKE_mesh_corner_edges_for_write(this), this->totloop}; } inline blender::Span Mesh::deform_verts() const diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index 950cf76174c..8a0ae63ce72 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -112,8 +112,15 @@ struct MVert *BKE_mesh_legacy_convert_positions_to_verts( void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh); +struct MLoop *BKE_mesh_legacy_convert_corners_to_loops( + Mesh *mesh, + blender::ResourceScope &temp_arrays_for_convert, + blender::Vector &loop_layers_to_write); + #endif +void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh); + /** * Recreate #MFace Tessellation. * diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index 6f14b25588f..839f9345aa7 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -15,7 +15,6 @@ extern "C" { #endif struct MEdge; -struct MLoop; struct MLoopTri; struct MPoly; @@ -104,7 +103,7 @@ typedef struct MeshElemMap { UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *polys, const bool *hide_poly, const bool *select_poly, - const struct MLoop *mloop, + const int *corner_verts, const float (*mloopuv)[2], unsigned int totpoly, unsigned int totvert, @@ -122,7 +121,7 @@ void BKE_mesh_uv_vert_map_free(UvVertMap *vmap); void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem, const struct MPoly *polys, - const struct MLoop *mloop, + const int *corner_verts, int totvert, int totpoly, int totloop); @@ -134,7 +133,7 @@ void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, int **r_mem, const struct MPoly *polys, - const struct MLoop *mloop, + const int *corner_verts, int totvert, int totpoly, int totloop); @@ -148,7 +147,7 @@ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, int totvert, const struct MLoopTri *mlooptri, int totlooptri, - const struct MLoop *mloop, + const int *corner_verts, int totloop); /** * Generates a map where the key is the vertex and the value @@ -173,7 +172,7 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, int totedge, const struct MPoly *polys, int totpoly, - const struct MLoop *mloop, + const int *corner_edges, int totloop); /** * Generates a map where the key is the edge and the value @@ -185,7 +184,7 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int totedge, const struct MPoly *polys, int totpoly, - const struct MLoop *mloop, + const int *corner_edges, int totloop); /** * This function creates a map so the source-data (vert/edge/loop/poly) @@ -263,7 +262,8 @@ typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3], const bool *uv_seams, const struct MPoly *polys, int totpoly, - const struct MLoop *loops, + const int *corner_verts, + const int *corner_edges, int totloop, struct MeshIslandStore *r_island_store); @@ -281,7 +281,8 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3], const bool *uv_seams, const struct MPoly *polys, int totpoly, - const struct MLoop *loops, + const int *corner_verts, + const int *corner_edges, int totloop, MeshIslandStore *r_island_store); @@ -305,7 +306,8 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], const bool *uv_seams, struct MPoly *polys, int totpoly, - struct MLoop *loops, + const int *corner_verts, + const int *corner_edges, int totloop, const float (*luvs)[2], MeshIslandStore *r_island_store); @@ -321,7 +323,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], int *BKE_mesh_calc_smoothgroups(int totedge, const struct MPoly *polys, int totpoly, - const struct MLoop *mloop, + const int *corner_edges, int totloop, const bool *sharp_edges, const bool *sharp_faces, @@ -351,11 +353,15 @@ namespace blender::bke::mesh_topology { Array build_loop_to_poly_map(Span polys, int loops_num); Array> build_vert_to_edge_map(Span edges, int verts_num); -Array> build_vert_to_poly_map(Span polys, Span loops, int verts_num); -Array> build_vert_to_loop_map(Span loops, int verts_num); -Array> build_edge_to_loop_map(Span loops, int edges_num); -Array> build_edge_to_poly_map(Span polys, Span loops, int edges_num); -Vector> build_edge_to_loop_map_resizable(Span loops, int edges_num); +Array> build_vert_to_poly_map(Span polys, + Span corner_verts, + int verts_num); +Array> build_vert_to_loop_map(Span corner_verts, int verts_num); +Array> build_edge_to_loop_map(Span corner_edges, int edges_num); +Array> build_edge_to_poly_map(Span polys, + Span corner_edges, + int edges_num); +Vector> build_edge_to_loop_map_resizable(Span corner_edges, int edges_num); inline int poly_loop_prev(const MPoly &poly, int loop_i) { diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h index d08c6cbbcee..81407732a20 100644 --- a/source/blender/blenkernel/BKE_mesh_remap.h +++ b/source/blender/blenkernel/BKE_mesh_remap.h @@ -202,7 +202,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode, int numverts_dst, const struct MEdge *edges_dst, int numedges_dst, - const struct MLoop *loops_dst, + const int *corner_verts_dst, + const int *corner_edges_dst, int numloops_dst, const struct MPoly *polys_dst, int numpolys_dst, @@ -222,7 +223,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode, const struct Mesh *mesh_dst, const float (*vert_positions_dst)[3], int numverts_dst, - const struct MLoop *loops_dst, + const int *corner_verts, const struct MPoly *polys_dst, int numpolys_dst, struct Mesh *me_src, diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h index 1d96da5fb69..48907c21bc8 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.h +++ b/source/blender/blenkernel/BKE_mesh_runtime.h @@ -17,7 +17,6 @@ extern "C" { struct CustomData_MeshMasks; struct Depsgraph; struct KeyBlock; -struct MLoop; struct MLoopTri; struct MVertTri; struct Mesh; @@ -63,7 +62,7 @@ void BKE_mesh_runtime_clear_cache(struct Mesh *mesh); * Convert triangles encoded as face corner indices to triangles encoded as vertex indices. */ void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri, - const struct MLoop *mloop, + const int *corner_verts, const struct MLoopTri *looptri, int looptri_num); diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index 191c5c57ee9..3f181d0ae28 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -128,7 +128,7 @@ int sample_surface_points_projected( Vector &r_positions); float3 compute_bary_coord_in_triangle(Span vert_positions, - Span loops, + Span corner_verts, const MLoopTri &looptri, const float3 &position); diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h index 085096c77f1..47d43e984be 100644 --- a/source/blender/blenkernel/BKE_mesh_tangent.h +++ b/source/blender/blenkernel/BKE_mesh_tangent.h @@ -20,7 +20,7 @@ struct ReportList; */ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], int numVerts, - const struct MLoop *mloops, + const int *corner_verts, float (*r_looptangent)[4], const float (*loop_normals)[3], const float (*loopuv)[2], @@ -45,7 +45,7 @@ void BKE_mesh_calc_loop_tangent_single(struct Mesh *mesh, void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], const struct MPoly *polys, uint polys_len, - const struct MLoop *mloop, + const int *corner_verts, const struct MLoopTri *looptri, uint looptri_len, const bool *sharp_faces, diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index 9b9efeeb761..9436ba971ca 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -49,7 +49,7 @@ typedef enum eMeshBatchDirtyMode { /** #MeshRuntime.wrapper_type */ typedef enum eMeshWrapperType { - /** Use mesh data (#Mesh.vert_positions(), #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */ + /** Use mesh data (#Mesh.vert_positions(), #Mesh.medge, #Mesh.corner_verts(), #Mesh.mpoly). */ ME_WRAPPER_TYPE_MDATA = 0, /** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */ ME_WRAPPER_TYPE_BMESH = 1, diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 02a0e184087..ffe1d75f052 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -24,6 +24,7 @@ struct Object; struct Scene; struct SubdivCCG; +struct MLoopTri; struct MPoly; /** diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index a9ac01c9f73..01a6b549923 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -37,7 +37,6 @@ struct Image; struct ImagePool; struct ImageUser; struct ListBase; -struct MLoop; struct MLoopTri; struct Main; struct Mesh; @@ -578,7 +577,7 @@ typedef struct SculptSession { /* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */ float (*vert_positions)[3]; const struct MPoly *polys; - const struct MLoop *mloop; + const int *corner_verts; /* These contain the vertex and poly counts of the final mesh. */ int totvert, totpoly; diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 833cb425987..719ffb9075e 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -29,7 +29,6 @@ struct CCGKey; struct CustomData; struct DMFlagMat; struct IsectRayPrecalc; -struct MLoop; struct MLoopTri; struct MPoly; struct Mesh; @@ -283,13 +282,13 @@ PBVH *BKE_pbvh_new(PBVHType type); /** * Do a full rebuild with on Mesh data structure. * - * \note Unlike mpoly/mloop/verts, looptri is *totally owned* by PBVH + * \note Unlike mpoly/corner_verts/verts, looptri is *totally owned* by PBVH * (which means it may rewrite it if needed, see #BKE_pbvh_vert_coords_apply(). */ void BKE_pbvh_build_mesh(PBVH *pbvh, struct Mesh *mesh, const struct MPoly *polys, - const struct MLoop *mloop, + const int *corner_verts, float (*vert_positions)[3], int totvert, struct CustomData *vdata, @@ -510,7 +509,7 @@ const int *BKE_pbvh_node_get_vert_indices(PBVHNode *node); void BKE_pbvh_node_get_loops(PBVH *pbvh, PBVHNode *node, const int **r_loop_indices, - const struct MLoop **r_loops); + const int **r_corner_verts); /* Get number of faces in the mesh; for PBVH_GRIDS the * number of base mesh faces is returned. @@ -737,7 +736,7 @@ typedef struct PBVHFaceIter { int *face_sets_; const struct MPoly *polys_; const struct MLoopTri *looptri_; - const struct MLoop *mloop_; + const int *corner_verts_; int prim_index_; const struct SubdivCCG *subdiv_ccg_; const struct BMesh *bm; diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 707dbc0ada6..40e45b58b52 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -75,6 +75,7 @@ typedef struct ShrinkwrapTreeData { const struct MPoly *polys; const float (*vert_normals)[3]; + const int *corner_edges; const float (*poly_normals)[3]; const bool *sharp_faces; const float (*clnors)[3]; diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h index 582e0774a58..bc35aae1ff6 100644 --- a/source/blender/blenkernel/BKE_subdiv_ccg.h +++ b/source/blender/blenkernel/BKE_subdiv_ccg.h @@ -21,7 +21,6 @@ struct CCGKey; struct DMFlagMat; struct Mesh; struct MPoly; -struct MLoop; struct Subdiv; /* -------------------------------------------------------------------- @@ -310,8 +309,8 @@ typedef enum SubdivCCGAdjacencyType { * adjacent to a vertex, r_v1 and r_v2 will be the index of that vertex. */ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord, - const struct MLoop *mloop, - const struct MPoly *polys, + const int *corner_verts, + const struct MPoly *mpoly, int *r_v1, int *r_v2); diff --git a/source/blender/blenkernel/BKE_volume_to_mesh.hh b/source/blender/blenkernel/BKE_volume_to_mesh.hh index 15e405a103d..33ff97b0fe9 100644 --- a/source/blender/blenkernel/BKE_volume_to_mesh.hh +++ b/source/blender/blenkernel/BKE_volume_to_mesh.hh @@ -64,7 +64,7 @@ void fill_mesh_from_openvdb_data(const Span vdb_verts, int loop_offset, MutableSpan vert_positions, MutableSpan polys, - MutableSpan loops); + MutableSpan corner_verts); #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index e42892ea937..f6fcd4278a0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -122,19 +122,32 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm) return edge; } -static MLoop *dm_getLoopArray(DerivedMesh *dm) +static int *dm_getCornerVertArray(DerivedMesh *dm) { - MLoop *mloop = (MLoop *)CustomData_get_layer_for_write( - &dm->loopData, CD_MLOOP, dm->getNumLoops(dm)); + int *corner_verts = (int *)CustomData_get_layer_named_for_write( + &dm->loopData, CD_PROP_INT32, ".corner_vert", dm->getNumLoops(dm)); - if (!mloop) { - mloop = (MLoop *)CustomData_add_layer( - &dm->loopData, CD_MLOOP, CD_SET_DEFAULT, dm->getNumLoops(dm)); - CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY); - dm->copyLoopArray(dm, mloop); + if (!corner_verts) { + corner_verts = (int *)CustomData_add_layer_named( + &dm->loopData, CD_PROP_INT32, CD_SET_DEFAULT, dm->getNumLoops(dm), ".corner_vert"); + dm->copyCornerVertArray(dm, corner_verts); } - return mloop; + return corner_verts; +} + +static int *dm_getCornerEdgeArray(DerivedMesh *dm) +{ + int *corner_edges = (int *)CustomData_get_layer_named( + &dm->loopData, CD_PROP_INT32, ".corner_edge"); + + if (!corner_edges) { + corner_edges = (int *)CustomData_add_layer_named( + &dm->loopData, CD_PROP_INT32, CD_SET_DEFAULT, dm->getNumLoops(dm), ".corner_edge"); + dm->copyCornerEdgeArray(dm, corner_edges); + } + + return corner_edges; } static MPoly *dm_getPolyArray(DerivedMesh *dm) @@ -188,7 +201,8 @@ void DM_init_funcs(DerivedMesh *dm) /* default function implementations */ dm->getVertArray = dm_getVertArray; dm->getEdgeArray = dm_getEdgeArray; - dm->getLoopArray = dm_getLoopArray; + dm->getCornerVertArray = dm_getCornerVertArray; + dm->getCornerEdgeArray = dm_getCornerEdgeArray; dm->getPolyArray = dm_getPolyArray; dm->getLoopTriArray = dm_getLoopTriArray; @@ -1891,7 +1905,7 @@ static void mesh_init_origspace(Mesh *mesh) &mesh->ldata, CD_ORIGSPACE_MLOOP, mesh->totloop); const Span positions = mesh->vert_positions(); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); int j, k; @@ -1907,7 +1921,6 @@ static void mesh_init_origspace(Mesh *mesh) } } else { - const MLoop *l = &loops[poly.loopstart]; float co[3]; float mat[3][3]; @@ -1915,13 +1928,13 @@ static void mesh_init_origspace(Mesh *mesh) float translate[2], scale[2]; const float3 p_nor = blender::bke::mesh::poly_normal_calc( - positions, loops.slice(poly.loopstart, poly.totloop)); + positions, corner_verts.slice(poly.loopstart, poly.totloop)); axis_dominant_v3_to_m3(mat, p_nor); vcos_2d.resize(poly.totloop); - for (j = 0; j < poly.totloop; j++, l++) { - mul_v3_m3v3(co, mat, positions[l->v]); + for (j = 0; j < poly.totloop; j++) { + mul_v3_m3v3(co, mat, positions[corner_verts[poly.loopstart + j]]); copy_v2_v2(vcos_2d[j], co); for (k = 0; k < 2; k++) { diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index feb2577e09f..8d032d07043 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -276,9 +276,9 @@ static void mesh_looptri_nearest_point(void *userdata, const float(*positions)[3] = data->vert_positions; const MLoopTri *lt = &data->looptri[index]; const float *vtri_co[3] = { - positions[data->loop[lt->tri[0]].v], - positions[data->loop[lt->tri[1]].v], - positions[data->loop[lt->tri[2]].v], + positions[data->corner_verts[lt->tri[0]]], + positions[data->corner_verts[lt->tri[1]]], + positions[data->corner_verts[lt->tri[2]]], }; float nearest_tmp[3], dist_sq; @@ -376,9 +376,9 @@ static void mesh_looptri_spherecast(void *userdata, const float(*positions)[3] = data->vert_positions; const MLoopTri *lt = &data->looptri[index]; const float *vtri_co[3] = { - positions[data->loop[lt->tri[0]].v], - positions[data->loop[lt->tri[1]].v], - positions[data->loop[lt->tri[2]].v], + positions[data->corner_verts[lt->tri[0]]], + positions[data->corner_verts[lt->tri[1]]], + positions[data->corner_verts[lt->tri[2]]], }; float dist; @@ -579,7 +579,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree, const float (*positions)[3], const MEdge *edge, const MFace *face, - const MLoop *loop, + const int *corner_verts, const Span looptris, BVHTreeFromMesh *r_data) { @@ -590,7 +590,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree, r_data->vert_positions = positions; r_data->edge = edge; r_data->face = face; - r_data->loop = loop; + r_data->corner_verts = corner_verts; r_data->looptri = looptris.data(); switch (bvh_cache_type) { @@ -1036,7 +1036,7 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, int tree_type, int axis, const float (*positions)[3], - const MLoop *mloop, + const int *corner_verts, const Span looptris, const BitSpan looptri_mask, int looptri_num_active) @@ -1065,9 +1065,9 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, continue; } - copy_v3_v3(co[0], positions[mloop[looptris[i].tri[0]].v]); - copy_v3_v3(co[1], positions[mloop[looptris[i].tri[1]].v]); - copy_v3_v3(co[2], positions[mloop[looptris[i].tri[2]].v]); + copy_v3_v3(co[0], positions[corner_verts[looptris[i].tri[0]]]); + copy_v3_v3(co[1], positions[corner_verts[looptris[i].tri[1]]]); + copy_v3_v3(co[2], positions[corner_verts[looptris[i].tri[2]]]); BLI_bvhtree_insert(tree, i, co[0], 3); } @@ -1106,7 +1106,7 @@ BVHTree *bvhtree_from_editmesh_looptri( BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, const float (*vert_positions)[3], - const struct MLoop *mloop, + const int *corner_verts, const struct MLoopTri *looptri, const int looptri_num, const BitSpan looptri_mask, @@ -1119,7 +1119,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, tree_type, axis, vert_positions, - mloop, + corner_verts, {looptri, looptri_num}, looptri_mask, looptri_num_active); @@ -1133,7 +1133,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, vert_positions, nullptr, nullptr, - mloop, + corner_verts, {looptri, looptri_num}, data); } @@ -1218,7 +1218,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, } const float(*positions)[3] = reinterpret_cast(mesh->vert_positions().data()); const Span edges = mesh->edges(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); /* Setup BVHTreeFromMesh */ bvhtree_from_mesh_setup_data(nullptr, @@ -1226,7 +1226,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, positions, edges.data(), (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), - loops.data(), + corner_verts.data(), looptris, data); @@ -1286,7 +1286,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, } case BVHTREE_FROM_LOOPTRI: data->tree = bvhtree_from_mesh_looptri_create_tree( - 0.0f, tree_type, 6, positions, loops.data(), looptris, mask, mask_bits_act_len); + 0.0f, tree_type, 6, positions, corner_verts.data(), looptris, mask, mask_bits_act_len); break; case BVHTREE_FROM_EM_VERTS: case BVHTREE_FROM_EM_EDGES: diff --git a/source/blender/blenkernel/intern/cdderivedmesh.cc b/source/blender/blenkernel/intern/cdderivedmesh.cc index 9d244f1b441..fa7273314a2 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.cc +++ b/source/blender/blenkernel/intern/cdderivedmesh.cc @@ -42,7 +42,8 @@ struct CDDerivedMesh { const blender::float3 *vert_normals; MEdge *medge; MFace *mface; - MLoop *mloop; + int *corner_verts; + int *corner_edges; MPoly *mpoly; /* Cached */ @@ -87,10 +88,16 @@ static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge) memcpy(r_edge, cddm->medge, sizeof(*r_edge) * dm->numEdgeData); } -static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop) +static void cdDM_copyCornerVertArray(DerivedMesh *dm, int *r_corner_verts) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - memcpy(r_loop, cddm->mloop, sizeof(*r_loop) * dm->numLoopData); + memcpy(r_corner_verts, cddm->corner_verts, sizeof(*r_corner_verts) * dm->numLoopData); +} + +static void cdDM_copyCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges) +{ + CDDerivedMesh *cddm = (CDDerivedMesh *)dm; + memcpy(r_corner_edges, cddm->corner_edges, sizeof(*r_corner_edges) * dm->numLoopData); } static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly) @@ -124,7 +131,7 @@ static void cdDM_recalc_looptri(DerivedMesh *dm) blender::bke::mesh::looptris_calc( {reinterpret_cast(cddm->vert_positions), dm->numVertData}, {cddm->mpoly, totpoly}, - {cddm->mloop, totloop}, + {cddm->corner_verts, totloop}, {dm->looptris.array_wip, dm->looptris.num}); BLI_assert(cddm->dm.looptris.array == NULL); @@ -166,7 +173,8 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->copyVertArray = cdDM_copyVertArray; dm->copyEdgeArray = cdDM_copyEdgeArray; - dm->copyLoopArray = cdDM_copyLoopArray; + dm->copyCornerVertArray = cdDM_copyCornerVertArray; + dm->copyCornerEdgeArray = cdDM_copyCornerEdgeArray; dm->copyPolyArray = cdDM_copyPolyArray; dm->getVertDataArray = DM_get_vert_data_layer; @@ -224,8 +232,10 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, cddm->vert_normals = mesh->vert_normals().data(); cddm->medge = static_cast( CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge)); - cddm->mloop = static_cast( - CustomData_get_layer_for_write(&dm->loopData, CD_MLOOP, mesh->totloop)); + cddm->corner_verts = static_cast(CustomData_get_layer_named_for_write( + &dm->loopData, CD_PROP_INT32, ".corner_vert", mesh->totloop)); + cddm->corner_edges = static_cast(CustomData_get_layer_named_for_write( + &dm->loopData, CD_PROP_INT32, ".corner_edge", mesh->totloop)); cddm->mpoly = static_cast( CustomData_get_layer_for_write(&dm->polyData, CD_MPOLY, mesh->totpoly)); #if 0 diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index f83e8056109..bd85b0f3f33 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -835,7 +835,7 @@ static bool cloth_from_object( static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh) { - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const blender::Span looptris = mesh->looptris(); const uint mvert_num = mesh->totvert; @@ -868,7 +868,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes return; } BKE_mesh_runtime_verttri_from_looptri( - clmd->clothObject->tri, loops.data(), looptris.data(), looptris.size()); + clmd->clothObject->tri, corner_verts.data(), looptris.data(), looptris.size()); clmd->clothObject->edges = mesh->edges().data(); @@ -1288,7 +1288,7 @@ void cloth_parallel_transport_hair_frame(float mat[3][3], /* Add a shear and a bend spring between two verts within a poly. */ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd, LinkNodePair *edgelist, - const blender::Span loops, + const blender::Span corner_verts, const blender::Span polys, int i, int j, @@ -1296,7 +1296,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd, { Cloth *cloth = clmd->clothObject; ClothSpring *spring; - const MLoop *tmp_loop; + const int *tmp_corner; float shrink_factor; int x, y; @@ -1308,7 +1308,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd, } spring_verts_ordered_set( - spring, loops[polys[i].loopstart + j].v, loops[polys[i].loopstart + k].v); + spring, corner_verts[polys[i].loopstart + j], corner_verts[polys[i].loopstart + k]); shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl); spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest) * @@ -1340,18 +1340,18 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd, return false; } - tmp_loop = &loops[polys[i].loopstart]; + tmp_corner = &corner_verts[polys[i].loopstart]; for (x = 0; x < spring->la; x++) { - spring->pa[x] = tmp_loop[j + x].v; + spring->pa[x] = tmp_corner[j + x]; } for (x = 0; x <= j; x++) { - spring->pb[x] = tmp_loop[x].v; + spring->pb[x] = tmp_corner[x]; } for (y = k; y < polys[i].totloop; x++, y++) { - spring->pb[x] = tmp_loop[y].v; + spring->pb[x] = tmp_corner[y]; } spring->mn = -1; @@ -1369,7 +1369,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd, return true; } -BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const MLoop *mloop) +BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const int *corner_verts) { int *p = static_cast(MEM_mallocN(sizeof(int) * len, "spring poly")); @@ -1377,8 +1377,8 @@ BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const MLoop return false; } - for (int i = 0; i < len; i++, mloop++) { - p[i] = mloop->v; + for (int i = 0; i < len; i++) { + p[i] = corner_verts[i]; } *poly = p; @@ -1431,7 +1431,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata, treedata->tree, new_co, no, radius, &rayhit, treedata->raycast_callback, treedata); uint vert_idx = -1; - const MLoop *mloop = treedata->loop; + const int *corner_verts = treedata->corner_verts; const MLoopTri *lt = nullptr; if (rayhit.index != -1 && rayhit.dist <= max_length) { @@ -1444,7 +1444,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata, lt = &treedata->looptri[rayhit.index]; for (int i = 0; i < 3; i++) { - uint tmp_vert_idx = mloop[lt->tri[i]].v; + uint tmp_vert_idx = corner_verts[lt->tri[i]]; if (tmp_vert_idx == v_idx) { /* We managed to hit ourselves. */ return false; @@ -1466,6 +1466,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata, static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) { + using namespace blender; using namespace blender::bke; Cloth *cloth = clmd->clothObject; ClothSpring *spring = nullptr, *tspring = nullptr, *tspring2 = nullptr; @@ -1476,7 +1477,8 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) float shrink_factor; const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); + const Span corner_edges = mesh->corner_edges(); int index2 = 0; /* our second vertex index */ LinkNodePair *edgelist = nullptr; EdgeSet *edgeset = nullptr; @@ -1672,7 +1674,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) if (polys[i].totloop > 3) { for (int j = 1; j < polys[i].totloop - 1; j++) { if (j > 1) { - if (cloth_add_shear_bend_spring(clmd, edgelist, loops, polys, i, 0, j)) { + if (cloth_add_shear_bend_spring(clmd, edgelist, corner_verts, polys, i, 0, j)) { shear_springs++; if (clmd->sim_parms->bending_model == CLOTH_BENDING_ANGULAR) { @@ -1686,7 +1688,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) } for (int k = j + 2; k < polys[i].totloop; k++) { - if (cloth_add_shear_bend_spring(clmd, edgelist, loops, polys, i, j, k)) { + if (cloth_add_shear_bend_spring(clmd, edgelist, corner_verts, polys, i, j, k)) { shear_springs++; if (clmd->sim_parms->bending_model == CLOTH_BENDING_ANGULAR) { @@ -1703,10 +1705,9 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) /* Angular bending springs along struct springs. */ if (clmd->sim_parms->bending_model == CLOTH_BENDING_ANGULAR) { - const MLoop *ml = &loops[polys[i].loopstart]; - - for (int j = 0; j < polys[i].totloop; j++, ml++) { - BendSpringRef *curr_ref = &spring_ref[ml->e]; + for (int j = 0; j < polys[i].totloop; j++) { + const int edge_i = corner_edges[polys[i].loopstart + j]; + BendSpringRef *curr_ref = &spring_ref[edge_i]; curr_ref->polys++; /* First poly found for this edge, store poly index. */ @@ -1723,14 +1724,14 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) spring->lb = polys[i].totloop; if (!cloth_bend_set_poly_vert_array( - &spring->pa, spring->la, &loops[polys[curr_ref->index].loopstart]) || + &spring->pa, spring->la, &corner_verts[polys[curr_ref->index].loopstart]) || !cloth_bend_set_poly_vert_array( - &spring->pb, spring->lb, &loops[polys[i].loopstart])) { + &spring->pb, spring->lb, &corner_verts[polys[i].loopstart])) { cloth_free_errorsprings(cloth, edgelist, spring_ref); return false; } - spring->mn = ml->e; + spring->mn = edge_i; spring->restang = cloth_spring_angle(cloth->verts, spring->ij, @@ -1897,8 +1898,10 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) for (int i = 0; i < numpolys; i++) { /* edge springs */ if (polys[i].totloop == 4) { - BLI_edgeset_add(edgeset, loops[polys[i].loopstart + 0].v, loops[polys[i].loopstart + 2].v); - BLI_edgeset_add(edgeset, loops[polys[i].loopstart + 1].v, loops[polys[i].loopstart + 3].v); + BLI_edgeset_add( + edgeset, corner_verts[polys[i].loopstart + 0], corner_verts[polys[i].loopstart + 2]); + BLI_edgeset_add( + edgeset, corner_verts[polys[i].loopstart + 1], corner_verts[polys[i].loopstart + 3]); } } diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index 0f1cd0a2f06..0557921e699 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -190,44 +190,44 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ const Span positions = me->vert_positions(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); for (int i = 0; i < me->totpoly; i++) { const MPoly &poly = polys[i]; - const MLoop *ml_next = &loops[poly.loopstart]; - const MLoop *ml_curr = &ml_next[poly.totloop - 1]; - const MLoop *ml_prev = &ml_next[poly.totloop - 2]; + const int *corner_vert_next = &corner_verts[poly.loopstart]; + const int *corner_vert_curr = &corner_vert_next[poly.totloop - 1]; + const int *corner_vert_prev = &corner_vert_next[poly.totloop - 2]; for (int j = 0; j < poly.totloop; j++) { - if (!BLI_BITMAP_TEST(vert_tag, ml_curr->v)) { + if (!BLI_BITMAP_TEST(vert_tag, *corner_vert_curr)) { const float *co_prev, *co_curr, *co_next; /* orig */ const float *vd_prev, *vd_curr, *vd_next; /* deform */ /* retrieve mapped coordinates */ - vd_prev = mappedcos[ml_prev->v]; - vd_curr = mappedcos[ml_curr->v]; - vd_next = mappedcos[ml_next->v]; + vd_prev = mappedcos[*corner_vert_prev]; + vd_curr = mappedcos[*corner_vert_curr]; + vd_next = mappedcos[*corner_vert_next]; if (origcos) { - co_prev = origcos[ml_prev->v]; - co_curr = origcos[ml_curr->v]; - co_next = origcos[ml_next->v]; + co_prev = origcos[*corner_vert_prev]; + co_curr = origcos[*corner_vert_curr]; + co_next = origcos[*corner_vert_next]; } else { - co_prev = positions[ml_prev->v]; - co_curr = positions[ml_curr->v]; - co_next = positions[ml_next->v]; + co_prev = positions[*corner_vert_prev]; + co_curr = positions[*corner_vert_curr]; + co_next = positions[*corner_vert_next]; } set_crazy_vertex_quat( - quats[ml_curr->v], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev); + quats[*corner_vert_curr], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev); - BLI_BITMAP_ENABLE(vert_tag, ml_curr->v); + BLI_BITMAP_ENABLE(vert_tag, *corner_vert_curr); } - ml_prev = ml_curr; - ml_curr = ml_next; - ml_next++; + corner_vert_prev = corner_vert_curr; + corner_vert_curr = corner_vert_next; + corner_vert_next++; } } diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index d90da24f2b2..8d893645f74 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -28,7 +28,8 @@ static void fill_mesh_topology(const int vert_offset, const bool profile_cyclic, const bool fill_caps, MutableSpan edges, - MutableSpan loops, + MutableSpan corner_verts, + MutableSpan corner_edges, MutableSpan polys) { const int main_segment_num = curves::segments_num(main_point_num, main_cyclic); @@ -104,18 +105,17 @@ static void fill_mesh_topology(const int vert_offset, poly.loopstart = ring_segment_loop_offset; poly.totloop = 4; - MLoop &loop_a = loops[ring_segment_loop_offset]; - loop_a.v = ring_vert_offset + i_profile; - loop_a.e = ring_edge_start + i_profile; - MLoop &loop_b = loops[ring_segment_loop_offset + 1]; - loop_b.v = ring_vert_offset + i_next_profile; - loop_b.e = next_main_edge_start + i_ring; - MLoop &loop_c = loops[ring_segment_loop_offset + 2]; - loop_c.v = next_ring_vert_offset + i_next_profile; - loop_c.e = next_ring_edge_offset + i_profile; - MLoop &loop_d = loops[ring_segment_loop_offset + 3]; - loop_d.v = next_ring_vert_offset + i_profile; - loop_d.e = main_edge_start + i_ring; + corner_verts[ring_segment_loop_offset] = ring_vert_offset + i_profile; + corner_edges[ring_segment_loop_offset] = ring_edge_start + i_profile; + + corner_verts[ring_segment_loop_offset + 1] = ring_vert_offset + i_next_profile; + corner_edges[ring_segment_loop_offset + 1] = next_main_edge_start + i_ring; + + corner_verts[ring_segment_loop_offset + 2] = next_ring_vert_offset + i_next_profile; + corner_edges[ring_segment_loop_offset + 2] = next_ring_edge_offset + i_profile; + + corner_verts[ring_segment_loop_offset + 3] = next_ring_vert_offset + i_profile; + corner_edges[ring_segment_loop_offset + 3] = main_edge_start + i_ring; } } @@ -138,13 +138,12 @@ static void fill_mesh_topology(const int vert_offset, for (const int i : IndexRange(profile_segment_num)) { const int i_inv = profile_segment_num - i - 1; - MLoop &loop_start = loops[cap_loop_offset + i]; - loop_start.v = vert_offset + i_inv; - loop_start.e = profile_edges_start + - ((i == (profile_segment_num - 1)) ? (profile_segment_num - 1) : (i_inv - 1)); - MLoop &loop_end = loops[cap_loop_offset + profile_segment_num + i]; - loop_end.v = last_ring_vert_offset + i; - loop_end.e = last_ring_edge_offset + i; + corner_verts[cap_loop_offset + i] = vert_offset + i_inv; + corner_edges[cap_loop_offset + i] = profile_edges_start + ((i == (profile_segment_num - 1)) ? + (profile_segment_num - 1) : + (i_inv - 1)); + corner_verts[cap_loop_offset + profile_segment_num + i] = last_ring_vert_offset + i; + corner_edges[cap_loop_offset + profile_segment_num + i] = last_ring_edge_offset + i; } } } @@ -672,7 +671,8 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); + MutableSpan corner_edges = mesh->corner_edges_for_write(); MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { @@ -686,7 +686,8 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, info.profile_cyclic, fill_caps, edges, - loops, + corner_verts, + corner_edges, polys); }); diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index d270b04bf50..0d7f55a6f26 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -1770,7 +1770,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MRecast), "MRecast", 1, N_("Recast"), nullptr, nullptr, nullptr, nullptr}, /* 25: CD_MPOLY */ {sizeof(MPoly), "MPoly", 1, N_("NGon Face"), nullptr, nullptr, nullptr, nullptr, nullptr}, - /* 26: CD_MLOOP */ + /* 26: CD_MLOOP */ /* DEPRECATED*/ {sizeof(MLoop), "MLoop", 1, @@ -2030,14 +2030,14 @@ const CustomData_MeshMasks CD_MASK_BAREMESH = { /*emask*/ CD_MASK_MEDGE, /*fmask*/ 0, /*pmask*/ CD_MASK_MPOLY | CD_MASK_FACEMAP, - /*lmask*/ CD_MASK_MLOOP, + /*lmask*/ CD_MASK_PROP_INT32, }; const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { /*vmask*/ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX, /*emask*/ CD_MASK_MEDGE | CD_MASK_ORIGINDEX, /*fmask*/ 0, /*pmask*/ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX, - /*lmask*/ CD_MASK_MLOOP, + /*lmask*/ CD_MASK_PROP_INT32, }; const CustomData_MeshMasks CD_MASK_MESH = { /*vmask*/ (CD_MASK_PROP_FLOAT3 | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | @@ -2048,8 +2048,7 @@ const CustomData_MeshMasks CD_MASK_MESH = { /*pmask*/ (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /*lmask*/ - (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | - CD_MASK_PROP_ALL), + (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /*vmask*/ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | @@ -2090,9 +2089,9 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { (CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /*lmask*/ - (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | - CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | - CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL | + CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | + CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; static const LayerTypeInfo *layerType_getInfo(int type) diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 552de64cf26..0265b2eb54e 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -380,7 +380,8 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, blender::bke::mesh::normals_calc_loop(me_dst->vert_positions(), me_dst->edges(), me_dst->polys(), - me_dst->loops(), + me_dst->corner_verts(), + me_dst->corner_edges(), {}, me_dst->vert_normals(), me_dst->poly_normals(), @@ -429,7 +430,8 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, blender::bke::mesh::normals_loop_custom_set(me_dst->vert_positions(), me_dst->edges(), me_dst->polys(), - me_dst->loops(), + me_dst->corner_verts(), + me_dst->corner_edges(), me_dst->vert_normals(), me_dst->poly_normals(), sharp_faces, @@ -1563,7 +1565,8 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, const int num_verts_dst = me_dst->totvert; const blender::Span edges_dst = me_dst->edges(); const blender::Span polys_dst = me_dst->polys(); - const blender::Span loops_dst = me_dst->loops(); + const blender::Span corner_verts_dst = me_dst->corner_verts(); + const blender::Span corner_edges_dst = me_dst->corner_edges(); CustomData *ldata_dst = &me_dst->ldata; MeshRemapIslandsCalc island_callback = data_transfer_get_loop_islands_generator(cddata_type); @@ -1571,7 +1574,8 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, if (!geom_map_init[LDATA]) { const int num_loops_src = me_src->totloop; - if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (loops_dst.size() != num_loops_src)) { + if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && + (corner_verts_dst.size() != num_loops_src)) { BKE_report(reports, RPT_ERROR, "Source and destination meshes do not have the same amount of face corners, " @@ -1585,7 +1589,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, "None of the 'Edge' mappings can be used in this case"); continue; } - if (ELEM(0, loops_dst.size(), num_loops_src)) { + if (ELEM(0, corner_verts_dst.size(), num_loops_src)) { BKE_report( reports, RPT_ERROR, @@ -1602,8 +1606,9 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, num_verts_dst, edges_dst.data(), edges_dst.size(), - loops_dst.data(), - loops_dst.size(), + corner_verts_dst.data(), + corner_edges_dst.data(), + corner_verts_dst.size(), polys_dst.data(), polys_dst.size(), ldata_dst, @@ -1619,12 +1624,12 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, if (mdef && vg_idx != -1 && !weights[LDATA]) { weights[LDATA] = static_cast( - MEM_mallocN(sizeof(*weights[LDATA]) * size_t(loops_dst.size()), __func__)); + MEM_mallocN(sizeof(*weights[LDATA]) * size_t(corner_verts_dst.size()), __func__)); BKE_defvert_extract_vgroup_to_loopweights(mdef, vg_idx, num_verts_dst, - loops_dst.data(), - loops_dst.size(), + corner_verts_dst.data(), + corner_verts_dst.size(), invert_vgroup, weights[LDATA]); } @@ -1639,7 +1644,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, mix_mode, mix_factor, weights[LDATA], - loops_dst.size(), + corner_verts_dst.size(), use_create, use_delete, fromlayers, @@ -1661,7 +1666,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst); const int num_verts_dst = me_dst->totvert; const blender::Span polys_dst = me_dst->polys(); - const blender::Span loops_dst = me_dst->loops(); + const blender::Span corner_verts_dst = me_dst->corner_verts(); if (!geom_map_init[PDATA]) { const int num_polys_src = me_src->totpoly; @@ -1695,7 +1700,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, me_dst, positions_dst, num_verts_dst, - loops_dst.data(), + corner_verts_dst.data(), polys_dst.data(), polys_dst.size(), me_src, @@ -1709,8 +1714,8 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, BKE_defvert_extract_vgroup_to_polyweights(mdef, vg_idx, num_verts_dst, - loops_dst.data(), - loops_dst.size(), + corner_verts_dst.data(), + corner_verts_dst.size(), polys_dst.data(), polys_dst.size(), invert_vgroup, diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index e759d012e58..4c7ddfe5877 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1074,7 +1074,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, const int defgroup, const int verts_num, - const MLoop *loops, + const int *corner_verts, const int loops_num, const bool invert_vgroup, float *r_weights) @@ -1088,9 +1088,7 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, dvert, defgroup, verts_num, invert_vgroup, tmp_weights); while (i--) { - const MLoop *ml = &loops[i]; - - r_weights[i] = tmp_weights[ml->v]; + r_weights[i] = tmp_weights[corner_verts[i]]; } MEM_freeN(tmp_weights); @@ -1103,7 +1101,7 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, const int defgroup, const int verts_num, - const MLoop *loops, + const int *corner_verts, const int /*loops_num*/, const MPoly *polys, const int polys_num, @@ -1120,12 +1118,12 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, while (i--) { const MPoly &poly = polys[i]; - const MLoop *ml = &loops[poly.loopstart]; + const int *corner_vert = &corner_verts[poly.loopstart]; int j = poly.totloop; float w = 0.0f; - for (; j--; ml++) { - w += tmp_weights[ml->v]; + for (; j--; corner_vert++) { + w += tmp_weights[*corner_vert]; } r_weights[i] = w / float(poly.totloop); } diff --git a/source/blender/blenkernel/intern/dynamicpaint.cc b/source/blender/blenkernel/intern/dynamicpaint.cc index 82ea253a27a..4388f1d2535 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.cc +++ b/source/blender/blenkernel/intern/dynamicpaint.cc @@ -1416,7 +1416,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b int numOfPolys = mesh->totpoly; const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); /* count number of edges per vertex */ for (int i = 0; i < numOfEdges; i++) { @@ -1431,7 +1431,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b * to locate points on "mesh edge" */ for (int i = 0; i < numOfPolys; i++) { for (int j = 0; j < polys[i].totloop; j++) { - temp_data[loops[polys[i].loopstart + j].v]++; + temp_data[corner_verts[polys[i].loopstart + j]]++; } } @@ -1479,7 +1479,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b struct DynamicPaintSetInitColorData { const DynamicPaintSurface *surface; - blender::Span loops; + blender::Span corner_verts; const float (*mloopuv)[2]; blender::Span looptris; const MLoopCol *mloopcol; @@ -1497,7 +1497,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdat const PaintSurfaceData *sData = data->surface->data; PaintPoint *pPoint = (PaintPoint *)sData->type_data; - const blender::Span loops = data->loops; + const blender::Span corner_verts = data->corner_verts; const blender::Span looptris = data->looptris; const float(*mloopuv)[2] = data->mloopuv; ImagePool *pool = data->pool; @@ -1509,7 +1509,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdat for (int j = 3; j--;) { TexResult texres = {0}; - const uint vert = loops[looptris[i].tri[j]].v; + const int vert = corner_verts[looptris[i].tri[j]]; /* remap to [-1.0, 1.0] */ uv[0] = mloopuv[looptris[i].tri[j]][0] * 2.0f - 1.0f; @@ -1618,7 +1618,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { Tex *tex = surface->init_texture; - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const blender::Span looptris = mesh->looptris(); char uvname[MAX_CUSTOMDATA_LAYER_NAME]; @@ -1643,7 +1643,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface DynamicPaintSetInitColorData data{}; data.surface = surface; - data.loops = loops; + data.corner_verts = corner_verts; data.looptris = looptris; data.mloopuv = mloopuv; data.pool = pool; @@ -1675,15 +1675,15 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* For vertex surface, just copy colors from #MLoopCol. */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const MLoopCol *col = static_cast( CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); if (!col) { return; } - for (const int i : loops.index_range()) { - rgba_uchar_to_float(pPoint[loops[i].v].color, (const uchar *)&col[i].r); + for (const int i : corner_verts.index_range()) { + rgba_uchar_to_float(pPoint[corner_verts[i]].color, (const uchar *)&col[i].r); } } else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { @@ -1791,7 +1791,7 @@ struct DynamicPaintModifierApplyData { float (*vert_positions)[3]; blender::Span vert_normals; blender::Span polys; - blender::Span loops; + blender::Span corner_verts; float (*fcolor)[4]; MLoopCol *mloopcol; @@ -1860,7 +1860,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, userdata); const blender::Span polys = data->polys; - const blender::Span loops = data->loops; + const blender::Span corner_verts = data->corner_verts; const DynamicPaintSurface *surface = data->surface; PaintPoint *pPoint = (PaintPoint *)surface->data->type_data; @@ -1871,7 +1871,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, for (int j = 0; j < polys[p_index].totloop; j++) { const int l_index = polys[p_index].loopstart + j; - const int v_index = loops[l_index].v; + const int v_index = corner_verts[l_index]; /* save layer data to output layer */ /* apply color */ @@ -1929,7 +1929,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* vertex color paint */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { const blender::Span polys = result->polys(); - const blender::Span loops = result->loops(); + const blender::Span corner_verts = result->corner_verts(); /* paint is stored on dry and wet layers, so mix final color first */ float(*fcolor)[4] = static_cast( @@ -1958,7 +1958,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * mloopcol = static_cast(CustomData_add_layer_named(&result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, - loops.size(), + corner_verts.size(), surface->output_name)); } @@ -1971,12 +1971,12 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * CustomData_add_layer_named(&result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, - loops.size(), + corner_verts.size(), surface->output_name2)); } data.ob = ob; - data.loops = loops; + data.corner_verts = corner_verts; data.polys = polys; data.mloopcol = mloopcol; data.mloopcol_wet = mloopcol_wet; @@ -2191,7 +2191,7 @@ struct DynamicPaintCreateUVSurfaceData { blender::Span looptris; const float (*mloopuv)[2]; - blender::Span loops; + blender::Span corner_verts; const Bounds2D *faceBB; uint32_t *active_points; @@ -2210,7 +2210,7 @@ static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, const blender::Span looptris = data->looptris; const float(*mloopuv)[2] = data->mloopuv; - const blender::Span loops = data->loops; + const blender::Span corner_verts = data->corner_verts; const Bounds2D *faceBB = data->faceBB; @@ -2281,9 +2281,9 @@ static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, tPoint->tri_index = i; /* save vertex indexes */ - tPoint->v1 = loops[looptris[i].tri[0]].v; - tPoint->v2 = loops[looptris[i].tri[1]].v; - tPoint->v3 = loops[looptris[i].tri[2]].v; + tPoint->v1 = corner_verts[looptris[i].tri[0]]; + tPoint->v2 = corner_verts[looptris[i].tri[1]]; + tPoint->v3 = corner_verts[looptris[i].tri[2]]; sample = 5; /* make sure we exit sample loop as well */ break; @@ -2306,7 +2306,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat const blender::Span looptris = data->looptris; const float(*mloopuv)[2] = data->mloopuv; - const blender::Span loops = data->loops; + const blender::Span corner_verts = data->corner_verts; uint32_t *active_points = data->active_points; @@ -2371,9 +2371,9 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat } /* save vertex indexes */ - tPoint->v1 = loops[looptris[i].tri[0]].v; - tPoint->v2 = loops[looptris[i].tri[1]].v; - tPoint->v3 = loops[looptris[i].tri[2]].v; + tPoint->v1 = corner_verts[looptris[i].tri[0]]; + tPoint->v2 = corner_verts[looptris[i].tri[1]]; + tPoint->v3 = corner_verts[looptris[i].tri[2]]; break; } @@ -2514,7 +2514,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa int in_edge, int depth) { - const blender::Span loops = data->loops; + const blender::Span corner_verts = data->corner_verts; const blender::Span looptris = data->looptris; const float(*mloopuv)[2] = data->mloopuv; @@ -2552,8 +2552,8 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa } /* Now find another face that is linked to that edge. */ - const int vert0 = loops[loop_idx[(edge_idx + 0)]].v; - const int vert1 = loops[loop_idx[(edge_idx + 1) % 3]].v; + const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]]; + const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]]; /* Use a pre-computed vert-to-looptri mapping, * speeds up things a lot compared to looping over all looptri. */ @@ -2576,8 +2576,8 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa /* Check edges for match, looping in the same order as the outer loop. */ for (int j = 0; j < 3; j++) { - const int overt0 = loops[other_loop_idx[(j + 0)]].v; - const int overt1 = loops[other_loop_idx[(j + 1) % 3]].v; + const int overt0 = corner_verts[other_loop_idx[(j + 0)]]; + const int overt1 = corner_verts[other_loop_idx[(j + 1) % 3]]; /* Allow for swapped vertex order */ if (overt0 == vert0 && overt1 == vert1) { @@ -2828,7 +2828,7 @@ int dynamicPaint_createUVSurface(Scene *scene, return setError(canvas, N_("Cannot bake non-'image sequence' formats")); } - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const blender::Span looptris = mesh->looptris(); /* get uv map */ @@ -2917,7 +2917,7 @@ int dynamicPaint_createUVSurface(Scene *scene, data.tempWeights = tempWeights; data.looptris = looptris; data.mloopuv = mloopuv; - data.loops = loops; + data.corner_verts = corner_verts; data.faceBB = faceBB; { @@ -2975,7 +2975,7 @@ int dynamicPaint_createUVSurface(Scene *scene, mesh->totvert, looptris.data(), looptris.size(), - loops.data(), + corner_verts.data(), mesh->totloop); int total_border = 0; @@ -3434,14 +3434,14 @@ static void mesh_tris_spherecast_dp(void *userdata, const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; const float(*positions)[3] = data->vert_positions; const MLoopTri *looptris = data->looptri; - const MLoop *loops = data->loop; + const int *corner_verts = data->corner_verts; const float *t0, *t1, *t2; float dist; - t0 = positions[loops[looptris[index].tri[0]].v]; - t1 = positions[loops[looptris[index].tri[1]].v]; - t2 = positions[loops[looptris[index].tri[2]].v]; + t0 = positions[corner_verts[looptris[index].tri[0]]]; + t1 = positions[corner_verts[looptris[index].tri[1]]]; + t2 = positions[corner_verts[looptris[index].tri[2]]]; dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); @@ -3466,13 +3466,13 @@ static void mesh_tris_nearest_point_dp(void *userdata, const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; const float(*positions)[3] = data->vert_positions; const MLoopTri *looptris = data->looptri; - const MLoop *loops = data->loop; + const int *corner_verts = data->corner_verts; float nearest_tmp[3], dist_sq; const float *t0, *t1, *t2; - t0 = positions[loops[looptris[index].tri[0]].v]; - t1 = positions[loops[looptris[index].tri[1]].v]; - t2 = positions[loops[looptris[index].tri[2]].v]; + t0 = positions[corner_verts[looptris[index].tri[0]]]; + t1 = positions[corner_verts[looptris[index].tri[1]]]; + t2 = positions[corner_verts[looptris[index].tri[2]]]; closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); dist_sq = len_squared_v3v3(co, nearest_tmp); @@ -3905,7 +3905,7 @@ struct DynamicPaintPaintData { Mesh *mesh; const float (*positions)[3]; - blender::Span loops; + blender::Span corner_verts; blender::Span looptris; float brush_radius; const float *avg_brushNor; @@ -3939,7 +3939,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, const int c_index = data->c_index; const float(*positions)[3] = data->positions; - const blender::Span loops = data->loops; + const blender::Span corner_verts = data->corner_verts; const blender::Span looptris = data->looptris; const float brush_radius = data->brush_radius; const float *avg_brushNor = data->avg_brushNor; @@ -4013,9 +4013,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, /* For optimization sake, hit point normal isn't calculated in ray cast loop */ const int vtri[3] = { - int(loops[looptris[hit.index].tri[0]].v), - int(loops[looptris[hit.index].tri[1]].v), - int(loops[looptris[hit.index].tri[2]].v), + corner_verts[looptris[hit.index].tri[0]], + corner_verts[looptris[hit.index].tri[1]], + corner_verts[looptris[hit.index].tri[2]], }; float dot; @@ -4163,9 +4163,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, float brushPointVelocity[3]; float velocity[3]; - const int v1 = loops[looptris[hitTri].tri[0]].v; - const int v2 = loops[looptris[hitTri].tri[1]].v; - const int v3 = loops[looptris[hitTri].tri[2]].v; + const int v1 = corner_verts[looptris[hitTri].tri[0]]; + const int v2 = corner_verts[looptris[hitTri].tri[1]]; + const int v3 = corner_verts[looptris[hitTri].tri[2]]; /* calculate barycentric weights for hit point */ interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord); @@ -4287,8 +4287,8 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, mesh = BKE_mesh_copy_for_eval(brush_mesh, false); float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); const blender::Span vert_normals = mesh->vert_normals(); + const blender::Span corner_verts = mesh->corner_verts(); const blender::Span looptris = mesh->looptris(); - const blender::Span loops = mesh->loops(); numOfVerts = mesh->totvert; /* Transform collider vertices to global space @@ -4342,7 +4342,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, data.c_index = c_index; data.mesh = mesh; data.positions = positions; - data.loops = loops; + data.corner_verts = corner_verts; data.looptris = looptris; data.brush_radius = brush_radius; data.avg_brushNor = avg_brushNor; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index e06c428349f..64b305accdd 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -660,12 +660,12 @@ bool closest_point_on_surface(SurfaceModifierData *surmd, } if (surface_vel) { - const MLoop *mloop = bvhtree->loop; + const int *corner_verts = bvhtree->corner_verts; const MLoopTri *lt = &bvhtree->looptri[nearest.index]; - copy_v3_v3(surface_vel, surmd->runtime.vert_velocities[mloop[lt->tri[0]].v]); - add_v3_v3(surface_vel, surmd->runtime.vert_velocities[mloop[lt->tri[1]].v]); - add_v3_v3(surface_vel, surmd->runtime.vert_velocities[mloop[lt->tri[2]].v]); + copy_v3_v3(surface_vel, surmd->runtime.vert_velocities[corner_verts[lt->tri[0]]]); + add_v3_v3(surface_vel, surmd->runtime.vert_velocities[corner_verts[lt->tri[1]]]); + add_v3_v3(surface_vel, surmd->runtime.vert_velocities[corner_verts[lt->tri[2]]]); mul_v3_fl(surface_vel, (1.0f / 3.0f)); } diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index af723bdd5e1..e3a00690b2a 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -840,7 +840,7 @@ BLI_INLINE void apply_effector_fields(FluidEffectorSettings * /*fes*/, static void update_velocities(FluidEffectorSettings *fes, const float (*vert_positions)[3], - const MLoop *mloop, + const int *corner_verts, const MLoopTri *mlooptri, float *velocity_map, int index, @@ -866,9 +866,9 @@ static void update_velocities(FluidEffectorSettings *fes, int v1, v2, v3, f_index = nearest.index; /* Calculate barycentric weights for nearest point. */ - v1 = mloop[mlooptri[f_index].tri[0]].v; - v2 = mloop[mlooptri[f_index].tri[1]].v; - v3 = mloop[mlooptri[f_index].tri[2]].v; + v1 = corner_verts[mlooptri[f_index].tri[0]]; + v2 = corner_verts[mlooptri[f_index].tri[1]]; + v3 = corner_verts[mlooptri[f_index].tri[2]]; interp_weights_tri_v3( weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); @@ -938,7 +938,7 @@ struct ObstaclesFromDMData { FluidEffectorSettings *fes; const float (*vert_positions)[3]; - blender::Span loops; + blender::Span corner_verts; blender::Span looptris; BVHTreeFromMesh *tree; @@ -973,7 +973,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata, /* Calculate object velocities. Result in bb->velocity. */ update_velocities(data->fes, data->vert_positions, - data->loops.data(), + data->corner_verts.data(), data->looptris.data(), bb->velocity, index, @@ -1008,7 +1008,7 @@ static void obstacles_from_mesh(Object *coll_ob, int min[3], max[3], res[3]; - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); const blender::Span looptris = me->looptris(); numverts = me->totvert; @@ -1072,7 +1072,7 @@ static void obstacles_from_mesh(Object *coll_ob, ObstaclesFromDMData data{}; data.fes = fes; data.vert_positions = positions; - data.loops = loops; + data.corner_verts = corner_verts; data.looptris = looptris; data.tree = &tree_data; data.bb = bb; @@ -1786,7 +1786,7 @@ static void update_distances(int index, static void sample_mesh(FluidFlowSettings *ffs, const float (*vert_positions)[3], const blender::Span vert_normals, - const MLoop *mloop, + const int *corner_verts, const MLoopTri *mlooptri, const float (*mloopuv)[2], float *influence_map, @@ -1869,9 +1869,9 @@ static void sample_mesh(FluidFlowSettings *ffs, float hit_normal[3]; /* Calculate barycentric weights for nearest point. */ - v1 = mloop[mlooptri[f_index].tri[0]].v; - v2 = mloop[mlooptri[f_index].tri[1]].v; - v3 = mloop[mlooptri[f_index].tri[2]].v; + v1 = corner_verts[mlooptri[f_index].tri[0]]; + v2 = corner_verts[mlooptri[f_index].tri[1]]; + v3 = corner_verts[mlooptri[f_index].tri[2]]; interp_weights_tri_v3( weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); @@ -1981,7 +1981,7 @@ struct EmitFromDMData { const float (*vert_positions)[3]; blender::Span vert_normals; - blender::Span loops; + blender::Span corner_verts; blender::Span looptris; const float (*mloopuv)[2]; const MDeformVert *dvert; @@ -2015,7 +2015,7 @@ static void emit_from_mesh_task_cb(void *__restrict userdata, sample_mesh(data->ffs, data->vert_positions, data->vert_normals, - data->loops.data(), + data->corner_verts.data(), data->looptris.data(), data->mloopuv, bb->influence, @@ -2065,7 +2065,7 @@ static void emit_from_mesh( Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false); float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); const blender::Span looptris = me->looptris(); const int numverts = me->totvert; const MDeformVert *dvert = BKE_mesh_deform_verts(me); @@ -2136,7 +2136,7 @@ static void emit_from_mesh( data.ffs = ffs; data.vert_positions = positions; data.vert_normals = me->vert_normals(); - data.loops = loops; + data.corner_verts = corner_verts; data.looptris = looptris; data.mloopuv = mloopuv; data.dvert = dvert; @@ -3235,7 +3235,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, } float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); blender::MutableSpan polys = me->polys_for_write(); - blender::MutableSpan loops = me->loops_for_write(); + blender::MutableSpan corner_verts = me->corner_verts_for_write(); const bool is_sharp = orgmesh->attributes().lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false)[0]; @@ -3332,9 +3332,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, polys[i].loopstart = i * 3; polys[i].totloop = 3; - loops[i * 3 + 0].v = manta_liquid_get_triangle_x_at(fds->fluid, i); - loops[i * 3 + 1].v = manta_liquid_get_triangle_y_at(fds->fluid, i); - loops[i * 3 + 2].v = manta_liquid_get_triangle_z_at(fds->fluid, i); + corner_verts[i * 3 + 0] = manta_liquid_get_triangle_x_at(fds->fluid, i); + corner_verts[i * 3 + 1] = manta_liquid_get_triangle_y_at(fds->fluid, i); + corner_verts[i * 3 + 2] = manta_liquid_get_triangle_z_at(fds->fluid, i); # ifdef DEBUG_PRINT /* Debugging: Print mesh faces. */ printf("mloops[0].v: %d, mloops[1].v: %d, mloops[2].v: %d\n", @@ -3356,7 +3356,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje float max[3]; float *co; MPoly *poly; - MLoop *ml; + int *corner_vert; int num_verts = 8; int num_faces = 6; @@ -3371,7 +3371,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje result = BKE_mesh_new_nomain(num_verts, 0, num_faces * 4, num_faces); float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan polys = result->polys_for_write(); - blender::MutableSpan loops = result->loops_for_write(); + blender::MutableSpan corner_verts = result->corner_verts_for_write(); if (num_verts) { /* Volume bounds. */ @@ -3417,58 +3417,58 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje /* Create faces. */ /* Top side. */ poly = &polys[0]; - ml = &loops[0 * 4]; + corner_vert = &corner_verts[0 * 4]; poly->loopstart = 0 * 4; poly->totloop = 4; - ml[0].v = 0; - ml[1].v = 1; - ml[2].v = 2; - ml[3].v = 3; + corner_vert[0] = 0; + corner_vert[1] = 1; + corner_vert[2] = 2; + corner_vert[3] = 3; /* Right side. */ poly = &polys[1]; - ml = &loops[1 * 4]; + corner_vert = &corner_verts[1 * 4]; poly->loopstart = 1 * 4; poly->totloop = 4; - ml[0].v = 2; - ml[1].v = 1; - ml[2].v = 5; - ml[3].v = 6; + corner_vert[0] = 2; + corner_vert[1] = 1; + corner_vert[2] = 5; + corner_vert[3] = 6; /* Bottom side. */ poly = &polys[2]; - ml = &loops[2 * 4]; + corner_vert = &corner_verts[2 * 4]; poly->loopstart = 2 * 4; poly->totloop = 4; - ml[0].v = 7; - ml[1].v = 6; - ml[2].v = 5; - ml[3].v = 4; + corner_vert[0] = 7; + corner_vert[1] = 6; + corner_vert[2] = 5; + corner_vert[3] = 4; /* Left side. */ poly = &polys[3]; - ml = &loops[3 * 4]; + corner_vert = &corner_verts[3 * 4]; poly->loopstart = 3 * 4; poly->totloop = 4; - ml[0].v = 0; - ml[1].v = 3; - ml[2].v = 7; - ml[3].v = 4; + corner_vert[0] = 0; + corner_vert[1] = 3; + corner_vert[2] = 7; + corner_vert[3] = 4; /* Front side. */ poly = &polys[4]; - ml = &loops[4 * 4]; + corner_vert = &corner_verts[4 * 4]; poly->loopstart = 4 * 4; poly->totloop = 4; - ml[0].v = 3; - ml[1].v = 2; - ml[2].v = 6; - ml[3].v = 7; + corner_vert[0] = 3; + corner_vert[1] = 2; + corner_vert[2] = 6; + corner_vert[3] = 7; /* Back side. */ poly = &polys[5]; - ml = &loops[5 * 4]; + corner_vert = &corner_verts[5 * 4]; poly->loopstart = 5 * 4; poly->totloop = 4; - ml[0].v = 1; - ml[1].v = 0; - ml[2].v = 4; - ml[3].v = 5; + corner_vert[0] = 1; + corner_vert[1] = 0; + corner_vert[2] = 4; + corner_vert[3] = 5; /* Calculate required shift to match domain's global position * it was originally simulated at (if object moves without manta step). */ diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index b5bc08039b2..b5337ec59b0 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -174,15 +174,11 @@ static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh, MutableSpan r_values) { BLI_assert(r_values.size() == mesh.totvert); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); attribute_math::DefaultMixer mixer(r_values); - - for (const int loop_index : IndexRange(mesh.totloop)) { - const T value = old_values[loop_index]; - const MLoop &loop = loops[loop_index]; - const int point_index = loop.v; - mixer.mix_in(point_index, value); + for (const int corner : IndexRange(mesh.totloop)) { + mixer.mix_in(corner_verts[corner], old_values[corner]); } mixer.finalize(); } @@ -194,17 +190,16 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh, MutableSpan r_values) { BLI_assert(r_values.size() == mesh.totvert); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); Array loose_verts(mesh.totvert, true); r_values.fill(true); - for (const int loop_index : IndexRange(mesh.totloop)) { - const MLoop &loop = loops[loop_index]; - const int point_index = loop.v; + for (const int corner : IndexRange(mesh.totloop)) { + const int point_index = corner_verts[corner]; loose_verts[point_index] = false; - if (!old_values[loop_index]) { + if (!old_values[corner]) { r_values[point_index] = false; } } @@ -242,16 +237,15 @@ static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray */ static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray &varray) { - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); - new_varray = VArray::ForFunc(mesh.totloop, - [loops, varray = varray.typed()](const int64_t loop_index) { - const int vertex_index = loops[loop_index].v; - return varray[vertex_index]; - }); + new_varray = VArray::ForFunc( + mesh.totloop, [corner_verts, varray = varray.typed()](const int64_t corner) { + return varray[corner_verts[corner]]; + }); }); return new_varray; } @@ -303,7 +297,7 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totedge); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); attribute_math::DefaultMixer mixer(r_values); @@ -315,8 +309,7 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh, const int next_i = (i + 1) % poly.totloop; const int loop_i = poly.loopstart + i; const int next_loop_i = poly.loopstart + next_i; - const MLoop &loop = loops[loop_i]; - const int edge_index = loop.e; + const int edge_index = corner_edges[loop_i]; mixer.mix_in(edge_index, old_values[loop_i]); mixer.mix_in(edge_index, old_values[next_loop_i]); } @@ -333,7 +326,7 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totedge); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); r_values.fill(true); for (const int poly_index : polys.index_range()) { @@ -343,8 +336,7 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh, const int next_i = (i + 1) % poly.totloop; const int loop_i = poly.loopstart + i; const int next_loop_i = poly.loopstart + next_i; - const MLoop &loop = loops[loop_i]; - const int edge_index = loop.e; + const int edge_index = corner_edges[loop_i]; if (!old_values[loop_i] || !old_values[next_loop_i]) { r_values[edge_index] = false; @@ -385,17 +377,15 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totvert); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); attribute_math::DefaultMixer mixer(r_values); for (const int poly_index : polys.index_range()) { const MPoly &poly = polys[poly_index]; const T value = old_values[poly_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - const int point_index = loop.v; - mixer.mix_in(point_index, value); + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + mixer.mix_in(vert, value); } } @@ -410,15 +400,15 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totvert); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); r_values.fill(false); threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) { for (const int poly_index : range) { if (old_values[poly_index]) { const MPoly &poly = polys[poly_index]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - r_values[loop.v] = true; + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + r_values[vert] = true; } } } @@ -476,16 +466,15 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totedge); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); attribute_math::DefaultMixer mixer(r_values); for (const int poly_index : polys.index_range()) { const MPoly &poly = polys[poly_index]; const T value = old_values[poly_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - mixer.mix_in(loop.e, value); + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + mixer.mix_in(edge, value); } } mixer.finalize(); @@ -499,15 +488,15 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totedge); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); r_values.fill(false); threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) { for (const int poly_index : range) { if (old_values[poly_index]) { const MPoly &poly = polys[poly_index]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - r_values[loop.e] = true; + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + r_values[edge] = true; } } } @@ -530,7 +519,7 @@ static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &v static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &varray) { const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { @@ -538,12 +527,12 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray & if constexpr (!std::is_void_v>) { if constexpr (std::is_same_v) { new_varray = VArray::ForFunc( - mesh.totpoly, [loops, polys, varray = varray.typed()](const int face_index) { + mesh.totpoly, + [corner_verts, polys, varray = varray.typed()](const int face_index) { /* A face is selected if all of its vertices were selected. */ const MPoly &poly = polys[face_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - if (!varray[loop.v]) { + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + if (!varray[vert]) { return false; } } @@ -552,14 +541,12 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray & } else { new_varray = VArray::ForFunc( - mesh.totpoly, [loops, polys, varray = varray.typed()](const int face_index) { + mesh.totpoly, [corner_verts, polys, varray = varray.typed()](const int face_index) { T return_value; attribute_math::DefaultMixer mixer({&return_value, 1}); const MPoly &poly = polys[face_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - const T value = varray[loop.v]; - mixer.mix_in(0, value); + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + mixer.mix_in(0, varray[vert]); } mixer.finalize(); return return_value; @@ -610,7 +597,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totloop); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); attribute_math::DefaultMixer mixer(r_values); @@ -620,10 +607,10 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, /* For every corner, mix the values from the adjacent edges on the face. */ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { const int loop_index_prev = mesh_topology::poly_loop_prev(poly, loop_index); - const MLoop &loop = loops[loop_index]; - const MLoop &loop_prev = loops[loop_index_prev]; - mixer.mix_in(loop_index, old_values[loop.e]); - mixer.mix_in(loop_index, old_values[loop_prev.e]); + const int edge = corner_edges[loop_index]; + const int edge_prev = corner_edges[loop_index_prev]; + mixer.mix_in(loop_index, old_values[edge]); + mixer.mix_in(loop_index, old_values[edge_prev]); } } @@ -638,7 +625,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, { BLI_assert(r_values.size() == mesh.totloop); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); r_values.fill(false); @@ -647,9 +634,9 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, const MPoly &poly = polys[poly_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { const int loop_index_prev = mesh_topology::poly_loop_prev(poly, loop_index); - const MLoop &loop = loops[loop_index]; - const MLoop &loop_prev = loops[loop_index_prev]; - if (old_values[loop.e] && old_values[loop_prev.e]) { + const int edge = corner_edges[loop_index]; + const int edge_prev = corner_edges[loop_index_prev]; + if (old_values[edge] && old_values[edge_prev]) { r_values[loop_index] = true; } } @@ -729,7 +716,7 @@ static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray & static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &varray) { const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { @@ -738,11 +725,10 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v if constexpr (std::is_same_v) { /* A face is selected if all of its edges are selected. */ new_varray = VArray::ForFunc( - polys.size(), [loops, polys, varray = varray.typed()](const int face_index) { + polys.size(), [corner_edges, polys, varray = varray.typed()](const int face_index) { const MPoly &poly = polys[face_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - if (!varray[loop.e]) { + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + if (!varray[edge]) { return false; } } @@ -751,14 +737,12 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v } else { new_varray = VArray::ForFunc( - polys.size(), [loops, polys, varray = varray.typed()](const int face_index) { + polys.size(), [corner_edges, polys, varray = varray.typed()](const int face_index) { T return_value; attribute_math::DefaultMixer mixer({&return_value, 1}); const MPoly &poly = polys[face_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - const T value = varray[loop.e]; - mixer.mix_in(0, value); + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + mixer.mix_in(0, varray[edge]); } mixer.finalize(); return return_value; @@ -1207,6 +1191,35 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() nullptr, AttributeValidator{&material_index_clamp}); + /* Note: This clamping is more of a last resort, since it's quite easy to make an + * invalid mesh that will crash Blender by arbitrarily editing this attribute. */ + static const auto int_index_clamp = mf::build::SI1_SO( + "Index Validate", + [](int value) { return std::max(value, 0); }, + mf::build::exec_presets::AllSpanOrSingle()); + static BuiltinCustomDataLayerProvider corner_vert(".corner_vert", + ATTR_DOMAIN_CORNER, + CD_PROP_INT32, + CD_PROP_INT32, + BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::NonDeletable, + corner_access, + make_array_read_attribute, + make_array_write_attribute, + nullptr, + AttributeValidator{&int_index_clamp}); + static BuiltinCustomDataLayerProvider corner_edge(".corner_edge", + ATTR_DOMAIN_CORNER, + CD_PROP_INT32, + CD_PROP_INT32, + BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::NonDeletable, + corner_access, + make_array_read_attribute, + make_array_write_attribute, + nullptr, + AttributeValidator{&int_index_clamp}); + static BuiltinCustomDataLayerProvider sharp_face("sharp_face", ATTR_DOMAIN_FACE, CD_PROP_BOOL, @@ -1247,13 +1260,19 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() static CustomDataAttributeProvider edge_custom_data(ATTR_DOMAIN_EDGE, edge_access); static CustomDataAttributeProvider face_custom_data(ATTR_DOMAIN_FACE, face_access); - return ComponentAttributeProviders( - {&position, &id, &material_index, &sharp_face, &sharp_edge, &crease}, - {&corner_custom_data, - &vertex_groups, - &point_custom_data, - &edge_custom_data, - &face_custom_data}); + return ComponentAttributeProviders({&position, + &corner_vert, + &corner_edge, + &id, + &material_index, + &sharp_face, + &sharp_edge, + &crease}, + {&corner_custom_data, + &vertex_groups, + &point_custom_data, + &edge_custom_data, + &face_custom_data}); } static AttributeAccessorFunctions get_mesh_accessor_functions() diff --git a/source/blender/blenkernel/intern/gpencil_geom_legacy.cc b/source/blender/blenkernel/intern/gpencil_geom_legacy.cc index ba0aac22385..4a2fd8ec6ce 100644 --- a/source/blender/blenkernel/intern/gpencil_geom_legacy.cc +++ b/source/blender/blenkernel/intern/gpencil_geom_legacy.cc @@ -2715,7 +2715,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain, const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); const Span positions = me_eval->vert_positions(); const Span polys = me_eval->polys(); - const Span loops = me_eval->loops(); + const Span corner_verts = me_eval->corner_verts(); int polys_len = me_eval->totpoly; char element_name[200]; @@ -2787,10 +2787,10 @@ bool BKE_gpencil_convert_mesh(Main *bmain, /* Add points to strokes. */ for (int j = 0; j < poly.totloop; j++) { - const MLoop *ml = &loops[poly.loopstart + j]; + const int vert = corner_verts[poly.loopstart + j]; bGPDspoint *pt = &gps_fill->points[j]; - copy_v3_v3(&pt->x, positions[ml->v]); + copy_v3_v3(&pt->x, positions[vert]); mul_m4_v3(matrix, &pt->x); pt->pressure = 1.0f; pt->strength = 1.0f; @@ -2798,7 +2798,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain, /* Copy vertex groups from mesh. Assuming they already exist in the same order. */ if (use_vgroups && !dverts.is_empty()) { MDeformVert *dv = &gps_fill->dvert[j]; - const MDeformVert *src_dv = &dverts[ml->v]; + const MDeformVert *src_dv = &dverts[vert]; dv->totweight = src_dv->totweight; dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight, "gp_fill_dverts_dw"); diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index ae29e681d50..60fa4cfc474 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2235,7 +2235,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, BKE_keyblock_convert_to_mesh(kb, positions, mesh->totvert); const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); + const blender::Span corner_edges = mesh->corner_edges(); const bool loop_normals_needed = r_loop_normals != nullptr; const bool vert_normals_needed = r_vert_normals != nullptr || loop_normals_needed; @@ -2261,20 +2262,20 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, blender::bke::mesh::normals_calc_polys( {reinterpret_cast(positions), mesh->totvert}, polys, - loops, + corner_verts, {reinterpret_cast(poly_normals), polys.size()}); } if (vert_normals_needed) { blender::bke::mesh::normals_calc_poly_vert( {reinterpret_cast(positions), mesh->totvert}, polys, - loops, + corner_verts, {reinterpret_cast(poly_normals), polys.size()}, {reinterpret_cast(vert_normals), mesh->totvert}); } if (loop_normals_needed) { short(*clnors)[2] = static_cast(CustomData_get_layer_for_write( - &mesh->ldata, CD_CUSTOMLOOPNORMAL, loops.size())); /* May be nullptr. */ + &mesh->ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); /* 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( @@ -2283,7 +2284,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, {reinterpret_cast(positions), mesh->totvert}, edges, polys, - loops, + corner_verts, + corner_edges, {}, {reinterpret_cast(vert_normals), mesh->totvert}, {reinterpret_cast(poly_normals), polys.size()}, @@ -2293,7 +2295,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, mesh->smoothresh, clnors, nullptr, - {reinterpret_cast(r_loop_normals), loops.size()}); + {reinterpret_cast(r_loop_normals), corner_verts.size()}); } if (free_vert_normals) { diff --git a/source/blender/blenkernel/intern/mball_tessellate.cc b/source/blender/blenkernel/intern/mball_tessellate.cc index 4be58dc1ec3..e4727845fdc 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.cc +++ b/source/blender/blenkernel/intern/mball_tessellate.cc @@ -1470,8 +1470,8 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) mesh->totpoly = int(process.curindex); MPoly *polys = static_cast( CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CONSTRUCT, mesh->totpoly)); - MLoop *mloop = static_cast( - CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CONSTRUCT, mesh->totpoly * 4)); + int *corner_verts = static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totpoly * 4, ".corner_vert")); int loop_offset = 0; for (int i = 0; i < mesh->totpoly; i++) { @@ -1481,11 +1481,11 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) polys[i].loopstart = loop_offset; polys[i].totloop = count; - mloop[loop_offset].v = uint32_t(indices[0]); - mloop[loop_offset + 1].v = uint32_t(indices[1]); - mloop[loop_offset + 2].v = uint32_t(indices[2]); + corner_verts[loop_offset] = indices[0]; + corner_verts[loop_offset + 1] = indices[1]; + corner_verts[loop_offset + 2] = indices[2]; if (count == 4) { - mloop[loop_offset + 3].v = uint32_t(indices[3]); + corner_verts[loop_offset + 3] = indices[3]; } loop_offset += count; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 2f94fe9febb..725a97ffb4a 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -256,6 +256,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address if (!BLO_write_is_undo(writer)) { /* When converting to the old mesh format, don't save redundant attributes. */ names_to_skip.add_multiple_new({"position", + ".corner_vert", + ".corner_edge", ".hide_vert", ".hide_edge", ".hide_poly", @@ -269,6 +271,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts( mesh, temp_arrays_for_legacy_format, vert_layers); + mesh->mloop = BKE_mesh_legacy_convert_corners_to_loops( + mesh, temp_arrays_for_legacy_format, loop_layers); 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); @@ -285,7 +289,6 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address /* Set deprecated mesh data pointers for forward compatibility. */ mesh->medge = const_cast(mesh->edges().data()); mesh->mpoly = const_cast(mesh->polys().data()); - mesh->mloop = const_cast(mesh->loops().data()); mesh->dvert = const_cast(mesh->deform_verts().data()); } @@ -518,14 +521,12 @@ static bool is_uv_bool_sublayer(CustomDataLayer const *l) /** Thresh is threshold for comparing vertices, UVs, vertex colors, weights, etc. */ static int customdata_compare( - CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh) + CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, const float thresh) { CustomDataLayer *l1, *l2; int layer_count1 = 0, layer_count2 = 0, j; const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | CD_MASK_MDEFORMVERT; const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic; - const Span loops_1 = m1->loops(); - const Span loops_2 = m2->loops(); /* The uv selection / pin layers are ignored in the comparisons because * the original flags they replace were ignored as well. Because of the @@ -574,6 +575,12 @@ static int customdata_compare( found_corresponding_layer = true; + if (StringRef(l1->name) == ".corner_edge") { + /* TODO(Hans): This attribute wasn't tested before loops were refactored into separate + * corner edges and corner verts attributes. Remove after updating tests. */ + continue; + } + switch (l1->type) { /* We're order-agnostic for edges here. */ case CD_MEDGE: { @@ -600,32 +607,9 @@ static int customdata_compare( int ptot = m1->totpoly; for (j = 0; j < ptot; j++, p1++, p2++) { - int k; - if (p1->totloop != p2->totloop) { return MESHCMP_POLYMISMATCH; } - - const MLoop *lp1 = &loops_1[p1->loopstart]; - const MLoop *lp2 = &loops_2[p2->loopstart]; - - for (k = 0; k < p1->totloop; k++, lp1++, lp2++) { - if (lp1->v != lp2->v) { - return MESHCMP_POLYVERTMISMATCH; - } - } - } - break; - } - case CD_MLOOP: { - MLoop *lp1 = (MLoop *)l1->data; - MLoop *lp2 = (MLoop *)l2->data; - int ltot = m1->totloop; - - for (j = 0; j < ltot; j++, lp1++, lp2++) { - if (lp1->v != lp2->v) { - return MESHCMP_LOOPMISMATCH; - } } break; } @@ -791,19 +775,19 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh) return "Number of loops don't match"; } - if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1->totvert, me1, me2, thresh))) { + if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1->totvert, me1, thresh))) { return cmpcode_to_str(c); } - if ((c = customdata_compare(&me1->edata, &me2->edata, me1->totedge, me1, me2, thresh))) { + if ((c = customdata_compare(&me1->edata, &me2->edata, me1->totedge, me1, thresh))) { return cmpcode_to_str(c); } - if ((c = customdata_compare(&me1->ldata, &me2->ldata, me1->totloop, me1, me2, thresh))) { + if ((c = customdata_compare(&me1->ldata, &me2->ldata, me1->totloop, me1, thresh))) { return cmpcode_to_str(c); } - if ((c = customdata_compare(&me1->pdata, &me2->pdata, me1->totpoly, me1, me2, thresh))) { + if ((c = customdata_compare(&me1->pdata, &me2->pdata, me1->totpoly, me1, thresh))) { return cmpcode_to_str(c); } @@ -812,7 +796,7 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh) bool BKE_mesh_attribute_required(const char *name) { - return StringRef(name) == "position"; + return ELEM(StringRef(name), "position", ".corner_vert", ".corner_edge"); } void BKE_mesh_ensure_skin_customdata(Mesh *me) @@ -970,8 +954,13 @@ static void mesh_ensure_cdlayers_primary(Mesh *mesh) if (!CustomData_get_layer(&mesh->edata, CD_MEDGE)) { CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_SET_DEFAULT, mesh->totedge); } - if (!CustomData_get_layer(&mesh->ldata, CD_MLOOP)) { - CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, mesh->totloop); + if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert")) { + CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert"); + } + if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { + CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_edge"); } if (!CustomData_get_layer(&mesh->pdata, CD_MPOLY)) { CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, mesh->totpoly); @@ -1516,10 +1505,10 @@ void BKE_mesh_auto_smooth_flag_set(Mesh *me, } } -int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, int vert) +int poly_find_loop_from_vert(const MPoly *poly, const int *poly_corner_verts, int vert) { - for (int j = 0; j < poly->totloop; j++, loopstart++) { - if (loopstart->v == vert) { + for (int j = 0; j < poly->totloop; j++) { + if (poly_corner_verts[j] == vert) { return j; } } @@ -1527,14 +1516,17 @@ int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, int vert return -1; } -int poly_get_adj_loops_from_vert(const MPoly *poly, const MLoop *mloop, int vert, int r_adj[2]) +int poly_get_adj_loops_from_vert(const MPoly *poly, + const int *corner_verts, + int vert, + int r_adj[2]) { - int corner = poly_find_loop_from_vert(poly, &mloop[poly->loopstart], vert); + int corner = poly_find_loop_from_vert(poly, &corner_verts[poly->loopstart], vert); if (corner != -1) { /* vertex was found */ - r_adj[0] = ME_POLY_LOOP_PREV(mloop, poly, corner)->v; - r_adj[1] = ME_POLY_LOOP_NEXT(mloop, poly, corner)->v; + r_adj[0] = corner_verts[ME_POLY_LOOP_PREV(poly, corner)]; + r_adj[1] = corner_verts[ME_POLY_LOOP_NEXT(poly, corner)]; } return corner; @@ -1553,18 +1545,23 @@ int BKE_mesh_edge_other_vert(const MEdge *edge, int v) } void BKE_mesh_looptri_get_real_edges(const MEdge *edges, - const MLoop *loops, + const int *corner_verts, + const int *corner_edges, const MLoopTri *tri, int r_edges[3]) { for (int i = 2, i_next = 0; i_next < 3; i = i_next++) { - const MLoop *l1 = &loops[tri->tri[i]], *l2 = &loops[tri->tri[i_next]]; - const MEdge *edge = &edges[l1->e]; + const int corner_1 = tri->tri[i]; + const int corner_2 = tri->tri[i_next]; + const int vert_1 = corner_verts[corner_1]; + const int vert_2 = corner_verts[corner_2]; + const int edge_i = corner_edges[corner_1]; + const MEdge *edge = &edges[edge_i]; - bool is_real = (l1->v == edge->v1 && l2->v == edge->v2) || - (l1->v == edge->v2 && l2->v == edge->v1); + bool is_real = (vert_1 == edge->v1 && vert_2 == edge->v2) || + (vert_1 == edge->v2 && vert_2 == edge->v1); - r_edges[i] = is_real ? l1->e : -1; + r_edges[i] = is_real ? edge_i : -1; } } @@ -1859,7 +1856,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, mesh->vert_positions(), mesh->edges(), mesh->polys(), - mesh->loops(), + mesh->corner_verts(), + mesh->corner_edges(), {}, mesh->vert_normals(), mesh->poly_normals(), diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 089cb6a5332..417666d6c75 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -304,7 +304,8 @@ static IMesh meshes_to_imesh(Span meshes, Vector verts(me->totvert); const Span vert_positions = me->vert_positions(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); + const Span corner_edges = me->corner_edges(); /* Allocate verts * Skip the matrix multiplication for each point when there is no transform for a mesh, @@ -339,20 +340,19 @@ static IMesh meshes_to_imesh(Span meshes, int flen = poly.totloop; face_vert.resize(flen); face_edge_orig.resize(flen); - const MLoop *l = &loops[poly.loopstart]; for (int i = 0; i < flen; ++i) { - int mverti = r_info->mesh_vert_offset[mi] + l->v; + const int corner_i = poly.loopstart + i; + int mverti = r_info->mesh_vert_offset[mi] + corner_verts[corner_i]; const Vert *fv = r_info->mesh_to_imesh_vert[mverti]; if (need_face_flip) { face_vert[flen - i - 1] = fv; int iedge = i < flen - 1 ? flen - i - 2 : flen - 1; - face_edge_orig[iedge] = e + l->e; + face_edge_orig[iedge] = e + corner_edges[corner_i]; } else { face_vert[i] = fv; - face_edge_orig[i] = e + l->e; + face_edge_orig[i] = e + corner_edges[corner_i]; } - ++l; } r_info->mesh_to_imesh_face[f] = arena.add_face(face_vert, f, face_edge_orig); ++f; @@ -466,7 +466,7 @@ static int fill_orig_loops(const Face *f, MutableSpan r_orig_loops) { r_orig_loops.fill(-1); - const Span orig_loops = orig_me->loops(); + const Span orig_corner_verts = orig_me->corner_verts(); int orig_mplen = orig_poly->totloop; if (f->size() != orig_mplen) { @@ -494,7 +494,7 @@ static int fill_orig_loops(const Face *f, int offset = -1; for (int i = 0; i < orig_mplen; ++i) { int loop_i = i + orig_poly->loopstart; - if (orig_loops[loop_i].v == first_orig_v_in_orig_me) { + if (orig_corner_verts[loop_i] == first_orig_v_in_orig_me) { offset = i; break; } @@ -505,7 +505,7 @@ static int fill_orig_loops(const Face *f, int num_orig_loops_found = 0; for (int mp_loop_index = 0; mp_loop_index < orig_mplen; ++mp_loop_index) { int orig_mp_loop_index = (mp_loop_index + offset) % orig_mplen; - const MLoop *l = &orig_loops[orig_poly->loopstart + orig_mp_loop_index]; + const int vert_i = orig_corner_verts[orig_poly->loopstart + orig_mp_loop_index]; int fv_orig = f->vert[mp_loop_index]->orig; if (fv_orig != NO_INDEX) { fv_orig -= orig_me_vert_offset; @@ -513,9 +513,9 @@ static int fill_orig_loops(const Face *f, fv_orig = NO_INDEX; } } - if (l->v == fv_orig) { - const MLoop *lnext = - &orig_loops[orig_poly->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)]; + if (vert_i == fv_orig) { + const int vert_next = + orig_corner_verts[orig_poly->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)]; int fvnext_orig = f->vert[(mp_loop_index + 1) % orig_mplen]->orig; if (fvnext_orig != NO_INDEX) { fvnext_orig -= orig_me_vert_offset; @@ -523,7 +523,7 @@ static int fill_orig_loops(const Face *f, fvnext_orig = NO_INDEX; } } - if (lnext->v == fvnext_orig) { + if (vert_next == fvnext_orig) { r_orig_loops[mp_loop_index] = orig_poly->loopstart + orig_mp_loop_index; ++num_orig_loops_found; } @@ -543,14 +543,14 @@ static void get_poly2d_cos(const Mesh *me, float r_axis_mat[3][3]) { const Span positions = me->vert_positions(); - const Span loops = me->loops(); - const Span poly_loops = loops.slice(poly->loopstart, poly->totloop); + const Span corner_verts = me->corner_verts(); + const Span poly_verts = corner_verts.slice(poly->loopstart, poly->totloop); /* Project coordinates to 2d in cos_2d, using normal as projection axis. */ - const float3 axis_dominant = bke::mesh::poly_normal_calc(positions, poly_loops); + const float3 axis_dominant = bke::mesh::poly_normal_calc(positions, poly_verts); axis_dominant_v3_to_m3(r_axis_mat, axis_dominant); - for (const int i : poly_loops.index_range()) { - float3 co = positions[poly_loops[i].v]; + for (const int i : poly_verts.index_range()) { + float3 co = positions[poly_verts[i]]; co = math::transform_point(trans_mat, co); *reinterpret_cast(&cos_2d[i]) = (float3x3(r_axis_mat) * co).xy(); } @@ -588,7 +588,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, } CustomData *target_cd = &dest_mesh->ldata; const Span dst_positions = dest_mesh->vert_positions(); - const Span dst_loops = dest_mesh->loops(); + const Span dst_corner_verts = dest_mesh->corner_verts(); for (int i = 0; i < poly->totloop; ++i) { int loop_index = poly->loopstart + i; int orig_loop_index = norig > 0 ? orig_loops[i] : -1; @@ -598,12 +598,13 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, * The coordinate needs to be projected into 2d, just like the interpolating polygon's * coordinates were. The `dest_mesh` coordinates are already in object 0 local space. */ float co[2]; - mul_v2_m3v3(co, axis_mat, dst_positions[dst_loops[loop_index].v]); + mul_v2_m3v3(co, axis_mat, dst_positions[dst_corner_verts[loop_index]]); interp_weights_poly_v2(weights.data(), cos_2d, orig_poly->totloop, co); } for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) { int ty = source_cd->layers[source_layer_i].type; - if (ty == CD_MLOOP) { + if (STREQ(source_cd->layers[source_layer_i].name, ".corner_vert") || + STREQ(source_cd->layers[source_layer_i].name, ".corner_edge")) { continue; } const char *name = source_cd->layers[source_layer_i].name; @@ -722,9 +723,8 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) result->attributes_for_write().lookup_or_add_for_write_only_span("material_index", ATTR_DOMAIN_FACE); int cur_loop_index = 0; - MutableSpan dst_loops = result->loops_for_write(); + MutableSpan dst_corner_verts = result->corner_verts_for_write(); MutableSpan dst_polys = result->polys_for_write(); - MLoop *l = dst_loops.data(); for (int fi : im->face_index_range()) { const Face *f = im->face(fi); const Mesh *orig_me; @@ -738,8 +738,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) for (int j : f->index_range()) { const Vert *vf = f->vert[j]; const int vfi = im->lookup_vert(vf); - l->v = vfi; - ++l; + dst_corner_verts[cur_loop_index] = vfi; ++cur_loop_index; } @@ -762,6 +761,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) /* Now that the MEdges are populated, we can copy over the required attributes and custom layers. */ + const Span dst_corner_edges = result->corner_edges(); for (int fi : im->face_index_range()) { const Face *f = im->face(fi); const MPoly &poly = dst_polys[fi]; @@ -770,7 +770,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) const Mesh *orig_me; int index_in_orig_me; mim.input_medge_for_orig_index(f->edge_orig[j], &orig_me, &index_in_orig_me); - int e_index = dst_loops[poly.loopstart + j].e; + int e_index = dst_corner_edges[poly.loopstart + j]; copy_edge_attributes(result, orig_me, e_index, index_in_orig_me); } } @@ -833,13 +833,13 @@ Mesh *direct_mesh_boolean(Span meshes, /* Store intersecting edge indices. */ if (r_intersecting_edges != nullptr) { const Span polys = result->polys(); - const Span loops = result->loops(); + const Span corner_edges = result->corner_edges(); for (int fi : m_out.face_index_range()) { const Face &face = *m_out.face(fi); const MPoly &poly = polys[fi]; for (int corner_i : face.index_range()) { if (face.is_intersect[corner_i]) { - int e_index = loops[poly.loopstart + corner_i].e; + int e_index = corner_edges[poly.loopstart + corner_i]; r_intersecting_edges->append(e_index); } } diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index 0d25de3c33c..bef3ad351ec 100644 --- a/source/blender/blenkernel/intern/mesh_calc_edges.cc +++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc @@ -98,22 +98,22 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh, uint32_t parallel_mask) { const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) { const int task_index = &edge_map - edge_maps.data(); for (const MPoly &poly : polys) { - Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - const MLoop *prev_loop = &poly_loops.last(); - for (const MLoop &next_loop : poly_loops) { + const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + int vert_prev = poly_verts.last(); + for (const int vert : poly_verts) { /* Can only be the same when the mesh data is invalid. */ - if (prev_loop->v != next_loop.v) { - OrderedEdge ordered_edge{prev_loop->v, next_loop.v}; + if (vert_prev != vert) { + OrderedEdge ordered_edge{vert_prev, vert}; /* Only add the edge when it belongs into this map. */ if (task_index == (parallel_mask & ordered_edge.hash2())) { edge_map.lookup_or_add(ordered_edge, {nullptr}); } } - prev_loop = &next_loop; + vert_prev = vert; } } }); @@ -158,17 +158,21 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh, uint32_t parallel_mask) { const Span polys = mesh->polys(); - MutableSpan loops = mesh->loops_for_write(); + const Span corner_verts = mesh->corner_verts(); + MutableSpan corner_edges = mesh->corner_edges_for_write(); threading::parallel_for(IndexRange(mesh->totpoly), 100, [&](IndexRange range) { for (const int poly_index : range) { const MPoly &poly = polys[poly_index]; - MutableSpan poly_loops = loops.slice(poly.loopstart, poly.totloop); + const IndexRange corners(poly.loopstart, poly.totloop); + + int prev_corner = corners.last(); + for (const int next_corner : corners) { + const int vert = corner_verts[next_corner]; + const int vert_prev = corner_verts[prev_corner]; - MLoop *prev_loop = &poly_loops.last(); - for (MLoop &next_loop : poly_loops) { int edge_index; - if (prev_loop->v != next_loop.v) { - OrderedEdge ordered_edge{prev_loop->v, next_loop.v}; + if (vert_prev != vert) { + OrderedEdge ordered_edge{vert_prev, vert}; /* Double lookup: First find the map that contains the edge, then lookup the edge. */ const EdgeMap &edge_map = edge_maps[parallel_mask & ordered_edge.hash2()]; edge_index = edge_map.lookup(ordered_edge).index; @@ -179,8 +183,8 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh, * #76514. */ edge_index = 0; } - prev_loop->e = edge_index; - prev_loop = &next_loop; + corner_edges[prev_corner] = edge_index; + prev_corner = next_corner; } } }); @@ -232,6 +236,10 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select } /* Create new edges. */ + if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { + CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_edge"); + } MutableSpan new_edges{ static_cast(MEM_calloc_arrayN(new_totedge, sizeof(MEdge), __func__)), new_totedge}; calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges); diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 51a15a7c25a..878edb31d8a 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -76,19 +76,18 @@ using blender::StringRefNull; static CLG_LogRef LOG = {"bke.mesh_convert"}; -static void poly_edgehash_insert(EdgeHash *ehash, const MPoly *poly, const MLoop *mloop) +static void poly_edgehash_insert(EdgeHash *ehash, const MPoly *poly, const Span corner_verts) { - const MLoop *ml, *ml_next; int i = poly->totloop; - ml_next = mloop; /* first loop */ - ml = &ml_next[i - 1]; /* last loop */ + int corner_next = poly->loopstart; /* first loop */ + int corner = corner_next + (i - 1); /* last loop */ while (i-- != 0) { - BLI_edgehash_reinsert(ehash, ml->v, ml_next->v, nullptr); + BLI_edgehash_reinsert(ehash, corner_verts[corner], corner_verts[corner_next], nullptr); - ml = ml_next; - ml_next++; + corner = corner_next; + corner_next++; } } @@ -100,13 +99,14 @@ static void make_edges_mdata_extend(Mesh &mesh) int totedge = mesh.totedge; const Span polys = mesh.polys(); - MutableSpan loops = mesh.loops_for_write(); + const Span corner_verts = mesh.corner_verts(); + MutableSpan corner_edges = mesh.corner_edges_for_write(); const int eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh.totpoly)); EdgeHash *eh = BLI_edgehash_new_ex(__func__, eh_reserve); for (const MPoly &poly : polys) { - poly_edgehash_insert(eh, &poly, &loops[poly.loopstart]); + poly_edgehash_insert(eh, &poly, corner_verts); } const int totedge_new = BLI_edgehash_len(eh); @@ -139,13 +139,14 @@ static void make_edges_mdata_extend(Mesh &mesh) for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - MLoop *l = &loops[poly.loopstart]; - MLoop *l_prev = (l + (poly.totloop - 1)); + int corner = poly.loopstart; + int corner_prev = poly.loopstart + (poly.totloop - 1); int j; - for (j = 0; j < poly.totloop; j++, l++) { + for (j = 0; j < poly.totloop; j++, corner++) { /* lookup hashed edge index */ - l_prev->e = POINTER_AS_UINT(BLI_edgehash_lookup(eh, l_prev->v, l->v)); - l_prev = l; + corner_edges[corner_prev] = POINTER_AS_UINT( + BLI_edgehash_lookup(eh, corner_verts[corner_prev], corner_verts[corner])); + corner_prev = corner; } } } @@ -206,7 +207,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_only_span( @@ -283,16 +284,16 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba a = dl->parts; const int *index = dl->index; while (a--) { - loops[dst_loop + 0].v = startvert + index[0]; - loops[dst_loop + 1].v = startvert + index[2]; - loops[dst_loop + 2].v = startvert + index[1]; + corner_verts[dst_loop + 0] = startvert + index[0]; + corner_verts[dst_loop + 1] = startvert + index[2]; + corner_verts[dst_loop + 2] = startvert + index[1]; polys[dst_poly].loopstart = dst_loop; polys[dst_poly].totloop = 3; material_indices.span[dst_poly] = dl->col; if (mloopuv) { for (int i = 0; i < 3; i++, mloopuv++) { - (*mloopuv)[0] = (loops[dst_loop + i].v - startvert) / float(dl->nr - 1); + (*mloopuv)[0] = (corner_verts[dst_loop + i] - startvert) / float(dl->nr - 1); (*mloopuv)[1] = 0.0f; } } @@ -340,10 +341,10 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } for (; b < dl->nr; b++) { - loops[dst_loop + 0].v = p1; - loops[dst_loop + 1].v = p3; - loops[dst_loop + 2].v = p4; - loops[dst_loop + 3].v = p2; + corner_verts[dst_loop + 0] = p1; + corner_verts[dst_loop + 1] = p3; + corner_verts[dst_loop + 2] = p4; + corner_verts[dst_loop + 3] = p2; polys[dst_poly].loopstart = dst_loop; polys[dst_poly].totloop = 4; material_indices.span[dst_poly] = dl->col; @@ -365,7 +366,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba for (int i = 0; i < 4; i++, mloopuv++) { /* find uv based on vertex index into grid array */ - int v = loops[dst_loop + i].v - startvert; + int v = corner_verts[dst_loop + i] - startvert; (*mloopuv)[0] = (v / dl->nr) / float(orco_sizev); (*mloopuv)[1] = (v % dl->nr) / float(orco_sizeu); @@ -470,7 +471,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed const Span positions = me->vert_positions(); const Span mesh_edges = me->edges(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_edges = me->corner_edges(); /* only to detect edge polylines */ int *edge_users; @@ -481,10 +482,9 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed edge_users = (int *)MEM_calloc_arrayN(mesh_edges.size(), sizeof(int), __func__); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - const MLoop *ml = &loops[poly.loopstart]; int j; - for (j = 0; j < poly.totloop; j++, ml++) { - edge_users[ml->e]++; + for (j = 0; j < poly.totloop; j++) { + edge_users[corner_edges[poly.loopstart + j]]++; } } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 979c3f6a064..59134f32e27 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -40,43 +40,42 @@ using blender::VArray; namespace blender::bke::mesh { -static float3 poly_center_calc_ngon(const Span vert_positions, - const Span poly_loops) +static float3 poly_center_calc_ngon(const Span vert_positions, const Span poly_verts) { - const float w = 1.0f / float(poly_loops.size()); + const float w = 1.0f / float(poly_verts.size()); float3 center(0); - for (const int i : poly_loops.index_range()) { - center += vert_positions[poly_loops[i].v] * w; + for (const int i : poly_verts.index_range()) { + center += vert_positions[poly_verts[i]] * w; } return center; } -float3 poly_center_calc(const Span vert_positions, const Span poly_loops) +float3 poly_center_calc(const Span vert_positions, const Span poly_verts) { - if (poly_loops.size() == 3) { + if (poly_verts.size() == 3) { float3 center; mid_v3_v3v3v3(center, - vert_positions[poly_loops[0].v], - vert_positions[poly_loops[1].v], - vert_positions[poly_loops[2].v]); + vert_positions[poly_verts[0]], + vert_positions[poly_verts[1]], + vert_positions[poly_verts[2]]); return center; } - if (poly_loops.size() == 4) { + if (poly_verts.size() == 4) { float3 center; mid_v3_v3v3v3v3(center, - vert_positions[poly_loops[0].v], - vert_positions[poly_loops[1].v], - vert_positions[poly_loops[2].v], - vert_positions[poly_loops[3].v]); + vert_positions[poly_verts[0]], + vert_positions[poly_verts[1]], + vert_positions[poly_verts[2]], + vert_positions[poly_verts[3]]); return center; } - return poly_center_calc_ngon(vert_positions, poly_loops); + return poly_center_calc_ngon(vert_positions, poly_verts); } } // namespace blender::bke::mesh -void BKE_mesh_calc_poly_center(const MLoop *poly_loops, +void BKE_mesh_calc_poly_center(const int *poly_verts, const int poly_size, const float (*vert_positions)[3], const int verts_num, @@ -85,51 +84,51 @@ void BKE_mesh_calc_poly_center(const MLoop *poly_loops, copy_v3_v3(r_cent, blender::bke::mesh::poly_center_calc( {reinterpret_cast(vert_positions), verts_num}, - {poly_loops, poly_size})); + {poly_verts, poly_size})); } namespace blender::bke::mesh { -float poly_area_calc(const Span vert_positions, const Span poly_loops) +float poly_area_calc(const Span vert_positions, const Span poly_verts) { - if (poly_loops.size() == 3) { - return area_tri_v3(vert_positions[poly_loops[0].v], - vert_positions[poly_loops[1].v], - vert_positions[poly_loops[2].v]); + if (poly_verts.size() == 3) { + return area_tri_v3(vert_positions[poly_verts[0]], + vert_positions[poly_verts[1]], + vert_positions[poly_verts[2]]); } - Array poly_coords(poly_loops.size()); - for (const int i : poly_loops.index_range()) { - poly_coords[i] = vert_positions[poly_loops[i].v]; + Array poly_coords(poly_verts.size()); + for (const int i : poly_verts.index_range()) { + poly_coords[i] = vert_positions[poly_verts[i]]; } - return area_poly_v3((const float(*)[3])poly_coords.data(), poly_loops.size()); + return area_poly_v3((const float(*)[3])poly_coords.data(), poly_verts.size()); } } // namespace blender::bke::mesh -float BKE_mesh_calc_poly_area(const MLoop *poly_loops, +float BKE_mesh_calc_poly_area(const int *poly_verts, const int poly_size, const float (*vert_positions)[3], const int verts_num) { return blender::bke::mesh::poly_area_calc( - {reinterpret_cast(vert_positions), verts_num}, {poly_loops, poly_size}); + {reinterpret_cast(vert_positions), verts_num}, {poly_verts, poly_size}); } float BKE_mesh_calc_area(const Mesh *me) { const Span positions = me->vert_positions(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); float total_area = 0.0f; for (const MPoly &poly : polys) { - total_area += blender::bke::mesh::poly_area_calc(positions, - loops.slice(poly.loopstart, poly.totloop)); + total_area += blender::bke::mesh::poly_area_calc( + positions, corner_verts.slice(poly.loopstart, poly.totloop)); } return total_area; } -static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MLoop *poly_loops, +static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const int *poly_verts, const int poly_size, const float (*positions)[3], float r_cent[3]) @@ -139,11 +138,11 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MLoop *poly_l zero_v3(r_cent); - v_pivot = positions[poly_loops[0].v]; - v_step1 = positions[poly_loops[1].v]; + v_pivot = positions[poly_verts[0]]; + v_step1 = positions[poly_verts[1]]; for (int i = 2; i < poly_size; i++) { - const float *v_step2 = positions[poly_loops[i].v]; + const float *v_step2 = positions[poly_verts[i]]; /* Calculate the 6x volume of the tetrahedron formed by the 3 vertices * of the triangle and the origin as the fourth vertex */ @@ -174,7 +173,7 @@ namespace blender::bke::mesh { * very low quality as the value moves away from 0.0, see: #65986. */ static float mesh_calc_poly_volume_centroid_with_reference_center(const Span positions, - const Span poly_loops, + const Span poly_verts, const float3 &reference_center, float r_cent[3]) { @@ -182,11 +181,11 @@ static float mesh_calc_poly_volume_centroid_with_reference_center(const Span positions, - const Span poly_loops, + const Span poly_verts, float r_cent[3]) { float total_area = 0.0f; float v1[3], v2[3], v3[3], tri_cent[3]; - const float3 normal = blender::bke::mesh::poly_normal_calc(positions, poly_loops); + const float3 normal = blender::bke::mesh::poly_normal_calc(positions, poly_verts); - copy_v3_v3(v1, positions[poly_loops[0].v]); - copy_v3_v3(v2, positions[poly_loops[1].v]); + copy_v3_v3(v1, positions[poly_verts[0]]); + copy_v3_v3(v2, positions[poly_verts[1]]); zero_v3(r_cent); - for (int i = 2; i < poly_loops.size(); i++) { - copy_v3_v3(v3, positions[poly_loops[i].v]); + for (int i = 2; i < poly_verts.size(); i++) { + copy_v3_v3(v3, positions[poly_verts[i]]); float tri_area = area_tri_signed_v3(v1, v2, v3, normal); total_area += tri_area; @@ -235,22 +234,21 @@ static float poly_area_centroid_calc(const Span positions, } void poly_angles_calc(const Span vert_positions, - const Span poly_loops, + const Span poly_verts, MutableSpan angles) { float nor_prev[3]; float nor_next[3]; - int i_this = poly_loops.size() - 1; + int i_this = poly_verts.size() - 1; int i_next = 0; sub_v3_v3v3( - nor_prev, vert_positions[poly_loops[i_this - 1].v], vert_positions[poly_loops[i_this].v]); + nor_prev, vert_positions[poly_verts[i_this - 1]], vert_positions[poly_verts[i_this]]); normalize_v3(nor_prev); - while (i_next < poly_loops.size()) { - sub_v3_v3v3( - nor_next, vert_positions[poly_loops[i_this].v], vert_positions[poly_loops[i_next].v]); + while (i_next < poly_verts.size()) { + sub_v3_v3v3(nor_next, vert_positions[poly_verts[i_this]], vert_positions[poly_verts[i_next]]); normalize_v3(nor_next); angles[i_this] = angle_normalized_v3v3(nor_prev, nor_next); @@ -288,12 +286,12 @@ bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3]) int tot = 0; const Span positions = me->vert_positions(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); zero_v3(r_cent); for (const MPoly &poly : polys) { int loopend = poly.loopstart + poly.totloop; for (int j = poly.loopstart; j < loopend; j++) { - add_v3_v3(r_cent, positions[loops[j].v]); + add_v3_v3(r_cent, positions[corner_verts[j]]); } tot += poly.totloop; } @@ -323,14 +321,14 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3]) float poly_cent[3]; const Span positions = me->vert_positions(); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); zero_v3(r_cent); /* calculate a weighted average of polygon centroids */ for (const int i : polys.index_range()) { poly_area = blender::bke::mesh::poly_area_centroid_calc( - positions, loops.slice(polys[i].loopstart, polys[i].totloop), poly_cent); + positions, corner_verts.slice(polys[i].loopstart, polys[i].totloop), poly_cent); madd_v3_v3fl(r_cent, poly_cent, poly_area); total_area += poly_area; @@ -355,7 +353,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) float poly_cent[3]; const Span positions = me->vert_positions(); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); /* Use an initial center to avoid numeric instability of geometry far away from the center. */ float init_cent[3]; @@ -366,7 +364,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) /* calculate a weighted average of polyhedron centroids */ for (const int i : polys.index_range()) { poly_volume = blender::bke::mesh::mesh_calc_poly_volume_centroid_with_reference_center( - positions, loops.slice(polys[i].loopstart, polys[i].totloop), init_cent, poly_cent); + positions, corner_verts.slice(polys[i].loopstart, polys[i].totloop), init_cent, poly_cent); /* poly_cent is already volume-weighted, so no need to multiply by the volume */ add_v3_v3(r_cent, poly_cent); @@ -399,7 +397,7 @@ static bool mesh_calc_center_centroid_ex(const float (*positions)[3], int /*mverts_num*/, const MLoopTri *looptri, int looptri_num, - const MLoop *mloop, + const int *corner_verts, float r_center[3]) { @@ -413,9 +411,9 @@ static bool mesh_calc_center_centroid_ex(const float (*positions)[3], const MLoopTri *lt; int i; for (i = 0, lt = looptri; i < looptri_num; i++, lt++) { - const float *v1 = positions[mloop[lt->tri[0]].v]; - const float *v2 = positions[mloop[lt->tri[1]].v]; - const float *v3 = positions[mloop[lt->tri[2]].v]; + const float *v1 = positions[corner_verts[lt->tri[0]]]; + const float *v2 = positions[corner_verts[lt->tri[1]]]; + const float *v3 = positions[corner_verts[lt->tri[2]]]; float area; area = area_tri_v3(v1, v2, v3); @@ -437,7 +435,7 @@ void BKE_mesh_calc_volume(const float (*vert_positions)[3], const int mverts_num, const MLoopTri *looptri, const int looptri_num, - const MLoop *mloop, + const int *corner_verts, float *r_volume, float r_center[3]) { @@ -458,16 +456,16 @@ void BKE_mesh_calc_volume(const float (*vert_positions)[3], } if (!mesh_calc_center_centroid_ex( - vert_positions, mverts_num, looptri, looptri_num, mloop, center)) { + vert_positions, mverts_num, looptri, looptri_num, corner_verts, center)) { return; } totvol = 0.0f; for (i = 0, lt = looptri; i < looptri_num; i++, lt++) { - const float *v1 = vert_positions[mloop[lt->tri[0]].v]; - const float *v2 = vert_positions[mloop[lt->tri[1]].v]; - const float *v3 = vert_positions[mloop[lt->tri[2]].v]; + const float *v1 = vert_positions[corner_verts[lt->tri[0]]]; + const float *v2 = vert_positions[corner_verts[lt->tri[1]]]; + const float *v3 = vert_positions[corner_verts[lt->tri[2]]]; float vol; vol = volume_tetrahedron_signed_v3(center, v1, v2, v3); @@ -538,7 +536,8 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip) } void BKE_mesh_polygon_flip_ex(const MPoly *poly, - MLoop *mloop, + int *corner_verts, + int *corner_edges, CustomData *ldata, float (*lnors)[3], MDisps *mdisp, @@ -546,7 +545,10 @@ void BKE_mesh_polygon_flip_ex(const MPoly *poly, { int loopstart = poly->loopstart; int loopend = loopstart + poly->totloop - 1; - const bool loops_in_ldata = (CustomData_get_layer(ldata, CD_MLOOP) == mloop); + const bool corner_verts_in_data = (CustomData_get_layer_named( + ldata, CD_PROP_INT32, ".corner_vert") == corner_verts); + const bool corner_edges_in_data = (CustomData_get_layer_named( + ldata, CD_PROP_INT32, ".corner_edge") == corner_edges); if (mdisp) { for (int i = loopstart; i <= loopend; i++) { @@ -559,15 +561,18 @@ void BKE_mesh_polygon_flip_ex(const MPoly *poly, /* We also have to update loops edge * (they will get their original 'other edge', that is, * the original edge of their original previous loop)... */ - uint prev_edge_index = mloop[loopstart].e; - mloop[loopstart].e = mloop[loopend].e; + int prev_edge_index = corner_edges[loopstart]; + corner_edges[loopstart] = corner_edges[loopend]; for (loopstart++; loopend > loopstart; loopstart++, loopend--) { - mloop[loopend].e = mloop[loopend - 1].e; - std::swap(mloop[loopstart].e, prev_edge_index); + corner_edges[loopend] = corner_edges[loopend - 1]; + std::swap(corner_edges[loopstart], prev_edge_index); - if (!loops_in_ldata) { - std::swap(mloop[loopstart], mloop[loopend]); + if (!corner_verts_in_data) { + std::swap(corner_verts[loopstart], corner_verts[loopend]); + } + if (!corner_edges_in_data) { + std::swap(corner_edges[loopstart], corner_edges[loopend]); } if (lnors) { swap_v3_v3(lnors[loopstart], lnors[loopend]); @@ -576,21 +581,23 @@ void BKE_mesh_polygon_flip_ex(const MPoly *poly, } /* Even if we did not swap the other 'pivot' loop, we need to set its swapped edge. */ if (loopstart == loopend) { - mloop[loopstart].e = prev_edge_index; + corner_edges[loopstart] = prev_edge_index; } } -void BKE_mesh_polygon_flip(const MPoly *poly, MLoop *mloop, CustomData *ldata, const int totloop) +void BKE_mesh_polygon_flip( + const MPoly *poly, int *corner_verts, int *corner_edges, CustomData *ldata, const int totloop) { MDisps *mdisp = (MDisps *)CustomData_get_layer_for_write(ldata, CD_MDISPS, totloop); - BKE_mesh_polygon_flip_ex(poly, mloop, ldata, nullptr, mdisp, true); + BKE_mesh_polygon_flip_ex(poly, corner_verts, corner_edges, ldata, nullptr, mdisp, true); } -void BKE_mesh_polys_flip(const MPoly *polys, MLoop *mloop, CustomData *ldata, int totpoly) +void BKE_mesh_polys_flip( + const MPoly *polys, int *corner_verts, int *corner_edges, CustomData *ldata, int totpoly) { MDisps *mdisp = (MDisps *)CustomData_get_layer_for_write(ldata, CD_MDISPS, totpoly); for (const int i : blender::IndexRange(totpoly)) { - BKE_mesh_polygon_flip_ex(&polys[i], mloop, ldata, nullptr, mdisp, true); + BKE_mesh_polygon_flip_ex(&polys[i], corner_verts, corner_edges, ldata, nullptr, mdisp, true); } } @@ -614,7 +621,7 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me) const VArraySpan hide_vert_span{hide_vert}; const Span edges = me->edges(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); /* Hide edges when either of their vertices are hidden. */ SpanAttributeWriter hide_edge = attributes.lookup_or_add_for_write_only_span( @@ -630,9 +637,9 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me) ".hide_poly", ATTR_DOMAIN_FACE); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - hide_poly.span[i] = std::any_of(poly_loops.begin(), poly_loops.end(), [&](const MLoop &loop) { - return hide_vert_span[loop.v]; + const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + hide_poly.span[i] = std::any_of(poly_verts.begin(), poly_verts.end(), [&](const int vert) { + return hide_vert_span[vert]; }); } hide_poly.finish(); @@ -653,7 +660,8 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me) } const VArraySpan hide_poly_span{hide_poly}; const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); + const Span corner_edges = me->corner_edges(); SpanAttributeWriter hide_vert = attributes.lookup_or_add_for_write_only_span( ".hide_vert", ATTR_DOMAIN_POINT); SpanAttributeWriter hide_edge = attributes.lookup_or_add_for_write_only_span( @@ -663,9 +671,9 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me) for (const int i : polys.index_range()) { if (hide_poly_span[i]) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - hide_vert.span[loop.v] = true; - hide_edge.span[loop.e] = true; + for (const int corner : IndexRange(poly.loopstart, poly.totloop)) { + hide_vert.span[corner_verts[corner]] = true; + hide_edge.span[corner_edges[corner]] = true; } } } @@ -673,9 +681,9 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me) for (const int i : polys.index_range()) { if (!hide_poly_span[i]) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - hide_vert.span[loop.v] = false; - hide_edge.span[loop.e] = false; + for (const int corner : IndexRange(poly.loopstart, poly.totloop)) { + hide_vert.span[corner_verts[corner]] = false; + hide_edge.span[corner_edges[corner]] = false; } } } @@ -713,7 +721,7 @@ void BKE_mesh_flush_select_from_polys(Mesh *me) static void mesh_flush_select_from_verts(const Span edges, const Span polys, - const Span loops, + const Span corner_verts, const VArray &hide_edge, const VArray &hide_poly, const VArray &select_vert, @@ -732,10 +740,9 @@ static void mesh_flush_select_from_verts(const Span edges, for (const int i : polys.index_range()) { if (!hide_poly[i]) { const MPoly &poly = polys[i]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - select_poly[i] = std::all_of(poly_loops.begin(), poly_loops.end(), [&](const MLoop &loop) { - return select_vert[loop.v]; - }); + const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + select_poly[i] = std::all_of( + poly_verts.begin(), poly_verts.end(), [&](const int vert) { return select_vert[vert]; }); } } } @@ -758,7 +765,7 @@ void BKE_mesh_flush_select_from_verts(Mesh *me) mesh_flush_select_from_verts( me->edges(), me->polys(), - me->loops(), + me->corner_verts(), attributes.lookup_or_default(".hide_edge", ATTR_DOMAIN_EDGE, false), attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false), select_vert, @@ -776,7 +783,7 @@ void BKE_mesh_flush_select_from_verts(Mesh *me) void BKE_mesh_calc_relative_deform(const MPoly *polys, const int totpoly, - const MLoop *mloop, + const int *corner_verts, const int totvert, const float (*vert_cos_src)[3], @@ -791,12 +798,12 @@ void BKE_mesh_calc_relative_deform(const MPoly *polys, for (const int i : blender::IndexRange(totpoly)) { const MPoly &poly = polys[i]; - const MLoop *loopstart = mloop + poly.loopstart; + const int *poly_verts = &corner_verts[poly.loopstart]; for (int j = 0; j < poly.totloop; j++) { - uint v_prev = loopstart[(poly.totloop + (j - 1)) % poly.totloop].v; - uint v_curr = loopstart[j].v; - uint v_next = loopstart[(j + 1) % poly.totloop].v; + const int v_prev = poly_verts[(poly.totloop + (j - 1)) % poly.totloop]; + const int v_curr = poly_verts[j]; + const int v_next = poly_verts[(j + 1) % poly.totloop]; float tvec[3]; diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc index b7e5fdc8104..e5180115d52 100644 --- a/source/blender/blenkernel/intern/mesh_fair.cc +++ b/source/blender/blenkernel/intern/mesh_fair.cc @@ -200,11 +200,12 @@ class MeshFairingContext : public FairingContext { MutableSpan positions = mesh->vert_positions_for_write(); edges_ = mesh->edges(); polys = mesh->polys(); - mloop_ = mesh->loops(); + corner_verts_ = mesh->corner_verts(); + corner_edges_ = mesh->corner_edges(); BKE_mesh_vert_loop_map_create(&vlmap_, &vlmap_mem_, polys.data(), - mloop_.data(), + corner_verts_.data(), mesh->totvert, mesh->totpoly, mesh->totloop); @@ -222,7 +223,8 @@ class MeshFairingContext : public FairingContext { } } - loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(polys, mloop_.size()); + loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(polys, + corner_verts_.size()); } ~MeshFairingContext() override @@ -235,16 +237,16 @@ class MeshFairingContext : public FairingContext { float r_adj_next[3], float r_adj_prev[3]) override { - const int vert = mloop_[loop].v; + const int vert = corner_verts_[loop]; const MPoly &poly = polys[loop_to_poly_map_[loop]]; - const int corner = poly_find_loop_from_vert(&poly, &mloop_[poly.loopstart], vert); - copy_v3_v3(r_adj_next, co_[ME_POLY_LOOP_NEXT(mloop_, &poly, corner)->v]); - copy_v3_v3(r_adj_prev, co_[ME_POLY_LOOP_PREV(mloop_, &poly, corner)->v]); + const int corner = poly_find_loop_from_vert(&poly, &corner_verts_[poly.loopstart], vert); + copy_v3_v3(r_adj_next, co_[corner_verts_[ME_POLY_LOOP_NEXT(&poly, corner)]]); + copy_v3_v3(r_adj_prev, co_[corner_verts_[ME_POLY_LOOP_PREV(&poly, corner)]]); } int other_vertex_index_from_loop(const int loop, const uint v) override { - const MEdge *edge = &edges_[mloop_[loop].e]; + const MEdge *edge = &edges_[corner_edges_[loop]]; if (edge->v1 == v) { return edge->v2; } @@ -253,7 +255,8 @@ class MeshFairingContext : public FairingContext { protected: Mesh *mesh_; - Span mloop_; + Span corner_verts_; + Span corner_edges_; Span polys; Span edges_; Array loop_to_poly_map_; diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index b1a47e176d3..b8dcc04940c 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -194,7 +194,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const int *v_index = static_cast( CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)); const int *f_index = static_cast( @@ -202,26 +202,24 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, if (v_index || f_index) { for (const int poly_i : polys.index_range()) { - for (const int loop_i : - blender::IndexRange(polys[poly_i].loopstart, polys[poly_i].totloop)) { - const int v_idx = v_index ? v_index[loops[loop_i].v] : loops[loop_i].v; + for (const int vert : corner_verts.slice(polys[poly_i].loopstart, polys[poly_i].totloop)) { + const int v_idx = v_index ? v_index[vert] : vert; const int f_idx = f_index ? f_index[poly_i] : poly_i; const float *no = loop_normals ? *loop_normals++ : nullptr; if (ELEM(ORIGINDEX_NONE, v_idx, f_idx)) { continue; } - func(userData, v_idx, f_idx, positions[loops[loop_i].v], no); + func(userData, v_idx, f_idx, positions[vert], no); } } } else { for (const int poly_i : polys.index_range()) { - for (const int loop_i : - blender::IndexRange(polys[poly_i].loopstart, polys[poly_i].totloop)) { - const int v_idx = loops[loop_i].v; + for (const int vert : corner_verts.slice(polys[poly_i].loopstart, polys[poly_i].totloop)) { + const int v_idx = vert; const int f_idx = poly_i; const float *no = loop_normals ? *loop_normals++ : nullptr; - func(userData, v_idx, f_idx, positions[loops[loop_i].v], no); + func(userData, v_idx, f_idx, positions[vert], no); } } } @@ -271,7 +269,7 @@ void BKE_mesh_foreach_mapped_face_center( else { const blender::Span positions = mesh->vert_positions(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const int *index = static_cast(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX)); if (index) { @@ -280,10 +278,10 @@ void BKE_mesh_foreach_mapped_face_center( if (orig == ORIGINDEX_NONE) { continue; } - const Span poly_loops = loops.slice(polys[i].loopstart, polys[i].totloop); - const float3 center = bke::mesh::poly_center_calc(positions, poly_loops); + const Span poly_verts = corner_verts.slice(polys[i].loopstart, polys[i].totloop); + const float3 center = bke::mesh::poly_center_calc(positions, poly_verts); if (flag & MESH_FOREACH_USE_NORMAL) { - const float3 normal = bke::mesh::poly_normal_calc(positions, poly_loops); + const float3 normal = bke::mesh::poly_normal_calc(positions, poly_verts); func(userData, orig, center, normal); } else { @@ -293,10 +291,10 @@ void BKE_mesh_foreach_mapped_face_center( } else { for (const int i : polys.index_range()) { - const Span poly_loops = loops.slice(polys[i].loopstart, polys[i].totloop); - const float3 center = bke::mesh::poly_center_calc(positions, poly_loops); + const Span poly_verts = corner_verts.slice(polys[i].loopstart, polys[i].totloop); + const float3 center = bke::mesh::poly_center_calc(positions, poly_verts); if (flag & MESH_FOREACH_USE_NORMAL) { - const float3 normal = bke::mesh::poly_normal_calc(positions, poly_loops); + const float3 normal = bke::mesh::poly_normal_calc(positions, poly_verts); func(userData, i, center, normal); } else { @@ -315,7 +313,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( { const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); blender::Span vert_normals; if (flag & MESH_FOREACH_USE_NORMAL) { vert_normals = mesh->vert_normals(); @@ -329,24 +327,24 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( if (orig == ORIGINDEX_NONE) { continue; } - for (const MLoop &loop : loops.slice(polys[i].loopstart, polys[i].totloop)) { - if (facedot_tags[loop.v]) { + for (const int vert : corner_verts.slice(polys[i].loopstart, polys[i].totloop)) { + if (facedot_tags[vert]) { func(userData, orig, - positions[loop.v], - (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[loop.v].x : nullptr); + positions[vert], + (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[vert].x : nullptr); } } } } else { for (const int i : polys.index_range()) { - for (const MLoop &loop : loops.slice(polys[i].loopstart, polys[i].totloop)) { - if (facedot_tags[loop.v]) { + for (const int vert : corner_verts.slice(polys[i].loopstart, polys[i].totloop)) { + if (facedot_tags[vert]) { func(userData, i, - positions[loop.v], - (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[loop.v].x : nullptr); + positions[vert], + (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[vert].x : nullptr); } } } diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 5201817c02b..10de69832a5 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -209,18 +209,18 @@ void BKE_mesh_calc_edges_legacy(Mesh *me) const Span verts(static_cast(CustomData_get_layer(&me->vdata, CD_MVERT)), me->totvert); const Span polys = me->polys(); - MutableSpan loops = me->loops_for_write(); - mesh_calc_edges_mdata(verts.data(), - (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), - loops.data(), - polys.data(), - verts.size(), - me->totface, - loops.size(), - polys.size(), - &edges, - &totedge); + mesh_calc_edges_mdata( + verts.data(), + (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), + static_cast(CustomData_get_layer_for_write(&me->ldata, CD_MLOOP, me->totloop)), + polys.data(), + verts.size(), + me->totface, + me->totloop, + polys.size(), + &edges, + &totedge); if (totedge == 0) { /* flag that mesh has edges */ @@ -705,6 +705,7 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh) &mesh->totpoly); mesh_ensure_tessellation_customdata(mesh); + BKE_mesh_legacy_convert_loops_to_corners(mesh); } /** @@ -964,7 +965,6 @@ static int mesh_tessface_calc(Mesh &mesh, const int looptri_num = poly_to_tri_count(totpoly, totloop); const MPoly *poly, *mpoly; - const MLoop *ml, *mloop; MFace *mface, *mf; MemArena *arena = nullptr; int *mface_to_poly_map; @@ -973,7 +973,7 @@ static int mesh_tessface_calc(Mesh &mesh, uint j; mpoly = (const MPoly *)CustomData_get_layer(pdata, CD_MPOLY); - mloop = (const MLoop *)CustomData_get_layer(ldata, CD_MLOOP); + const Span corner_verts = mesh.corner_verts(); const int *material_indices = static_cast( CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); const bool *sharp_faces = static_cast( @@ -1008,9 +1008,9 @@ static int mesh_tessface_calc(Mesh &mesh, l1 = mp_loopstart + i1; \ l2 = mp_loopstart + i2; \ l3 = mp_loopstart + i3; \ - mf->v1 = mloop[l1].v; \ - mf->v2 = mloop[l2].v; \ - mf->v3 = mloop[l3].v; \ + mf->v1 = corner_verts[l1]; \ + mf->v2 = corner_verts[l2]; \ + mf->v3 = corner_verts[l3]; \ mf->v4 = 0; \ lidx[0] = l1; \ lidx[1] = l2; \ @@ -1031,10 +1031,10 @@ static int mesh_tessface_calc(Mesh &mesh, l2 = mp_loopstart + 1; /* EXCEPTION */ \ l3 = mp_loopstart + 2; /* EXCEPTION */ \ l4 = mp_loopstart + 3; /* EXCEPTION */ \ - mf->v1 = mloop[l1].v; \ - mf->v2 = mloop[l2].v; \ - mf->v3 = mloop[l3].v; \ - mf->v4 = mloop[l4].v; \ + mf->v1 = corner_verts[l1]; \ + mf->v2 = corner_verts[l2]; \ + mf->v3 = corner_verts[l3]; \ + mf->v4 = corner_verts[l4]; \ lidx[0] = l1; \ lidx[1] = l2; \ lidx[2] = l3; \ @@ -1081,10 +1081,10 @@ static int mesh_tessface_calc(Mesh &mesh, zero_v3(normal); /* Calculate the normal, flipped: to get a positive 2D cross product. */ - ml = mloop + mp_loopstart; - co_prev = positions[ml[mp_totloop - 1].v]; - for (j = 0; j < mp_totloop; j++, ml++) { - co_curr = positions[ml->v]; + co_prev = positions[corner_verts[mp_loopstart + mp_totloop - 1]]; + for (j = 0; j < mp_totloop; j++) { + const int vert = corner_verts[mp_loopstart + j]; + co_curr = positions[vert]; add_newell_cross_v3_v3v3(normal, co_prev, co_curr); co_prev = co_curr; } @@ -1095,9 +1095,9 @@ static int mesh_tessface_calc(Mesh &mesh, /* Project verts to 2D. */ axis_dominant_v3_to_m3_negate(axis_mat, normal); - ml = mloop + mp_loopstart; - for (j = 0; j < mp_totloop; j++, ml++) { - mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]); + for (j = 0; j < mp_totloop; j++) { + const int vert = corner_verts[mp_loopstart + j]; + mul_v2_m3v3(projverts[j], axis_mat, positions[vert]); } BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, arena); @@ -1115,9 +1115,9 @@ static int mesh_tessface_calc(Mesh &mesh, l2 = mp_loopstart + tri[1]; l3 = mp_loopstart + tri[2]; - mf->v1 = mloop[l1].v; - mf->v2 = mloop[l2].v; - mf->v3 = mloop[l3].v; + mf->v1 = corner_verts[l1]; + mf->v2 = corner_verts[l2]; + mf->v3 = corner_verts[l3]; mf->v4 = 0; lidx[0] = l1; @@ -2138,3 +2138,61 @@ void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Face Corner Conversion + * \{ */ + +MLoop *BKE_mesh_legacy_convert_corners_to_loops( + Mesh *mesh, + blender::ResourceScope &temp_arrays_for_convert, + blender::Vector &loop_layers_to_write) +{ + using namespace blender; + const Span corner_verts = mesh->corner_verts(); + const Span corner_edges = mesh->corner_edges(); + + CustomDataLayer mloop_layer{}; + mloop_layer.type = CD_MLOOP; + MutableSpan loops = temp_arrays_for_convert.construct>(mesh->totloop); + mloop_layer.data = loops.data(); + + threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + loops[i].v = corner_verts[i]; + loops[i].e = corner_edges[i]; + } + }); + + loop_layers_to_write.append(mloop_layer); + return loops.data(); +} + +void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh) +{ + using namespace blender; + if (CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert") && + CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { + return; + } + const Span loops(static_cast(CustomData_get_layer(&mesh->ldata, CD_MLOOP)), + mesh->totloop); + MutableSpan corner_verts( + static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_vert")), + mesh->totloop); + MutableSpan corner_edges( + static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_edge")), + mesh->totloop); + threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + corner_verts[i] = loops[i].v; + corner_edges[i] = loops[i].e; + } + }); + + CustomData_free_layers(&mesh->ldata, CD_MLOOP, mesh->totloop); +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 6ee3d0981b1..f3e53757758 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -33,7 +33,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *polys, const bool *hide_poly, const bool *select_poly, - const MLoop *mloop, + const int *corner_verts, const float (*mloopuv)[2], uint totpoly, uint totvert, @@ -92,8 +92,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *polys, buf->loop_of_poly_index = ushort(i); buf->poly_index = uint(a); buf->separate = false; - buf->next = vmap->vert[mloop[poly.loopstart + i].v]; - vmap->vert[mloop[poly.loopstart + i].v] = buf; + buf->next = vmap->vert[corner_verts[poly.loopstart + i]]; + vmap->vert[corner_verts[poly.loopstart + i]] = buf; if (use_winding) { copy_v2_v2(tf_uv[i], mloopuv[poly.loopstart + i]); @@ -192,7 +192,7 @@ void BKE_mesh_uv_vert_map_free(UvVertMap *vmap) static void mesh_vert_poly_or_loop_map_create(MeshElemMap **r_map, int **r_mem, const MPoly *polys, - const MLoop *mloop, + const int *corner_verts, int totvert, int totpoly, int totloop, @@ -210,7 +210,7 @@ static void mesh_vert_poly_or_loop_map_create(MeshElemMap **r_map, const MPoly &poly = polys[i]; for (j = 0; j < poly.totloop; j++) { - map[mloop[poly.loopstart + j].v].count++; + map[corner_verts[poly.loopstart + j]].count++; } } @@ -228,7 +228,7 @@ static void mesh_vert_poly_or_loop_map_create(MeshElemMap **r_map, const MPoly &poly = polys[i]; for (j = 0; j < poly.totloop; j++) { - uint v = mloop[poly.loopstart + j].v; + const int v = corner_verts[poly.loopstart + j]; map[v].indices[map[v].count] = do_loops ? poly.loopstart + j : i; map[v].count++; @@ -242,23 +242,25 @@ static void mesh_vert_poly_or_loop_map_create(MeshElemMap **r_map, void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem, const MPoly *polys, - const MLoop *mloop, + const int *corner_verts, int totvert, int totpoly, int totloop) { - mesh_vert_poly_or_loop_map_create(r_map, r_mem, polys, mloop, totvert, totpoly, totloop, false); + mesh_vert_poly_or_loop_map_create( + r_map, r_mem, polys, corner_verts, totvert, totpoly, totloop, false); } void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, int **r_mem, const MPoly *polys, - const MLoop *mloop, + const int *corner_verts, int totvert, int totpoly, int totloop) { - mesh_vert_poly_or_loop_map_create(r_map, r_mem, polys, mloop, totvert, totpoly, totloop, true); + mesh_vert_poly_or_loop_map_create( + r_map, r_mem, polys, corner_verts, totvert, totpoly, totloop, true); } void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, @@ -266,7 +268,7 @@ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, const int totvert, const MLoopTri *mlooptri, const int totlooptri, - const MLoop *mloop, + const int *corner_verts, const int /*totloop*/) { MeshElemMap *map = MEM_cnew_array(size_t(totvert), __func__); @@ -278,7 +280,7 @@ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, /* count face users */ for (i = 0, mlt = mlooptri; i < totlooptri; mlt++, i++) { for (int j = 3; j--;) { - map[mloop[mlt->tri[j]].v].count++; + map[corner_verts[mlt->tri[j]]].count++; } } @@ -295,7 +297,7 @@ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, /* assign looptri-edge users */ for (i = 0, mlt = mlooptri; i < totlooptri; mlt++, i++) { for (int j = 3; j--;) { - MeshElemMap *map_ele = &map[mloop[mlt->tri[j]].v]; + MeshElemMap *map_ele = &map[corner_verts[mlt->tri[j]]]; map_ele->indices[map_ele->count++] = i; } } @@ -387,21 +389,17 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, const int totedge, const MPoly *polys, const int totpoly, - const MLoop *mloop, + const int *corner_edges, const int totloop) { + using namespace blender; MeshElemMap *map = MEM_cnew_array(size_t(totedge), __func__); int *indices = static_cast(MEM_mallocN(sizeof(int) * size_t(totloop) * 2, __func__)); int *index_step; /* count face users */ - for (const int64_t i : blender::IndexRange(totpoly)) { - const MPoly &poly = polys[i]; - const MLoop *ml; - int j = poly.totloop; - for (ml = &mloop[poly.loopstart]; j--; ml++) { - map[ml->e].count += 2; - } + for (const int64_t i : IndexRange(totloop)) { + map[corner_edges[i]].count += 2; } /* create offsets */ @@ -417,12 +415,10 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, /* assign loop-edge users */ for (const int64_t i : blender::IndexRange(totpoly)) { const MPoly &poly = polys[i]; - const MLoop *ml; MeshElemMap *map_ele; const int max_loop = poly.loopstart + poly.totloop; - int j = poly.loopstart; - for (ml = &mloop[j]; j < max_loop; j++, ml++) { - map_ele = &map[ml->e]; + for (int j = poly.loopstart; j < max_loop; j++) { + map_ele = &map[corner_edges[j]]; map_ele->indices[map_ele->count++] = j; map_ele->indices[map_ele->count++] = j + 1; } @@ -439,7 +435,7 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, const int totedge, const MPoly *polys, const int totpoly, - const MLoop *mloop, + const int *corner_edges, const int totloop) { MeshElemMap *map = MEM_cnew_array(size_t(totedge), __func__); @@ -447,13 +443,8 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int *index_step; /* count face users */ - for (const int64_t i : blender::IndexRange(totpoly)) { - const MPoly &poly = polys[i]; - const MLoop *ml; - int j = poly.totloop; - for (ml = &mloop[poly.loopstart]; j--; ml++) { - map[ml->e].count++; - } + for (const int64_t i : blender::IndexRange(totloop)) { + map[corner_edges[i]].count++; } /* create offsets */ @@ -469,10 +460,9 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, /* assign poly-edge users */ for (const int64_t i : blender::IndexRange(totpoly)) { const MPoly &poly = polys[i]; - const MLoop *ml; - int j = poly.totloop; - for (ml = &mloop[poly.loopstart]; j--; ml++) { - MeshElemMap *map_ele = &map[ml->e]; + for (int j = 0; j < poly.totloop; j++) { + const int edge_i = corner_edges[poly.loopstart + j]; + MeshElemMap *map_ele = &map[edge_i]; map_ele->indices[map_ele->count++] = int(i); } } @@ -576,56 +566,58 @@ Array> build_vert_to_edge_map(const Span edges, const int ver } Array> build_vert_to_poly_map(const Span polys, - const Span loops, + const Span corner_verts, int verts_num) { Array> map(verts_num); for (const int64_t i : polys.index_range()) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - map[loop.v].append(int(i)); + for (const int64_t vert_i : corner_verts.slice(poly.loopstart, poly.totloop)) { + map[int(vert_i)].append(int(i)); } } return map; } -Array> build_vert_to_loop_map(const Span loops, const int verts_num) +Array> build_vert_to_loop_map(const Span corner_verts, const int verts_num) { Array> map(verts_num); - for (const int64_t i : loops.index_range()) { - map[loops[i].v].append(int(i)); + for (const int64_t i : corner_verts.index_range()) { + map[corner_verts[i]].append(int(i)); } return map; } -Array> build_edge_to_loop_map(const Span loops, const int edges_num) +Array> build_edge_to_loop_map(const Span corner_edges, const int edges_num) { Array> map(edges_num); - for (const int64_t i : loops.index_range()) { - map[loops[i].e].append(int(i)); + for (const int64_t i : corner_edges.index_range()) { + map[corner_edges[i]].append(int(i)); } return map; } Array> build_edge_to_poly_map(const Span polys, - const Span loops, + const Span corner_edges, const int edges_num) { Array> map(edges_num); for (const int64_t i : polys.index_range()) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - map[loop.e].append(int(i)); + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + map[edge].append(int(i)); } } return map; } -Vector> build_edge_to_loop_map_resizable(const Span loops, const int edges_num) +Vector> build_edge_to_loop_map_resizable(const Span corner_edges, + const int edges_num) + { Vector> map(edges_num); - for (const int64_t i : loops.index_range()) { - map[loops[i].e].append(int(i)); + for (const int64_t i : corner_edges.index_range()) { + map[corner_edges[i]].append(int(i)); } return map; } @@ -651,7 +643,7 @@ using MeshRemap_CheckIslandBoundary = static void poly_edge_loop_islands_calc(const int totedge, const blender::Span polys, - const blender::Span loops, + const blender::Span corner_edges, MeshElemMap *edge_poly_map, const bool use_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check, @@ -699,8 +691,8 @@ static void poly_edge_loop_islands_calc(const int totedge, totedge, polys.data(), int(polys.size()), - loops.data(), - int(loops.size())); + corner_edges.data(), + int(corner_edges.size())); } poly_groups = static_cast(MEM_callocN(sizeof(int) * size_t(polys.size()), __func__)); @@ -736,7 +728,7 @@ static void poly_edge_loop_islands_calc(const int totedge, BLI_assert(poly_groups[poly] == poly_group_id); for (const int64_t loop : blender::IndexRange(polys[poly].loopstart, polys[poly].totloop)) { - const int edge = int(loops[loop].e); + const int edge = corner_edges[loop]; /* loop over poly users */ const MeshElemMap &map_ele = edge_poly_map[edge]; const int *p = map_ele.indices; @@ -842,7 +834,7 @@ static void poly_edge_loop_islands_calc(const int totedge, int *BKE_mesh_calc_smoothgroups(const int totedge, const MPoly *polys, const int totpoly, - const MLoop *mloop, + const int *corner_edges, const int totloop, const bool *sharp_edges, const bool *sharp_faces, @@ -873,7 +865,7 @@ int *BKE_mesh_calc_smoothgroups(const int totedge, poly_edge_loop_islands_calc(totedge, {polys, totpoly}, - {mloop, totloop}, + {corner_edges, totloop}, nullptr, use_bitflags, poly_is_island_boundary_smooth, @@ -1004,7 +996,8 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge, const bool *uv_seams, const MPoly *polys, const int totpoly, - const MLoop *loops, + const int *corner_verts, + const int *corner_edges, const int totloop, const float (*luvs)[2], MeshIslandStore *r_island_store) @@ -1039,11 +1032,11 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge, r_island_store, MISLAND_TYPE_LOOP, totloop, MISLAND_TYPE_POLY, MISLAND_TYPE_EDGE); BKE_mesh_edge_poly_map_create( - &edge_poly_map, &edge_poly_mem, totedge, polys, totpoly, loops, totloop); + &edge_poly_map, &edge_poly_mem, totedge, polys, totpoly, corner_edges, totloop); if (luvs) { BKE_mesh_edge_loop_map_create( - &edge_loop_map, &edge_loop_mem, totedge, polys, totpoly, loops, totloop); + &edge_loop_map, &edge_loop_mem, totedge, polys, totpoly, corner_edges, totloop); } /* TODO: I'm not sure edge seam flag is enough to define UV islands? @@ -1058,23 +1051,23 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge, const int /*edge_user_count*/, const MeshElemMap & /*edge_poly_map_elem*/) -> bool { if (luvs) { - const MeshElemMap &edge_to_loops = edge_loop_map[loops[loop_index].e]; + const MeshElemMap &edge_to_loops = edge_loop_map[corner_edges[loop_index]]; BLI_assert(edge_to_loops.count >= 2 && (edge_to_loops.count % 2) == 0); - const uint v1 = loops[edge_to_loops.indices[0]].v; - const uint v2 = loops[edge_to_loops.indices[1]].v; + const int v1 = corner_verts[edge_to_loops.indices[0]]; + const int v2 = corner_verts[edge_to_loops.indices[1]]; const float *uvco_v1 = luvs[edge_to_loops.indices[0]]; const float *uvco_v2 = luvs[edge_to_loops.indices[1]]; for (int i = 2; i < edge_to_loops.count; i += 2) { - if (loops[edge_to_loops.indices[i]].v == v1) { + if (corner_verts[edge_to_loops.indices[i]] == v1) { if (!equals_v2v2(uvco_v1, luvs[edge_to_loops.indices[i]]) || !equals_v2v2(uvco_v2, luvs[edge_to_loops.indices[i + 1]])) { return true; } } else { - BLI_assert(loops[edge_to_loops.indices[i]].v == v2); + BLI_assert(corner_verts[edge_to_loops.indices[i]] == v2); UNUSED_VARS_NDEBUG(v2); if (!equals_v2v2(uvco_v2, luvs[edge_to_loops.indices[i]]) || !equals_v2v2(uvco_v1, luvs[edge_to_loops.indices[i + 1]])) { @@ -1091,7 +1084,7 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge, poly_edge_loop_islands_calc(totedge, {polys, totpoly}, - {loops, totloop}, + {corner_edges, totloop}, edge_poly_map, false, mesh_check_island_boundary_uv, @@ -1138,13 +1131,13 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge, const MPoly &poly = polys[p_idx]; poly_indices[num_pidx++] = p_idx; for (l_idx = poly.loopstart, pl_idx = 0; pl_idx < poly.totloop; l_idx++, pl_idx++) { - const MLoop *ml = &loops[l_idx]; + const int edge_i = corner_edges[l_idx]; loop_indices[num_lidx++] = l_idx; - if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, ml->e) && - (edge_border_count[ml->e] < 2)) { - edge_border_count[ml->e]++; - if (edge_border_count[ml->e] == 2) { - edge_innercut_indices[num_einnercuts++] = int(ml->e); + if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, edge_i) && + (edge_border_count[edge_i] < 2)) { + edge_border_count[edge_i]++; + if (edge_border_count[edge_i] == 2) { + edge_innercut_indices[num_einnercuts++] = edge_i; } } } @@ -1189,13 +1182,21 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3], const bool *uv_seams, const MPoly *polys, const int totpoly, - const MLoop *loops, + const int *corner_verts, + const int *corner_edges, const int totloop, MeshIslandStore *r_island_store) { UNUSED_VARS(vert_positions, totvert, edges); - return mesh_calc_islands_loop_poly_uv( - totedge, uv_seams, polys, totpoly, loops, totloop, nullptr, r_island_store); + return mesh_calc_islands_loop_poly_uv(totedge, + uv_seams, + polys, + totpoly, + corner_verts, + corner_edges, + totloop, + nullptr, + r_island_store); } bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], @@ -1205,15 +1206,23 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], const bool *uv_seams, MPoly *polys, const int totpoly, - MLoop *loops, + const int *corner_verts, + const int *corner_edges, const int totloop, const float (*luvs)[2], MeshIslandStore *r_island_store) { UNUSED_VARS(vert_positions, totvert, edges); BLI_assert(luvs != nullptr); - return mesh_calc_islands_loop_poly_uv( - totedge, uv_seams, polys, totpoly, loops, totloop, luvs, r_island_store); + return mesh_calc_islands_loop_poly_uv(totedge, + uv_seams, + polys, + totpoly, + corner_verts, + corner_edges, + totloop, + luvs, + r_island_store); } /** \} */ diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc index b0eaa53d345..c91850c971b 100644 --- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc +++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc @@ -117,7 +117,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) BKE_mesh_vert_loop_map_create(&vert_to_loop, &vert_map_mem, me->polys().data(), - me->loops().data(), + me->corner_verts().data(), me->totvert, me->totpoly, me->totloop); diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 3d8ea9223a6..1ec200136ec 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -288,7 +288,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, blender::MutableSpan result_edges = result->edges_for_write(); blender::MutableSpan result_polys = result->polys_for_write(); - blender::MutableSpan result_loops = result->loops_for_write(); + blender::MutableSpan result_corner_verts = result->corner_verts_for_write(); + blender::MutableSpan result_corner_edges = result->corner_edges_for_write(); /* adjust mirrored edge vertex indices */ for (const int i : result_edges.index_range().drop_front(src_edges_num)) { @@ -315,18 +316,20 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, CustomData_copy_data(&mesh->ldata, &result->ldata, src_poly[j], mirror_poly.last(j - 1), 1); } - blender::MutableSpan mirror_loops = result_loops.slice(mirror_poly); - const int e = mirror_loops.first().e; + blender::MutableSpan mirror_poly_edges = result_corner_edges.slice(mirror_poly); + const int e = mirror_poly_edges.first(); for (int j = 0; j < mirror_poly.size() - 1; j++) { - mirror_loops[j].e = mirror_loops[j + 1].e; + mirror_poly_edges[j] = mirror_poly_edges[j + 1]; } - mirror_loops.last().e = e; + mirror_poly_edges.last() = e; } /* adjust mirrored loop vertex and edge indices */ - for (const int i : result_loops.index_range().drop_front(src_loops_num)) { - result_loops[i].v += src_verts_num; - result_loops[i].e += src_edges_num; + for (const int i : result_corner_verts.index_range().drop_front(src_loops_num)) { + result_corner_verts[i] += src_verts_num; + } + for (const int i : result_corner_edges.index_range().drop_front(src_loops_num)) { + result_corner_edges[i] += src_edges_num; } /* handle uvs, @@ -373,7 +376,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* handle custom split normals */ if (ob->type == OB_MESH && (((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) && CustomData_has_layer(&result->ldata, CD_CUSTOMLOOPNORMAL) && result->totpoly > 0) { - blender::Array loop_normals(result_loops.size()); + blender::Array loop_normals(result_corner_verts.size()); CustomData *ldata = &result->ldata; short(*clnors)[2] = static_cast( CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, result->totloop)); @@ -394,7 +397,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, blender::bke::mesh::normals_calc_loop(result->vert_positions(), result_edges, result_polys, - result_loops, + result_corner_verts, + result_corner_edges, {}, result->vert_normals(), result->poly_normals(), @@ -456,6 +460,5 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, if (mesh_bisect != nullptr) { BKE_id_free(nullptr, mesh_bisect); } - return result; } diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index a302091a065..84d6423a952 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -149,14 +149,14 @@ namespace blender::bke::mesh { * polygon See Graphics Gems for * computing newell normal. */ -static float3 normal_calc_ngon(const Span vert_positions, const Span poly_loops) +static float3 normal_calc_ngon(const Span vert_positions, const Span poly_verts) { float3 normal(0); /* Newell's Method */ - const float *v_prev = vert_positions[poly_loops.last().v]; - for (const int i : poly_loops.index_range()) { - const float *v_curr = vert_positions[poly_loops[i].v]; + const float *v_prev = vert_positions[poly_verts.last()]; + for (const int i : poly_verts.index_range()) { + const float *v_curr = vert_positions[poly_verts[i]]; add_newell_cross_v3_v3v3(normal, v_prev, v_curr); v_prev = v_curr; } @@ -168,23 +168,23 @@ static float3 normal_calc_ngon(const Span vert_positions, const Span vert_positions, const Span poly_loops) +float3 poly_normal_calc(const Span vert_positions, const Span poly_verts) { - if (poly_loops.size() > 4) { - return normal_calc_ngon(vert_positions, poly_loops); + if (poly_verts.size() > 4) { + return normal_calc_ngon(vert_positions, poly_verts); } - if (poly_loops.size() == 3) { - return math::normal_tri(vert_positions[poly_loops[0].v], - vert_positions[poly_loops[1].v], - vert_positions[poly_loops[2].v]); + if (poly_verts.size() == 3) { + return math::normal_tri(vert_positions[poly_verts[0]], + vert_positions[poly_verts[1]], + vert_positions[poly_verts[2]]); } - if (poly_loops.size() == 4) { + if (poly_verts.size() == 4) { float3 normal; normal_quad_v3(normal, - vert_positions[poly_loops[0].v], - vert_positions[poly_loops[1].v], - vert_positions[poly_loops[2].v], - vert_positions[poly_loops[3].v]); + vert_positions[poly_verts[0]], + vert_positions[poly_verts[1]], + vert_positions[poly_verts[2]], + vert_positions[poly_verts[3]]); return normal; } /* horrible, two sided face! */ @@ -193,7 +193,7 @@ float3 poly_normal_calc(const Span vert_positions, const Span pol } // namespace blender::bke::mesh -void BKE_mesh_calc_poly_normal(const MLoop *poly_loops, +void BKE_mesh_calc_poly_normal(const int *poly_verts, const int poly_size, const float (*vert_positions)[3], const int verts_num, @@ -202,21 +202,22 @@ void BKE_mesh_calc_poly_normal(const MLoop *poly_loops, copy_v3_v3(r_no, blender::bke::mesh::poly_normal_calc( {reinterpret_cast(vert_positions), verts_num}, - {poly_loops, poly_size})); + {poly_verts, poly_size})); } namespace blender::bke::mesh { void normals_calc_polys(const Span positions, const Span polys, - const Span loops, + const Span corner_verts, MutableSpan poly_normals) { BLI_assert(polys.size() == poly_normals.size()); threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { for (const int i : range) { const MPoly &poly = polys[i]; - poly_normals[i] = poly_normal_calc(positions, loops.slice(poly.loopstart, poly.totloop)); + poly_normals[i] = poly_normal_calc(positions, + corner_verts.slice(poly.loopstart, poly.totloop)); } }); } @@ -232,7 +233,7 @@ void normals_calc_polys(const Span positions, void normals_calc_poly_vert(const Span positions, const Span polys, - const Span loops, + const Span corner_verts, MutableSpan poly_normals, MutableSpan vert_normals) { @@ -247,7 +248,7 @@ void normals_calc_poly_vert(const Span positions, threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { for (const int poly_i : range) { const MPoly &poly = polys[poly_i]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); + const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); float3 &pnor = poly_normals[poly_i]; @@ -258,9 +259,9 @@ void normals_calc_poly_vert(const Span positions, { zero_v3(pnor); /* Newell's Method */ - const float *v_curr = positions[poly_loops[i_end].v]; + const float *v_curr = positions[poly_verts[i_end]]; for (int i_next = 0; i_next <= i_end; i_next++) { - const float *v_next = positions[poly_loops[i_next].v]; + const float *v_next = positions[poly_verts[i_next]]; add_newell_cross_v3_v3v3(pnor, v_curr, v_next); v_curr = v_next; } @@ -273,13 +274,13 @@ void normals_calc_poly_vert(const Span positions, /* Inline version of #accumulate_vertex_normals_poly_v3. */ { float edvec_prev[3], edvec_next[3], edvec_end[3]; - const float *v_curr = positions[poly_loops[i_end].v]; - sub_v3_v3v3(edvec_prev, positions[poly_loops[i_end - 1].v], v_curr); + const float *v_curr = positions[poly_verts[i_end]]; + sub_v3_v3v3(edvec_prev, positions[poly_verts[i_end - 1]], v_curr); normalize_v3(edvec_prev); copy_v3_v3(edvec_end, edvec_prev); for (int i_next = 0, i_curr = i_end; i_next <= i_end; i_curr = i_next++) { - const float *v_next = positions[poly_loops[i_next].v]; + const float *v_next = positions[poly_verts[i_next]]; /* Skip an extra normalization by reusing the first calculated edge. */ if (i_next != i_end) { @@ -294,7 +295,7 @@ void normals_calc_poly_vert(const Span positions, const float fac = saacos(-dot_v3v3(edvec_prev, edvec_next)); const float vnor_add[3] = {pnor[0] * fac, pnor[1] * fac, pnor[2] * fac}; - float *vnor = vert_normals[poly_loops[i_curr].v]; + float *vnor = vert_normals[poly_verts[i_curr]]; add_v3_v3_atomic(vnor, vnor_add); v_curr = v_next; copy_v3_v3(edvec_prev, edvec_next); @@ -344,12 +345,12 @@ blender::Span Mesh::vert_normals() const blender::threading::isolate_task([&]() { const Span positions = this->vert_positions(); const Span polys = this->polys(); - const Span loops = this->loops(); + const Span corner_verts = this->corner_verts(); this->runtime->vert_normals.reinitialize(positions.size()); this->runtime->poly_normals.reinitialize(polys.size()); blender::bke::mesh::normals_calc_poly_vert( - positions, polys, loops, this->runtime->poly_normals, this->runtime->vert_normals); + positions, polys, corner_verts, this->runtime->poly_normals, this->runtime->vert_normals); this->runtime->vert_normals_dirty = false; this->runtime->poly_normals_dirty = false; @@ -375,10 +376,11 @@ blender::Span Mesh::poly_normals() const blender::threading::isolate_task([&]() { const Span positions = this->vert_positions(); const Span polys = this->polys(); - const Span loops = this->loops(); + const Span corner_verts = this->corner_verts(); this->runtime->poly_normals.reinitialize(polys.size()); - blender::bke::mesh::normals_calc_polys(positions, polys, loops, this->runtime->poly_normals); + blender::bke::mesh::normals_calc_polys( + positions, polys, corner_verts, this->runtime->poly_normals); this->runtime->poly_normals_dirty = false; }); @@ -715,7 +717,8 @@ struct LoopSplitTaskDataCommon { /* Read-only. */ Span positions; Span edges; - Span loops; + Span corner_verts; + Span corner_edges; Span polys; Span edge_to_loops; Span loop_to_poly; @@ -731,7 +734,8 @@ struct LoopSplitTaskDataCommon { namespace blender::bke::mesh { static void mesh_edges_sharp_tag(const Span polys, - const Span loops, + const Span corner_verts, + const Span corner_edges, const Span loop_to_poly_map, const Span poly_normals, const Span sharp_faces, @@ -749,8 +753,8 @@ static void mesh_edges_sharp_tag(const Span polys, for (const int poly_i : polys.index_range()) { const MPoly &poly = polys[poly_i]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const int vert_i = loops[loop_index].v; - const int edge_i = loops[loop_index].e; + const int vert_i = corner_verts[loop_index]; + const int edge_i = corner_edges[loop_index]; int2 &e2l = edge_to_loops[edge_i]; @@ -772,7 +776,7 @@ static void mesh_edges_sharp_tag(const Span polys, * same vertex, or angle between both its polys' normals is above split_angle value. */ if (!poly_is_smooth(poly_i) || (!sharp_edges.is_empty() && sharp_edges[edge_i]) || - vert_i == loops[e2l[0]].v || is_angle_sharp) { + vert_i == corner_verts[e2l[0]] || is_angle_sharp) { /* NOTE: we are sure that loop != 0 here ;). */ e2l[1] = INDEX_INVALID; @@ -802,7 +806,8 @@ static void mesh_edges_sharp_tag(const Span polys, } void edges_sharp_from_angle_set(const Span polys, - const Span loops, + const Span corner_verts, + const Span corner_edges, const Span poly_normals, const bool *sharp_faces, const float split_angle, @@ -817,10 +822,12 @@ void edges_sharp_from_angle_set(const Span polys, Array edge_to_loops(sharp_edges.size(), int2(0)); /* Simple mapping from a loop to its polygon index. */ - const Array loop_to_poly = mesh_topology::build_loop_to_poly_map(polys, loops.size()); + const Array loop_to_poly = mesh_topology::build_loop_to_poly_map(polys, + corner_verts.size()); mesh_edges_sharp_tag(polys, - loops, + corner_verts, + corner_edges, loop_to_poly, poly_normals, Span(sharp_faces, sharp_faces ? polys.size() : 0), @@ -831,7 +838,7 @@ void edges_sharp_from_angle_set(const Span polys, sharp_edges); } -static void loop_manifold_fan_around_vert_next(const Span loops, +static void loop_manifold_fan_around_vert_next(const Span corner_verts, const Span polys, const Span loop_to_poly, const int *e2lfan_curr, @@ -841,7 +848,7 @@ static void loop_manifold_fan_around_vert_next(const Span loops, int *r_mpfan_curr_index) { const int mlfan_curr_orig = *r_mlfan_curr_index; - const uint vert_fan_orig = loops[mlfan_curr_orig].v; + const uint vert_fan_orig = corner_verts[mlfan_curr_orig]; /* WARNING: This is rather complex! * We have to find our next edge around the vertex (fan mode). @@ -856,7 +863,7 @@ static void loop_manifold_fan_around_vert_next(const Span loops, BLI_assert(*r_mlfan_curr_index >= 0); BLI_assert(*r_mpfan_curr_index >= 0); - const uint vert_fan_next = loops[*r_mlfan_curr_index].v; + const uint vert_fan_next = corner_verts[*r_mlfan_curr_index]; const MPoly &mpfan_next = polys[*r_mpfan_curr_index]; if ((vert_fan_orig == vert_fan_next && vert_fan_orig == mv_pivot_index) || !ELEM(vert_fan_orig, vert_fan_next, mv_pivot_index)) { @@ -882,7 +889,8 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS const Span positions = common_data->positions; const Span edges = common_data->edges; - const Span loops = common_data->loops; + const Span corner_verts = common_data->corner_verts; + const Span corner_edges = common_data->corner_edges; const Span poly_normals = common_data->poly_normals; MutableSpan loop_normals = common_data->loop_normals; @@ -908,10 +916,11 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS if (lnors_spacearr) { float vec_curr[3], vec_prev[3]; - const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */ - const MEdge *me_curr = &edges[loops[ml_curr_index].e]; + const uint mv_pivot_index = + corner_verts[ml_curr_index]; /* The vertex we are "fanning" around! */ + const MEdge *me_curr = &edges[corner_edges[ml_curr_index]]; const int vert_2 = me_curr->v1 == mv_pivot_index ? me_curr->v2 : me_curr->v1; - const MEdge *me_prev = &edges[loops[ml_prev_index].e]; + const MEdge *me_prev = &edges[corner_edges[ml_prev_index]]; const int vert_3 = me_prev->v1 == mv_pivot_index ? me_prev->v2 : me_prev->v1; sub_v3_v3v3(vec_curr, positions[vert_2], positions[mv_pivot_index]); @@ -941,7 +950,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, const Span positions = common_data->positions; const Span edges = common_data->edges; const Span polys = common_data->polys; - const Span loops = common_data->loops; + const Span corner_verts = common_data->corner_verts; + const Span corner_edges = common_data->corner_edges; const Span edge_to_loops = common_data->edge_to_loops; const Span loop_to_poly = common_data->loop_to_poly; const Span poly_normals = common_data->poly_normals; @@ -960,10 +970,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, * same as the vertex normal, but I do not see any easy way to detect that (would need to count * number of sharp edges per vertex, I doubt the additional memory usage would be worth it, * especially as it should not be a common case in real-life meshes anyway). */ - const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */ + const int mv_pivot_index = corner_verts[ml_curr_index]; /* The vertex we are "fanning" around! */ /* `ml_curr_index` would be mlfan_prev if we needed that one. */ - const MEdge *me_org = &edges[loops[ml_curr_index].e]; + const MEdge *me_org = &edges[corner_edges[ml_curr_index]]; float vec_curr[3], vec_prev[3], vec_org[3]; float lnor[3] = {0.0f, 0.0f, 0.0f}; @@ -1006,7 +1016,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, // printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e); while (true) { - const MEdge *me_curr = &edges[loops[mlfan_curr_index].e]; + const MEdge *me_curr = &edges[corner_edges[mlfan_curr_index]]; /* Compute edge vectors. * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing * them twice (or more) here. However, time gained is not worth memory and time lost, @@ -1020,7 +1030,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, normalize_v3(vec_curr); } - // printf("\thandling edge %d / loop %d\n", loops[mlfan_curr_index].e, mlfan_curr_index); + // printf("\thandling edge %d / loop %d\n", corner_edges[mlfan_curr_index], mlfan_curr_index); { /* Code similar to accumulate_vertex_normals_poly_v3. */ @@ -1058,7 +1068,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, } } - if (IS_EDGE_SHARP(edge_to_loops[loops[mlfan_curr_index].e]) || (me_curr == me_org)) { + if (IS_EDGE_SHARP(edge_to_loops[corner_edges[mlfan_curr_index]]) || (me_curr == me_org)) { /* Current edge is sharp and we have finished with this fan of faces around this vert, * or this vert is smooth, and we have completed a full turn around it. */ // printf("FAN: Finished!\n"); @@ -1068,10 +1078,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, copy_v3_v3(vec_prev, vec_curr); /* Find next loop of the smooth fan. */ - loop_manifold_fan_around_vert_next(loops, + loop_manifold_fan_around_vert_next(corner_verts, polys, loop_to_poly, - edge_to_loops[loops[mlfan_curr_index].e], + edge_to_loops[corner_edges[mlfan_curr_index]], mv_pivot_index, &mlfan_curr_index, &mlfan_vert_index, @@ -1159,7 +1169,6 @@ static void loop_split_worker(TaskPool *__restrict pool, void *taskdata) if (data->flag == LoopSplitTaskData::Type::BlockEnd) { break; } - loop_split_worker_do(common_data, data, edge_vectors); } @@ -1173,7 +1182,8 @@ static void loop_split_worker(TaskPool *__restrict pool, void *taskdata) * Needed because cyclic smooth fans have no obvious 'entry point', * and yet we need to walk them once, and only once. */ -static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloops, +static bool loop_split_generator_check_cyclic_smooth_fan(const Span corner_verts, + const Span corner_edges, const Span polys, const Span edge_to_loops, const Span loop_to_poly, @@ -1183,7 +1193,8 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop const int ml_prev_index, const int mp_curr_index) { - const uint mv_pivot_index = mloops[ml_curr_index].v; /* The vertex we are "fanning" around! */ + /* The vertex we are "fanning" around! */ + const uint mv_pivot_index = corner_verts[ml_curr_index]; const int *e2lfan_curr = e2l_prev; if (IS_EDGE_SHARP(e2lfan_curr)) { @@ -1206,7 +1217,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop while (true) { /* Find next loop of the smooth fan. */ - loop_manifold_fan_around_vert_next(mloops, + loop_manifold_fan_around_vert_next(corner_verts, polys, loop_to_poly, e2lfan_curr, @@ -1215,7 +1226,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop &mlfan_vert_index, &mpfan_curr_index); - e2lfan_curr = edge_to_loops[mloops[mlfan_curr_index].e]; + e2lfan_curr = edge_to_loops[corner_edges[mlfan_curr_index]]; if (IS_EDGE_SHARP(e2lfan_curr)) { /* Sharp loop/edge, so not a cyclic smooth fan. */ @@ -1241,12 +1252,13 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common { MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr; - const Span loops = common_data->loops; + const Span corner_verts = common_data->corner_verts; + const Span corner_edges = common_data->corner_edges; const Span polys = common_data->polys; const Span loop_to_poly = common_data->loop_to_poly; const Span edge_to_loops = common_data->edge_to_loops; - BitVector<> skip_loops(loops.size(), false); + BitVector<> skip_loops(corner_verts.size(), false); LoopSplitTaskData *data_buff = nullptr; int data_idx = 0; @@ -1277,9 +1289,9 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common #if 0 printf("Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)", ml_curr_index, - loops[ml_curr_index].e, - loops[ml_curr_index].v, - IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]), + corner_edges[ml_curr_index], + corner_verts[ml_curr_index], + IS_EDGE_SHARP(edge_to_loops[corner_edges[ml_curr_index]]), skip_loops[ml_curr_index]); #endif @@ -1293,17 +1305,18 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common * However, this would complicate the code, add more memory usage, and despite its logical * complexity, #loop_manifold_fan_around_vert_next() is quite cheap in term of CPU cycles, * so really think it's not worth it. */ - if (!IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]) && - (skip_loops[ml_curr_index] || - !loop_split_generator_check_cyclic_smooth_fan(loops, - polys, - edge_to_loops, - loop_to_poly, - edge_to_loops[loops[ml_prev_index].e], - skip_loops, - ml_curr_index, - ml_prev_index, - poly_index))) { + if (!IS_EDGE_SHARP(edge_to_loops[corner_edges[ml_curr_index]]) && + (skip_loops[ml_curr_index] || !loop_split_generator_check_cyclic_smooth_fan( + corner_verts, + corner_edges, + polys, + edge_to_loops, + loop_to_poly, + edge_to_loops[corner_edges[ml_prev_index]], + skip_loops, + ml_curr_index, + ml_prev_index, + poly_index))) { // printf("SKIPPING!\n"); } else { @@ -1323,8 +1336,8 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common memset(data, 0, sizeof(*data)); } - if (IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]) && - IS_EDGE_SHARP(edge_to_loops[loops[ml_prev_index].e])) { + if (IS_EDGE_SHARP(edge_to_loops[corner_edges[ml_curr_index]]) && + IS_EDGE_SHARP(edge_to_loops[corner_edges[ml_prev_index]])) { data->ml_curr_index = ml_curr_index; data->ml_prev_index = ml_prev_index; data->flag = LoopSplitTaskData::Type::Single; @@ -1376,7 +1389,8 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common void normals_calc_loop(const Span vert_positions, const Span edges, const Span polys, - const Span loops, + const Span corner_verts, + const Span corner_edges, const Span loop_to_poly_map, const Span vert_normals, const Span poly_normals, @@ -1410,7 +1424,7 @@ void normals_calc_loop(const Span vert_positions, copy_v3_v3(r_loop_normals[ml_index], poly_normals[poly_index]); } else { - copy_v3_v3(r_loop_normals[ml_index], vert_normals[loops[ml_index].v]); + copy_v3_v3(r_loop_normals[ml_index], vert_normals[corner_verts[ml_index]]); } } } @@ -1437,7 +1451,7 @@ void normals_calc_loop(const Span vert_positions, Span loop_to_poly; Array local_loop_to_poly_map; if (loop_to_poly_map.is_empty()) { - local_loop_to_poly_map = mesh_topology::build_loop_to_poly_map(polys, loops.size()); + local_loop_to_poly_map = mesh_topology::build_loop_to_poly_map(polys, corner_verts.size()); loop_to_poly = local_loop_to_poly_map; } else { @@ -1458,7 +1472,7 @@ void normals_calc_loop(const Span vert_positions, r_lnors_spacearr = &_lnors_spacearr; } if (r_lnors_spacearr) { - BKE_lnor_spacearr_init(r_lnors_spacearr, loops.size(), MLNOR_SPACEARR_LOOP_INDEX); + BKE_lnor_spacearr_init(r_lnors_spacearr, corner_verts.size(), MLNOR_SPACEARR_LOOP_INDEX); } /* Init data common to all tasks. */ @@ -1466,11 +1480,12 @@ void normals_calc_loop(const Span vert_positions, common_data.lnors_spacearr = r_lnors_spacearr; common_data.loop_normals = r_loop_normals; common_data.clnors_data = {reinterpret_cast(clnors_data), - clnors_data ? loops.size() : 0}; + clnors_data ? corner_verts.size() : 0}; common_data.positions = vert_positions; common_data.edges = edges; common_data.polys = polys; - common_data.loops = loops; + common_data.corner_verts = corner_verts; + common_data.corner_edges = corner_edges; common_data.edge_to_loops = edge_to_loops; common_data.loop_to_poly = loop_to_poly; common_data.poly_normals = poly_normals; @@ -1482,14 +1497,15 @@ void normals_calc_loop(const Span vert_positions, for (const int poly_i : range) { const MPoly &poly = polys[poly_i]; for (const int loop_i : IndexRange(poly.loopstart, poly.totloop)) { - copy_v3_v3(r_loop_normals[loop_i], vert_normals[loops[loop_i].v]); + copy_v3_v3(r_loop_normals[loop_i], vert_normals[corner_verts[loop_i]]); } } }); /* This first loop check which edges are actually smooth, and compute edge vectors. */ mesh_edges_sharp_tag(polys, - loops, + corner_verts, + corner_edges, loop_to_poly, poly_normals, Span(sharp_faces, sharp_faces ? polys.size() : 0), @@ -1499,7 +1515,7 @@ void normals_calc_loop(const Span vert_positions, edge_to_loops, {}); - if (loops.size() < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) { + if (corner_verts.size() < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) { /* Not enough loops to be worth the whole threading overhead. */ loop_split_generator(nullptr, &common_data); } @@ -1537,7 +1553,8 @@ void normals_calc_loop(const Span vert_positions, static void mesh_normals_loop_custom_set(Span positions, Span edges, Span polys, - Span loops, + Span corner_verts, + Span corner_edges, Span vert_normals, Span poly_normals, const bool *sharp_faces, @@ -1552,9 +1569,10 @@ static void mesh_normals_loop_custom_set(Span positions, * when importing custom normals, and modifier (and perhaps from some editing tools later?). So * better to keep some simplicity here, and just call #bke::mesh::normals_calc_loop() twice! */ MLoopNorSpaceArray lnors_spacearr = {nullptr}; - BitVector<> done_loops(loops.size(), false); - Array loop_normals(loops.size()); - const Array loop_to_poly = mesh_topology::build_loop_to_poly_map(polys, loops.size()); + BitVector<> done_loops(corner_verts.size(), false); + Array loop_normals(corner_verts.size()); + const Array loop_to_poly = mesh_topology::build_loop_to_poly_map(polys, + corner_verts.size()); /* In this case we always consider split nors as ON, * and do not want to use angle to define smooth fans! */ const bool use_split_normals = true; @@ -1566,7 +1584,8 @@ static void mesh_normals_loop_custom_set(Span positions, normals_calc_loop(positions, edges, polys, - loops, + corner_verts, + corner_edges, loop_to_poly, vert_normals, poly_normals, @@ -1587,7 +1606,7 @@ static void mesh_normals_loop_custom_set(Span positions, } } else { - for (const int i : loops.index_range()) { + for (const int i : corner_verts.index_range()) { if (is_zero_v3(r_custom_loop_normals[i])) { copy_v3_v3(r_custom_loop_normals[i], loop_normals[i]); } @@ -1606,7 +1625,7 @@ static void mesh_normals_loop_custom_set(Span positions, done_loops.fill(true); } else { - for (const int i : loops.index_range()) { + for (const int i : corner_verts.index_range()) { if (!lnors_spacearr.lspacearr[i]) { /* This should not happen in theory, but in some rare case (probably ugly geometry) * we can get some nullptr loopspacearr at this point. :/ @@ -1636,14 +1655,12 @@ static void mesh_normals_loop_custom_set(Span positions, } LinkNode *loop_link = lnors_spacearr.lspacearr[i]->loops; - const MLoop *prev_ml = nullptr; + int prev_corner = -1; const float *org_nor = nullptr; while (loop_link) { const int lidx = POINTER_AS_INT(loop_link->link); - const MLoop *ml = &loops[lidx]; - const int nidx = lidx; - float *nor = r_custom_loop_normals[nidx]; + float *nor = r_custom_loop_normals[lidx]; if (!org_nor) { org_nor = nor; @@ -1654,14 +1671,16 @@ static void mesh_normals_loop_custom_set(Span positions, * We know those two loops do not point to the same edge, * since we do not allow reversed winding in a same smooth fan. */ const MPoly &poly = polys[loop_to_poly[lidx]]; - const MLoop *mlp = - &loops[(lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1]; - sharp_edges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e] = true; + const int mlp = (lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1; + const int edge = corner_edges[lidx]; + const int edge_p = corner_edges[mlp]; + const int prev_edge = corner_edges[prev_corner]; + sharp_edges[prev_edge == edge_p ? prev_edge : edge] = true; org_nor = nor; } - prev_ml = ml; + prev_corner = lidx; loop_link = loop_link->next; done_loops[lidx].set(); } @@ -1673,15 +1692,15 @@ static void mesh_normals_loop_custom_set(Span positions, loop_link = lnors_spacearr.lspacearr[i]->loops; if (loop_link && org_nor) { const int lidx = POINTER_AS_INT(loop_link->link); - const MLoop *ml = &loops[lidx]; - const int nidx = lidx; - float *nor = r_custom_loop_normals[nidx]; + float *nor = r_custom_loop_normals[lidx]; if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) { const MPoly &poly = polys[loop_to_poly[lidx]]; - const MLoop *mlp = - &loops[(lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1]; - sharp_edges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e] = true; + const int mlp = (lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1; + const int edge = corner_edges[lidx]; + const int edge_p = corner_edges[mlp]; + const int prev_edge = corner_edges[prev_corner]; + sharp_edges[prev_edge == edge_p ? prev_edge : edge] = true; } } } @@ -1691,7 +1710,8 @@ static void mesh_normals_loop_custom_set(Span positions, normals_calc_loop(positions, edges, polys, - loops, + corner_verts, + corner_edges, loop_to_poly, vert_normals, poly_normals, @@ -1706,7 +1726,7 @@ static void mesh_normals_loop_custom_set(Span positions, /* And we just have to convert plain object-space custom normals to our * lnor space-encoded ones. */ - for (const int i : loops.index_range()) { + for (const int i : corner_verts.index_range()) { if (!lnors_spacearr.lspacearr[i]) { done_loops[i].reset(); if (G.debug & G_DEBUG) { @@ -1723,7 +1743,7 @@ static void mesh_normals_loop_custom_set(Span positions, LinkNode *loop_link = lnors_spacearr.lspacearr[i]->loops; if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) { BLI_assert(POINTER_AS_INT(loop_link) == i); - const int nidx = use_vertices ? int(loops[i].v) : i; + const int nidx = use_vertices ? corner_verts[i] : i; float *nor = r_custom_loop_normals[nidx]; BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]); @@ -1737,7 +1757,7 @@ static void mesh_normals_loop_custom_set(Span positions, zero_v3(avg_nor); while (loop_link) { const int lidx = POINTER_AS_INT(loop_link->link); - const int nidx = use_vertices ? int(loops[lidx].v) : lidx; + const int nidx = use_vertices ? corner_verts[lidx] : lidx; float *nor = r_custom_loop_normals[nidx]; avg_nor_count++; @@ -1765,7 +1785,8 @@ static void mesh_normals_loop_custom_set(Span positions, void normals_loop_custom_set(const Span vert_positions, const Span edges, const Span polys, - const Span loops, + const Span corner_verts, + const Span corner_edges, const Span vert_normals, const Span poly_normals, const bool *sharp_faces, @@ -1776,7 +1797,8 @@ void normals_loop_custom_set(const Span vert_positions, mesh_normals_loop_custom_set(vert_positions, edges, polys, - loops, + corner_verts, + corner_edges, vert_normals, poly_normals, sharp_faces, @@ -1789,7 +1811,8 @@ void normals_loop_custom_set(const Span vert_positions, void normals_loop_custom_set_from_verts(const Span vert_positions, const Span edges, const Span polys, - const Span loops, + const Span corner_verts, + const Span corner_edges, const Span vert_normals, const Span poly_normals, const bool *sharp_faces, @@ -1800,7 +1823,8 @@ void normals_loop_custom_set_from_verts(const Span vert_positions, mesh_normals_loop_custom_set(vert_positions, edges, polys, - loops, + corner_verts, + corner_edges, vert_normals, poly_normals, sharp_faces, @@ -1833,7 +1857,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const mesh_normals_loop_custom_set(mesh->vert_positions(), mesh->edges(), mesh->polys(), - mesh->loops(), + mesh->corner_verts(), + mesh->corner_edges(), mesh->vert_normals(), mesh->poly_normals(), sharp_faces, @@ -1859,7 +1884,7 @@ void BKE_mesh_set_custom_normals_from_verts(Mesh *mesh, float (*r_custom_vert_no } void BKE_mesh_normals_loop_to_vertex(const int numVerts, - const MLoop *mloops, + const int *corner_verts, const int numLoops, const float (*clnors)[3], float (*r_vert_clnors)[3]) @@ -1870,12 +1895,10 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts, copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f); int i; - const MLoop *ml; - for (i = 0, ml = mloops; i < numLoops; i++, ml++) { - const uint v = ml->v; - - add_v3_v3(r_vert_clnors[v], clnors[i]); - vert_loops_count[v]++; + for (i = 0; i < numLoops; i++) { + const int vert = corner_verts[i]; + add_v3_v3(r_vert_clnors[vert], clnors[i]); + vert_loops_count[vert]++; } for (i = 0; i < numVerts; i++) { diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index 6a7bade9818..d2feef7d002 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -369,7 +369,7 @@ void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index) } static int mesh_remap_interp_poly_data_get(const MPoly &poly, - const blender::Span loops, + const blender::Span corner_verts, const float (*vcos_src)[3], const float point[3], size_t *buff_size, @@ -380,7 +380,6 @@ static int mesh_remap_interp_poly_data_get(const MPoly &poly, const bool do_weights, int *r_closest_index) { - const MLoop *ml; float(*vco)[3]; float ref_dist_sq = FLT_MAX; int *index; @@ -396,10 +395,10 @@ static int mesh_remap_interp_poly_data_get(const MPoly &poly, } } - for (i = 0, ml = &loops[poly.loopstart], vco = *vcos, index = *indices; i < sources_num; - i++, ml++, vco++, index++) { - *index = use_loops ? int(poly.loopstart) + i : int(ml->v); - copy_v3_v3(*vco, vcos_src[ml->v]); + for (i = 0, vco = *vcos, index = *indices; i < sources_num; i++, vco++, index++) { + const int vert = corner_verts[poly.loopstart + i]; + *index = use_loops ? int(poly.loopstart) + i : vert; + copy_v3_v3(*vco, vcos_src[vert]); if (r_closest_index) { /* Find closest vert/loop in this case. */ const float dist_sq = len_squared_v3v3(point, *vco); @@ -564,7 +563,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, MREMAP_MODE_VERT_POLYINTERP_NEAREST, MREMAP_MODE_VERT_POLYINTERP_VNORPROJ)) { const blender::Span polys_src = me_src->polys(); - const blender::Span loops_src = me_src->loops(); + const blender::Span corner_verts_src = me_src->corner_verts(); const float(*vcos_src)[3] = BKE_mesh_vert_positions(me_src); const blender::Span vert_normals_dst = me_dst->vert_normals(); @@ -592,7 +591,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, &treedata, &rayhit, tmp_co, tmp_no, ray_radius, max_dist, &hit_dist)) { const MLoopTri *lt = &treedata.looptri[rayhit.index]; const int sources_num = mesh_remap_interp_poly_data_get(polys_src[lt->poly], - loops_src, + corner_verts_src, vcos_src, rayhit.co, &tmp_buff_size, @@ -629,7 +628,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, if (mode == MREMAP_MODE_VERT_POLY_NEAREST) { int index; mesh_remap_interp_poly_data_get(polys_src[lt->poly], - loops_src, + corner_verts_src, vcos_src, nearest.co, &tmp_buff_size, @@ -644,7 +643,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, } else if (mode == MREMAP_MODE_VERT_POLYINTERP_NEAREST) { const int sources_num = mesh_remap_interp_poly_data_get(polys_src[lt->poly], - loops_src, + corner_verts_src, vcos_src, nearest.co, &tmp_buff_size, @@ -866,7 +865,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, else if (mode == MREMAP_MODE_EDGE_POLY_NEAREST) { const blender::Span edges_src = me_src->edges(); const blender::Span polys_src = me_src->polys(); - const blender::Span loops_src = me_src->loops(); + const blender::Span corner_edges_src = me_src->corner_edges(); const float(*vcos_src)[3] = BKE_mesh_vert_positions(me_src); BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_LOOPTRI, 2); @@ -886,13 +885,13 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, &treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) { const MLoopTri *lt = &treedata.looptri[nearest.index]; const MPoly &poly_src = polys_src[lt->poly]; - const MLoop *ml_src = &loops_src[poly_src.loopstart]; + const int *corner_edge_src = &corner_edges_src[poly_src.loopstart]; int nloops = poly_src.totloop; float best_dist_sq = FLT_MAX; int best_eidx_src = -1; - for (; nloops--; ml_src++) { - const MEdge *edge_src = &edges_src[ml_src->e]; + for (; nloops--; corner_edge_src++) { + const MEdge *edge_src = &edges_src[*corner_edge_src]; const float *co1_src = vcos_src[edge_src->v1]; const float *co2_src = vcos_src[edge_src->v2]; float co_src[3]; @@ -902,7 +901,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, dist_sq = len_squared_v3v3(tmp_co, co_src); if (dist_sq < best_dist_sq) { best_dist_sq = dist_sq; - best_eidx_src = int(ml_src->e); + best_eidx_src = *corner_edge_src; } } if (best_eidx_src >= 0) { @@ -1036,7 +1035,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, BLI_AStarGraph *as_graph, const blender::Span positions, const blender::Span polys, - const blender::Span loops, + const blender::Span corner_verts, const int edge_idx, BLI_bitmap *done_edges, MeshElemMap *edge_to_poly_map, @@ -1067,8 +1066,8 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, if (poly_status[pidx_isld] == POLY_UNSET) { copy_v3_v3(poly_centers[pidx_isld], - blender::bke::mesh::poly_center_calc(positions, - loops.slice(poly.loopstart, poly.totloop))); + blender::bke::mesh::poly_center_calc( + positions, corner_verts.slice(poly.loopstart, poly.totloop))); BLI_astar_node_init(as_graph, pidx_isld, poly_centers[pidx_isld]); poly_status[pidx_isld] = POLY_CENTER_INIT; } @@ -1097,7 +1096,8 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, MeshElemMap *edge_to_poly_map, const int numedges, const blender::Span polys, - const blender::Span loops, + const blender::Span corner_verts, + const blender::Span corner_edges, const int numpolys, BLI_AStarGraph *r_as_graph) { @@ -1136,7 +1136,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, r_as_graph, positions, polys, - loops, + corner_verts, island_einnercut_map->indices[i], done_edges, edge_to_poly_map, @@ -1157,9 +1157,9 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, } for (pl_idx = 0, l_idx = poly.loopstart; pl_idx < poly.totloop; pl_idx++, l_idx++) { - const MLoop *ml = &loops[l_idx]; + const int edge = corner_edges[l_idx]; - if (BLI_BITMAP_TEST(done_edges, ml->e)) { + if (BLI_BITMAP_TEST(done_edges, edge)) { continue; } @@ -1168,8 +1168,8 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, r_as_graph, positions, polys, - loops, - int(ml->e), + corner_verts, + edge, done_edges, edge_to_poly_map, false, @@ -1229,7 +1229,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, const int numverts_dst, const MEdge *edges_dst, const int numedges_dst, - const MLoop *loops_dst, + const int *corner_verts_dst, + const int *corner_edges_dst, const int numloops_dst, const MPoly *polys_dst, const int numpolys_dst, @@ -1302,7 +1303,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, const float(*vcos_src)[3] = nullptr; const blender::Span edges_src = me_src->edges(); const blender::Span polys_src = me_src->polys(); - const blender::Span loops_src = me_src->loops(); + const blender::Span corner_verts_src = me_src->corner_verts(); + const blender::Span corner_edges_src = me_src->corner_edges(); blender::Span looptris_src; size_t buff_size_interp = MREMAP_DEFAULT_BUFSIZE; @@ -1310,8 +1312,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int *indices_interp = nullptr; float *weights_interp = nullptr; - const MLoop *ml_src; - const MLoop *ml_dst; const MPoly *mp_dst; int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src; @@ -1362,7 +1362,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, {reinterpret_cast(vert_positions_dst), numverts_dst}, {edges_dst, numedges_dst}, {polys_dst, numpolys_dst}, - {loops_dst, numloops_dst}, + {corner_verts_dst, numloops_dst}, + {corner_edges_dst, numloops_dst}, {}, mesh_dst->vert_normals(), mesh_dst->poly_normals(), @@ -1392,18 +1393,18 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, BKE_mesh_vert_loop_map_create(&vert_to_loop_map_src, &vert_to_loop_map_src_buff, polys_src.data(), - loops_src.data(), + corner_verts_src.data(), num_verts_src, int(polys_src.size()), - int(loops_src.size())); + int(corner_verts_src.size())); if (mode & MREMAP_USE_POLY) { BKE_mesh_vert_poly_map_create(&vert_to_poly_map_src, &vert_to_poly_map_src_buff, polys_src.data(), - loops_src.data(), + corner_verts_src.data(), num_verts_src, int(polys_src.size()), - int(loops_src.size())); + int(corner_verts_src.size())); } } @@ -1413,21 +1414,20 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int(edges_src.size()), polys_src.data(), int(polys_src.size()), - loops_src.data(), - int(loops_src.size())); + corner_edges_src.data(), + int(corner_edges_src.size())); if (use_from_vert) { loop_to_poly_map_src = static_cast( - MEM_mallocN(sizeof(*loop_to_poly_map_src) * size_t(loops_src.size()), __func__)); + MEM_mallocN(sizeof(*loop_to_poly_map_src) * size_t(corner_verts_src.size()), __func__)); poly_cents_src.reinitialize(polys_src.size()); for (pidx_src = 0; pidx_src < polys_src.size(); pidx_src++) { const MPoly &poly = polys_src[pidx_src]; - ml_src = &loops_src[poly.loopstart]; for (plidx_src = 0, lidx_src = poly.loopstart; plidx_src < poly.totloop; plidx_src++, lidx_src++) { loop_to_poly_map_src[lidx_src] = pidx_src; } poly_cents_src[pidx_src] = blender::bke::mesh::poly_center_calc( - positions_src, loops_src.slice(poly.loopstart, poly.totloop)); + positions_src, corner_verts_src.slice(poly.loopstart, poly.totloop)); } } @@ -1449,8 +1449,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, uv_seams, polys_src.data(), int(polys_src.size()), - loops_src.data(), - int(loops_src.size()), + corner_verts_src.data(), + corner_edges_src.data(), + int(corner_verts_src.size()), &island_store); num_trees = use_islands ? island_store.islands_num : 1; @@ -1487,7 +1488,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, edge_to_poly_map_src, int(edges_src.size()), polys_src, - loops_src, + corner_verts_src, + corner_edges_src, int(polys_src.size()), &as_graphdata[tindex]); } @@ -1505,7 +1507,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, for (int i = 0; i < isld->count; i++) { const MPoly &poly = polys_src[isld->indices[i]]; for (lidx_src = poly.loopstart; lidx_src < poly.loopstart + poly.totloop; lidx_src++) { - const uint vidx_src = loops_src[lidx_src].v; + const int vidx_src = corner_verts_src[lidx_src]; if (!verts_active[vidx_src]) { verts_active[vidx_src].set(); num_verts_active++; @@ -1544,7 +1546,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } bvhtree_from_mesh_looptri_ex(&treedata[tindex], reinterpret_cast(positions_src.data()), - loops_src.data(), + corner_verts_src.data(), looptris_src.data(), int(looptris_src.size()), looptri_active, @@ -1594,12 +1596,12 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, for (tindex = 0; tindex < num_trees; tindex++) { BVHTreeFromMesh *tdata = &treedata[tindex]; - ml_dst = &loops_dst[mp_dst->loopstart]; - for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++, ml_dst++) { + for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) { + const int vert_dst = corner_verts_dst[mp_dst->loopstart + plidx_dst]; if (use_from_vert) { MeshElemMap *vert_to_refelem_map_src = nullptr; - copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); + copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]); nearest.index = -1; /* Convert the vertex to tree coordinates, if needed. */ @@ -1657,14 +1659,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, float *pcent_src; float sqdist; - const MPoly &poly = polys_src[pidx_src]; - ml_src = &loops_src[poly.loopstart]; - if (!pcent_dst_valid) { pcent_dst = blender::bke::mesh::poly_center_calc( {reinterpret_cast(vert_positions_dst), numverts_dst}, - {&loops_dst[mp_dst->loopstart], mp_dst->totloop}); + {&corner_verts_dst[mp_dst->loopstart], mp_dst->totloop}); pcent_dst_valid = true; } pcent_src = poly_cents_src[pidx_src]; @@ -1686,9 +1685,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, /* Our best_index_src is a poly one for now! * Have to find its loop matching our closest vertex. */ const MPoly &poly = polys_src[best_index_src]; - ml_src = &loops_src[poly.loopstart]; - for (plidx_src = 0; plidx_src < poly.totloop; plidx_src++, ml_src++) { - if (int(ml_src->v) == nearest.index) { + for (plidx_src = 0; plidx_src < poly.totloop; plidx_src++) { + const int vert_src = corner_verts_src[poly.loopstart + plidx_src]; + if (vert_src == nearest.index) { best_index_src = plidx_src + poly.loopstart; break; } @@ -1710,7 +1709,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1; float w = 1.0f; - copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); + copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]); copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + mp_dst->loopstart]); /* We do our transform here, since we may do several raycast/nearest queries. */ @@ -1738,7 +1737,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, * is null, it means none of its loop mapped to this source island, * hence we can skip it later. */ - copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); + copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]); nearest.index = -1; /* Convert the vertex to tree coordinates, if needed. */ @@ -1764,7 +1763,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } } else { /* Nearest poly either to use all its loops/verts or just closest one. */ - copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); + copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]); nearest.index = -1; /* Convert the vertex to tree coordinates, if needed. */ @@ -1893,8 +1892,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int j; float best_dist_sq = FLT_MAX; - ml_dst = &loops_dst[lidx_dst]; - copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); + copy_v3_v3(tmp_co, vert_positions_dst[corner_verts_dst[lidx_dst]]); /* We do our transform here, * since we may do several raycast/nearest queries. */ @@ -1905,9 +1903,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, pidx_src = (use_islands ? best_island->indices[last_valid_pidx_isld_src] : last_valid_pidx_isld_src); const MPoly &poly = polys_src[pidx_src]; - ml_src = &loops_src[poly.loopstart]; - for (j = 0; j < poly.totloop; j++, ml_src++) { - const float dist_sq = len_squared_v3v3(positions_src[ml_src->v], tmp_co); + for (j = 0; j < poly.totloop; j++) { + const int vert_src = corner_verts_src[poly.loopstart + j]; + const float dist_sq = len_squared_v3v3(positions_src[vert_src], tmp_co); if (dist_sq < best_dist_sq) { best_dist_sq = dist_sq; lidx_src = poly.loopstart + j; @@ -1986,8 +1984,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, float best_dist_sq = FLT_MAX; int j; - ml_dst = &loops_dst[lidx_dst]; - copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); + const int vert_dst = corner_verts_dst[lidx_dst]; + copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]); /* We do our transform here, * since we may do several raycast/nearest queries. */ @@ -2016,9 +2014,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, closest_on_tri_to_point_v3(h, tmp_co, - vcos_src[loops_src[lt->tri[0]].v], - vcos_src[loops_src[lt->tri[1]].v], - vcos_src[loops_src[lt->tri[2]].v]); + vcos_src[corner_verts_src[lt->tri[0]]], + vcos_src[corner_verts_src[lt->tri[1]]], + vcos_src[corner_verts_src[lt->tri[2]]]); dist_sq = len_squared_v3v3(tmp_co, h); if (dist_sq < best_dist_sq) { copy_v3_v3(hit_co, h); @@ -2031,7 +2029,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, if (mode == MREMAP_MODE_LOOP_POLY_NEAREST) { mesh_remap_interp_poly_data_get(poly, - loops_src, + corner_verts_src, vcos_src, hit_co, &buff_size_interp, @@ -2052,7 +2050,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } else { const int sources_num = mesh_remap_interp_poly_data_get(poly, - loops_src, + corner_verts_src, vcos_src, hit_co, &buff_size_interp, @@ -2149,7 +2147,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, const Mesh *mesh_dst, const float (*vert_positions_dst)[3], const int numverts_dst, - const MLoop *loops_dst, + const int *corner_verts_dst, const MPoly *polys_dst, const int numpolys_dst, Mesh *me_src, @@ -2190,7 +2188,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, const MPoly &poly = polys_dst[i]; tmp_co = blender::bke::mesh::poly_center_calc( {reinterpret_cast(vert_positions_dst), numverts_dst}, - {&loops_dst[poly.loopstart], poly.totloop}); + {&corner_verts_dst[poly.loopstart], poly.totloop}); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -2215,7 +2213,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, tmp_co = blender::bke::mesh::poly_center_calc( {reinterpret_cast(vert_positions_dst), numverts_dst}, - {&loops_dst[poly.loopstart], poly.totloop}); + {&corner_verts_dst[poly.loopstart], poly.totloop}); copy_v3_v3(tmp_no, poly_normals_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ @@ -2280,7 +2278,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, pcent_dst = blender::bke::mesh::poly_center_calc( {reinterpret_cast(vert_positions_dst), numverts_dst}, - {&loops_dst[poly.loopstart], poly.totloop}); + {&corner_verts_dst[poly.loopstart], poly.totloop}); copy_v3_v3(tmp_no, poly_normals_dst[i]); @@ -2310,8 +2308,8 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, INIT_MINMAX2(poly_dst_2d_min, poly_dst_2d_max); for (j = 0; j < poly.totloop; j++) { - const MLoop *ml = &loops_dst[j + poly.loopstart]; - copy_v3_v3(tmp_co, vert_positions_dst[ml->v]); + const int vert = corner_verts_dst[poly.loopstart + j]; + copy_v3_v3(tmp_co, vert_positions_dst[vert]); if (space_transform) { BLI_space_transform_apply(space_transform, tmp_co); } diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index e7af9b326ed..1f661f69f12 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -64,13 +64,13 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, void *update_cb_data) { const Span input_positions = input_mesh->vert_positions(); - const Span input_loops = input_mesh->loops(); + const Span input_corner_verts = input_mesh->corner_verts(); const Span looptris = input_mesh->looptris(); /* Gather the required data for export to the internal quadriflow mesh format. */ Array verttri(looptris.size()); BKE_mesh_runtime_verttri_from_looptri( - verttri.data(), input_loops.data(), looptris.data(), looptris.size()); + verttri.data(), input_corner_verts.data(), looptris.data(), looptris.size()); const int totfaces = looptris.size(); const int totverts = input_mesh->totvert; @@ -120,7 +120,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, qrd.out_totfaces * 4, qrd.out_totfaces); BKE_mesh_copy_parameters(mesh, input_mesh); MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); mesh->vert_positions_for_write().copy_from( Span(reinterpret_cast(qrd.out_verts), qrd.out_totverts)); @@ -130,10 +130,10 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, const int loopstart = i * 4; poly.loopstart = loopstart; poly.totloop = 4; - loops[loopstart].v = qrd.out_faces[loopstart]; - loops[loopstart + 1].v = qrd.out_faces[loopstart + 1]; - loops[loopstart + 2].v = qrd.out_faces[loopstart + 2]; - loops[loopstart + 3].v = qrd.out_faces[loopstart + 3]; + corner_verts[loopstart] = qrd.out_faces[loopstart]; + corner_verts[loopstart + 1] = qrd.out_faces[loopstart + 1]; + corner_verts[loopstart + 2] = qrd.out_faces[loopstart + 2]; + corner_verts[loopstart + 3] = qrd.out_faces[loopstart + 3]; } BKE_mesh_calc_edges(mesh, false, false); @@ -184,7 +184,7 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, const float voxel_size) { const Span positions = mesh->vert_positions(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); const Span looptris = mesh->looptris(); std::vector points(mesh->totvert); @@ -197,8 +197,9 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, for (const int i : IndexRange(looptris.size())) { const MLoopTri &loop_tri = looptris[i]; - triangles[i] = openvdb::Vec3I( - loops[loop_tri.tri[0]].v, loops[loop_tri.tri[1]].v, loops[loop_tri.tri[2]].v); + triangles[i] = openvdb::Vec3I(corner_verts[loop_tri.tri[0]], + corner_verts[loop_tri.tri[1]], + corner_verts[loop_tri.tri[2]]); } openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform( @@ -224,7 +225,7 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set vertices.size(), 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size()); MutableSpan vert_positions = mesh->vert_positions_for_write(); MutableSpan mesh_polys = mesh->polys_for_write(); - MutableSpan mesh_loops = mesh->loops_for_write(); + MutableSpan mesh_corner_verts = mesh->corner_verts_for_write(); for (const int i : vert_positions.index_range()) { vert_positions[i] = float3(vertices[i].x(), vertices[i].y(), vertices[i].z()); @@ -235,10 +236,10 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set const int loopstart = i * 4; poly.loopstart = loopstart; poly.totloop = 4; - mesh_loops[loopstart].v = quads[i][0]; - mesh_loops[loopstart + 1].v = quads[i][3]; - mesh_loops[loopstart + 2].v = quads[i][2]; - mesh_loops[loopstart + 3].v = quads[i][1]; + mesh_corner_verts[loopstart] = quads[i][0]; + mesh_corner_verts[loopstart + 1] = quads[i][3]; + mesh_corner_verts[loopstart + 2] = quads[i][2]; + mesh_corner_verts[loopstart + 3] = quads[i][1]; } const int triangle_loop_start = quads.size() * 4; @@ -247,9 +248,9 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set const int loopstart = triangle_loop_start + i * 3; poly.loopstart = loopstart; poly.totloop = 3; - mesh_loops[loopstart].v = tris[i][2]; - mesh_loops[loopstart + 1].v = tris[i][1]; - mesh_loops[loopstart + 2].v = tris[i][0]; + mesh_corner_verts[loopstart] = tris[i][2]; + mesh_corner_verts[loopstart + 1] = tris[i][1]; + mesh_corner_verts[loopstart + 2] = tris[i][0]; } BKE_mesh_calc_edges(mesh, false, false); @@ -316,7 +317,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source) MutableAttributeAccessor dst_attributes = target->attributes_for_write(); const Span target_positions = target->vert_positions(); const Span target_polys = target->polys(); - const Span target_loops = target->loops(); + const Span target_corner_verts = target->corner_verts(); const VArray src_face_sets = src_attributes.lookup(".sculpt_face_set", ATTR_DOMAIN_FACE); @@ -343,7 +344,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source) nearest.dist_sq = FLT_MAX; const MPoly &poly = target_polys[i]; const float3 from_co = mesh::poly_center_calc( - target_positions, target_loops.slice(poly.loopstart, poly.totloop)); + target_positions, target_corner_verts.slice(poly.loopstart, poly.totloop)); BLI_bvhtree_find_nearest( bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree); if (nearest.index != -1) { @@ -416,7 +417,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) BKE_mesh_vert_loop_map_create(&source_lmap, &source_lmap_mem, source->polys().data(), - source->loops().data(), + source->corner_verts().data(), source->totvert, source->totpoly, source->totloop); @@ -424,7 +425,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) BKE_mesh_vert_loop_map_create(&target_lmap, &target_lmap_mem, target->polys().data(), - target->loops().data(), + target->corner_verts().data(), target->totvert, target->totpoly, target->totloop); diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 83f3de9c8fe..662b6d05b71 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -117,9 +117,9 @@ const blender::bke::LooseEdgeCache &Mesh::loose_edges() const loose_edges.resize(this->totedge, true); int count = this->totedge; - for (const MLoop &loop : this->loops()) { - if (loose_edges[loop.e]) { - loose_edges[loop.e].reset(); + for (const int edge : this->corner_edges()) { + if (loose_edges[edge]) { + loose_edges[edge].reset(); count--; } } @@ -146,16 +146,16 @@ blender::Span Mesh::looptris() const this->runtime->looptris_cache.ensure([&](blender::Array &r_data) { const Span positions = this->vert_positions(); const Span polys = this->polys(); - const Span loops = this->loops(); + const Span corner_verts = this->corner_verts(); - r_data.reinitialize(poly_to_tri_count(polys.size(), loops.size())); + r_data.reinitialize(poly_to_tri_count(polys.size(), corner_verts.size())); if (BKE_mesh_poly_normals_are_dirty(this)) { - blender::bke::mesh::looptris_calc(positions, polys, loops, r_data); + blender::bke::mesh::looptris_calc(positions, polys, corner_verts, r_data); } else { blender::bke::mesh::looptris_calc_with_normals( - positions, polys, loops, this->poly_normals(), r_data); + positions, polys, corner_verts, this->poly_normals(), r_data); } }); @@ -174,14 +174,14 @@ const MLoopTri *BKE_mesh_runtime_looptri_ensure(const Mesh *mesh) } void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri, - const MLoop *mloop, + const int *corner_verts, const MLoopTri *looptri, int looptri_num) { for (int i = 0; i < looptri_num; i++) { - r_verttri[i].tri[0] = mloop[looptri[i].tri[0]].v; - r_verttri[i].tri[1] = mloop[looptri[i].tri[1]].v; - r_verttri[i].tri[2] = mloop[looptri[i].tri[2]].v; + r_verttri[i].tri[0] = corner_verts[looptri[i].tri[0]]; + r_verttri[i].tri[1] = corner_verts[looptri[i].tri[1]]; + r_verttri[i].tri[2] = corner_verts[looptri[i].tri[2]]; } } @@ -318,7 +318,8 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) MutableSpan positions = me_eval->vert_positions_for_write(); MutableSpan edges = me_eval->edges_for_write(); MutableSpan polys = me_eval->polys_for_write(); - MutableSpan loops = me_eval->loops_for_write(); + MutableSpan corner_verts = me_eval->corner_verts_for_write(); + MutableSpan corner_edges = me_eval->corner_edges_for_write(); is_valid &= BKE_mesh_validate_all_customdata( &me_eval->vdata, @@ -342,8 +343,9 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) static_cast(CustomData_get_layer_for_write( &me_eval->fdata, CD_MFACE, me_eval->totface)), me_eval->totface, - loops.data(), - loops.size(), + corner_verts.data(), + corner_edges.data(), + corner_verts.size(), polys.data(), polys.size(), me_eval->deform_verts_for_write().data(), diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index 3fe710d1d69..4c7474e244c 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -21,7 +21,7 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh, const IndexMask mask, const MutableSpan dst) { - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span looptris = mesh.looptris(); for (const int i : mask) { @@ -29,9 +29,9 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh, const MLoopTri &looptri = looptris[looptri_index]; const float3 &bary_coord = bary_coords[i]; - const int v0_index = loops[looptri.tri[0]].v; - const int v1_index = loops[looptri.tri[1]].v; - const int v2_index = loops[looptri.tri[2]].v; + const int v0_index = corner_verts[looptri.tri[0]]; + const int v1_index = corner_verts[looptri.tri[1]]; + const int v2_index = corner_verts[looptri.tri[2]]; const T v0 = src[v0_index]; const T v1 = src[v1_index]; @@ -157,21 +157,17 @@ Span MeshAttributeInterpolator::ensure_barycentric_coords() bary_coords_.reinitialize(mask_.min_array_size()); const Span positions = mesh_->vert_positions(); - const Span loops = mesh_->loops(); + const Span corner_verts = mesh_->corner_verts(); const Span looptris = mesh_->looptris(); for (const int i : mask_) { const int looptri_index = looptri_indices_[i]; const MLoopTri &looptri = looptris[looptri_index]; - const int v0_index = loops[looptri.tri[0]].v; - const int v1_index = loops[looptri.tri[1]].v; - const int v2_index = loops[looptri.tri[2]].v; - interp_weights_tri_v3(bary_coords_[i], - positions[v0_index], - positions[v1_index], - positions[v2_index], + positions[corner_verts[looptri.tri[0]]], + positions[corner_verts[looptri.tri[1]]], + positions[corner_verts[looptri.tri[2]]], positions_[i]); } return bary_coords_; @@ -186,20 +182,16 @@ Span MeshAttributeInterpolator::ensure_nearest_weights() nearest_weights_.reinitialize(mask_.min_array_size()); const Span positions = mesh_->vert_positions(); - const Span loops = mesh_->loops(); + const Span corner_verts = mesh_->corner_verts(); const Span looptris = mesh_->looptris(); for (const int i : mask_) { const int looptri_index = looptri_indices_[i]; const MLoopTri &looptri = looptris[looptri_index]; - const int v0_index = loops[looptri.tri[0]].v; - const int v1_index = loops[looptri.tri[1]].v; - const int v2_index = loops[looptri.tri[2]].v; - - const float d0 = len_squared_v3v3(positions_[i], positions[v0_index]); - const float d1 = len_squared_v3v3(positions_[i], positions[v1_index]); - const float d2 = len_squared_v3v3(positions_[i], positions[v2_index]); + const float d0 = len_squared_v3v3(positions_[i], positions[corner_verts[looptri.tri[0]]]); + const float d1 = len_squared_v3v3(positions_[i], positions[corner_verts[looptri.tri[1]]]); + const float d2 = len_squared_v3v3(positions_[i], positions[corner_verts[looptri.tri[2]]]); nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1)); } @@ -259,7 +251,7 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng, Vector &r_positions) { const Span positions = mesh.vert_positions(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span looptris = mesh.looptris(); const float sample_radius_sq = pow2f(sample_radius); @@ -272,9 +264,9 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng, for (const int looptri_index : looptri_indices_to_sample) { const MLoopTri &looptri = looptris[looptri_index]; - const float3 &v0 = positions[loops[looptri.tri[0]].v]; - const float3 &v1 = positions[loops[looptri.tri[1]].v]; - const float3 &v2 = positions[loops[looptri.tri[2]].v]; + const float3 &v0 = positions[corner_verts[looptri.tri[0]]]; + const float3 &v1 = positions[corner_verts[looptri.tri[1]]]; + const float3 &v2 = positions[corner_verts[looptri.tri[2]]]; const float looptri_area = area_tri_v3(v0, v1, v2); @@ -356,7 +348,7 @@ int sample_surface_points_projected( Vector &r_positions) { const Span positions = mesh.vert_positions(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span looptris = mesh.looptris(); int point_count = 0; @@ -398,7 +390,7 @@ int sample_surface_points_projected( const float3 pos = ray_hit.co; const float3 bary_coords = compute_bary_coord_in_triangle( - positions, loops, looptris[looptri_index], pos); + positions, corner_verts, looptris[looptri_index], pos); r_positions.append(pos); r_bary_coords.append(bary_coords); @@ -409,13 +401,13 @@ int sample_surface_points_projected( } float3 compute_bary_coord_in_triangle(const Span vert_positions, - const Span loops, + const Span corner_verts, const MLoopTri &looptri, const float3 &position) { - const float3 &v0 = vert_positions[loops[looptri.tri[0]].v]; - const float3 &v1 = vert_positions[loops[looptri.tri[1]].v]; - const float3 &v2 = vert_positions[loops[looptri.tri[2]].v]; + const float3 &v0 = vert_positions[corner_verts[looptri.tri[0]]]; + const float3 &v1 = vert_positions[corner_verts[looptri.tri[1]]]; + const float3 &v2 = vert_positions[corner_verts[looptri.tri[2]]]; float3 bary_coords; interp_weights_tri_v3(bary_coords, v0, v1, v2, position); return bary_coords; diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index c4d8db512a2..7a7a8a78dd7 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -50,7 +50,7 @@ struct BKEMeshToTangent { mikk::float3 GetPosition(const uint face_num, const uint vert_num) { const uint loop_idx = uint(polys[face_num].loopstart) + vert_num; - return mikk::float3(positions[mloops[loop_idx].v]); + return mikk::float3(positions[corner_verts[loop_idx]]); } mikk::float3 GetTexCoord(const uint face_num, const uint vert_num) @@ -71,7 +71,7 @@ struct BKEMeshToTangent { } const MPoly *polys; /* faces */ - const MLoop *mloops; /* faces vertices */ + const int *corner_verts; /* faces vertices */ const float (*positions)[3]; /* vertices */ const float (*luvs)[2]; /* texture coordinates */ const float (*loop_normals)[3]; /* loops' normals */ @@ -81,7 +81,7 @@ struct BKEMeshToTangent { void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], const int /*numVerts*/, - const MLoop *mloops, + const int *corner_verts, float (*r_looptangent)[4], const float (*loop_normals)[3], const float (*loop_uvs)[2], @@ -93,7 +93,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], /* Compute Mikktspace's tangent normals. */ BKEMeshToTangent mesh_to_tangent; mesh_to_tangent.polys = polys; - mesh_to_tangent.mloops = mloops; + mesh_to_tangent.corner_verts = corner_verts; mesh_to_tangent.positions = vert_positions; mesh_to_tangent.luvs = loop_uvs; mesh_to_tangent.loop_normals = loop_normals; @@ -146,7 +146,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_vert_positions(mesh), mesh->totvert, - mesh->loops().data(), + mesh->corner_verts().data(), r_looptangents, loop_normals, reinterpret_cast(uv_map.data()), @@ -216,7 +216,7 @@ struct SGLSLMeshToTangent { { const MLoopTri *lt; uint loop_index = GetLoop(face_num, vert_num, lt); - return mikk::float3(positions[mloop[loop_index].v]); + return mikk::float3(positions[corner_verts[loop_index]]); } mikk::float3 GetTexCoord(const uint face_num, const uint vert_num) @@ -227,7 +227,7 @@ struct SGLSLMeshToTangent { const float2 &uv = mloopuv[loop_index]; return mikk::float3(uv[0], uv[1], 1.0f); } - const float *l_orco = orco[mloop[loop_index].v]; + const float *l_orco = orco[corner_verts[loop_index]]; float u, v; map_to_sphere(&u, &v, l_orco[0], l_orco[1], l_orco[2]); return mikk::float3(u, v, 1.0f); @@ -249,22 +249,22 @@ struct SGLSLMeshToTangent { float normal[3]; if (poly.totloop == 4) { normal_quad_v3(normal, - positions[mloop[poly.loopstart + 0].v], - positions[mloop[poly.loopstart + 1].v], - positions[mloop[poly.loopstart + 2].v], - positions[mloop[poly.loopstart + 3].v]); + positions[corner_verts[poly.loopstart + 0]], + positions[corner_verts[poly.loopstart + 1]], + positions[corner_verts[poly.loopstart + 2]], + positions[corner_verts[poly.loopstart + 3]]); } else #endif { normal_tri_v3(normal, - positions[mloop[lt->tri[0]].v], - positions[mloop[lt->tri[1]].v], - positions[mloop[lt->tri[2]].v]); + positions[corner_verts[lt->tri[0]]], + positions[corner_verts[lt->tri[1]]], + positions[corner_verts[lt->tri[2]]]); } return mikk::float3(normal); } - return mikk::float3(vert_normals[mloop[loop_index].v]); + return mikk::float3(vert_normals[corner_verts[loop_index]]); } void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation) @@ -280,7 +280,7 @@ struct SGLSLMeshToTangent { const MLoopTri *looptri; const float2 *mloopuv; /* texture coordinates */ const MPoly *polys; /* indices */ - const MLoop *mloop; /* indices */ + const int *corner_verts; /* indices */ const float (*positions)[3]; /* vertex coordinates */ const float (*vert_normals)[3]; const float (*orco)[3]; @@ -391,7 +391,7 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], const MPoly *polys, const uint polys_len, - const MLoop *mloop, + const int *corner_verts, const MLoopTri *looptri, const uint looptri_len, const bool *sharp_faces, @@ -497,7 +497,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], mesh2tangent->positions = vert_positions; mesh2tangent->vert_normals = vert_normals; mesh2tangent->polys = polys; - mesh2tangent->mloop = mloop; + mesh2tangent->corner_verts = corner_verts; mesh2tangent->looptri = looptri; mesh2tangent->sharp_faces = sharp_faces; /* NOTE: we assume we do have tessellated loop normals at this point @@ -582,7 +582,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, BKE_mesh_vert_positions(me_eval), me_eval->polys().data(), uint(me_eval->totpoly), - me_eval->loops().data(), + me_eval->corner_verts().data(), looptris.data(), uint(looptris.size()), static_cast( diff --git a/source/blender/blenkernel/intern/mesh_tessellate.cc b/source/blender/blenkernel/intern/mesh_tessellate.cc index 62c69dc9286..9bd881d0ca5 100644 --- a/source/blender/blenkernel/intern/mesh_tessellate.cc +++ b/source/blender/blenkernel/intern/mesh_tessellate.cc @@ -34,7 +34,7 @@ namespace blender::bke::mesh { /** * \param face_normal: This will be optimized out as a constant. */ -BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, +BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span corner_verts, const Span polys, const Span positions, uint poly_index, @@ -46,37 +46,37 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, const uint mp_loopstart = uint(polys[poly_index].loopstart); const uint mp_totloop = uint(polys[poly_index].totloop); -#define ML_TO_MLT(i1, i2, i3) \ - { \ - ARRAY_SET_ITEMS(mlt->tri, mp_loopstart + i1, mp_loopstart + i2, mp_loopstart + i3); \ - mlt->poly = poly_index; \ - } \ - ((void)0) + auto create_tri = [&](uint i1, uint i2, uint i3) { + mlt->tri[0] = mp_loopstart + i1; + mlt->tri[1] = mp_loopstart + i2; + mlt->tri[2] = mp_loopstart + i3; + mlt->poly = poly_index; + }; switch (mp_totloop) { case 3: { - ML_TO_MLT(0, 1, 2); + create_tri(0, 1, 2); break; } case 4: { - ML_TO_MLT(0, 1, 2); + create_tri(0, 1, 2); MLoopTri *mlt_a = mlt++; - ML_TO_MLT(0, 2, 3); + create_tri(0, 2, 3); MLoopTri *mlt_b = mlt; if (UNLIKELY(face_normal ? is_quad_flip_v3_first_third_fast_with_normal( /* Simpler calculation (using the normal). */ - positions[mloop[mlt_a->tri[0]].v], - positions[mloop[mlt_a->tri[1]].v], - positions[mloop[mlt_a->tri[2]].v], - positions[mloop[mlt_b->tri[2]].v], + positions[corner_verts[mlt_a->tri[0]]], + positions[corner_verts[mlt_a->tri[1]]], + positions[corner_verts[mlt_a->tri[2]]], + positions[corner_verts[mlt_b->tri[2]]], normal_precalc) : is_quad_flip_v3_first_third_fast( /* Expensive calculation (no normal). */ - positions[mloop[mlt_a->tri[0]].v], - positions[mloop[mlt_a->tri[1]].v], - positions[mloop[mlt_a->tri[2]].v], - positions[mloop[mlt_b->tri[2]].v]))) { + positions[corner_verts[mlt_a->tri[0]]], + positions[corner_verts[mlt_a->tri[1]]], + positions[corner_verts[mlt_a->tri[2]]], + positions[corner_verts[mlt_b->tri[2]]]))) { /* Flip out of degenerate 0-2 state. */ mlt_a->tri[2] = mlt_b->tri[2]; mlt_b->tri[0] = mlt_a->tri[1]; @@ -84,7 +84,6 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, break; } default: { - const MLoop *ml; float axis_mat[3][3]; /* Calculate `axis_mat` to project verts to 2D. */ @@ -95,10 +94,9 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, zero_v3(normal); /* Calc normal, flipped: to get a positive 2D cross product. */ - ml = mloop.data() + mp_loopstart; - co_prev = positions[ml[mp_totloop - 1].v]; - for (uint j = 0; j < mp_totloop; j++, ml++) { - co_curr = positions[ml->v]; + co_prev = positions[corner_verts[mp_totloop - 1]]; + for (uint j = 0; j < mp_totloop; j++) { + co_curr = positions[corner_verts[mp_loopstart + j]]; add_newell_cross_v3_v3v3(normal, co_prev, co_curr); co_prev = co_curr; } @@ -123,9 +121,8 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, float(*projverts)[2] = static_cast( BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(mp_totloop))); - ml = mloop.data() + mp_loopstart; - for (uint j = 0; j < mp_totloop; j++, ml++) { - mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]); + for (uint j = 0; j < mp_totloop; j++) { + mul_v2_m3v3(projverts[j], axis_mat, positions[corner_verts[mp_loopstart + j]]); } BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, pf_arena); @@ -133,7 +130,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, /* Apply fill. */ for (uint j = 0; j < totfilltri; j++, mlt++) { const uint *tri = tris[j]; - ML_TO_MLT(tri[0], tri[1], tri[2]); + create_tri(tri[0], tri[1], tri[2]); } BLI_memarena_clear(pf_arena); @@ -144,7 +141,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span mloop, #undef ML_TO_MLT } -static void mesh_calc_tessellation_for_face(const Span mloop, +static void mesh_calc_tessellation_for_face(const Span corner_verts, const Span polys, const Span positions, uint poly_index, @@ -152,10 +149,10 @@ static void mesh_calc_tessellation_for_face(const Span mloop, MemArena **pf_arena_p) { mesh_calc_tessellation_for_face_impl( - mloop, polys, positions, poly_index, mlt, pf_arena_p, false, nullptr); + corner_verts, polys, positions, poly_index, mlt, pf_arena_p, false, nullptr); } -static void mesh_calc_tessellation_for_face_with_normal(const Span mloop, +static void mesh_calc_tessellation_for_face_with_normal(const Span corner_verts, const Span polys, const Span positions, uint poly_index, @@ -164,10 +161,10 @@ static void mesh_calc_tessellation_for_face_with_normal(const Span mloop, const float normal_precalc[3]) { mesh_calc_tessellation_for_face_impl( - mloop, polys, positions, poly_index, mlt, pf_arena_p, true, normal_precalc); + corner_verts, polys, positions, poly_index, mlt, pf_arena_p, true, normal_precalc); } -static void mesh_recalc_looptri__single_threaded(const Span mloop, +static void mesh_recalc_looptri__single_threaded(const Span corner_verts, const Span polys, const Span positions, int totloop, @@ -181,7 +178,7 @@ static void mesh_recalc_looptri__single_threaded(const Span mloop, if (poly_normals != nullptr) { for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, poly++) { - mesh_calc_tessellation_for_face_with_normal(mloop, + mesh_calc_tessellation_for_face_with_normal(corner_verts, polys, positions, poly_index, @@ -194,7 +191,7 @@ static void mesh_recalc_looptri__single_threaded(const Span mloop, else { for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, poly++) { mesh_calc_tessellation_for_face( - mloop, polys, positions, poly_index, &mlooptri[tri_index], &pf_arena); + corner_verts, polys, positions, poly_index, &mlooptri[tri_index], &pf_arena); tri_index += uint(poly->totloop - 2); } } @@ -208,7 +205,7 @@ static void mesh_recalc_looptri__single_threaded(const Span mloop, } struct TessellationUserData { - Span mloop; + Span corner_verts; Span polys; Span positions; @@ -230,7 +227,7 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata, const TessellationUserData *data = static_cast(userdata); TessellationUserTLS *tls_data = static_cast(tls->userdata_chunk); const int tri_index = poly_to_tri_count(index, data->polys[index].loopstart); - mesh_calc_tessellation_for_face_impl(data->mloop, + mesh_calc_tessellation_for_face_impl(data->corner_verts, data->polys, data->positions, uint(index), @@ -247,7 +244,7 @@ static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict user const TessellationUserData *data = static_cast(userdata); TessellationUserTLS *tls_data = static_cast(tls->userdata_chunk); const int tri_index = poly_to_tri_count(index, data->polys[index].loopstart); - mesh_calc_tessellation_for_face_impl(data->mloop, + mesh_calc_tessellation_for_face_impl(data->corner_verts, data->polys, data->positions, uint(index), @@ -268,15 +265,15 @@ static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict /*use static void looptris_calc_all(const Span positions, const Span polys, - const Span loops, + const Span corner_verts, const Span poly_normals, MutableSpan looptris) { - if (loops.size() < MESH_FACE_TESSELLATE_THREADED_LIMIT) { - mesh_recalc_looptri__single_threaded(loops, + if (corner_verts.size() < MESH_FACE_TESSELLATE_THREADED_LIMIT) { + mesh_recalc_looptri__single_threaded(corner_verts, polys, positions, - int(loops.size()), + int(corner_verts.size()), int(polys.size()), looptris.data(), reinterpret_cast(poly_normals.data())); @@ -286,7 +283,7 @@ static void looptris_calc_all(const Span positions, struct TessellationUserData data { }; - data.mloop = loops; + data.corner_verts = corner_verts; data.polys = polys; data.positions = positions; data.mlooptri = looptris; @@ -310,25 +307,25 @@ static void looptris_calc_all(const Span positions, void looptris_calc(const Span vert_positions, const Span polys, - const Span loops, + const Span corner_verts, MutableSpan looptris) { - looptris_calc_all(vert_positions, polys, loops, {}, looptris); + looptris_calc_all(vert_positions, polys, corner_verts, {}, looptris); } void looptris_calc_with_normals(const Span vert_positions, const Span polys, - const Span loops, + const Span corner_verts, const Span poly_normals, MutableSpan looptris) { BLI_assert(!poly_normals.is_empty() || polys.is_empty()); - looptris_calc_all(vert_positions, polys, loops, poly_normals, looptris); + looptris_calc_all(vert_positions, polys, corner_verts, poly_normals, looptris); } } // namespace blender::bke::mesh -void BKE_mesh_recalc_looptri(const MLoop *mloop, +void BKE_mesh_recalc_looptri(const int *corner_verts, const MPoly *polys, const float (*vert_positions)[3], int totvert, @@ -339,7 +336,7 @@ void BKE_mesh_recalc_looptri(const MLoop *mloop, blender::bke::mesh::looptris_calc( {reinterpret_cast(vert_positions), totvert}, {polys, totpoly}, - {mloop, totloop}, + {corner_verts, totloop}, {mlooptri, poly_to_tri_count(totpoly, totloop)}); } diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 19e5e525015..f15020c9c46 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -216,7 +216,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, uint totedge, MFace *mfaces, uint totface, - MLoop *mloops, + int *corner_verts, + int *corner_edges, uint totloop, MPoly *polys, uint totpoly, @@ -233,9 +234,9 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, (void)0 #define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1) -#define REMOVE_LOOP_TAG(_ml) \ +#define REMOVE_LOOP_TAG(corner) \ { \ - _ml->e = INVALID_LOOP_EDGE_MARKER; \ + corner_edges[corner] = INVALID_LOOP_EDGE_MARKER; \ free_flag.polyloops = do_fixes; \ } \ (void)0 @@ -251,7 +252,6 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, blender::MutableVArraySpan material_indices_span(material_indices.varray); MEdge *edge; - MLoop *ml; uint i, j; int *v; @@ -575,27 +575,29 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, /* Ideally we would only have to do that once on all vertices * before we start checking each poly, but several polys can use same vert, * so we have to ensure here all verts of current poly are cleared. */ - for (j = 0, ml = &mloops[sp->loopstart]; j < poly.totloop; j++, ml++) { - if (ml->v < totvert) { - BLI_BITMAP_DISABLE(vert_tag, ml->v); + for (j = 0; j < poly.totloop; j++) { + const int vert = corner_verts[sp->loopstart + j]; + if (vert < totvert) { + BLI_BITMAP_DISABLE(vert_tag, vert); } } /* Test all poly's loops' vert idx. */ - for (j = 0, ml = &mloops[sp->loopstart]; j < poly.totloop; j++, ml++, v++) { - if (ml->v >= totvert) { + for (j = 0; j < poly.totloop; j++, v++) { + const int vert = corner_verts[sp->loopstart + j]; + if (vert >= totvert) { /* Invalid vert idx. */ - PRINT_ERR("\tLoop %u has invalid vert reference (%u)", sp->loopstart + j, ml->v); + PRINT_ERR("\tLoop %u has invalid vert reference (%d)", sp->loopstart + j, vert); sp->invalid = true; } - else if (BLI_BITMAP_TEST(vert_tag, ml->v)) { + else if (BLI_BITMAP_TEST(vert_tag, vert)) { PRINT_ERR("\tPoly %u has duplicated vert reference at corner (%u)", uint(i), j); sp->invalid = true; } else { - BLI_BITMAP_ENABLE(vert_tag, ml->v); + BLI_BITMAP_ENABLE(vert_tag, vert); } - *v = ml->v; + *v = vert; } if (sp->invalid) { @@ -604,9 +606,12 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, } /* Test all poly's loops. */ - for (j = 0, ml = &mloops[sp->loopstart]; j < poly.totloop; j++, ml++) { - v1 = ml->v; - v2 = mloops[sp->loopstart + (j + 1) % poly.totloop].v; + for (j = 0; j < poly.totloop; j++) { + const int corner = sp->loopstart + j; + const int vert = corner_verts[corner]; + const int edge_i = corner_edges[corner]; + v1 = vert; + v2 = corner_verts[sp->loopstart + (j + 1) % poly.totloop]; if (!BLI_edgehash_haskey(edge_hash, v1, v2)) { /* Edge not existing. */ PRINT_ERR("\tPoly %u needs missing edge (%d, %d)", sp->index, v1, v2); @@ -617,44 +622,44 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, sp->invalid = true; } } - else if (ml->e >= totedge) { + else if (edge_i >= totedge) { /* Invalid edge idx. * We already know from previous text that a valid edge exists, use it (if allowed)! */ if (do_fixes) { - int prev_e = ml->e; - ml->e = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2)); + int prev_e = edge_i; + corner_edges[corner] = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2)); fix_flag.loops_edge = true; - PRINT_ERR("\tLoop %u has invalid edge reference (%d), fixed using edge %u", - sp->loopstart + j, + PRINT_ERR("\tLoop %d has invalid edge reference (%d), fixed using edge %d", + corner, prev_e, - ml->e); + corner_edges[corner]); } else { - PRINT_ERR("\tLoop %u has invalid edge reference (%u)", sp->loopstart + j, ml->e); + PRINT_ERR("\tLoop %d has invalid edge reference (%d)", corner, edge_i); sp->invalid = true; } } else { - edge = &edges[ml->e]; + edge = &edges[edge_i]; if (IS_REMOVED_EDGE(edge) || !((edge->v1 == v1 && edge->v2 == v2) || (edge->v1 == v2 && edge->v2 == v1))) { /* The pointed edge is invalid (tagged as removed, or vert idx mismatch), * and we already know from previous test that a valid one exists, * use it (if allowed)! */ if (do_fixes) { - int prev_e = ml->e; - ml->e = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2)); + int prev_e = edge_i; + corner_edges[corner] = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2)); fix_flag.loops_edge = true; PRINT_ERR( "\tPoly %u has invalid edge reference (%d, is_removed: %d), fixed using edge " - "%u", + "%d", sp->index, prev_e, IS_REMOVED_EDGE(edge), - ml->e); + corner_edges[corner]); } else { - PRINT_ERR("\tPoly %u has invalid edge reference (%u)", sp->index, ml->e); + PRINT_ERR("\tPoly %u has invalid edge reference (%d)", sp->index, edge_i); sp->invalid = true; } } @@ -733,10 +738,11 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, else { /* Unused loops. */ if (prev_end < sp->loopstart) { - for (j = prev_end, ml = &mloops[prev_end]; j < sp->loopstart; j++, ml++) { + int corner; + for (j = prev_end, corner = prev_end; j < sp->loopstart; j++, corner++) { PRINT_ERR("\tLoop %u is unused.", j); if (do_fixes) { - REMOVE_LOOP_TAG(ml); + REMOVE_LOOP_TAG(corner); } } prev_end = sp->loopstart + sp->numverts; @@ -766,10 +772,11 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, } /* We may have some remaining unused loops to get rid of! */ if (prev_end < totloop) { - for (j = prev_end, ml = &mloops[prev_end]; j < totloop; j++, ml++) { + int corner; + for (j = prev_end, corner = prev_end; j < totloop; j++, corner++) { PRINT_ERR("\tLoop %u is unused.", j); if (do_fixes) { - REMOVE_LOOP_TAG(ml); + REMOVE_LOOP_TAG(corner); } } } @@ -1043,7 +1050,8 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_ MutableSpan positions = me->vert_positions_for_write(); MutableSpan edges = me->edges_for_write(); MutableSpan polys = me->polys_for_write(); - MutableSpan loops = me->loops_for_write(); + MutableSpan corner_verts = me->corner_verts_for_write(); + MutableSpan corner_edges = me->corner_edges_for_write(); BKE_mesh_validate_arrays( me, @@ -1053,8 +1061,9 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_ edges.size(), (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface), me->totface, - loops.data(), - loops.size(), + corner_verts.data(), + corner_edges.data(), + corner_verts.size(), polys.data(), polys.size(), me->deform_verts_for_write().data(), @@ -1095,7 +1104,8 @@ bool BKE_mesh_is_valid(Mesh *me) MutableSpan positions = me->vert_positions_for_write(); MutableSpan edges = me->edges_for_write(); MutableSpan polys = me->polys_for_write(); - MutableSpan loops = me->loops_for_write(); + MutableSpan corner_verts = me->corner_verts_for_write(); + MutableSpan corner_edges = me->corner_edges_for_write(); is_valid &= BKE_mesh_validate_arrays( me, @@ -1105,8 +1115,9 @@ bool BKE_mesh_is_valid(Mesh *me) edges.size(), (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface), me->totface, - loops.data(), - loops.size(), + corner_verts.data(), + corner_edges.data(), + corner_verts.size(), polys.data(), polys.size(), me->deform_verts_for_write().data(), @@ -1175,9 +1186,8 @@ void BKE_mesh_strip_loose_faces(Mesh *me) void mesh_strip_polysloops(Mesh *me) { MutableSpan polys = me->polys_for_write(); - MutableSpan loops = me->loops_for_write(); + MutableSpan corner_edges = me->corner_edges_for_write(); - MLoop *l; int a, b; /* New loops idx! */ int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__); @@ -1192,14 +1202,11 @@ void mesh_strip_polysloops(Mesh *me) invalid = true; } else { - l = &loops[i]; - i = stop - i; /* If one of the poly's loops is invalid, the whole poly is invalid! */ - for (; i--; l++) { - if (l->e == INVALID_LOOP_EDGE_MARKER) { - invalid = true; - break; - } + if (corner_edges.slice(poly.loopstart, poly.totloop) + .as_span() + .contains(INVALID_LOOP_EDGE_MARKER)) { + invalid = true; } } @@ -1217,10 +1224,10 @@ void mesh_strip_polysloops(Mesh *me) } /* And now, get rid of invalid loops. */ - for (a = b = 0, l = loops.data(); a < me->totloop; a++, l++) { - if (l->e != INVALID_LOOP_EDGE_MARKER) { + int corner = 0; + for (a = b = 0; a < me->totloop; a++, corner++) { + if (corner_edges[corner] != INVALID_LOOP_EDGE_MARKER) { if (a != b) { - memcpy(&loops[b], l, sizeof(loops[b])); CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1); } new_idx[a] = b; @@ -1274,9 +1281,9 @@ void mesh_strip_edges(Mesh *me) /* And now, update loops' edge indices. */ /* XXX We hope no loop was pointing to a striped edge! * Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */ - MutableSpan loops = me->loops_for_write(); - for (MLoop &loop : loops) { - loop.e = new_idx[loop.e]; + MutableSpan corner_edges = me->corner_edges_for_write(); + for (const int i : corner_edges.index_range()) { + corner_edges[i] = new_idx[corner_edges[i]]; } MEM_freeN(new_idx); diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 63792623c56..659710a1892 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -7,7 +7,7 @@ * output of a modified mesh. * * This API handles the case when the modifier stack outputs a mesh which does not have - * #Mesh data (#MPoly, #MLoop, #MEdge, etc). + * #Mesh data (#MPoly, corner verts, corner edges, #MEdge, etc). * Currently this is used so the resulting mesh can have #BMEditMesh data, * postponing the converting until it's needed or avoiding conversion entirely * which can be an expensive operation. diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index a2f2c52b9cf..a3c88309898 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -673,7 +673,6 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) if (mdisps && levels > 0) { if (lvl > 0) { - // MLoop *ml = me->mloop; /*UNUSED*/ int nsize = multires_side_tot[lvl]; int hsize = multires_side_tot[mmd->totlvl]; int j; @@ -1629,7 +1628,7 @@ int mdisp_rot_face_to_crn( float mindist = FLT_MAX; for (i = 0; i < poly->totloop; i++) { - float len = len_v3v3(nullptr, positions[mloop[poly->loopstart + i].v]); + float len = len_v3v3(nullptr, positions[corner_verts[poly->loopstart + i]]); if (len < mindist) { mindist = len; minS = i; diff --git a/source/blender/blenkernel/intern/multires_reshape.hh b/source/blender/blenkernel/intern/multires_reshape.hh index d709afca86f..66731f212ea 100644 --- a/source/blender/blenkernel/intern/multires_reshape.hh +++ b/source/blender/blenkernel/intern/multires_reshape.hh @@ -17,7 +17,6 @@ struct GridPaintMask; struct MDisps; struct MEdge; struct Mesh; -struct MLoop; struct MPoly; struct MultiresModifierData; struct Object; @@ -37,7 +36,8 @@ struct MultiresReshapeContext { const float (*base_positions)[3]; blender::Span base_edges; blender::Span base_polys; - blender::Span base_loops; + blender::Span base_corner_verts; + blender::Span base_corner_edges; /* Subdivision surface created for multires modifier. * diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.cc b/source/blender/blenkernel/intern/multires_reshape_apply_base.cc index 46a990c6e07..0b48aa8f282 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.cc +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.cc @@ -34,9 +34,8 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *resh /* Update the context in case the vertices were duplicated. */ reshape_context->base_positions = base_positions; - const blender::Span loops = reshape_context->base_loops; - for (const int loop_index : loops.index_range()) { - const MLoop *loop = &loops[loop_index]; + const blender::Span corner_verts = reshape_context->base_corner_verts; + for (const int loop_index : corner_verts.index_range()) { GridCoord grid_coord; grid_coord.grid_index = loop_index; @@ -52,7 +51,7 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *resh float D[3]; mul_v3_m3v3(D, tangent_matrix, grid_element.displacement); - add_v3_v3v3(base_positions[loop->v], P, D); + add_v3_v3v3(base_positions[corner_verts[loop_index]], P, D); } } @@ -76,7 +75,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape BKE_mesh_vert_poly_map_create(&pmap, &pmap_mem, reshape_context->base_polys.data(), - reshape_context->base_loops.data(), + reshape_context->base_corner_verts.data(), base_mesh->totvert, base_mesh->totpoly, base_mesh->totloop); @@ -102,7 +101,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape /* This double counts, not sure if that's bad or good. */ for (int k = 0; k < poly.totloop; k++) { - const int vndx = reshape_context->base_loops[poly.loopstart + k].v; + const int vndx = reshape_context->base_corner_verts[poly.loopstart + k]; if (vndx != i) { add_v3_v3(center, origco[vndx]); tot++; @@ -116,13 +115,13 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape const MPoly &poly = reshape_context->base_polys[pmap[i].indices[j]]; /* Set up poly, loops, and coords in order to call #bke::mesh::poly_normal_calc(). */ - blender::Array fake_loops(poly.totloop); + blender::Array poly_verts(poly.totloop); blender::Array fake_co(poly.totloop); for (int k = 0; k < poly.totloop; k++) { - const int vndx = reshape_context->base_loops[poly.loopstart + k].v; + const int vndx = reshape_context->base_corner_verts[poly.loopstart + k]; - fake_loops[k].v = k; + poly_verts[k] = k; if (vndx == i) { copy_v3_v3(fake_co[k], center); @@ -132,7 +131,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape } } - const blender::float3 no = blender::bke::mesh::poly_normal_calc(fake_co, fake_loops); + const blender::float3 no = blender::bke::mesh::poly_normal_calc(fake_co, poly_verts); add_v3_v3(avg_no, no); } normalize_v3(avg_no); diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.cc b/source/blender/blenkernel/intern/multires_reshape_smooth.cc index 2586a968b80..bcb13cab559 100644 --- a/source/blender/blenkernel/intern/multires_reshape_smooth.cc +++ b/source/blender/blenkernel/intern/multires_reshape_smooth.cc @@ -850,7 +850,7 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; const Mesh *base_mesh = reshape_context->base_mesh; const blender::Span base_polys = reshape_context->base_polys; - const blender::Span base_loops = reshape_context->base_loops; + const blender::Span base_corner_edges = reshape_context->base_corner_edges; reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge, "non_loose_base_edge_map"); @@ -858,12 +858,11 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap int num_used_edges = 0; for (const int poly_index : base_polys.index_range()) { const MPoly &base_poly = base_polys[poly_index]; - for (int corner = 0; corner < base_poly.totloop; corner++) { - const MLoop *loop = &base_loops[base_poly.loopstart + corner]; - if (!BLI_BITMAP_TEST_BOOL(reshape_smooth_context->non_loose_base_edge_map, loop->e)) { - BLI_BITMAP_ENABLE(reshape_smooth_context->non_loose_base_edge_map, loop->e); + for (const int edge : base_corner_edges.slice(base_poly.loopstart, base_poly.totloop)) { + if (!BLI_BITMAP_TEST_BOOL(reshape_smooth_context->non_loose_base_edge_map, edge)) { + BLI_BITMAP_ENABLE(reshape_smooth_context->non_loose_base_edge_map, edge); - const float crease = get_effective_crease(reshape_smooth_context, loop->e); + const float crease = get_effective_crease(reshape_smooth_context, edge); if (crease > 0.0f) { ++num_used_edges; } diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.cc b/source/blender/blenkernel/intern/multires_reshape_subdivide.cc index 866c35a7a73..f558ad73cda 100644 --- a/source/blender/blenkernel/intern/multires_reshape_subdivide.cc +++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.cc @@ -32,14 +32,14 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) using namespace blender::bke; const Span positions = mesh->vert_positions(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); MDisps *mdisps = static_cast( CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop)); for (const int p : polys.index_range()) { const MPoly &poly = polys[p]; - const float3 poly_center = mesh::poly_center_calc(positions, - loops.slice(poly.loopstart, poly.totloop)); + const float3 poly_center = mesh::poly_center_calc( + positions, corner_verts.slice(poly.loopstart, poly.totloop)); for (int l = 0; l < poly.totloop; l++) { const int loop_index = poly.loopstart + l; @@ -50,14 +50,14 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) int prev_loop_index = l - 1 >= 0 ? loop_index - 1 : loop_index + poly.totloop - 1; int next_loop_index = l + 1 < poly.totloop ? loop_index + 1 : poly.loopstart; - const MLoop *loop = &loops[loop_index]; - const MLoop *loop_next = &loops[next_loop_index]; - const MLoop *loop_prev = &loops[prev_loop_index]; + const int vert = corner_verts[loop_index]; + const int vert_next = corner_verts[next_loop_index]; + const int vert_prev = corner_verts[prev_loop_index]; copy_v3_v3(disps[0], poly_center); - mid_v3_v3v3(disps[1], positions[loop->v], positions[loop_next->v]); - mid_v3_v3v3(disps[2], positions[loop->v], positions[loop_prev->v]); - copy_v3_v3(disps[3], positions[loop->v]); + mid_v3_v3v3(disps[1], positions[vert], positions[vert_next]); + mid_v3_v3v3(disps[2], positions[vert], positions[vert_prev]); + copy_v3_v3(disps[3], positions[vert]); } } } diff --git a/source/blender/blenkernel/intern/multires_reshape_util.cc b/source/blender/blenkernel/intern/multires_reshape_util.cc index aea8f8a3ca6..62a2667c52f 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.cc +++ b/source/blender/blenkernel/intern/multires_reshape_util.cc @@ -158,7 +158,8 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = base_mesh->edges(); reshape_context->base_polys = base_mesh->polys(); - reshape_context->base_loops = base_mesh->loops(); + reshape_context->base_corner_verts = base_mesh->corner_verts(); + reshape_context->base_corner_edges = base_mesh->corner_edges(); reshape_context->subdiv = multires_reshape_create_subdiv(nullptr, object, mmd); reshape_context->need_free_subdiv = true; @@ -195,7 +196,8 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = base_mesh->edges(); reshape_context->base_polys = base_mesh->polys(); - reshape_context->base_loops = base_mesh->loops(); + reshape_context->base_corner_verts = base_mesh->corner_verts(); + reshape_context->base_corner_edges = base_mesh->corner_edges(); reshape_context->subdiv = multires_reshape_create_subdiv(depsgraph, object, mmd); reshape_context->need_free_subdiv = true; @@ -229,7 +231,8 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = base_mesh->edges(); reshape_context->base_polys = base_mesh->polys(); - reshape_context->base_loops = base_mesh->loops(); + reshape_context->base_corner_verts = base_mesh->corner_verts(); + reshape_context->base_corner_edges = base_mesh->corner_edges(); reshape_context->subdiv = subdiv_ccg->subdiv; reshape_context->need_free_subdiv = false; @@ -276,7 +279,8 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = base_mesh->edges(); reshape_context->base_polys = base_mesh->polys(); - reshape_context->base_loops = base_mesh->loops(); + reshape_context->base_corner_verts = base_mesh->corner_verts(); + reshape_context->base_corner_edges = base_mesh->corner_edges(); reshape_context->cd_vertex_crease = (const float *)CustomData_get_layer(&base_mesh->edata, CD_CREASE); diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.cc b/source/blender/blenkernel/intern/multires_unsubdivide.cc index eac1c869aa5..be6b1251942 100644 --- a/source/blender/blenkernel/intern/multires_unsubdivide.cc +++ b/source/blender/blenkernel/intern/multires_unsubdivide.cc @@ -643,7 +643,7 @@ static void store_grid_data(MultiresUnsubdivideContext *context, { Mesh *original_mesh = context->original_mesh; const blender::Span polys = original_mesh->polys(); - const blender::Span loops = original_mesh->loops(); + const blender::Span corner_verts = original_mesh->corner_verts(); const MPoly &poly = polys[BM_elem_index_get(f)]; const int corner_vertex_index = BM_elem_index_get(v); @@ -653,8 +653,7 @@ static void store_grid_data(MultiresUnsubdivideContext *context, int loop_offset = 0; for (int i = 0; i < poly.totloop; i++) { const int loop_index = poly.loopstart + i; - const MLoop *l = &loops[loop_index]; - if (l->v == corner_vertex_index) { + if (corner_verts[loop_index] == corner_vertex_index) { loop_offset = i; break; } @@ -967,22 +966,22 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract( * necessary. */ static bool multires_unsubdivide_flip_grid_x_axis(const blender::Span polys, - const blender::Span loops, + const blender::Span corner_verts, int poly_index, int loop, int v_x) { const MPoly &poly = polys[poly_index]; - const MLoop *l_first = &loops[poly.loopstart]; - if ((loop == (poly.loopstart + (poly.totloop - 1))) && l_first->v == v_x) { + const int v_first = corner_verts[poly.loopstart]; + if ((loop == (poly.loopstart + (poly.totloop - 1))) && v_first == v_x) { return true; } int next_l_index = loop + 1; if (next_l_index < poly.loopstart + poly.totloop) { - const MLoop *l_next = &loops[next_l_index]; - if (l_next->v == v_x) { + const int v_next = corner_verts[next_l_index]; + if (v_next == v_x) { return true; } } @@ -1045,7 +1044,7 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte &bm_base_mesh->ldata, CD_PROP_INT32, base_l_layer_index); const blender::Span polys = base_mesh->polys(); - const blender::Span loops = base_mesh->loops(); + const blender::Span corner_verts = base_mesh->corner_verts(); /* Main loop for extracting the grids. Iterates over the base mesh vertices. */ BM_ITER_MESH (v, &iter, bm_base_mesh, BM_VERTS_OF_MESH) { @@ -1084,7 +1083,7 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte /* Check the orientation of the loops in case that is needed to flip the x and y axis * when extracting the grid. */ const bool flip_grid = multires_unsubdivide_flip_grid_x_axis( - polys, loops, base_mesh_face_index, base_mesh_loop_index, corner_x_index); + polys, corner_verts, base_mesh_face_index, base_mesh_loop_index, corner_x_index); /* Extract the grid for that loop. */ context->base_mesh_grids[base_mesh_loop_index].grid_index = base_mesh_loop_index; diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index c648a339b0a..2b7bce2e8a4 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -1057,7 +1057,7 @@ struct FaceDupliData_Mesh { int totface; const MPoly *polys; - const MLoop *mloop; + const int *corner_verts; Span vert_positions; const float (*orco)[3]; const float2 *mloopuv; @@ -1156,15 +1156,14 @@ static DupliObject *face_dupli_from_mesh(const DupliContext *ctx, /* Mesh variables. */ const MPoly &poly, - const MLoop *mloopstart, + const int *poly_verts, const Span vert_positions) { const int coords_len = poly.totloop; Array coords(coords_len); - const MLoop *ml = mloopstart; - for (int i = 0; i < coords_len; i++, ml++) { - coords[i] = vert_positions[ml->v]; + for (int i = 0; i < coords_len; i++) { + coords[i] = vert_positions[poly_verts[i]]; } return face_dupli(ctx, inst_ob, child_imat, index, use_scale, scale_fac, coords); @@ -1207,7 +1206,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, { FaceDupliData_Mesh *fdd = (FaceDupliData_Mesh *)userdata; const MPoly *polys = fdd->polys; - const MLoop *mloop = fdd->mloop; + const int *corner_verts = fdd->corner_verts; const float(*orco)[3] = fdd->orco; const float2 *mloopuv = fdd->mloopuv; const int totface = fdd->totface; @@ -1222,7 +1221,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, for (const int a : blender::IndexRange(totface)) { const MPoly &poly = polys[a]; - const MLoop *loopstart = mloop + poly.loopstart; + const int *poly_verts = &corner_verts[poly.loopstart]; DupliObject *dob = face_dupli_from_mesh(fdd->params.ctx, inst_ob, child_imat, @@ -1230,13 +1229,13 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, use_scale, scale_fac, poly, - loopstart, + poly_verts, fdd->vert_positions); const float w = 1.0f / float(poly.totloop); if (orco) { for (int j = 0; j < poly.totloop; j++) { - madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w); + madd_v3_v3fl(dob->orco, orco[poly_verts[j]], w); } } if (mloopuv) { @@ -1320,7 +1319,7 @@ static void make_duplis_faces(const DupliContext *ctx) fdd.params = fdd_params; fdd.totface = me_eval->totpoly; fdd.polys = me_eval->polys().data(); - fdd.mloop = me_eval->loops().data(); + fdd.corner_verts = me_eval->corner_verts().data(); fdd.vert_positions = me_eval->vert_positions(); fdd.mloopuv = (uv_idx != -1) ? (const float2 *)CustomData_get_layer_n( &me_eval->ldata, CD_PROP_FLOAT2, uv_idx) : @@ -1331,9 +1330,8 @@ static void make_duplis_faces(const DupliContext *ctx) } } -static const DupliGenerator gen_dupli_faces = { - /*type*/ OB_DUPLIFACES, - /*make_duplis*/ make_duplis_faces}; +static const DupliGenerator gen_dupli_faces = {/*type*/ OB_DUPLIFACES, + /*make_duplis*/ make_duplis_faces}; /** \} */ @@ -1680,9 +1678,8 @@ static void make_duplis_particles(const DupliContext *ctx) } } -static const DupliGenerator gen_dupli_particles = { - /*type*/ OB_DUPLIPARTS, - /*make_duplis*/ make_duplis_particles}; +static const DupliGenerator gen_dupli_particles = {/*type*/ OB_DUPLIPARTS, + /*make_duplis*/ make_duplis_particles}; /** \} */ diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index a633acae610..4c9165c2c33 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1697,7 +1697,7 @@ static void sculpt_update_object( * and tools use the Face Sets data from the base mesh when Multires is active. */ ss->vert_positions = BKE_mesh_vert_positions_for_write(me); ss->polys = me->polys().data(); - ss->mloop = me->loops().data(); + ss->corner_verts = me->corner_verts().data(); } else { ss->totvert = me->totvert; @@ -1705,7 +1705,7 @@ static void sculpt_update_object( ss->totfaces = me->totpoly; ss->vert_positions = BKE_mesh_vert_positions_for_write(me); ss->polys = me->polys().data(); - ss->mloop = me->loops().data(); + ss->corner_verts = me->corner_verts().data(); ss->multires.active = false; ss->multires.modifier = nullptr; ss->multires.level = 0; @@ -1766,7 +1766,7 @@ static void sculpt_update_object( BKE_mesh_vert_poly_map_create(&ss->pmap, &ss->pmap_mem, me->polys().data(), - me->loops().data(), + me->corner_verts().data(), me->totvert, me->totpoly, me->totloop); @@ -1986,7 +1986,7 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, { Mesh *me = static_cast(ob->data); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); int ret = 0; const float *paint_mask = static_cast( @@ -2020,22 +2020,22 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, /* mask center */ for (j = 0; j < poly.totloop; j++) { - const MLoop *l = &loops[poly.loopstart + j]; - avg += paint_mask[l->v]; + const int vert = corner_verts[poly.loopstart + j]; + avg += paint_mask[vert]; } avg /= float(poly.totloop); /* fill in multires mask corner */ for (j = 0; j < poly.totloop; j++) { GridPaintMask *gpm = &gmask[poly.loopstart + j]; - const MLoop *l = &loops[poly.loopstart + j]; - const MLoop *prev = ME_POLY_LOOP_PREV(loops, &poly, j); - const MLoop *next = ME_POLY_LOOP_NEXT(loops, &poly, j); + const int vert = corner_verts[poly.loopstart + j]; + const int prev = ME_POLY_LOOP_PREV(&poly, j); + const int next = ME_POLY_LOOP_NEXT(&poly, j); gpm->data[0] = avg; - gpm->data[1] = (paint_mask[l->v] + paint_mask[next->v]) * 0.5f; - gpm->data[2] = (paint_mask[l->v] + paint_mask[prev->v]) * 0.5f; - gpm->data[3] = paint_mask[l->v]; + gpm->data[1] = (paint_mask[vert] + paint_mask[corner_verts[next]]) * 0.5f; + gpm->data[2] = (paint_mask[vert] + paint_mask[corner_verts[prev]]) * 0.5f; + gpm->data[3] = paint_mask[vert]; } } } @@ -2183,17 +2183,17 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool MutableSpan positions = me->vert_positions_for_write(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); MLoopTri *looptri = static_cast( MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__)); - blender::bke::mesh::looptris_calc(positions, polys, loops, {looptri, looptris_num}); + blender::bke::mesh::looptris_calc(positions, polys, corner_verts, {looptri, looptris_num}); BKE_pbvh_build_mesh(pbvh, me, polys.data(), - loops.data(), + corner_verts.data(), reinterpret_cast(positions.data()), me->totvert, &me->vdata, diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 0db48119969..29a34c291ba 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -336,7 +336,7 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]]; for (int j = 0; j < 3; j++) { face_vert_indices[i][j] = map_insert_vert( - pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->mloop[lt->tri[j]].v); + pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[lt->tri[j]]); } if (has_visible == false) { @@ -688,7 +688,8 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->face_sets_color_default = pbvh->face_sets_color_default; args->face_sets_color_seed = pbvh->face_sets_color_seed; args->vert_positions = pbvh->vert_positions; - args->mloop = pbvh->mloop; + args->corner_verts = {pbvh->corner_verts, pbvh->mesh->totloop}; + args->corner_edges = pbvh->mesh ? pbvh->mesh->corner_edges() : blender::Span(); args->polys = pbvh->polys; args->mlooptri = pbvh->looptri; @@ -823,7 +824,7 @@ static void pbvh_validate_node_prims(PBVH *pbvh) void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh, const MPoly *polys, - const MLoop *mloop, + const int *corner_verts, float (*vert_positions)[3], int totvert, CustomData *vdata, @@ -842,7 +843,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly)); pbvh->material_indices = static_cast( CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, "material_index")); - pbvh->mloop = mloop; + pbvh->corner_verts = corner_verts; pbvh->looptri = looptri; pbvh->vert_positions = vert_positions; /* Make sure cached normals start out calculated. */ @@ -884,7 +885,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, BB_reset((BB *)bbc); for (int j = 0; j < sides; j++) { - BB_expand((BB *)bbc, vert_positions[pbvh->mloop[lt->tri[j]].v]); + BB_expand((BB *)bbc, vert_positions[pbvh->corner_verts[lt->tri[j]]]); } BBC_update_centroid(bbc); @@ -955,7 +956,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh, pbvh->pdata = &me->pdata; pbvh->polys = me->polys().data(); - pbvh->mloop = me->loops().data(); + pbvh->corner_verts = me->corner_verts().data(); /* We also need the base mesh for PBVH draw. */ pbvh->mesh = me; @@ -1417,10 +1418,10 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata, for (int i = 0; i < totface; i++) { const MLoopTri *lt = &pbvh->looptri[faces[i]]; - const uint vtri[3] = { - pbvh->mloop[lt->tri[0]].v, - pbvh->mloop[lt->tri[1]].v, - pbvh->mloop[lt->tri[2]].v, + const int vtri[3] = { + pbvh->corner_verts[lt->tri[0]], + pbvh->corner_verts[lt->tri[1]], + pbvh->corner_verts[lt->tri[2]], }; const int sides = 3; @@ -1429,7 +1430,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata, const MPoly &poly = pbvh->polys[lt->poly]; fn = blender::bke::mesh::poly_normal_calc( {reinterpret_cast(pbvh->vert_positions), pbvh->totvert}, - {&pbvh->mloop[poly.loopstart], poly.totloop}); + {&pbvh->corner_verts[poly.loopstart], poly.totloop}); mpoly_prev = lt->poly; } @@ -2206,7 +2207,7 @@ void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, PBVHVertRef vertex) void BKE_pbvh_node_get_loops(PBVH *pbvh, PBVHNode *node, const int **r_loop_indices, - const MLoop **r_loops) + const int **r_corner_verts) { BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); @@ -2214,8 +2215,8 @@ void BKE_pbvh_node_get_loops(PBVH *pbvh, *r_loop_indices = node->loop_indices; } - if (r_loops) { - *r_loops = pbvh->mloop; + if (r_corner_verts) { + *r_corner_verts = pbvh->corner_verts; } } @@ -2548,7 +2549,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, float *r_face_normal) { const float(*positions)[3] = pbvh->vert_positions; - const MLoop *mloop = pbvh->mloop; + const int *corner_verts = pbvh->corner_verts; const int *faces = node->prim_indices; int totface = node->totprim; bool hit = false; @@ -2571,9 +2572,9 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, } else { /* intersect with current coordinates */ - co[0] = positions[mloop[lt->tri[0]].v]; - co[1] = positions[mloop[lt->tri[1]].v]; - co[2] = positions[mloop[lt->tri[2]].v]; + co[0] = positions[corner_verts[lt->tri[0]]]; + co[1] = positions[corner_verts[lt->tri[1]]]; + co[2] = positions[corner_verts[lt->tri[2]]]; } if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) { @@ -2593,7 +2594,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, if (j == 0 || len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) { copy_v3_v3(nearest_vertex_co, co[j]); - r_active_vertex->i = mloop[lt->tri[j]].v; + r_active_vertex->i = corner_verts[lt->tri[j]]; *r_active_face_index = lt->poly; } } @@ -2858,7 +2859,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, float *dist_sq) { const float(*positions)[3] = pbvh->vert_positions; - const MLoop *mloop = pbvh->mloop; + const int *corner_verts = pbvh->corner_verts; const int *faces = node->prim_indices; int i, totface = node->totprim; bool hit = false; @@ -2885,9 +2886,9 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, /* intersect with current coordinates */ hit |= ray_face_nearest_tri(ray_start, ray_normal, - positions[mloop[lt->tri[0]].v], - positions[mloop[lt->tri[1]].v], - positions[mloop[lt->tri[2]].v], + positions[corner_verts[lt->tri[0]]], + positions[corner_verts[lt->tri[1]]], + positions[corner_verts[lt->tri[2]]], depth, dist_sq); } @@ -3740,16 +3741,16 @@ static void pbvh_face_iter_step(PBVHFaceIter *fd, bool do_step) pbvh_face_iter_verts_reserve(fd, poly.totloop); - const MLoop *ml = fd->mloop_ + poly.loopstart; + const int *poly_verts = &fd->corner_verts_[poly.loopstart]; const int grid_area = fd->subdiv_key_.grid_area; - for (int i = 0; i < poly.totloop; i++, ml++) { + for (int i = 0; i < poly.totloop; i++) { if (fd->pbvh_type_ == PBVH_GRIDS) { /* Grid corners. */ fd->verts[i].i = (poly.loopstart + i) * grid_area + grid_area - 1; } else { - fd->verts[i].i = ml->v; + fd->verts[i].i = poly_verts[i]; } } break; @@ -3778,7 +3779,7 @@ void BKE_pbvh_face_iter_init(PBVH *pbvh, PBVHNode *node, PBVHFaceIter *fd) ATTR_FALLTHROUGH; case PBVH_FACES: fd->polys_ = pbvh->polys; - fd->mloop_ = pbvh->mloop; + fd->corner_verts_ = pbvh->corner_verts; fd->looptri_ = pbvh->looptri; fd->hide_poly_ = pbvh->hide_poly; fd->face_sets_ = pbvh->face_sets; diff --git a/source/blender/blenkernel/intern/pbvh_colors.cc b/source/blender/blenkernel/intern/pbvh_colors.cc index 73a32dea777..507d3ed9315 100644 --- a/source/blender/blenkernel/intern/pbvh_colors.cc +++ b/source/blender/blenkernel/intern/pbvh_colors.cc @@ -97,12 +97,12 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_ const MPoly &poly = pbvh.polys[i_poly]; Span colors{static_cast(pbvh.color_layer->data) + poly.loopstart, poly.totloop}; - Span loops{pbvh.mloop + poly.loopstart, poly.totloop}; + Span poly_verts{pbvh.corner_verts + poly.loopstart, poly.totloop}; - for (const int i_loop : IndexRange(poly.totloop)) { - if (loops[i_loop].v == index) { + for (const int i : poly_verts.index_range()) { + if (poly_verts[i] == index) { float temp[4]; - to_float(colors[i_loop], temp); + to_float(colors[i], temp); add_v4_v4(r_color, temp); count++; @@ -131,11 +131,11 @@ static void pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float co const MPoly &poly = pbvh.polys[i_poly]; MutableSpan colors{static_cast(pbvh.color_layer->data) + poly.loopstart, poly.totloop}; - Span loops{pbvh.mloop + poly.loopstart, poly.totloop}; + Span poly_verts{pbvh.corner_verts + poly.loopstart, poly.totloop}; - for (const int i_loop : IndexRange(poly.totloop)) { - if (loops[i_loop].v == index) { - from_float(color, colors[i_loop]); + for (const int i : poly_verts.index_range()) { + if (poly_verts[i] == index) { + from_float(color, colors[i]); } } } diff --git a/source/blender/blenkernel/intern/pbvh_intern.hh b/source/blender/blenkernel/intern/pbvh_intern.hh index cf051e20540..0936c333c48 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.hh +++ b/source/blender/blenkernel/intern/pbvh_intern.hh @@ -7,7 +7,6 @@ */ struct PBVHGPUFormat; -struct MLoop; struct MLoopTri; struct MPoly; struct MeshElemMap; @@ -71,7 +70,7 @@ struct PBVHNode { const int *vert_indices; unsigned int uniq_verts, face_verts; - /* Array of indices into the Mesh's MLoop array. + /* Array of indices into the Mesh's corner array. * PBVH_FACES only. */ int *loop_indices; @@ -161,7 +160,7 @@ struct PBVH { bool *hide_poly; /** Material indices. Only valid for polygon meshes. */ const int *material_indices; - const MLoop *mloop; + const int *corner_verts; const MLoopTri *looptri; CustomData *vdata; CustomData *ldata; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 0a3f485610f..4aaa4d96a87 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -409,9 +409,9 @@ static void update_geom_primitives(PBVH &pbvh, const uv_islands::MeshData &mesh_ PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh); pbvh_data.clear_data(); for (const MLoopTri &looptri : mesh_data.looptris) { - pbvh_data.geom_primitives.append(int3(mesh_data.loops[looptri.tri[0]].v, - mesh_data.loops[looptri.tri[1]].v, - mesh_data.loops[looptri.tri[2]].v)); + pbvh_data.geom_primitives.append(int3(mesh_data.corner_verts[looptri.tri[0]], + mesh_data.corner_verts[looptri.tri[1]], + mesh_data.corner_verts[looptri.tri[2]])); } } @@ -672,7 +672,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image uv_islands::MeshData mesh_data( {pbvh->looptri, pbvh->totprim}, - {pbvh->mloop, mesh->totloop}, + {pbvh->corner_verts, mesh->totloop}, uv_map, {static_cast(static_cast(pbvh->vert_positions)), pbvh->totvert}); uv_islands::UVIslands islands(mesh_data); diff --git a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc index b09a192ec8b..214b74f060a 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc @@ -157,9 +157,9 @@ class NonManifoldUVEdges : public Vector> { int vertex_i) { for (int i = 0; i < 3; i++) { - int loop_i = loop_tri.tri[i]; - const MLoop &loop = mesh_data.loops[loop_i]; - if (loop.v == vertex_i) { + const int loop_i = loop_tri.tri[i]; + const int vert = mesh_data.corner_verts[loop_i]; + if (vert == vertex_i) { return mesh_data.uv_map[loop_i]; } } diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 511f4cf27d5..649cf39803b 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -38,17 +38,17 @@ static int primitive_get_other_uv_vertex(const MeshData &mesh_data, const int v1, const int v2) { - const Span mesh_loops = mesh_data.loops; + const Span corner_verts = mesh_data.corner_verts; BLI_assert(ELEM(v1, - mesh_loops[looptri.tri[0]].v, - mesh_loops[looptri.tri[1]].v, - mesh_loops[looptri.tri[2]].v)); + corner_verts[looptri.tri[0]], + corner_verts[looptri.tri[1]], + corner_verts[looptri.tri[2]])); BLI_assert(ELEM(v2, - mesh_loops[looptri.tri[0]].v, - mesh_loops[looptri.tri[1]].v, - mesh_loops[looptri.tri[2]].v)); + corner_verts[looptri.tri[0]], + corner_verts[looptri.tri[1]], + corner_verts[looptri.tri[2]])); for (const int loop : looptri.tri) { - const int vert = mesh_loops[loop].v; + const int vert = corner_verts[loop]; if (!ELEM(vert, v1, v2)) { return vert; } @@ -74,7 +74,7 @@ static bool primitive_has_shared_uv_edge(const Span uv_map, static int get_uv_loop(const MeshData &mesh_data, const MLoopTri &looptri, const int vert) { for (const int loop : looptri.tri) { - if (mesh_data.loops[loop].v == vert) { + if (mesh_data.corner_verts[loop] == vert) { return loop; } } @@ -106,8 +106,8 @@ static void mesh_data_init_edges(MeshData &mesh_data) const MLoopTri &tri = mesh_data.looptris[i]; Vector edges; for (int j = 0; j < 3; j++) { - int v1 = mesh_data.loops[tri.tri[j]].v; - int v2 = mesh_data.loops[tri.tri[(j + 1) % 3]].v; + int v1 = mesh_data.corner_verts[tri.tri[j]]; + int v2 = mesh_data.corner_verts[tri.tri[(j + 1) % 3]]; void **edge_index_ptr; int64_t edge_index; @@ -199,11 +199,11 @@ static void mesh_data_init(MeshData &mesh_data) } MeshData::MeshData(const Span looptris, - const Span loops, + const Span corner_verts, const Span uv_map, const Span vert_positions) : looptris(looptris), - loops(loops), + corner_verts(corner_verts), uv_map(uv_map), vert_positions(vert_positions), vert_to_edge_map(vert_positions.size()), @@ -231,7 +231,7 @@ UVVertex::UVVertex() } UVVertex::UVVertex(const MeshData &mesh_data, const int loop) - : vertex(mesh_data.loops[loop].v), uv(mesh_data.uv_map[loop]) + : vertex(mesh_data.corner_verts[loop]), uv(mesh_data.uv_map[loop]) { uv_vertex_init_flags(*this); } @@ -520,18 +520,18 @@ struct FanSegment { flags.found = false; /* Reorder so the first edge starts with the given vertex. */ - if (mesh_data.loops[primitive->tri[1]].v == vertex) { + if (mesh_data.corner_verts[primitive->tri[1]] == vertex) { vert_order[0] = 1; vert_order[1] = 2; vert_order[2] = 0; } - else if (mesh_data.loops[primitive->tri[2]].v == vertex) { + else if (mesh_data.corner_verts[primitive->tri[2]] == vertex) { vert_order[0] = 2; vert_order[1] = 0; vert_order[2] = 1; } else { - BLI_assert(mesh_data.loops[primitive->tri[0]].v == vertex); + BLI_assert(mesh_data.corner_verts[primitive->tri[0]] == vertex); vert_order[0] = 0; vert_order[1] = 1; vert_order[2] = 2; @@ -542,9 +542,9 @@ struct FanSegment { { std::stringstream ss; ss << "# p:" << primitive->poly; - ss << " v1:" << mesh_data.loops[primitive->tri[vert_order[0]]].v; - ss << " v2:" << mesh_data.loops[primitive->tri[vert_order[1]]].v; - ss << " v3:" << mesh_data.loops[primitive->tri[vert_order[2]]].v; + ss << " v1:" << mesh_data.corner_verts[primitive->tri[vert_order[0]]]; + ss << " v2:" << mesh_data.corner_verts[primitive->tri[vert_order[1]]]; + ss << " v3:" << mesh_data.corner_verts[primitive->tri[vert_order[2]]]; ss << " uv1:" << uvs[0]; ss << " uv2:" << uvs[1]; ss << " uv3:" << uvs[2]; @@ -633,9 +633,9 @@ struct Fan { void init_uv_coordinates(const MeshData &mesh_data, UVVertex &uv_vertex) { for (FanSegment &fan_edge : segments) { - int other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[0]]].v; + int other_v = mesh_data.corner_verts[fan_edge.primitive->tri[fan_edge.vert_order[0]]]; if (other_v == uv_vertex.vertex) { - other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[1]]].v; + other_v = mesh_data.corner_verts[fan_edge.primitive->tri[fan_edge.vert_order[1]]]; } for (UVEdge *edge : uv_vertex.uv_edges) { @@ -663,7 +663,7 @@ struct Fan { bool contains_vertex_on_outside(const MeshData &mesh_data, const int vertex_index) const { for (const FanSegment &segment : segments) { - int v2 = mesh_data.loops[segment.primitive->tri[segment.vert_order[1]]].v; + int v2 = mesh_data.corner_verts[segment.primitive->tri[segment.vert_order[1]]]; if (vertex_index == v2) { return true; } @@ -680,8 +680,8 @@ struct Fan { { int current_vert = from_vertex; for (FanSegment *segment : path) { - int v1 = mesh_data.loops[segment->primitive->tri[segment->vert_order[1]]].v; - int v2 = mesh_data.loops[segment->primitive->tri[segment->vert_order[2]]].v; + int v1 = mesh_data.corner_verts[segment->primitive->tri[segment->vert_order[1]]]; + int v2 = mesh_data.corner_verts[segment->primitive->tri[segment->vert_order[2]]]; if (!ELEM(current_vert, v1, v2)) { return false; } @@ -711,7 +711,8 @@ struct Fan { int index = 0; while (true) { FanSegment *segment = edge_order[index]; - int v2 = mesh_data.loops[segment->primitive->tri[segment->vert_order[from_vert_order]]].v; + int v2 = + mesh_data.corner_verts[segment->primitive->tri[segment->vert_order[from_vert_order]]]; if (v2 == from_vertex) { break; } @@ -722,7 +723,7 @@ struct Fan { FanSegment *segment = edge_order[index]; result.append(segment); - int v3 = mesh_data.loops[segment->primitive->tri[segment->vert_order[to_vert_order]]].v; + int v3 = mesh_data.corner_verts[segment->primitive->tri[segment->vert_order[to_vert_order]]]; if (v3 == to_vertex) { break; } @@ -817,12 +818,12 @@ static void add_uv_primitive_shared_uv_edge(const MeshData &mesh_data, const int loop_1 = get_uv_loop(mesh_data, looptri, connected_vert_1->vertex); vert_template.uv = connected_vert_1->uv; - vert_template.vertex = mesh_data.loops[loop_1].v; + vert_template.vertex = mesh_data.corner_verts[loop_1]; UVVertex *vert_1_ptr = island.lookup_or_create(vert_template); const int loop_2 = get_uv_loop(mesh_data, looptri, connected_vert_2->vertex); vert_template.uv = connected_vert_2->uv; - vert_template.vertex = mesh_data.loops[loop_2].v; + vert_template.vertex = mesh_data.corner_verts[loop_2]; UVVertex *vert_2_ptr = island.lookup_or_create(vert_template); UVEdge edge_template; @@ -1337,7 +1338,7 @@ const UVVertex *UVPrimitive::get_uv_vertex(const MeshData &mesh_data, const uint8_t mesh_vert_index) const { const MLoopTri &looptri = mesh_data.looptris[this->primitive_i]; - const int mesh_vertex = mesh_data.loops[looptri.tri[mesh_vert_index]].v; + const int mesh_vertex = mesh_data.corner_verts[looptri.tri[mesh_vert_index]]; for (const UVEdge *uv_edge : edges) { for (const UVVertex *uv_vert : uv_edge->vertices) { if (uv_vert->vertex == mesh_vertex) { diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index f38a7c79ea5..4ae3fe34993 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -119,7 +119,7 @@ class TriangleToEdgeMap { struct MeshData { public: const Span looptris; - const Span loops; + const Span corner_verts; const Span uv_map; const Span vert_positions; @@ -140,7 +140,7 @@ struct MeshData { public: explicit MeshData(Span looptris, - Span loops, + Span corner_verts, const Span uv_map, const Span vert_positions); }; diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 3499839e03d..f0d3b09feed 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -406,7 +406,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); tottri = BKE_mesh_runtime_looptri_len(mesh); - const MLoop *mloop = BKE_mesh_loops(mesh); + const int *corner_verts = BKE_mesh_corner_verts(mesh); /* sanity checking - potential case when no data will be present */ if ((totvert == 0) || (tottri == 0)) { @@ -431,9 +431,9 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) const MLoopTri *lt = &looptri[i]; int vtri[3]; - vtri[0] = mloop[lt->tri[0]].v; - vtri[1] = mloop[lt->tri[1]].v; - vtri[2] = mloop[lt->tri[2]].v; + vtri[0] = corner_verts[lt->tri[0]]; + vtri[1] = corner_verts[lt->tri[1]]; + vtri[2] = corner_verts[lt->tri[2]]; RB_trimesh_add_triangle_indices(mdata, i, UNPACK3(vtri)); } @@ -681,10 +681,10 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) totvert = mesh->totvert; lt = BKE_mesh_runtime_looptri_ensure(mesh); tottri = BKE_mesh_runtime_looptri_len(mesh); - const MLoop *mloop = BKE_mesh_loops(mesh); + const int *corner_verts = BKE_mesh_corner_verts(mesh); if (totvert > 0 && tottri > 0) { - BKE_mesh_calc_volume(positions, totvert, lt, tottri, mloop, &volume, NULL); + BKE_mesh_calc_volume(positions, totvert, lt, tottri, corner_verts, &volume, NULL); const float volume_scale = mat4_to_volume_scale(ob->object_to_world); volume *= fabsf(volume_scale); } @@ -755,10 +755,10 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); tottri = BKE_mesh_runtime_looptri_len(mesh); - const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { - BKE_mesh_calc_volume(positions, totvert, looptri, tottri, mloop, NULL, r_center); + BKE_mesh_calc_volume( + positions, totvert, looptri, tottri, BKE_mesh_corner_verts(mesh), NULL, r_center); } } break; diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 1939f09944c..a7a59e8aa8c 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -115,6 +115,7 @@ bool BKE_shrinkwrap_init_tree( data->mesh = mesh; data->polys = mesh->polys().data(); + data->corner_edges = mesh->corner_edges().data(); data->vert_normals = reinterpret_cast(mesh->vert_normals().data()), data->sharp_faces = static_cast( CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_face")); @@ -190,16 +191,18 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata, static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) { + using namespace blender; const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const blender::Span edges = mesh->edges(); - const blender::Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); + const Span corner_edges = mesh->corner_edges(); /* Count faces per edge (up to 2). */ char *edge_mode = static_cast( MEM_calloc_arrayN(size_t(mesh->totedge), sizeof(char), __func__)); for (int i = 0; i < mesh->totloop; i++) { - uint eidx = loops[i].e; + const int eidx = corner_edges[i]; if (edge_mode[eidx] < 2) { edge_mode[eidx]++; @@ -240,7 +243,8 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) for (const int64_t i : looptris.index_range()) { int real_edges[3]; - BKE_mesh_looptri_get_real_edges(edges.data(), loops.data(), &looptris[i], real_edges); + BKE_mesh_looptri_get_real_edges( + edges.data(), corner_verts.data(), corner_edges.data(), &looptris[i], real_edges); for (int j = 0; j < 3; j++) { if (real_edges[j] >= 0 && edge_mode[real_edges[j]]) { @@ -1012,11 +1016,12 @@ static void mesh_looptri_target_project(void *userdata, const ShrinkwrapTreeData *tree = (ShrinkwrapTreeData *)userdata; const BVHTreeFromMesh *data = &tree->treeData; const MLoopTri *lt = &data->looptri[index]; - const MLoop *loop[3] = { - &data->loop[lt->tri[0]], &data->loop[lt->tri[1]], &data->loop[lt->tri[2]]}; - const float *vtri_co[3] = {data->vert_positions[loop[0]->v], - data->vert_positions[loop[1]->v], - data->vert_positions[loop[2]->v]}; + const int tri_verts[3] = {data->corner_verts[lt->tri[0]], + data->corner_verts[lt->tri[1]], + data->corner_verts[lt->tri[2]]}; + const float *vtri_co[3] = {data->vert_positions[tri_verts[0]], + data->vert_positions[tri_verts[1]], + data->vert_positions[tri_verts[2]]}; float raw_hit_co[3], hit_co[3], hit_no[3], dist_sq, vtri_no[3][3]; /* First find the closest point and bail out if it's worse than the current solution. */ @@ -1038,9 +1043,9 @@ static void mesh_looptri_target_project(void *userdata, } /* Decode normals */ - copy_v3_v3(vtri_no[0], tree->vert_normals[loop[0]->v]); - copy_v3_v3(vtri_no[1], tree->vert_normals[loop[1]->v]); - copy_v3_v3(vtri_no[2], tree->vert_normals[loop[2]->v]); + copy_v3_v3(vtri_no[0], tree->vert_normals[tri_verts[0]]); + copy_v3_v3(vtri_no[1], tree->vert_normals[tri_verts[1]]); + copy_v3_v3(vtri_no[2], tree->vert_normals[tri_verts[2]]); /* Solve the equations for the triangle */ if (target_project_solve_point_tri(vtri_co, vtri_no, co, raw_hit_co, dist_sq, hit_co, hit_no)) { @@ -1051,7 +1056,7 @@ static void mesh_looptri_target_project(void *userdata, const BLI_bitmap *is_boundary = tree->boundary->edge_is_boundary; int edges[3]; - BKE_mesh_looptri_get_real_edges(data->edge, data->loop, lt, edges); + BKE_mesh_looptri_get_real_edges(data->edge, data->corner_verts, tree->corner_edges, lt, edges); for (int i = 0; i < 3; i++) { if (edges[i] >= 0 && BLI_BITMAP_TEST(is_boundary, edges[i])) { @@ -1178,9 +1183,9 @@ void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree, /* Interpolate smooth normals if enabled. */ 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}; + const int vert_indices[3] = {treeData->corner_verts[tri->tri[0]], + treeData->corner_verts[tri->tri[1]], + treeData->corner_verts[tri->tri[2]]}; float w[3], no[3][3], tmp_co[3]; /* Custom and auto smooth split normals. */ diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 92beefcbc2d..b563a2a3675 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -588,7 +588,7 @@ static void add_mesh_quad_diag_springs(Object *ob) nofquads = count_mesh_quads(me); if (nofquads) { - const MLoop *mloop = BKE_mesh_loops(me); + const int *corner_verts = BKE_mesh_corner_verts(me); const MPoly *polys = BKE_mesh_polys(me); BodySpring *bs; @@ -602,12 +602,12 @@ static void add_mesh_quad_diag_springs(Object *ob) for (int a = 0; a < me->totpoly; a++) { const MPoly *poly = &polys[a]; if (poly->totloop == 4) { - bs->v1 = mloop[poly->loopstart + 0].v; - bs->v2 = mloop[poly->loopstart + 2].v; + bs->v1 = corner_verts[poly->loopstart + 0]; + bs->v2 = corner_verts[poly->loopstart + 2]; bs->springtype = SB_STIFFQUAD; bs++; - bs->v1 = mloop[poly->loopstart + 1].v; - bs->v2 = mloop[poly->loopstart + 3].v; + bs->v1 = corner_verts[poly->loopstart + 1]; + bs->v2 = corner_verts[poly->loopstart + 3]; bs->springtype = SB_STIFFQUAD; bs++; } @@ -2753,22 +2753,22 @@ static void mesh_faces_to_scratch(Object *ob) int a; const float(*vert_positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); - const MLoop *loops = BKE_mesh_loops(me); + const int *corner_verts = BKE_mesh_corner_verts(me); /* Allocate and copy faces. */ sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop); looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__); BKE_mesh_recalc_looptri( - loops, polys, vert_positions, me->totvert, me->totloop, me->totpoly, looptri); + corner_verts, polys, vert_positions, me->totvert, me->totloop, me->totpoly, looptri); bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface, "SB_body_Faces"); for (a = 0; a < sb->scratch->totface; a++, lt++, bodyface++) { - bodyface->v1 = loops[lt->tri[0]].v; - bodyface->v2 = loops[lt->tri[1]].v; - bodyface->v3 = loops[lt->tri[2]].v; + bodyface->v1 = corner_verts[lt->tri[0]]; + bodyface->v2 = corner_verts[lt->tri[1]]; + bodyface->v3 = corner_verts[lt->tri[2]]; zero_v3(bodyface->ext_force); bodyface->ext_force[0] = bodyface->ext_force[1] = bodyface->ext_force[2] = 0.0f; bodyface->flag = 0; diff --git a/source/blender/blenkernel/intern/subdiv_ccg.cc b/source/blender/blenkernel/intern/subdiv_ccg.cc index a1b779d07e6..d1e2d841c8a 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.cc +++ b/source/blender/blenkernel/intern/subdiv_ccg.cc @@ -1986,7 +1986,7 @@ const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg) static void adjacet_vertices_index_from_adjacent_edge(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord, - const MLoop *mloop, + const int *corner_verts, const MPoly *polys, int *r_v1, int *r_v2) @@ -1994,22 +1994,22 @@ static void adjacet_vertices_index_from_adjacent_edge(const SubdivCCG *subdiv_cc const int grid_size_1 = subdiv_ccg->grid_size - 1; const int poly_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, coord->grid_index); const MPoly &poly = polys[poly_index]; - *r_v1 = mloop[coord->grid_index].v; + *r_v1 = corner_verts[coord->grid_index]; - const int corner = poly_find_loop_from_vert(&poly, &mloop[poly.loopstart], *r_v1); + const int corner = poly_find_loop_from_vert(&poly, &corner_verts[poly.loopstart], *r_v1); if (coord->x == grid_size_1) { - const MLoop *next = ME_POLY_LOOP_NEXT(mloop, &poly, corner); - *r_v2 = next->v; + const int next = ME_POLY_LOOP_NEXT(&poly, corner); + *r_v2 = corner_verts[next]; } if (coord->y == grid_size_1) { - const MLoop *prev = ME_POLY_LOOP_PREV(mloop, &poly, corner); - *r_v2 = prev->v; + const int prev = ME_POLY_LOOP_PREV(&poly, corner); + *r_v2 = corner_verts[prev]; } } SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord, - const MLoop *mloop, + const int *corner_verts, const MPoly *polys, int *r_v1, int *r_v2) @@ -2023,18 +2023,19 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi } if (coord->x == grid_size_1 && coord->y == grid_size_1) { /* Grid corner adjacent to a coarse mesh vertex. */ - *r_v1 = *r_v2 = mloop[coord->grid_index].v; + *r_v1 = *r_v2 = corner_verts[coord->grid_index]; return SUBDIV_CCG_ADJACENT_VERTEX; } /* Grid corner adjacent to the middle of a coarse mesh edge. */ - adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, mloop, polys, r_v1, r_v2); + adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, corner_verts, polys, r_v1, r_v2); return SUBDIV_CCG_ADJACENT_EDGE; } if (is_boundary_grid_coord(subdiv_ccg, coord)) { if (!is_inner_edge_grid_coordinate(subdiv_ccg, coord)) { /* Grid boundary adjacent to a coarse mesh edge. */ - adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, mloop, polys, r_v1, r_v2); + adjacet_vertices_index_from_adjacent_edge( + subdiv_ccg, coord, corner_verts, polys, r_v1, r_v2); return SUBDIV_CCG_ADJACENT_EDGE; } } diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.cc b/source/blender/blenkernel/intern/subdiv_converter_mesh.cc index b28fe42b1c5..a36f7cf021b 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.cc @@ -37,7 +37,8 @@ struct ConverterStorage { const float (*vert_positions)[3]; blender::Span edges; blender::Span polys; - blender::Span loops; + blender::Span corner_verts; + blender::Span corner_edges; /* CustomData layer for vertex sharpnesses. */ const float *cd_vertex_crease; @@ -135,10 +136,9 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter, { ConverterStorage *storage = static_cast(converter->user_data); const MPoly &poly = storage->polys[manifold_face_index]; - const blender::Span loops = storage->loops; - for (int corner = 0; corner < poly.totloop; corner++) { - manifold_face_vertices[corner] = - storage->manifold_vertex_index[loops[poly.loopstart + corner].v]; + for (int i = 0; i < poly.totloop; i++) { + const int vert = storage->corner_verts[poly.loopstart + i]; + manifold_face_vertices[i] = storage->manifold_vertex_index[vert]; } } @@ -216,7 +216,7 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la storage->polys.data(), (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"), (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".select_poly"), - storage->loops.data(), + storage->corner_verts.data(), mloopuv, num_poly, num_vert, @@ -355,17 +355,18 @@ static void initialize_manifold_indices(ConverterStorage *storage) { const Mesh *mesh = storage->mesh; const blender::Span edges = storage->edges; - const blender::Span loops = storage->loops; const blender::Span polys = storage->polys; + const blender::Span corner_verts = storage->corner_verts; + const blender::Span corner_edges = storage->corner_edges; /* Set bits of elements which are not loose. */ BLI_bitmap *vert_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map"); BLI_bitmap *edge_used_map = BLI_BITMAP_NEW(mesh->totedge, "edge used map"); for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { const MPoly &poly = polys[poly_index]; - for (int corner = 0; corner < poly.totloop; corner++) { - const MLoop *loop = &loops[poly.loopstart + corner]; - BLI_BITMAP_ENABLE(vert_used_map, loop->v); - BLI_BITMAP_ENABLE(edge_used_map, loop->e); + for (int i = 0; i < poly.totloop; i++) { + const int corner = poly.loopstart + i; + BLI_BITMAP_ENABLE(vert_used_map, corner_verts[corner]); + BLI_BITMAP_ENABLE(edge_used_map, corner_edges[corner]); } } initialize_manifold_index_array(vert_used_map, @@ -403,7 +404,8 @@ static void init_user_data(OpenSubdiv_Converter *converter, user_data->vert_positions = BKE_mesh_vert_positions(mesh); user_data->edges = mesh->edges(); user_data->polys = mesh->polys(); - user_data->loops = mesh->loops(); + user_data->corner_verts = mesh->corner_verts(); + user_data->corner_edges = mesh->corner_edges(); user_data->cd_vertex_crease = static_cast( CustomData_get_layer(&mesh->vdata, CD_CREASE)); user_data->cd_edge_crease = static_cast( diff --git a/source/blender/blenkernel/intern/subdiv_eval.cc b/source/blender/blenkernel/intern/subdiv_eval.cc index 8dac6807872..3387b23bd22 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.cc +++ b/source/blender/blenkernel/intern/subdiv_eval.cc @@ -83,7 +83,7 @@ static void set_coarse_positions(Subdiv *subdiv, { const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); /* Mark vertices which needs new coordinates. */ /* TODO(sergey): This is annoying to calculate this on every update, * maybe it's better to cache this mapping. Or make it possible to have @@ -91,9 +91,8 @@ static void set_coarse_positions(Subdiv *subdiv, BLI_bitmap *vertex_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map"); for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { const MPoly &poly = polys[poly_index]; - for (int corner = 0; corner < poly.totloop; corner++) { - const MLoop *loop = &loops[poly.loopstart + corner]; - BLI_BITMAP_ENABLE(vertex_used_map, loop->v); + for (int i = 0; i < poly.totloop; i++) { + BLI_BITMAP_ENABLE(vertex_used_map, corner_verts[poly.loopstart + i]); } } /* Use a temporary buffer so we do not upload vertices one at a time to the GPU. */ diff --git a/source/blender/blenkernel/intern/subdiv_foreach.cc b/source/blender/blenkernel/intern/subdiv_foreach.cc index 8231f0e7ca0..bc73b4fa061 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.cc +++ b/source/blender/blenkernel/intern/subdiv_foreach.cc @@ -69,7 +69,8 @@ struct SubdivForeachTaskContext { const Mesh *coarse_mesh; blender::Span coarse_edges; blender::Span coarse_polys; - blender::Span coarse_loops; + blender::Span coarse_corner_verts; + blender::Span coarse_corner_edges; const SubdivToMeshSettings *settings; /* Callbacks. */ const SubdivForeachContext *foreach_context; @@ -290,12 +291,12 @@ static void subdiv_foreach_corner_vertices_regular_do( const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data(); const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; if (check_usage && - BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) { + BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_vert)) { continue; } - const int coarse_vertex_index = coarse_loop->v; + const int coarse_vertex_index = coarse_vert; const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index; const float u = weights[corner][0]; const float v = weights[corner][1]; @@ -329,12 +330,12 @@ static void subdiv_foreach_corner_vertices_special_do( const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data(); int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; if (check_usage && - BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) { + BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_vert)) { continue; } - const int coarse_vertex_index = coarse_loop->v; + const int coarse_vertex_index = coarse_vert; const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index; vertex_corner(ctx->foreach_context, tls, @@ -416,14 +417,14 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data(); const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; - const int coarse_edge_index = coarse_loop->e; + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; + const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; if (check_usage && BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) { continue; } const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + const bool flip = (coarse_edge->v2 == coarse_vert); int subdiv_vertex_index = ctx->vertices_edge_offset + coarse_edge_index * num_subdiv_vertices_per_coarse_edge; for (int vertex_index = 0; vertex_index < num_subdiv_vertices_per_coarse_edge; @@ -479,14 +480,14 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct const int ptex_face_start_index = ctx->face_ptex_offset[coarse_poly_index]; int ptex_face_index = ptex_face_start_index; for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; - const int coarse_edge_index = coarse_loop->e; + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; + const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; if (check_usage && BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) { continue; } const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + const bool flip = (coarse_edge->v2 == coarse_vert); int subdiv_vertex_index = ctx->vertices_edge_offset + coarse_edge_index * num_subdiv_vertices_per_coarse_edge; int vertex_delta = 1; @@ -778,11 +779,12 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c } /* Connect inner part of patch to boundary. */ for (int corner = 0; corner < coarse_poly->totloop; corner++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; - const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; + const int coarse_vert_index = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; + const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; + const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; const int start_edge_vertex = ctx->vertices_edge_offset + - coarse_loop->e * num_subdiv_vertices_per_coarse_edge; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + coarse_edge_index * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_vert_index); int side_start_index = start_vertex_index; int side_stride = 0; /* Calculate starting vertex of corresponding inner part of ptex. */ @@ -886,15 +888,16 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c } } /* Connect inner path of patch to boundary. */ - const MLoop *prev_coarse_loop = - &ctx->coarse_loops[coarse_poly->loopstart + coarse_poly->totloop - 1]; + int prev_corner = coarse_poly->totloop - 1; for (int corner = 0; corner < coarse_poly->totloop; corner++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; + const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; + const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly->loopstart + prev_corner]; { - const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; + const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i]; const int start_edge_vertex = ctx->vertices_edge_offset + - coarse_loop->e * num_subdiv_vertices_per_coarse_edge; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + coarse_edge_i * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_vert); int side_start_index; if (ptex_face_resolution >= 3) { side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner; @@ -911,10 +914,10 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c } } if (ptex_face_resolution >= 3) { - const MEdge *coarse_edge = &ctx->coarse_edges[prev_coarse_loop->e]; + const MEdge *coarse_edge = &ctx->coarse_edges[coarse_prev_edge]; const int start_edge_vertex = ctx->vertices_edge_offset + - prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_vert); int side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner; for (int i = 0; i < ptex_face_resolution - 2; i++, subdiv_edge_index++) { const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : @@ -924,7 +927,7 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); } } - prev_coarse_loop = coarse_loop; + prev_corner = corner; } } @@ -1134,30 +1137,35 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx, } } /* Loops for faces connecting inner ptex part with boundary. */ - const MLoop *prev_coarse_loop = - &ctx->coarse_loops[coarse_poly->loopstart + coarse_poly->totloop - 1]; + int prev_corner_index = coarse_poly->totloop - 1; for (int corner = 0; corner < coarse_poly->totloop; corner++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; - const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; - const MEdge *prev_coarse_edge = &ctx->coarse_edges[prev_coarse_loop->e]; + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; + const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; + const int coase_prev_vert = + ctx->coarse_corner_verts[coarse_poly->loopstart + prev_corner_index]; + const int coarse_prev_edge = + ctx->coarse_corner_edges[coarse_poly->loopstart + prev_corner_index]; + + const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i]; + const MEdge *prev_coarse_edge = &ctx->coarse_edges[coarse_prev_edge]; const int start_edge_vertex = ctx->vertices_edge_offset + - coarse_loop->e * num_subdiv_vertices_per_coarse_edge; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + coarse_edge_i * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_vert); int side_start_index = start_vertex_index; int side_stride = 0; - int v0 = ctx->vertices_corner_offset + coarse_loop->v; + int v0 = ctx->vertices_corner_offset + coarse_vert; int v3, e3; int e2_offset, e2_stride; float u, v, delta_u, delta_v; - if (prev_coarse_loop->v == prev_coarse_edge->v1) { - v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + + if (coase_prev_vert == prev_coarse_edge->v1) { + v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge + num_subdiv_vertices_per_coarse_edge - 1; - e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + + e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - 1; } else { - v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; - e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge; + v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; + e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge; } /* Calculate starting vertex of corresponding inner part of ptex. */ if (corner == 0) { @@ -1214,11 +1222,11 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx, const int v2 = side_start_index + side_stride * i; int e0; if (flip) { - e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + + e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - i - 1; } else { - e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i; + e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + i; } int e1 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) + corner * num_subdiv_vertices_per_coarse_edge + i; @@ -1259,7 +1267,7 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx, v3 = v2; e3 = e1; } - prev_coarse_loop = coarse_loop; + prev_corner_index = corner; } } @@ -1436,30 +1444,32 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, } } /* Loops for faces connecting inner ptex part with boundary. */ - const MLoop *prev_coarse_loop = - &ctx->coarse_loops[coarse_poly->loopstart + coarse_poly->totloop - 1]; for (int prev_corner = coarse_poly->totloop - 1, corner = 0; corner < coarse_poly->totloop; prev_corner = corner, corner++) { - const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; - const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; - const MEdge *prev_coarse_edge = &ctx->coarse_edges[prev_coarse_loop->e]; - const bool flip = (coarse_edge->v2 == coarse_loop->v); + const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; + const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; + const int coase_prev_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + prev_corner]; + const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly->loopstart + prev_corner]; + + const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i]; + const MEdge *prev_coarse_edge = &ctx->coarse_edges[coarse_prev_edge]; + const bool flip = (coarse_edge->v2 == coarse_vert); const int start_edge_vertex = ctx->vertices_edge_offset + - coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + coarse_edge_i * num_subdiv_vertices_per_coarse_edge; const int corner_vertex_index = start_vertex_index + corner * num_inner_vertices_per_ptex; const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face; /* Create loops for polygons along U axis. */ - int v0 = ctx->vertices_corner_offset + coarse_loop->v; + int v0 = ctx->vertices_corner_offset + coarse_vert; int v3, e3; - if (prev_coarse_loop->v == prev_coarse_edge->v1) { - v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + + if (coase_prev_vert == prev_coarse_edge->v1) { + v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge + num_subdiv_vertices_per_coarse_edge - 1; - e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + + e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - 1; } else { - v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; - e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge; + v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; + e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge; } for (int i = 0; i <= ptex_face_inner_resolution; i++, subdiv_loop_index += 4) { int v1; @@ -1478,11 +1488,11 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, } int e0; if (flip) { - e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + + e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - i - 1; } else { - e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i; + e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + i; } int e1 = start_edge_index + corner * (2 * ptex_face_inner_resolution + 1); if (ptex_face_resolution >= 3) { @@ -1529,14 +1539,14 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, e3 = e1; } /* Create loops for polygons along V axis. */ - const bool flip_prev = (prev_coarse_edge->v2 == coarse_loop->v); + const bool flip_prev = (prev_coarse_edge->v2 == coarse_vert); v0 = corner_vertex_index; - if (prev_coarse_loop->v == prev_coarse_edge->v1) { - v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + + if (coase_prev_vert == prev_coarse_edge->v1) { + v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge + num_subdiv_vertices_per_coarse_edge - 1; } else { - v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; } e3 = start_edge_index + coarse_poly->totloop * (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) + @@ -1563,12 +1573,12 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, int v2 = flip_prev ? v3 - 1 : v3 + 1; int e2; if (flip_prev) { - e2 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + + e2 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - 2 - i; } else { - e2 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + - 1 + i; + e2 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + 1 + + i; } const float u = 0.0f; const float v = du * (i + 1); @@ -1595,7 +1605,6 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, v3 = v2; e3 = e1; } - prev_coarse_loop = coarse_loop; } } @@ -1724,9 +1733,10 @@ static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly &coarse_poly = ctx->coarse_polys[poly_index]; for (int corner = 0; corner < coarse_poly.totloop; corner++) { - const MLoop *loop = &ctx->coarse_loops[coarse_poly.loopstart + corner]; - BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, loop->e); - BLI_BITMAP_ENABLE(ctx->coarse_vertices_used_map, loop->v); + BLI_BITMAP_ENABLE(ctx->coarse_vertices_used_map, + ctx->coarse_corner_verts[coarse_poly.loopstart + corner]); + BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, + ctx->coarse_corner_verts[coarse_poly.loopstart + corner]); } } } @@ -1797,7 +1807,8 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv, ctx.coarse_mesh = coarse_mesh; ctx.coarse_edges = coarse_mesh->edges(); ctx.coarse_polys = coarse_mesh->polys(); - ctx.coarse_loops = coarse_mesh->loops(); + ctx.coarse_corner_verts = coarse_mesh->corner_verts(); + ctx.coarse_corner_edges = coarse_mesh->corner_edges(); ctx.settings = mesh_settings; ctx.foreach_context = context; subdiv_foreach_ctx_init(subdiv, &ctx); diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index 5db8b815b33..4945a9180dc 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -32,6 +32,7 @@ using blender::float2; using blender::float3; +using blender::MutableSpan; using blender::Span; /* -------------------------------------------------------------------- */ @@ -44,14 +45,15 @@ struct SubdivMeshContext { const float (*coarse_positions)[3]; blender::Span coarse_edges; blender::Span coarse_polys; - blender::Span coarse_loops; + blender::Span coarse_corner_verts; Subdiv *subdiv; Mesh *subdiv_mesh; blender::MutableSpan subdiv_positions; blender::MutableSpan subdiv_edges; blender::MutableSpan subdiv_polys; - blender::MutableSpan subdiv_loops; + blender::MutableSpan subdiv_corner_verts; + blender::MutableSpan subdiv_corner_edges; /* Cached custom data arrays for faster access. */ int *vert_origindex; @@ -95,7 +97,8 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) ctx->subdiv_positions = subdiv_mesh->vert_positions_for_write(); ctx->subdiv_edges = subdiv_mesh->edges_for_write(); ctx->subdiv_polys = subdiv_mesh->polys_for_write(); - ctx->subdiv_loops = subdiv_mesh->loops_for_write(); + ctx->subdiv_corner_verts = subdiv_mesh->corner_verts_for_write(); + ctx->subdiv_corner_edges = subdiv_mesh->corner_edges_for_write(); /* Pointers to original indices layers. */ ctx->vert_origindex = static_cast( CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORIGINDEX, subdiv_mesh->totvert)); @@ -138,16 +141,15 @@ static void subdiv_mesh_context_free(SubdivMeshContext *ctx) struct LoopsOfPtex { /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */ - const MLoop *first_loop; + int first_loop; /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */ - const MLoop *last_loop; + int last_loop; /* For quad coarse faces only. */ - const MLoop *second_loop; - const MLoop *third_loop; + int second_loop; + int third_loop; }; -static void loops_of_ptex_get(const SubdivMeshContext *ctx, - LoopsOfPtex *loops_of_ptex, +static void loops_of_ptex_get(LoopsOfPtex *loops_of_ptex, const MPoly *coarse_poly, const int ptex_of_poly_index) { @@ -159,15 +161,15 @@ static void loops_of_ptex_get(const SubdivMeshContext *ctx, const int last_ptex_loop_index = coarse_poly->loopstart + (ptex_of_poly_index + coarse_poly->totloop - 1) % coarse_poly->totloop; - loops_of_ptex->first_loop = &ctx->coarse_loops[first_ptex_loop_index]; - loops_of_ptex->last_loop = &ctx->coarse_loops[last_ptex_loop_index]; + loops_of_ptex->first_loop = first_ptex_loop_index; + loops_of_ptex->last_loop = last_ptex_loop_index; if (coarse_poly->totloop == 4) { loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1; loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2; } else { - loops_of_ptex->second_loop = nullptr; - loops_of_ptex->third_loop = nullptr; + loops_of_ptex->second_loop = -1; + loops_of_ptex->third_loop = -1; } } @@ -206,13 +208,12 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx, const MPoly &coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const blender::Span coarse_loops = ctx->coarse_loops; if (coarse_poly.totloop == 4) { vertex_interpolation->vertex_data = &coarse_mesh->vdata; - vertex_interpolation->vertex_indices[0] = coarse_loops[coarse_poly.loopstart + 0].v; - vertex_interpolation->vertex_indices[1] = coarse_loops[coarse_poly.loopstart + 1].v; - vertex_interpolation->vertex_indices[2] = coarse_loops[coarse_poly.loopstart + 2].v; - vertex_interpolation->vertex_indices[3] = coarse_loops[coarse_poly.loopstart + 3].v; + vertex_interpolation->vertex_indices[0] = ctx->coarse_corner_verts[coarse_poly.loopstart + 0]; + vertex_interpolation->vertex_indices[1] = ctx->coarse_corner_verts[coarse_poly.loopstart + 1]; + vertex_interpolation->vertex_indices[2] = ctx->coarse_corner_verts[coarse_poly.loopstart + 2]; + vertex_interpolation->vertex_indices[3] = ctx->coarse_corner_verts[coarse_poly.loopstart + 3]; vertex_interpolation->vertex_data_storage_allocated = false; } else { @@ -236,7 +237,7 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx, blender::Array indices(coarse_poly.totloop); for (int i = 0; i < coarse_poly.totloop; i++) { weights[i] = weight; - indices[i] = coarse_loops[coarse_poly.loopstart + i].v; + indices[i] = ctx->coarse_corner_verts[coarse_poly.loopstart + i]; } CustomData_interp(&coarse_mesh->vdata, &vertex_interpolation->vertex_data_storage, @@ -258,13 +259,12 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, } else { const CustomData *vertex_data = &ctx->coarse_mesh->vdata; - const blender::Span coarse_loops = ctx->coarse_loops; LoopsOfPtex loops_of_ptex; - loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner); + loops_of_ptex_get(&loops_of_ptex, coarse_poly, corner); /* Ptex face corner corresponds to a poly loop with same index. */ CustomData_copy_data(vertex_data, &vertex_interpolation->vertex_data_storage, - coarse_loops[coarse_poly->loopstart + corner].v, + ctx->coarse_corner_verts[coarse_poly->loopstart + corner], 0, 1); /* Interpolate remaining ptex face corners, which hits loops @@ -273,17 +273,15 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, * TODO(sergey): Re-use one of interpolation results from previous * iteration. */ const float weights[2] = {0.5f, 0.5f}; - const int first_loop_index = loops_of_ptex.first_loop - coarse_loops.data(); - const int last_loop_index = loops_of_ptex.last_loop - coarse_loops.data(); + const int first_loop_index = loops_of_ptex.first_loop; + const int last_loop_index = loops_of_ptex.last_loop; const int first_indices[2] = { - int(coarse_loops[first_loop_index].v), - int(coarse_loops[coarse_poly->loopstart + - (first_loop_index - coarse_poly->loopstart + 1) % coarse_poly->totloop] - .v)}; - const int last_indices[2] = { - int(coarse_loops[first_loop_index].v), - int(coarse_loops[last_loop_index].v), - }; + ctx->coarse_corner_verts[first_loop_index], + ctx->coarse_corner_verts[coarse_poly->loopstart + + (first_loop_index - coarse_poly->loopstart + 1) % + coarse_poly->totloop]}; + const int last_indices[2] = {ctx->coarse_corner_verts[first_loop_index], + ctx->coarse_corner_verts[last_loop_index]}; CustomData_interp(vertex_data, &vertex_interpolation->vertex_data_storage, first_indices, @@ -391,9 +389,8 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx, } else { const CustomData *loop_data = &ctx->coarse_mesh->ldata; - const blender::Span coarse_loops = ctx->coarse_loops; LoopsOfPtex loops_of_ptex; - loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner); + loops_of_ptex_get(&loops_of_ptex, coarse_poly, corner); /* Ptex face corner corresponds to a poly loop with same index. */ CustomData_free_elem(&loop_interpolation->loop_data_storage, 0, 1); CustomData_copy_data( @@ -405,14 +402,11 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx, * iteration. */ const float weights[2] = {0.5f, 0.5f}; const int base_loop_index = coarse_poly->loopstart; - const int first_loop_index = loops_of_ptex.first_loop - coarse_loops.data(); + const int first_loop_index = loops_of_ptex.first_loop; const int second_loop_index = base_loop_index + (first_loop_index - base_loop_index + 1) % coarse_poly->totloop; const int first_indices[2] = {first_loop_index, second_loop_index}; - const int last_indices[2] = { - int(loops_of_ptex.last_loop - coarse_loops.data()), - int(loops_of_ptex.first_loop - coarse_loops.data()), - }; + const int last_indices[2] = {loops_of_ptex.last_loop, loops_of_ptex.first_loop}; CustomData_interp( loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, nullptr, 2, 1); CustomData_interp( @@ -828,12 +822,11 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context, * \{ */ static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx, - MLoop *subdiv_loop, + const int subdiv_loop_index, const LoopsForInterpolation *loop_interpolation, const float u, const float v) { - const int subdiv_loop_index = subdiv_loop - ctx->subdiv_loops.data(); const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v}; CustomData_interp(loop_interpolation->loop_data, &ctx->subdiv_mesh->ldata, @@ -846,7 +839,7 @@ static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx, } static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, - MLoop *subdiv_loop, + const int corner_index, const int ptex_face_index, const float u, const float v) @@ -855,10 +848,9 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, return; } Subdiv *subdiv = ctx->subdiv; - const int mloop_index = subdiv_loop - ctx->subdiv_loops.data(); for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { BKE_subdiv_eval_face_varying( - subdiv, layer_index, ptex_face_index, u, v, ctx->uv_layers[layer_index][mloop_index]); + subdiv, layer_index, ptex_face_index, u, v, ctx->uv_layers[layer_index][corner_index]); } } @@ -905,12 +897,11 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context, SubdivMeshContext *ctx = static_cast(foreach_context->user_data); SubdivMeshTLS *tls = static_cast(tls_v); const MPoly &coarse_poly = ctx->coarse_polys[coarse_poly_index]; - MLoop *subdiv_loop = &ctx->subdiv_loops[subdiv_loop_index]; subdiv_mesh_ensure_loop_interpolation(ctx, tls, &coarse_poly, coarse_corner); - subdiv_interpolate_loop_data(ctx, subdiv_loop, &tls->loop_interpolation, u, v); - subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v); - subdiv_loop->v = subdiv_vertex_index; - subdiv_loop->e = subdiv_edge_index; + subdiv_interpolate_loop_data(ctx, subdiv_loop_index, &tls->loop_interpolation, u, v); + subdiv_eval_uv_layer(ctx, subdiv_loop_index, ptex_face_index, u, v); + ctx->subdiv_corner_verts[subdiv_loop_index] = subdiv_vertex_index; + ctx->subdiv_corner_edges[subdiv_loop_index] = subdiv_edge_index; } /** \} */ @@ -1182,7 +1173,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, subdiv_context.coarse_positions = BKE_mesh_vert_positions(coarse_mesh); subdiv_context.coarse_edges = coarse_mesh->edges(); subdiv_context.coarse_polys = coarse_mesh->polys(); - subdiv_context.coarse_loops = coarse_mesh->loops(); + subdiv_context.coarse_corner_verts = coarse_mesh->corner_verts(); subdiv_context.subdiv = subdiv; subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index 3bdf8a27136..43066341ae0 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -228,13 +228,13 @@ static int getFaceIndex( } static void get_face_uv_map_vert( - UvVertMap *vmap, const MPoly *polys, MLoop *ml, int fi, CCGVertHDL *fverts) + UvVertMap *vmap, const MPoly *polys, const int *poly_verts, int fi, CCGVertHDL *fverts) { UvMapVert *v, *nv; int j, nverts = polys[fi].totloop; for (j = 0; j < nverts; j++) { - for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) { + for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, poly_verts[j]); v; v = v->next) { if (v->separate) { nv = v; } @@ -253,7 +253,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, const float (*mloopuv)[2]) { MPoly *polys = dm->getPolyArray(dm); - MLoop *mloop = dm->getLoopArray(dm); + int *corner_verts = dm->getCornerVertArray(dm); int totvert = dm->getNumVerts(dm); int totface = dm->getNumPolys(dm); int i, seam; @@ -270,7 +270,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, * Also, initially intention is to treat merged vertices from mirror modifier as seams. * This fixes a very old regression (2.49 was correct here) */ vmap = BKE_mesh_uv_vert_map_create( - polys, nullptr, nullptr, mloop, mloopuv, totface, totvert, limit, false, true); + polys, nullptr, nullptr, corner_verts, mloopuv, totface, totvert, limit, false, true); if (!vmap) { return 0; } @@ -312,12 +312,11 @@ static int ss_sync_from_uv(CCGSubSurf *ss, int nverts = poly.totloop; int j, j_next; CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i)); - // uint *fv = &poly.v1; - MLoop *ml = mloop + poly.loopstart; + /* uint *fv = &poly.v1; */ fverts.reinitialize(nverts); - get_face_uv_map_vert(vmap, polys, ml, i, fverts.data()); + get_face_uv_map_vert(vmap, &poly, &corner_verts[poly.loopstart], i, fverts.data()); for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) { uint v0 = POINTER_AS_UINT(fverts[j_next]); @@ -338,13 +337,12 @@ static int ss_sync_from_uv(CCGSubSurf *ss, /* create faces */ for (i = 0; i < totface; i++) { const MPoly &poly = polys[i]; - MLoop *ml = &mloop[poly.loopstart]; int nverts = poly.totloop; CCGFace *f; fverts.reinitialize(nverts); - get_face_uv_map_vert(vmap, polys, ml, i, fverts.data()); + get_face_uv_map_vert(vmap, polys, &corner_verts[poly.loopstart], i, fverts.data()); ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts.data(), &f); } @@ -539,7 +537,7 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); MEdge *edges = dm->getEdgeArray(dm); MEdge *edge; - MLoop *mloop = dm->getLoopArray(dm), *ml; + int *corner_verts = dm->getCornerVertArray(dm); MPoly *polys = dm->getPolyArray(dm); int totvert = dm->getNumVerts(dm); int totedge = dm->getNumEdges(dm); @@ -588,9 +586,9 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, fverts.reinitialize(poly.totloop); - ml = mloop + poly.loopstart; - for (j = 0; j < poly.totloop; j++, ml++) { - fverts[j] = POINTER_FROM_UINT(ml->v); + int corner = poly.loopstart; + for (j = 0; j < poly.totloop; j++, corner++) { + fverts[j] = POINTER_FROM_UINT(corner_verts[corner]); } /* This is very bad, means mesh is internally inconsistent. @@ -965,7 +963,8 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *edges) struct CopyFinalLoopArrayData { CCGDerivedMesh *ccgdm; - MLoop *mloop; + int *corner_verts; + int *corner_edges; int grid_size; int *grid_offset; int edge_size; @@ -984,38 +983,39 @@ static void copyFinalLoopArray_task_cb(void *__restrict userdata, CCGFace *f = ccgdm->faceMap[iter].face; const int num_verts = ccgSubSurf_getFaceNumVerts(f); const int grid_index = data->grid_offset[iter]; - const size_t loop_index = 4 * size_t(grid_index) * (grid_size - 1) * (grid_size - 1); - MLoop *ml = &data->mloop[loop_index]; + int *corner_verts = data->corner_verts; + int *corner_edges = data->corner_edges; + + size_t loop_i = 4 * size_t(grid_index) * (grid_size - 1) * (grid_size - 1); for (int S = 0; S < num_verts; S++) { for (int y = 0; y < grid_size - 1; y++) { for (int x = 0; x < grid_size - 1; x++) { - uint v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edge_size, grid_size); - uint v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edge_size, grid_size); - uint v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size); - uint v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size); + const int v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edge_size, grid_size); + const int v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edge_size, grid_size); + const int v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size); + const int v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size); - ml->v = v1; - ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2)); - ml++; + if (corner_verts) { + corner_verts[loop_i + 0] = v1; + corner_verts[loop_i + 1] = v2; + corner_verts[loop_i + 2] = v3; + corner_verts[loop_i + 3] = v4; + } + if (corner_edges) { + corner_edges[loop_i + 0] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2)); + corner_edges[loop_i + 1] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3)); + corner_edges[loop_i + 2] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4)); + corner_edges[loop_i + 3] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1)); + } - ml->v = v2; - ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3)); - ml++; - - ml->v = v3; - ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4)); - ml++; - - ml->v = v4; - ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1)); - ml++; + loop_i += 4; } } } } -static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop) +static void ccgDM_copyFinalCornerVertArray(DerivedMesh *dm, int *r_corner_verts) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGSubSurf *ss = ccgdm->ss; @@ -1040,7 +1040,53 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop) CopyFinalLoopArrayData data; data.ccgdm = ccgdm; - data.mloop = mloop; + data.corner_verts = r_corner_verts; + data.corner_edges = NULL; + data.grid_size = ccgSubSurf_getGridSize(ss); + data.grid_offset = dm->getGridOffset(dm); + data.edge_size = ccgSubSurf_getEdgeSize(ss); + + /* NOTE: For a dense subdivision we've got enough work for each face and + * hence can dedicate whole thread to single face. For less dense + * subdivision we handle multiple faces per thread. + */ + data.mloop_index = data.grid_size >= 5 ? 1 : 8; + + TaskParallelSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.min_iter_per_thread = 1; + + BLI_task_parallel_range( + 0, ccgSubSurf_getNumFaces(ss), &data, copyFinalLoopArray_task_cb, &settings); +} + +static void ccgDM_copyFinalCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges) +{ + CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; + CCGSubSurf *ss = ccgdm->ss; + + if (!ccgdm->ehash) { + BLI_mutex_lock(&ccgdm->loops_cache_lock); + if (!ccgdm->ehash) { + MEdge *medge; + EdgeHash *ehash; + + ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData); + medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm); + + for (int i = 0; i < ccgdm->dm.numEdgeData; i++) { + BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i)); + } + + atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash); + } + BLI_mutex_unlock(&ccgdm->loops_cache_lock); + } + + CopyFinalLoopArrayData data; + data.ccgdm = ccgdm; + data.corner_verts = NULL; + data.corner_edges = r_corner_edges; data.grid_size = ccgSubSurf_getGridSize(ss); data.grid_offset = dm->getGridOffset(dm); data.edge_size = ccgSubSurf_getEdgeSize(ss); @@ -1446,7 +1492,8 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray; ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray; - ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray; + ccgdm->dm.copyCornerVertArray = ccgDM_copyFinalCornerVertArray; + ccgdm->dm.copyCornerEdgeArray = ccgDM_copyFinalCornerEdgeArray; ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray; ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer; diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index 9c64277525c..69d8bb0f12f 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -115,7 +115,7 @@ void fill_mesh_from_openvdb_data(const Span vdb_verts, const int loop_offset, MutableSpan vert_positions, MutableSpan polys, - MutableSpan loops) + MutableSpan corner_verts) { /* Write vertices. */ vert_positions.slice(vert_offset, vdb_verts.size()).copy_from(vdb_verts.cast()); @@ -126,7 +126,7 @@ void fill_mesh_from_openvdb_data(const Span vdb_verts, polys[poly_offset + i].totloop = 3; for (int j = 0; j < 3; j++) { /* Reverse vertex order to get correct normals. */ - loops[loop_offset + 3 * i + j].v = vert_offset + vdb_tris[i][2 - j]; + corner_verts[loop_offset + 3 * i + j] = vert_offset + vdb_tris[i][2 - j]; } } @@ -138,7 +138,7 @@ void fill_mesh_from_openvdb_data(const Span vdb_verts, polys[quad_offset + i].totloop = 4; for (int j = 0; j < 4; j++) { /* Reverse vertex order to get correct normals. */ - loops[quad_loop_offset + 4 * i + j].v = vert_offset + vdb_quads[i][3 - j]; + corner_verts[quad_loop_offset + 4 * i + j] = vert_offset + vdb_quads[i][3 - j]; } } } @@ -177,7 +177,7 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid, 0, mesh->vert_positions_for_write(), mesh->polys_for_write(), - mesh->loops_for_write()); + mesh->corner_verts_for_write()); BKE_mesh_calc_edges(mesh, false, false); BKE_mesh_smooth_flag_set(mesh, false); diff --git a/source/blender/blenloader/intern/versioning_290.cc b/source/blender/blenloader/intern/versioning_290.cc index c71becf5606..718bd66f746 100644 --- a/source/blender/blenloader/intern/versioning_290.cc +++ b/source/blender/blenloader/intern/versioning_290.cc @@ -49,6 +49,7 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_mesh.hh" +#include "BKE_mesh_legacy_convert.h" #include "BKE_multires.h" #include "BKE_node.h" @@ -820,6 +821,7 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain) for (const int i : polys.index_range()) { if (polys[i].totloop == 2) { bool changed; + BKE_mesh_legacy_convert_loops_to_corners(me); BKE_mesh_validate_arrays( me, BKE_mesh_vert_positions_for_write(me), @@ -828,7 +830,8 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain) me->totedge, (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface), me->totface, - me->loops_for_write().data(), + me->corner_verts_for_write().data(), + me->corner_edges_for_write().data(), polys.size(), polys.data(), me->totpoly, diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index b7465e37186..5aab24d4eb5 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -39,6 +39,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) BKE_mesh_legacy_uv_seam_from_flags(&mesh); BKE_mesh_legacy_convert_verts_to_positions(&mesh); BKE_mesh_legacy_attribute_flags_to_strings(&mesh); + BKE_mesh_legacy_convert_loops_to_corners(&mesh); } static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip) diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 0b8ad1970b9..2f039000e8b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -118,6 +118,8 @@ bool BM_attribute_stored_in_bmesh_builtin(const StringRef name) { return ELEM(name, "position", + ".corner_vert", + ".corner_edge", ".hide_vert", ".hide_edge", ".hide_poly", @@ -131,19 +133,21 @@ bool BM_attribute_stored_in_bmesh_builtin(const StringRef name) } static BMFace *bm_face_create_from_mpoly(BMesh &bm, - Span loops, + Span poly_verts, + Span poly_edges, Span vtable, Span etable) { - Array verts(loops.size()); - Array edges(loops.size()); + const int size = poly_verts.size(); + Array verts(size); + Array edges(size); - for (const int i : loops.index_range()) { - verts[i] = vtable[loops[i].v]; - edges[i] = etable[loops[i].e]; + for (const int i : IndexRange(size)) { + verts[i] = vtable[poly_verts[i]]; + edges[i] = etable[poly_edges[i]]; } - return BM_face_create(&bm, verts.data(), edges.data(), loops.size(), nullptr, BM_CREATE_SKIP_CD); + return BM_face_create(&bm, verts.data(), edges.data(), size, nullptr, BM_CREATE_SKIP_CD); } struct MeshToBMeshLayerInfo { @@ -484,7 +488,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar } const Span polys = me->polys(); - const Span mloop = me->loops(); + const Span corner_verts = me->corner_verts(); + const Span corner_edges = me->corner_edges(); /* Only needed for selection. */ @@ -495,8 +500,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar int totloops = 0; for (const int i : polys.index_range()) { - BMFace *f = bm_face_create_from_mpoly( - *bm, mloop.slice(polys[i].loopstart, polys[i].totloop), vtable, etable); + BMFace *f = bm_face_create_from_mpoly(*bm, + corner_verts.slice(polys[i].loopstart, polys[i].totloop), + corner_edges.slice(polys[i].loopstart, polys[i].totloop), + vtable, + etable); if (!ftable.is_empty()) { ftable[i] = f; } @@ -950,6 +958,8 @@ static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) { (void)bm; /* Unused in the release builds. */ BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position") == nullptr); + BLI_assert(CustomData_get_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_vert") == nullptr); + BLI_assert(CustomData_get_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_edge") == nullptr); /* The "hide" attributes are stored as flags on #BMesh. */ BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); @@ -1354,15 +1364,16 @@ static void bm_to_mesh_faces(const BMesh &bm, static void bm_to_mesh_loops(const BMesh &bm, const Span bm_loops, Mesh &mesh) { - CustomData_add_layer(&mesh.ldata, CD_MLOOP, CD_SET_DEFAULT, mesh.totloop); + CustomData_add_layer_named(&mesh.ldata, CD_PROP_INT32, CD_CONSTRUCT, bm.totloop, ".corner_vert"); + CustomData_add_layer_named(&mesh.ldata, CD_PROP_INT32, CD_CONSTRUCT, bm.totloop, ".corner_edge"); const Vector info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata); - MutableSpan dst_loops = mesh.loops_for_write(); - threading::parallel_for(dst_loops.index_range(), 1024, [&](const IndexRange range) { + MutableSpan dst_corner_verts = mesh.corner_verts_for_write(); + MutableSpan dst_corner_edges = mesh.corner_edges_for_write(); + threading::parallel_for(dst_corner_verts.index_range(), 1024, [&](const IndexRange range) { for (const int loop_i : range) { const BMLoop &src_loop = *bm_loops[loop_i]; - MLoop &dst_loop = dst_loops[loop_i]; - dst_loop.v = BM_elem_index_get(src_loop.v); - dst_loop.e = BM_elem_index_get(src_loop.e); + dst_corner_verts[loop_i] = BM_elem_index_get(src_loop.v); + dst_corner_edges[loop_i] = BM_elem_index_get(src_loop.e); bmesh_block_copy_to_mesh_attributes(info, loop_i, src_loop.head.data); } }); diff --git a/source/blender/draw/DRW_pbvh.hh b/source/blender/draw/DRW_pbvh.hh index 22c21fc9c8d..58a32944337 100644 --- a/source/blender/draw/DRW_pbvh.hh +++ b/source/blender/draw/DRW_pbvh.hh @@ -10,6 +10,7 @@ /* Needed for BKE_ccg.h. */ #include "BLI_assert.h" #include "BLI_bitmap.h" +#include "BLI_span.hh" #include "BKE_ccg.h" @@ -23,7 +24,6 @@ struct DMFlagMat; struct Mesh; struct MLoopTri; struct CustomData; -struct MLoop; struct MPoly; struct SubdivCCG; struct BMesh; @@ -34,7 +34,8 @@ struct PBVH_GPU_Args { BMesh *bm; const Mesh *me; const float (*vert_positions)[3]; - const MLoop *mloop; + blender::Span corner_verts; + blender::Span corner_edges; const MPoly *polys; int mesh_verts_num, mesh_faces_num, mesh_grids_num; CustomData *vdata, *ldata, *pdata; 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 ab83b2ebdb8..30a174754cc 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 @@ -365,7 +365,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ mr->poly_normals = mr->me->poly_normals(); } if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) { - mr->loop_normals.reinitialize(mr->loops.size()); + mr->loop_normals.reinitialize(mr->corner_verts.size()); short(*clnors)[2] = static_cast( CustomData_get_layer_for_write(&mr->me->ldata, CD_CUSTOMLOOPNORMAL, mr->me->totloop)); const bool *sharp_edges = static_cast( @@ -373,7 +373,8 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ blender::bke::mesh::normals_calc_loop(mr->vert_positions, mr->edges, mr->polys, - mr->loops, + mr->corner_verts, + mr->corner_edges, {}, mr->vert_normals, mr->poly_normals, @@ -548,7 +549,8 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->vert_positions = mr->me->vert_positions(); mr->edges = mr->me->edges(); mr->polys = mr->me->polys(); - mr->loops = mr->me->loops(); + mr->corner_verts = mr->me->corner_verts(); + mr->corner_edges = mr->me->corner_edges(); mr->v_origindex = static_cast(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); mr->e_origindex = static_cast(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index a5f2461f06c..c8d99de3a16 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -347,7 +347,7 @@ struct PBVHBatches { const MPoly &poly = args->polys[tri->poly]; const float3 fno = blender::bke::mesh::poly_normal_calc( {reinterpret_cast(args->vert_positions), args->mesh_verts_num}, - {&args->mloop[poly.loopstart], poly.totloop}); + {&args->corner_verts[poly.loopstart], poly.totloop}); normal_float_to_short_v3(no, fno); } } @@ -546,10 +546,10 @@ struct PBVHBatches { void fill_vbo_faces(PBVHVbo &vbo, PBVH_GPU_Args *args) { + const blender::Span corner_verts = args->corner_verts; auto foreach_faces = [&](std::function func) { int buffer_i = 0; - const MLoop *mloop = args->mloop; for (int i : IndexRange(args->totprim)) { int face_index = args->mlooptri[args->prim_indices[i]].poly; @@ -561,7 +561,7 @@ struct PBVHBatches { const MLoopTri *tri = args->mlooptri + args->prim_indices[i]; for (int j : IndexRange(3)) { - func(buffer_i, j, mloop[tri->tri[j]].v, tri); + func(buffer_i, j, corner_verts[tri->tri[j]], tri); buffer_i++; } } @@ -990,7 +990,8 @@ struct PBVHBatches { } int r_edges[3]; - BKE_mesh_looptri_get_real_edges(edges.data(), args->mloop, lt, r_edges); + BKE_mesh_looptri_get_real_edges( + edges.data(), args->corner_verts.data(), args->corner_edges.data(), lt, r_edges); if (r_edges[0] != -1) { edge_count++; @@ -1015,7 +1016,8 @@ struct PBVHBatches { } int r_edges[3]; - BKE_mesh_looptri_get_real_edges(edges.data(), args->mloop, lt, r_edges); + BKE_mesh_looptri_get_real_edges( + edges.data(), args->corner_verts.data(), args->corner_edges.data(), lt, r_edges); if (r_edges[0] != -1) { GPU_indexbuf_add_line_verts(&elb_lines, vertex_i, vertex_i + 1); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 7991e7b256c..1f76174de88 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -78,7 +78,8 @@ struct MeshRenderData { blender::Span vert_positions; blender::Span edges; blender::Span polys; - blender::Span loops; + blender::Span corner_verts; + blender::Span corner_edges; BMVert *eve_act; BMEdge *eed_act; BMFace *efa_act; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc index c71fc5619ad..d8bd1a34864 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc @@ -209,7 +209,6 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr, void *_data) { MeshExtract_EditUvElem_Data *data = static_cast(_data); - const MLoop *mloop = mr->loops.data(); const int ml_index_end = poly->loopstart + poly->totloop; bool mp_hidden, mp_select; @@ -224,12 +223,11 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr, } for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mloop[ml_index]; + const int edge = mr->corner_edges[ml_index]; const int ml_index_last = poly->totloop + poly->loopstart - 1; const int ml_index_next = (ml_index == ml_index_last) ? poly->loopstart : (ml_index + 1); - const bool real_edge = (mr->e_origindex == nullptr || - mr->e_origindex[ml->e] != ORIGINDEX_NONE); + const bool real_edge = (mr->e_origindex == nullptr || mr->e_origindex[edge] != ORIGINDEX_NONE); edituv_edge_add(data, mp_hidden || !real_edge, mp_select, ml_index, ml_index_next); } } @@ -402,9 +400,9 @@ static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; - const bool real_vert = !mr->v_origindex || mr->v_origindex[ml->v] != ORIGINDEX_NONE; + const bool real_vert = !mr->v_origindex || mr->v_origindex[vert] != ORIGINDEX_NONE; edituv_point_add(data, mp_hidden || !real_vert, mp_select, ml_index); } } @@ -560,10 +558,10 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; const bool real_fdot = !mr->p_origindex || (mr->p_origindex[poly_index] != ORIGINDEX_NONE); - const bool subd_fdot = facedot_tags[ml->v]; + const bool subd_fdot = facedot_tags[vert]; edituv_facedot_add(data, mp_hidden || !real_fdot || !subd_fdot, mp_select, poly_index); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc index c27ba8bdf89..4e8516f508c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc @@ -50,8 +50,8 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; - if (facedot_tags[ml->v] && !hidden) { + const int vert = mr->corner_verts[ml_index]; + if (facedot_tags[vert] && !hidden) { GPU_indexbuf_set_point_vert(elb, poly_index, poly_index); return; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc index 49179307011..b044756c71d 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc @@ -62,13 +62,13 @@ static void extract_lines_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_last = poly->loopstart + (poly->totloop - 1); int ml_index = ml_index_last, ml_index_next = poly->loopstart; do { - const MLoop *ml = &mr->loops[ml_index]; - if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[ml->e]) || - ((e_origindex) && (e_origindex[ml->e] == ORIGINDEX_NONE)))) { - GPU_indexbuf_set_line_verts(elb, ml->e, ml_index, ml_index_next); + const int edge = mr->corner_edges[ml_index]; + if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[edge]) || + ((e_origindex) && (e_origindex[edge] == ORIGINDEX_NONE)))) { + GPU_indexbuf_set_line_verts(elb, edge, ml_index, ml_index_next); } else { - GPU_indexbuf_set_line_restart(elb, ml->e); + GPU_indexbuf_set_line_restart(elb, edge); } } while ((ml_index = ml_index_next++) != ml_index_last); } @@ -76,8 +76,8 @@ static void extract_lines_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_last = poly->loopstart + (poly->totloop - 1); int ml_index = ml_index_last, ml_index_next = poly->loopstart; do { - const MLoop *ml = &mr->loops[ml_index]; - GPU_indexbuf_set_line_verts(elb, ml->e, ml_index, ml_index_next); + const int edge = mr->corner_edges[ml_index]; + GPU_indexbuf_set_line_verts(elb, edge, ml_index, ml_index_next); } while ((ml_index = ml_index_next++) != ml_index_last); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc index 39253de805d..c1a9fe7ef19 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc @@ -123,9 +123,9 @@ static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr, if (hidden) { return; } - lines_adjacency_triangle(mr->loops[mlt->tri[0]].v, - mr->loops[mlt->tri[1]].v, - mr->loops[mlt->tri[2]].v, + lines_adjacency_triangle(mr->corner_verts[mlt->tri[0]], + mr->corner_verts[mlt->tri[1]], + mr->corner_verts[mlt->tri[2]], mlt->tri[0], mlt->tri[1], mlt->tri[2], diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc index 082299e82f0..b4680191a36 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc @@ -43,9 +43,8 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr, MeshExtract_LinePaintMask_Data *data = static_cast(_data); const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int e_index = mr->corner_edges[ml_index]; - const int e_index = ml->e; if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[e_index]) || ((mr->e_origindex) && (mr->e_origindex[e_index] == ORIGINDEX_NONE)))) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc index f0bf091d6ad..d283a064d72 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc @@ -76,8 +76,7 @@ static void extract_points_iter_poly_mesh(const MeshRenderData *mr, GPUIndexBufBuilder *elb = static_cast(_userdata); const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; - vert_set_mesh(elb, mr, ml->v, ml_index); + vert_set_mesh(elb, mr, mr->corner_verts[ml_index], ml_index); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index 20e90dc249f..596e6e6750a 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -185,7 +185,8 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr, BLI_assert(custom_data); const int layer_index = request.layer_index; - const MLoop *mloop = mr->loops.data(); + const Span corner_verts = mr->corner_verts; + const Span corner_edges = mr->corner_edges; const AttributeType *attr_data = static_cast( CustomData_get_layer_n(custom_data, request.cd_type, layer_index)); @@ -194,8 +195,8 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr, switch (request.domain) { case ATTR_DOMAIN_POINT: - for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++, mloop++) { - *vbo_data = Converter::convert_value(attr_data[mloop->v]); + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++) { + *vbo_data = Converter::convert_value(attr_data[corner_verts[ml_index]]); } break; case ATTR_DOMAIN_CORNER: @@ -204,8 +205,8 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr, } break; case ATTR_DOMAIN_EDGE: - for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++, mloop++) { - *vbo_data = Converter::convert_value(attr_data[mloop->e]); + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++) { + *vbo_data = Converter::convert_value(attr_data[corner_edges[ml_index]]); } break; case ATTR_DOMAIN_FACE: diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc index 8a9fb4a184a..340fa51f184 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc @@ -106,26 +106,27 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; + const int edge = mr->corner_edges[ml_index]; if (data->use_edge_render) { - data->vbo_data[ml_index] = optimal_display_edges[ml->e] ? 255 : 0; + data->vbo_data[ml_index] = optimal_display_edges[edge] ? 255 : 0; } else { /* Count loop per edge to detect non-manifold. */ - if (data->edge_loop_count[ml->e] < 3) { - data->edge_loop_count[ml->e]++; + if (data->edge_loop_count[edge] < 3) { + data->edge_loop_count[edge]++; } - if (data->edge_loop_count[ml->e] == 2) { + if (data->edge_loop_count[edge] == 2) { /* Manifold */ const int ml_index_last = poly->totloop + poly->loopstart - 1; const int ml_index_other = (ml_index == ml_index_last) ? poly->loopstart : (ml_index + 1); - const MLoop *ml_next = &mr->loops[ml_index_other]; + const int vert_next = mr->corner_verts[ml_index_other]; float ratio = loop_edge_factor_get(mr->poly_normals[poly_index], - mr->vert_positions[ml->v], - mr->vert_normals[ml->v], - mr->vert_positions[ml_next->v]); + mr->vert_positions[vert], + mr->vert_normals[vert], + mr->vert_positions[vert_next]); data->vbo_data[ml_index] = ratio * 253 + 1; } else { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc index 553ad0cb4c9..1d56228c089 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc @@ -153,12 +153,11 @@ static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; EditLoopData *data = vbo_data + ml_index; memset(data, 0x0, sizeof(*data)); BMFace *efa = bm_original_face_get(mr, poly_index); - BMEdge *eed = bm_original_edge_get(mr, ml->e); - BMVert *eve = bm_original_vert_get(mr, ml->v); + BMVert *eve = bm_original_vert_get(mr, mr->corner_verts[ml_index]); + BMEdge *eed = bm_original_edge_get(mr, mr->corner_edges[ml_index]); if (efa) { mesh_render_data_face_flag(mr, efa, {-1, -1, -1, -1}, data); } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc index e93c341f73d..1d31665d041 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc @@ -77,14 +77,12 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, MeshExtract_EditUVData_Data *data = static_cast(_data); const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; - EditLoopData *eldata = &data->vbo_data[ml_index]; memset(eldata, 0x0, sizeof(*eldata)); BMFace *efa = bm_original_face_get(mr, poly_index); if (efa) { - BMEdge *eed = bm_original_edge_get(mr, ml->e); - BMVert *eve = bm_original_vert_get(mr, ml->v); + BMVert *eve = bm_original_vert_get(mr, mr->corner_verts[ml_index]); + BMEdge *eed = bm_original_edge_get(mr, mr->corner_edges[ml_index]); if (eed && eve) { /* Loop on an edge endpoint. */ BMLoop *l = BM_face_edge_share_loop(efa, eed); @@ -97,8 +95,7 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, * For this, we check if the previous loop was on an edge. */ const int ml_index_last = poly->loopstart + poly->totloop - 1; const int l_prev = (ml_index == poly->loopstart) ? ml_index_last : (ml_index - 1); - const MLoop *ml_prev = &mr->loops[l_prev]; - eed = bm_original_edge_get(mr, ml_prev->e); + eed = bm_original_edge_get(mr, mr->corner_edges[l_prev]); } if (eed) { /* Mapped points on an edge between two edit verts. */ diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc index fc71862328a..bca1efa1f48 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc @@ -173,8 +173,8 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr av, data->uv[ml_index_last], data->uv[l_next_tmp], - mr->vert_positions[mr->loops[ml_index_last].v], - mr->vert_positions[mr->loops[l_next_tmp].v]); + mr->vert_positions[mr->corner_verts[ml_index_last]], + mr->vert_positions[mr->corner_verts[l_next_tmp]]); /* Save last edge. */ copy_v2_v2(last_auv, auv[1]); copy_v3_v3(last_av, av[1]); @@ -193,8 +193,8 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr av, data->uv[ml_index], data->uv[l_next], - mr->vert_positions[mr->loops[ml_index].v], - mr->vert_positions[mr->loops[l_next].v]); + mr->vert_positions[mr->corner_verts[ml_index]], + mr->vert_positions[mr->corner_verts[l_next]]); } edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[ml_index]); } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc index 8566a07d764..685e247a5a0 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc @@ -77,8 +77,8 @@ static void compute_area_ratio(const MeshRenderData *mr, const float2 *uv_data = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2); for (int poly_index = 0; poly_index < mr->poly_len; poly_index++) { const MPoly &poly = mr->polys[poly_index]; - const float area = bke::mesh::poly_area_calc(mr->vert_positions, - mr->loops.slice(poly.loopstart, poly.totloop)); + const float area = bke::mesh::poly_area_calc( + mr->vert_positions, mr->corner_verts.slice(poly.loopstart, poly.totloop)); float uvarea = area_poly_v2(reinterpret_cast(&uv_data[poly.loopstart]), poly.totloop); tot_area += area; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc index 0ac3bf50bf5..8736d15f454 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc @@ -79,15 +79,15 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; if (mr->use_subsurf_fdots) { - if (facedot_tags[ml->v]) { - copy_v3_v3(center[poly_index], mr->vert_positions[ml->v]); + if (facedot_tags[vert]) { + copy_v3_v3(center[poly_index], mr->vert_positions[vert]); break; } } else { - add_v3_v3(center[poly_index], mr->vert_positions[ml->v]); + add_v3_v3(center[poly_index], mr->vert_positions[vert]); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc index 113d5ddea56..c5f04823f8a 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc @@ -78,9 +78,9 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; if (mr->use_subsurf_fdots) { - if (facedot_tags[ml->v]) { + if (facedot_tags[vert]) { copy_v2_v2(data->vbo_data[poly_index], data->uv_data[ml_index]); } } 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 bd15573d859..3bbf3a43080 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 @@ -66,7 +66,7 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; GPUPackedNormal *lnor_data = &(*(GPUPackedNormal **)data)[ml_index]; if (!mr->loop_normals.is_empty()) { *lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[ml_index]); @@ -75,14 +75,14 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr, *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[poly_index]); } else { - *lnor_data = GPU_normal_convert_i10_v3(mr->vert_normals[ml->v]); + *lnor_data = GPU_normal_convert_i10_v3(mr->vert_normals[vert]); } /* Flag for paint mode overlay. * Only use origindex in edit mode where it is used to display the edge-normals. * In paint mode it will use the un-mapped data to draw the wire-frame. */ if (hidden || - (mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) { + (mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[vert] == ORIGINDEX_NONE)) { lnor_data->w = -1; } else if (mr->select_poly && mr->select_poly[poly_index]) { @@ -190,7 +190,7 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; gpuHQNor *lnor_data = &(*(gpuHQNor **)data)[ml_index]; if (!mr->loop_normals.is_empty()) { normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[ml_index]); @@ -199,14 +199,14 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr, normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[poly_index]); } else { - normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[ml->v]); + normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[vert]); } /* Flag for paint mode overlay. * Only use origindex in edit mode where it is used to display the edge-normals. * In paint mode it will use the un-mapped data to draw the wire-frame. */ if (hidden || - (mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) { + (mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[vert] == ORIGINDEX_NONE)) { lnor_data->w = -1; } else if (mr->select_poly && mr->select_poly[poly_index]) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc index 55f65dac942..c0788cb4eb2 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc @@ -217,9 +217,9 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) const Span looptris = mr->looptris; for (const int i : looptris.index_range()) { const int index = looptris[i].poly; - const float *cos[3] = {mr->vert_positions[mr->loops[looptris[i].tri[0]].v], - mr->vert_positions[mr->loops[looptris[i].tri[1]].v], - mr->vert_positions[mr->loops[looptris[i].tri[2]].v]}; + const float *cos[3] = {mr->vert_positions[mr->corner_verts[looptris[i].tri[0]]], + mr->vert_positions[mr->corner_verts[looptris[i].tri[1]]], + mr->vert_positions[mr->corner_verts[looptris[i].tri[2]]]}; float ray_co[3]; float ray_no[3]; @@ -260,7 +260,7 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) struct BVHTree_OverlapData { Span positions; - Span loops; + Span corner_verts; Span looptris; float epsilon; }; @@ -276,12 +276,12 @@ static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int /*threa return false; } - const float *tri_a_co[3] = {data->positions[data->loops[tri_a->tri[0]].v], - data->positions[data->loops[tri_a->tri[1]].v], - data->positions[data->loops[tri_a->tri[2]].v]}; - const float *tri_b_co[3] = {data->positions[data->loops[tri_b->tri[0]].v], - data->positions[data->loops[tri_b->tri[1]].v], - data->positions[data->loops[tri_b->tri[2]].v]}; + const float *tri_a_co[3] = {data->positions[data->corner_verts[tri_a->tri[0]]], + data->positions[data->corner_verts[tri_a->tri[1]]], + data->positions[data->corner_verts[tri_a->tri[2]]]}; + const float *tri_b_co[3] = {data->positions[data->corner_verts[tri_b->tri[0]]], + data->positions[data->corner_verts[tri_b->tri[1]]], + data->positions[data->corner_verts[tri_b->tri[2]]]}; float ix_pair[2][3]; int verts_shared = 0; @@ -343,7 +343,7 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) struct BVHTree_OverlapData data = {}; data.positions = mr->vert_positions; - data.loops = mr->loops; + data.corner_verts = mr->corner_verts; data.looptris = mr->looptris; data.epsilon = BLI_bvhtree_get_epsilon(tree); @@ -450,14 +450,14 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort) fac = 0.0f; for (int i = 1; i <= poly.totloop; i++) { - const MLoop *l_prev = &mr->loops[poly.loopstart + (i - 1) % poly.totloop]; - const MLoop *l_curr = &mr->loops[poly.loopstart + (i + 0) % poly.totloop]; - const MLoop *l_next = &mr->loops[poly.loopstart + (i + 1) % poly.totloop]; + const int corner_prev = poly.loopstart + (i - 1) % poly.totloop; + const int corner_curr = poly.loopstart + (i + 0) % poly.totloop; + const int corner_next = poly.loopstart + (i + 1) % poly.totloop; float no_corner[3]; normal_tri_v3(no_corner, - mr->vert_positions[l_prev->v], - mr->vert_positions[l_curr->v], - mr->vert_positions[l_next->v]); + mr->vert_positions[mr->corner_verts[corner_prev]], + mr->vert_positions[mr->corner_verts[corner_curr]], + mr->vert_positions[mr->corner_verts[corner_next]]); /* simple way to detect (what is most likely) concave */ if (dot_v3v3(f_no, no_corner) < 0.0f) { negate_v3(no_corner); @@ -533,11 +533,11 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) for (const int poly_index : mr->polys.index_range()) { const MPoly &poly = mr->polys[poly_index]; for (int i = 0; i < poly.totloop; i++) { - const MLoop *l_curr = &mr->loops[poly.loopstart + (i + 0) % poly.totloop]; - const MLoop *l_next = &mr->loops[poly.loopstart + (i + 1) % poly.totloop]; + const int vert_curr = mr->corner_verts[poly.loopstart + (i + 0) % poly.totloop]; + const int vert_next = mr->corner_verts[poly.loopstart + (i + 1) % poly.totloop]; float angle; void **pval; - bool value_is_init = BLI_edgehash_ensure_p(eh, l_curr->v, l_next->v, &pval); + bool value_is_init = BLI_edgehash_ensure_p(eh, vert_curr, vert_next, &pval); if (!value_is_init) { *pval = (void *)&mr->poly_normals[poly_index]; /* non-manifold edge, yet... */ @@ -548,7 +548,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) const float *f2_no = static_cast(*pval); angle = angle_normalized_v3v3(f1_no, f2_no); angle = is_edge_convex_v3( - mr->vert_positions[l_curr->v], mr->vert_positions[l_next->v], f1_no, f2_no) ? + mr->vert_positions[vert_curr], mr->vert_positions[vert_next], f1_no, f2_no) ? angle : -angle; /* Tag as manifold. */ @@ -558,8 +558,8 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) /* non-manifold edge */ angle = DEG2RADF(90.0f); } - float *col1 = &vert_angles[l_curr->v]; - float *col2 = &vert_angles[l_next->v]; + float *col1 = &vert_angles[vert_curr]; + float *col2 = &vert_angles[vert_next]; *col1 = max_ff(*col1, angle); *col2 = max_ff(*col2, angle); } @@ -580,9 +580,9 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) BLI_edgehashIterator_free(ehi); BLI_edgehash_free(eh, nullptr); - const MLoop *ml = mr->loops.data(); - for (int l_index = 0; l_index < mr->loop_len; l_index++, ml++) { - r_sharp[l_index] = sharp_remap(vert_angles[ml->v], min, max, minmax_irange); + for (int l_index = 0; l_index < mr->loop_len; l_index++) { + const int vert = mr->corner_verts[l_index]; + r_sharp[l_index] = sharp_remap(vert_angles[vert], min, max, minmax_irange); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc index db0de3761e3..ef212b25387 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc @@ -68,10 +68,10 @@ static void extract_orco_iter_poly_mesh(const MeshRenderData *mr, { const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; MeshExtract_Orco_Data *orco_data = (MeshExtract_Orco_Data *)data; float *loop_orco = orco_data->vbo_data[ml_index]; - copy_v3_v3(loop_orco, orco_data->orco[ml->v]); + copy_v3_v3(loop_orco, orco_data->orco[vert]); loop_orco[3] = 0.0; /* Tag as not a generic attribute. */ } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index d9fc2b71d15..b9813feaecb 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -91,18 +91,18 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert_i = mr->corner_verts[ml_index]; PosNorLoop *vert = &data->vbo_data[ml_index]; - const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v]; - copy_v3_v3(vert->pos, mr->vert_positions[ml->v]); - vert->nor = data->normals[ml->v].low; + const bool vert_hidden = mr->hide_vert && mr->hide_vert[vert_i]; + copy_v3_v3(vert->pos, mr->vert_positions[vert_i]); + vert->nor = data->normals[vert_i].low; /* Flag for paint mode overlay. */ if (poly_hidden || vert_hidden || - ((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) { + ((mr->v_origindex) && (mr->v_origindex[vert_i] == ORIGINDEX_NONE))) { vert->nor.w = -1; } - else if (mr->select_vert && mr->select_vert[ml->v]) { + else if (mr->select_vert && mr->select_vert[vert_i]) { vert->nor.w = 1; } else { @@ -464,22 +464,21 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr, MeshExtract_PosNorHQ_Data *data = static_cast(_data); const bool poly_hidden = mr->hide_poly && mr->hide_poly[poly - mr->polys.data()]; - const MLoop *mloop = mr->loops.data(); const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mloop[ml_index]; + const int vert_i = mr->corner_verts[ml_index]; - const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v]; + const bool vert_hidden = mr->hide_vert && mr->hide_vert[vert_i]; PosNorHQLoop *vert = &data->vbo_data[ml_index]; - copy_v3_v3(vert->pos, mr->vert_positions[ml->v]); - copy_v3_v3_short(vert->nor, data->normals[ml->v].high); + copy_v3_v3(vert->pos, mr->vert_positions[vert_i]); + copy_v3_v3_short(vert->nor, data->normals[vert_i].high); /* Flag for paint mode overlay. */ if (poly_hidden || vert_hidden || - ((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) { + ((mr->v_origindex) && (mr->v_origindex[vert_i] == ORIGINDEX_NONE))) { vert->nor[3] = -1; } - else if (mr->select_vert && mr->select_vert[ml->v]) { + else if (mr->select_vert && mr->select_vert[vert_i]) { vert->nor[3] = 1; } else { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc index 163ebf3a2f8..40dedd12cc9 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc @@ -39,7 +39,6 @@ static void extract_sculpt_data_init(const MeshRenderData *mr, GPUVertBuf *vbo = static_cast(buf); GPUVertFormat *format = get_sculpt_data_format(); - CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata; CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata; CustomData *cd_pdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->pdata : &mr->me->pdata; @@ -56,7 +55,6 @@ static void extract_sculpt_data_init(const MeshRenderData *mr, }; gpuSculptData *vbo_data = (gpuSculptData *)GPU_vertbuf_get_data(vbo); - const MLoop *loops = (const MLoop *)CustomData_get_layer(cd_ldata, CD_MLOOP); if (mr->extract_type == MR_EXTRACT_BMESH) { int cd_mask_ofs = CustomData_get_offset(cd_vdata, CD_PAINT_MASK); @@ -92,7 +90,7 @@ static void extract_sculpt_data_init(const MeshRenderData *mr, for (int l = 0; l < poly.totloop; l++) { float v_mask = 0.0f; if (cd_mask) { - v_mask = cd_mask[loops[mp_loop].v]; + v_mask = cd_mask[mr->corner_verts[mp_loop]]; } vbo_data->mask = v_mask; @@ -131,7 +129,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache, const float *cd_mask = (const float *)CustomData_get_layer(cd_vdata, CD_PAINT_MASK); const Span coarse_polys = coarse_mesh->polys(); - const Span coarse_loops = coarse_mesh->loops(); + const Span coarse_corner_verts = coarse_mesh->corner_verts(); if (cd_mask) { GPUVertFormat mask_format = {0}; @@ -147,8 +145,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache, for (int loop_index = poly.loopstart; loop_index < poly.loopstart + poly.totloop; loop_index++) { - const MLoop *ml = &coarse_loops[loop_index]; - *v_mask++ = cd_mask[ml->v]; + *v_mask++ = cd_mask[coarse_corner_verts[loop_index]]; } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc index 3c40c481c8f..efc06c4e4e6 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc @@ -127,8 +127,8 @@ static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr, { const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; - (*(int32_t **)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[ml->e] : ml->e; + const int edge = mr->corner_edges[ml_index]; + (*(int32_t **)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[edge] : edge; } } @@ -139,8 +139,8 @@ static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr, { const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; - (*(int32_t **)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[ml->v] : ml->v; + const int vert = mr->corner_verts[ml_index]; + (*(int32_t **)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[vert] : vert; } } 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 e7da5722f56..9e5007bf172 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 @@ -117,7 +117,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, BKE_mesh_calc_loop_tangent_ex(reinterpret_cast(mr->vert_positions.data()), mr->polys.data(), mr->polys.size(), - mr->loops.data(), + mr->corner_verts.data(), mr->looptris.data(), mr->tri_len, mr->sharp_faces, @@ -130,7 +130,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, reinterpret_cast(mr->loop_normals.data()), orco, r_loop_data, - mr->loops.size(), + mr->corner_verts.size(), &tangent_mask); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc index 7a88e2308d2..efc234bf2cc 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc @@ -140,9 +140,9 @@ static void extract_weights_iter_poly_mesh(const MeshRenderData *mr, MeshExtract_Weight_Data *data = static_cast(_data); const int ml_index_end = poly->loopstart + poly->totloop; for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) { - const MLoop *ml = &mr->loops[ml_index]; + const int vert = mr->corner_verts[ml_index]; if (data->dvert != nullptr) { - const MDeformVert *dvert = &data->dvert[ml->v]; + const MDeformVert *dvert = &data->dvert[vert]; data->vbo_data[ml_index] = evaluate_vertex_weight(dvert, data->wstate); } else { diff --git a/source/blender/editors/armature/meshlaplacian.cc b/source/blender/editors/armature/meshlaplacian.cc index 17f3d35b425..71120a413b2 100644 --- a/source/blender/editors/armature/meshlaplacian.cc +++ b/source/blender/editors/armature/meshlaplacian.cc @@ -74,7 +74,7 @@ struct LaplacianSystem { struct HeatWeighting { const MLoopTri *mlooptri; - blender::Span loops; /* needed to find vertices by index */ + blender::Span corner_verts; /* needed to find vertices by index */ int verts_num; int tris_num; float (*verts)[3]; /* vertex coordinates */ @@ -382,14 +382,14 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr { BVHCallbackUserData *data = (struct BVHCallbackUserData *)userdata; const MLoopTri *lt = &data->sys->heat.mlooptri[index]; - const blender::Span loops = data->sys->heat.loops; + const blender::Span corner_verts = data->sys->heat.corner_verts; float(*verts)[3] = data->sys->heat.verts; const float *vtri_co[3]; float dist_test; - vtri_co[0] = verts[loops[lt->tri[0]].v]; - vtri_co[1] = verts[loops[lt->tri[1]].v]; - vtri_co[2] = verts[loops[lt->tri[2]].v]; + vtri_co[0] = verts[corner_verts[lt->tri[0]]]; + vtri_co[1] = verts[corner_verts[lt->tri[1]]]; + vtri_co[2] = verts[corner_verts[lt->tri[2]]]; #ifdef USE_KDOPBVH_WATERTIGHT if (isect_ray_tri_watertight_v3( @@ -414,7 +414,7 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr static void heat_ray_tree_create(LaplacianSystem *sys) { const MLoopTri *looptri = sys->heat.mlooptri; - const blender::Span loops = sys->heat.loops; + const blender::Span corner_verts = sys->heat.corner_verts; float(*verts)[3] = sys->heat.verts; int tris_num = sys->heat.tris_num; int verts_num = sys->heat.verts_num; @@ -429,9 +429,9 @@ static void heat_ray_tree_create(LaplacianSystem *sys) float bb[6]; int vtri[3]; - vtri[0] = loops[lt->tri[0]].v; - vtri[1] = loops[lt->tri[1]].v; - vtri[2] = loops[lt->tri[2]].v; + vtri[0] = corner_verts[lt->tri[0]]; + vtri[1] = corner_verts[lt->tri[1]]; + vtri[2] = corner_verts[lt->tri[2]]; INIT_MINMAX(bb, bb + 3); minmax_v3v3_v3(bb, bb + 3, verts[vtri[0]]); @@ -581,7 +581,7 @@ static void heat_calc_vnormals(LaplacianSystem *sys) static void heat_laplacian_create(LaplacianSystem *sys) { const MLoopTri *mlooptri = sys->heat.mlooptri, *lt; - const blender::Span loops = sys->heat.loops; + const blender::Span corner_verts = sys->heat.corner_verts; int tris_num = sys->heat.tris_num; int verts_num = sys->heat.verts_num; int a; @@ -598,9 +598,9 @@ static void heat_laplacian_create(LaplacianSystem *sys) for (a = 0, lt = mlooptri; a < tris_num; a++, lt++) { int vtri[3]; - vtri[0] = loops[lt->tri[0]].v; - vtri[1] = loops[lt->tri[1]].v; - vtri[2] = loops[lt->tri[2]].v; + vtri[0] = corner_verts[lt->tri[0]]; + vtri[1] = corner_verts[lt->tri[1]]; + vtri[2] = corner_verts[lt->tri[2]]; laplacian_add_triangle(sys, UNPACK3(vtri)); } @@ -658,7 +658,7 @@ void heat_bone_weighting(Object *ob, const blender::Span vert_positions = me->vert_positions(); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; @@ -677,8 +677,8 @@ void heat_bone_weighting(Object *ob, &me->vdata, CD_PROP_BOOL, ".select_vert"); if (select_vert) { for (const int i : polys.index_range()) { - for (const MLoop &loop : loops.slice(polys[i].loopstart, polys[i].totloop)) { - mask[loop.v] = select_vert[loop.v]; + for (const int vert : corner_verts.slice(polys[i].loopstart, polys[i].totloop)) { + mask[vert] = select_vert[vert]; } } } @@ -689,8 +689,8 @@ void heat_bone_weighting(Object *ob, if (select_poly) { for (const int i : polys.index_range()) { if (select_poly[i]) { - for (const MLoop &loop : loops.slice(polys[i].loopstart, polys[i].totloop)) { - mask[loop.v] = 1; + for (const int vert : corner_verts.slice(polys[i].loopstart, polys[i].totloop)) { + mask[vert] = 1; } } } @@ -705,10 +705,11 @@ void heat_bone_weighting(Object *ob, mlooptri = static_cast( MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__)); - blender::bke::mesh::looptris_calc(vert_positions, polys, loops, {mlooptri, sys->heat.tris_num}); + blender::bke::mesh::looptris_calc( + vert_positions, polys, corner_verts, {mlooptri, sys->heat.tris_num}); sys->heat.mlooptri = mlooptri; - sys->heat.loops = loops; + sys->heat.corner_verts = corner_verts; sys->heat.verts_num = me->totvert; sys->heat.verts = verts; sys->heat.root = root; @@ -926,7 +927,7 @@ typedef struct MeshDeformBind { /* avoid DM function calls during intersections */ struct { blender::Span polys; - blender::Span loops; + blender::Span corner_verts; blender::Span looptris; blender::Span poly_normals; } cagemesh_cache; @@ -957,7 +958,7 @@ static void harmonic_ray_callback(void *userdata, { MeshRayCallbackData *data = static_cast(userdata); MeshDeformBind *mdb = data->mdb; - const blender::Span loops = mdb->cagemesh_cache.loops; + const blender::Span corner_verts = mdb->cagemesh_cache.corner_verts; const blender::Span poly_normals = mdb->cagemesh_cache.poly_normals; MeshDeformIsect *isec = data->isec; float no[3], co[3], dist; @@ -965,9 +966,9 @@ static void harmonic_ray_callback(void *userdata, const MLoopTri *lt = &mdb->cagemesh_cache.looptris[index]; - face[0] = mdb->cagecos[loops[lt->tri[0]].v]; - face[1] = mdb->cagecos[loops[lt->tri[1]].v]; - face[2] = mdb->cagecos[loops[lt->tri[2]].v]; + face[0] = mdb->cagecos[corner_verts[lt->tri[0]]]; + face[1] = mdb->cagecos[corner_verts[lt->tri[1]]]; + face[2] = mdb->cagecos[corner_verts[lt->tri[2]]]; bool isect_ray_tri = isect_ray_tri_watertight_v3( ray->origin, ray->isect_precalc, UNPACK3(face), &dist, nullptr); @@ -1031,7 +1032,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, harmonic_ray_callback, &data, BVH_RAYCAST_WATERTIGHT) != -1) { - const blender::Span loops = mdb->cagemesh_cache.loops; + const blender::Span corner_verts = mdb->cagemesh_cache.corner_verts; const MLoopTri *lt = &mdb->cagemesh_cache.looptris[hit.index]; const MPoly &poly = mdb->cagemesh_cache.polys[lt->poly]; const float(*cagecos)[3] = mdb->cagecos; @@ -1055,7 +1056,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, /* compute mean value coordinates for interpolation */ for (int i = 0; i < poly.totloop; i++) { - copy_v3_v3(mp_cagecos[i], cagecos[loops[poly.loopstart + i].v]); + copy_v3_v3(mp_cagecos[i], cagecos[corner_verts[poly.loopstart + i]]); } interp_weights_poly_v3(isect->poly_weights, @@ -1224,11 +1225,11 @@ static float meshdeform_boundary_phi(const MeshDeformBind *mdb, const MDefBoundIsect *isect, int cagevert) { - const blender::Span loops = mdb->cagemesh_cache.loops; + const blender::Span corner_verts = mdb->cagemesh_cache.corner_verts; const MPoly &poly = mdb->cagemesh_cache.polys[isect->poly_index]; for (int i = 0; i < poly.totloop; i++) { - if (loops[poly.loopstart + i].v == cagevert) { + if (corner_verts[poly.loopstart + i] == cagevert) { return isect->poly_weights[i]; } } @@ -1629,7 +1630,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin { Mesh *me = mdb->cagemesh; mdb->cagemesh_cache.polys = me->polys(); - mdb->cagemesh_cache.loops = me->loops(); + mdb->cagemesh_cache.corner_verts = me->corner_verts(); mdb->cagemesh_cache.looptris = me->looptris(); mdb->cagemesh_cache.poly_normals = me->poly_normals(); } diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 7e267b93101..960be0b5032 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -580,7 +580,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const Mesh &surface_mesh = *static_cast(surface_ob.data); const Span surface_positions = surface_mesh.vert_positions(); - const Span loops = surface_mesh.loops(); + const Span corner_verts = surface_mesh.corner_verts(); const Span surface_looptris = surface_mesh.looptris(); VArraySpan surface_uv_map; if (curves_id.surface_uv_map != nullptr) { @@ -640,9 +640,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const float2 &uv0 = surface_uv_map[corner0]; const float2 &uv1 = surface_uv_map[corner1]; const float2 &uv2 = surface_uv_map[corner2]; - const float3 &p0_su = surface_positions[loops[corner0].v]; - const float3 &p1_su = surface_positions[loops[corner1].v]; - const float3 &p2_su = surface_positions[loops[corner2].v]; + const float3 &p0_su = surface_positions[corner_verts[corner0]]; + const float3 &p1_su = surface_positions[corner_verts[corner1]]; + const float3 &p2_su = surface_positions[corner_verts[corner2]]; float3 bary_coords; interp_weights_tri_v3(bary_coords, p0_su, p1_su, p2_su, new_first_point_pos_su); const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2); @@ -676,9 +676,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const MLoopTri &looptri = surface_looptris[lookup_result.looptri_index]; const float3 &bary_coords = lookup_result.bary_weights; - const float3 &p0_su = surface_positions[loops[looptri.tri[0]].v]; - const float3 &p1_su = surface_positions[loops[looptri.tri[1]].v]; - const float3 &p2_su = surface_positions[loops[looptri.tri[2]].v]; + const float3 &p0_su = surface_positions[corner_verts[looptri.tri[0]]]; + const float3 &p1_su = surface_positions[corner_verts[looptri.tri[1]]]; + const float3 &p2_su = surface_positions[corner_verts[looptri.tri[2]]]; float3 new_first_point_pos_su; interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords); diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 64a4f59a5e7..2c293400d85 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -224,7 +224,7 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands, { using namespace blender; const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); const bke::AttributeAccessor attributes = mesh.attributes(); const VArray uv_seams = attributes.lookup_or_default( @@ -240,23 +240,23 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands, continue; } const MPoly &poly = polys[poly_index]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); + const Span poly_edges = corner_edges.slice(poly.loopstart, poly.totloop); - for (const int poly_loop_index : poly_loops.index_range()) { - const MLoop &outer_mloop = poly_loops[poly_loop_index]; - if (skip_seams && uv_seams[outer_mloop.e]) { + for (const int poly_loop_index : poly_edges.index_range()) { + const int outer_edge = poly_edges[poly_loop_index]; + if (skip_seams && uv_seams[outer_edge]) { continue; } - for (const MLoop &inner_mloop : - poly_loops.slice(poly_loop_index, poly_loops.size() - poly_loop_index)) { - if (&outer_mloop == &inner_mloop) { + for (const int inner_edge : + poly_edges.slice(poly_loop_index, poly_edges.size() - poly_loop_index)) { + if (outer_edge == inner_edge) { continue; } - if (skip_seams && uv_seams[inner_mloop.e]) { + if (skip_seams && uv_seams[inner_edge]) { continue; } - islands.join(inner_mloop.e, outer_mloop.e); + islands.join(inner_edge, outer_edge); } } } @@ -274,7 +274,7 @@ static void paintface_select_linked_faces(Mesh &mesh, build_poly_connections(islands, mesh); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); const VArray uv_seams = attributes.lookup_or_default( @@ -285,11 +285,11 @@ static void paintface_select_linked_faces(Mesh &mesh, Set selected_roots; for (const int i : face_indices) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - if (uv_seams[loop.e]) { + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + if (uv_seams[edge]) { continue; } - const int root = islands.find_root(loop.e); + const int root = islands.find_root(edge); selected_roots.add(root); } } @@ -297,8 +297,8 @@ static void paintface_select_linked_faces(Mesh &mesh, threading::parallel_for(select_poly.span.index_range(), 1024, [&](const IndexRange range) { for (const int poly_index : range) { const MPoly &poly = polys[poly_index]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - const int root = islands.find_root(loop.e); + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + const int root = islands.find_root(edge); if (selected_roots.contains(root)) { select_poly.span[poly_index] = select; break; @@ -424,7 +424,7 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) const Span positions = me->vert_positions(); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); bke::AttributeAccessor attributes = me->attributes(); const VArray hide_poly = attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); @@ -437,9 +437,9 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) } const MPoly &poly = polys[i]; - const MLoop *ml = &loops[poly.loopstart]; - for (int b = 0; b < poly.totloop; b++, ml++) { - mul_v3_m3v3(vec, bmat, positions[ml->v]); + for (int b = 0; b < poly.totloop; b++) { + const int corner = poly.loopstart + b; + mul_v3_m3v3(vec, bmat, positions[corner_verts[corner]]); add_v3_v3v3(vec, vec, ob->object_to_world[3]); minmax_v3v3_v3(r_min, r_max, vec); } diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 9627d88f258..856f021f529 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -800,7 +800,8 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator const bool *sharp_faces = static_cast( CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, "sharp_face")); bke::mesh::edges_sharp_from_angle_set(me->polys(), - me->loops(), + me->corner_verts(), + me->corner_edges(), me->poly_normals(), sharp_faces, me->smoothresh, @@ -1209,8 +1210,11 @@ static void mesh_add_loops(Mesh *mesh, int len) CustomData_copy(&mesh->ldata, &ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop); CustomData_copy_data(&mesh->ldata, &ldata, 0, 0, mesh->totloop); - if (!CustomData_has_layer(&ldata, CD_MLOOP)) { - CustomData_add_layer(&ldata, CD_MLOOP, CD_SET_DEFAULT, totloop); + if (!CustomData_get_layer_named(&ldata, CD_PROP_INT32, ".corner_vert")) { + CustomData_add_layer_named(&ldata, CD_PROP_INT32, CD_SET_DEFAULT, totloop, ".corner_vert"); + } + if (!CustomData_get_layer_named(&ldata, CD_PROP_INT32, ".corner_edge")) { + CustomData_add_layer_named(&ldata, CD_PROP_INT32, CD_SET_DEFAULT, totloop, ".corner_edge"); } BKE_mesh_runtime_clear_cache(mesh); @@ -1459,7 +1463,8 @@ void ED_mesh_split_faces(Mesh *mesh) { using namespace blender; const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); + const Span corner_edges = mesh->corner_edges(); const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); const bke::AttributeAccessor attributes = mesh->attributes(); const VArray mesh_sharp_edges = attributes.lookup_or_default( @@ -1470,15 +1475,20 @@ void ED_mesh_split_faces(Mesh *mesh) Array sharp_edges(mesh->totedge); mesh_sharp_edges.materialize(sharp_edges); - bke::mesh::edges_sharp_from_angle_set( - polys, loops, mesh->poly_normals(), sharp_faces, split_angle, sharp_edges); + bke::mesh::edges_sharp_from_angle_set(polys, + corner_verts, + corner_edges, + mesh->poly_normals(), + sharp_faces, + split_angle, + sharp_edges); 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; + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + sharp_edges[edge] = true; } } } diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index 0949361ddea..fef735387b7 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -74,7 +74,8 @@ static void join_mesh_single(Depsgraph *depsgraph, const float imat[4][4], float3 **vert_positions_pp, MEdge **medge_pp, - MLoop **mloop_pp, + int **corner_verts_pp, + int **corner_edges_pp, MPoly **mpoly_pp, CustomData *vdata, CustomData *edata, @@ -99,7 +100,8 @@ static void join_mesh_single(Depsgraph *depsgraph, Mesh *me = static_cast(ob_src->data); float3 *vert_positions = *vert_positions_pp; MEdge *edge = *medge_pp; - MLoop *mloop = *mloop_pp; + int *corner_verts = *corner_verts_pp; + int *corner_edges = *corner_edges_pp; if (me->totvert) { /* standard data */ @@ -227,9 +229,9 @@ static void join_mesh_single(Depsgraph *depsgraph, CustomData_merge(&me->ldata, ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop); CustomData_copy_data_named(&me->ldata, ldata, 0, *loopofs, me->totloop); - for (a = 0; a < me->totloop; a++, mloop++) { - mloop->v += *vertofs; - mloop->e += *edgeofs; + for (a = 0; a < me->totloop; a++) { + corner_verts[a] += *vertofs; + corner_edges[a] += *edgeofs; } } @@ -293,7 +295,8 @@ static void join_mesh_single(Depsgraph *depsgraph, *edgeofs += me->totedge; *medge_pp += me->totedge; *loopofs += me->totloop; - *mloop_pp += me->totloop; + *corner_verts_pp += me->totloop; + *corner_edges_pp += me->totloop; *polyofs += me->totpoly; *mpoly_pp += me->totpoly; } @@ -334,7 +337,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) Mesh *me; MEdge *edge = nullptr; MPoly *polys = nullptr; - MLoop *mloop = nullptr; Key *key, *nkey = nullptr; float imat[4][4]; int a, b, totcol, totmat = 0, totedge = 0, totvert = 0; @@ -585,7 +587,10 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) float3 *vert_positions = (float3 *)CustomData_add_layer_named( &vdata, CD_PROP_FLOAT3, CD_SET_DEFAULT, totvert, "position"); edge = (MEdge *)CustomData_add_layer(&edata, CD_MEDGE, CD_SET_DEFAULT, totedge); - mloop = (MLoop *)CustomData_add_layer(&ldata, CD_MLOOP, CD_SET_DEFAULT, totloop); + int *corner_verts = (int *)CustomData_add_layer_named( + &ldata, CD_PROP_INT32, CD_CONSTRUCT, totloop, ".corner_vert"); + int *corner_edges = (int *)CustomData_add_layer_named( + &ldata, CD_PROP_INT32, CD_CONSTRUCT, totloop, ".corner_edge"); polys = (MPoly *)CustomData_add_layer(&pdata, CD_MPOLY, CD_SET_DEFAULT, totpoly); vertofs = 0; @@ -610,7 +615,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) imat, &vert_positions, &edge, - &mloop, + &corner_verts, + &corner_edges, &polys, &vdata, &edata, @@ -644,7 +650,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) imat, &vert_positions, &edge, - &mloop, + &corner_verts, + &corner_edges, &polys, &vdata, &edata, @@ -1225,16 +1232,14 @@ static void ed_mesh_pick_face_vert__mpoly_find( /* mesh data (evaluated) */ const MPoly *poly, const Span vert_positions, - const MLoop *mloop, + const int *corner_verts, /* return values */ float *r_len_best, int *r_v_idx_best) { - const MLoop *ml; - int j = poly->totloop; - for (ml = &mloop[poly->loopstart]; j--; ml++) { + for (int j = poly->totloop; j--;) { float sco[2]; - const int v_idx = ml->v; + const int v_idx = corner_verts[poly->loopstart + j]; if (ED_view3d_project_float_object(region, vert_positions[v_idx], sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { const float len_test = len_manhattan_v2v2(mval, sco); @@ -1271,7 +1276,7 @@ bool ED_mesh_pick_face_vert( const Span vert_positions = me_eval->vert_positions(); const Span polys = me_eval->polys(); - const Span loops = me_eval->loops(); + const Span corner_verts = me_eval->corner_verts(); const int *index_mp_to_orig = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); @@ -1279,8 +1284,13 @@ bool ED_mesh_pick_face_vert( if (index_mp_to_orig) { for (const int i : polys.index_range()) { if (index_mp_to_orig[i] == poly_index) { - ed_mesh_pick_face_vert__mpoly_find( - region, mval_f, &polys[i], vert_positions, loops.data(), &len_best, &v_idx_best); + ed_mesh_pick_face_vert__mpoly_find(region, + mval_f, + &polys[i], + vert_positions, + corner_verts.data(), + &len_best, + &v_idx_best); } } } @@ -1290,7 +1300,7 @@ bool ED_mesh_pick_face_vert( mval_f, &polys[poly_index], vert_positions, - loops.data(), + corner_verts.data(), &len_best, &v_idx_best); } diff --git a/source/blender/editors/object/object_bake_api.cc b/source/blender/editors/object/object_bake_api.cc index 2b689adc9d0..8f571f03e7e 100644 --- a/source/blender/editors/object/object_bake_api.cc +++ b/source/blender/editors/object/object_bake_api.cc @@ -979,7 +979,7 @@ static bool bake_targets_init_vertex_colors(Main *bmain, } static int find_original_loop(const blender::Span orig_polys, - const blender::Span orig_loops, + const blender::Span orig_corner_verts, const int *vert_origindex, const int *poly_origindex, const int poly_eval, @@ -996,9 +996,9 @@ static int find_original_loop(const blender::Span orig_polys, /* Find matching loop with original vertex in original polygon. */ const MPoly &poly_orig = orig_polys[poly_orig_i]; - const MLoop *mloop_orig = &orig_loops[poly_orig.loopstart]; - for (int j = 0; j < poly_orig.totloop; ++j, ++mloop_orig) { - if (mloop_orig->v == vert_orig) { + const int *poly_verts_orig = &orig_corner_verts[poly_orig.loopstart]; + for (int j = 0; j < poly_orig.totloop; ++j) { + if (poly_verts_orig[j] == vert_orig) { return poly_orig.loopstart + j; } } @@ -1033,9 +1033,9 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop); MLoopTri *looptri = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); - const blender::Span loops = me_eval->loops(); + const blender::Span corner_verts = me_eval->corner_verts(); blender::bke::mesh::looptris_calc( - me_eval->vert_positions(), me_eval->polys(), loops, {looptri, tottri}); + me_eval->vert_positions(), me_eval->polys(), corner_verts, {looptri, tottri}); /* For mapping back to original mesh in case there are modifiers. */ const int *vert_origindex = static_cast( @@ -1043,19 +1043,19 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, const int *poly_origindex = static_cast( CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX)); const blender::Span orig_polys = me->polys(); - const blender::Span orig_loops = me->loops(); + const blender::Span orig_corner_verts = me->corner_verts(); for (int i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; for (int j = 0; j < 3; j++) { uint l = lt->tri[j]; - uint v = loops[l].v; + const int v = corner_verts[l]; /* Map back to original loop if there are modifiers. */ if (vert_origindex != nullptr && poly_origindex != nullptr) { l = find_original_loop( - orig_polys, orig_loops, vert_origindex, poly_origindex, lt->poly, v); + orig_polys, orig_corner_verts, vert_origindex, poly_origindex, lt->poly, v); if (l == ORIGINDEX_NONE || l >= me->totloop) { continue; } @@ -1152,9 +1152,9 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex")); memset(mcol, 0, sizeof(MPropCol) * me->totvert); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); for (int i = 0; i < totloop; i++) { - const int v = loops[i].v; + const int v = corner_verts[i]; bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num); num_loops_for_vertex[v]++; } diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index 678b19f8ef2..d6181d28de9 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -680,7 +680,8 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) */ const Span positions = mesh->vert_positions(); const Span edges = mesh->edges(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); + const Span corner_edges = mesh->corner_edges(); bool is_manifold_consistent = true; char *edge_faces = (char *)MEM_callocN(mesh->totedge * sizeof(char), "remesh_manifold_check"); @@ -691,17 +692,19 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) edge_vert[i] = -1; } - for (const MLoop &loop : loops) { - edge_faces[loop.e] += 1; - if (edge_faces[loop.e] > 2) { + for (const int corner_i : corner_verts.index_range()) { + const int vert = corner_verts[corner_i]; + const int edge = corner_edges[corner_i]; + edge_faces[edge] += 1; + if (edge_faces[edge] > 2) { is_manifold_consistent = false; break; } - if (edge_vert[loop.e] == -1) { - edge_vert[loop.e] = loop.v; + if (edge_vert[edge] == -1) { + edge_vert[edge] = vert; } - else if (edge_vert[loop.e] == loop.v) { + else if (edge_vert[edge] == vert) { /* Mesh has flips in the surface so it is non consistent */ is_manifold_consistent = false; break; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index bb12782cad5..5f953071804 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -91,7 +91,7 @@ struct AddOperationExecutor { Object *surface_ob_eval_ = nullptr; Mesh *surface_eval_ = nullptr; Span surface_positions_eval_; - Span surface_loops_eval_; + Span surface_corner_verts_eval_; Span surface_looptris_eval_; VArraySpan surface_uv_map_eval_; BVHTreeFromMesh surface_bvh_eval_; @@ -143,7 +143,7 @@ struct AddOperationExecutor { return; } surface_positions_eval_ = surface_eval_->vert_positions(); - surface_loops_eval_ = surface_eval_->loops(); + surface_corner_verts_eval_ = surface_eval_->corner_verts(); surface_looptris_eval_ = surface_eval_->looptris(); BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2); BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); }); @@ -306,7 +306,7 @@ struct AddOperationExecutor { const MLoopTri &looptri = surface_looptris_eval_[looptri_index]; const float3 brush_pos_su = ray_hit.co; const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle( - surface_positions_eval_, surface_loops_eval_, looptri, brush_pos_su); + surface_positions_eval_, surface_corner_verts_eval_, looptri, brush_pos_su); const float2 uv = bke::mesh_surface_sample::sample_corner_attrribute_with_bary_coords( bary_coords, looptri, surface_uv_map_eval_); @@ -436,9 +436,12 @@ struct AddOperationExecutor { brush_radius_su, [&](const int index, const float3 & /*co*/, const float /*dist_sq*/) { const MLoopTri &looptri = surface_looptris_eval_[index]; - const float3 &v0_su = surface_positions_eval_[surface_loops_eval_[looptri.tri[0]].v]; - const float3 &v1_su = surface_positions_eval_[surface_loops_eval_[looptri.tri[1]].v]; - const float3 &v2_su = surface_positions_eval_[surface_loops_eval_[looptri.tri[2]].v]; + const float3 &v0_su = + surface_positions_eval_[surface_corner_verts_eval_[looptri.tri[0]]]; + const float3 &v1_su = + surface_positions_eval_[surface_corner_verts_eval_[looptri.tri[1]]]; + const float3 &v2_su = + surface_positions_eval_[surface_corner_verts_eval_[looptri.tri[2]]]; float3 normal_su; normal_tri_v3(normal_su, v0_su, v1_su, v2_su); if (math::dot(normal_su, view_direction_su) >= 0.0f) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index f0745ef3d0d..8e484e4fb70 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -74,7 +74,7 @@ struct PuffOperationExecutor { Object *surface_ob_ = nullptr; Mesh *surface_ = nullptr; Span surface_positions_; - Span surface_loops_; + Span surface_corner_verts_; Span surface_looptris_; Span corner_normals_su_; BVHTreeFromMesh surface_bvh_; @@ -125,7 +125,7 @@ struct PuffOperationExecutor { surface_->totloop}; surface_positions_ = surface_->vert_positions(); - surface_loops_ = surface_->loops(); + surface_corner_verts_ = surface_->corner_verts(); surface_looptris_ = surface_->looptris(); BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2); BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); }); @@ -315,9 +315,9 @@ struct PuffOperationExecutor { const MLoopTri &looptri = surface_looptris_[nearest.index]; const float3 closest_pos_su = nearest.co; - const float3 &v0_su = surface_positions_[surface_loops_[looptri.tri[0]].v]; - const float3 &v1_su = surface_positions_[surface_loops_[looptri.tri[1]].v]; - const float3 &v2_su = surface_positions_[surface_loops_[looptri.tri[2]].v]; + const float3 &v0_su = surface_positions_[surface_corner_verts_[looptri.tri[0]]]; + const float3 &v1_su = surface_positions_[surface_corner_verts_[looptri.tri[1]]]; + const float3 &v2_su = surface_positions_[surface_corner_verts_[looptri.tri[2]]]; float3 bary_coords; interp_weights_tri_v3(bary_coords, v0_su, v1_su, v2_su, closest_pos_su); const float3 normal_su = geometry::compute_surface_point_normal( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index b4ce8ebc295..2f198b89da9 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -105,7 +105,7 @@ struct SlideOperationExecutor { Object *surface_ob_eval_ = nullptr; Mesh *surface_eval_ = nullptr; Span surface_positions_eval_; - Span surface_loops_eval_; + Span surface_corner_verts_eval_; Span surface_looptris_eval_; VArraySpan surface_uv_map_eval_; BVHTreeFromMesh surface_bvh_eval_; @@ -199,7 +199,7 @@ struct SlideOperationExecutor { } surface_looptris_eval_ = surface_eval_->looptris(); surface_positions_eval_ = surface_eval_->vert_positions(); - surface_loops_eval_ = surface_eval_->loops(); + surface_corner_verts_eval_ = surface_eval_->corner_verts(); surface_uv_map_eval_ = surface_eval_->attributes().lookup(uv_map_name, ATTR_DOMAIN_CORNER); if (surface_uv_map_eval_.is_empty()) { @@ -317,7 +317,7 @@ struct SlideOperationExecutor { const float4x4 brush_transform_inv = math::invert(brush_transform); const Span positions_orig_su = surface_orig_->vert_positions(); - const Span loops_orig = surface_orig_->loops(); + const Span corner_verts_orig = surface_orig_->corner_verts(); const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); MutableSpan positions_orig_cu = curves_orig_->positions_for_write(); @@ -383,7 +383,7 @@ struct SlideOperationExecutor { /* Compute the uv of the new surface position on the evaluated mesh. */ const MLoopTri &looptri_eval = surface_looptris_eval_[looptri_index_eval]; const float3 bary_weights_eval = bke::mesh_surface_sample::compute_bary_coord_in_triangle( - surface_positions_eval_, surface_loops_eval_, looptri_eval, hit_pos_eval_su); + surface_positions_eval_, surface_corner_verts_eval_, looptri_eval, hit_pos_eval_su); const float2 uv = attribute_math::mix3(bary_weights_eval, surface_uv_map_eval_[looptri_eval.tri[0]], surface_uv_map_eval_[looptri_eval.tri[1]], @@ -408,9 +408,9 @@ struct SlideOperationExecutor { /* Gather old and new surface position. */ const float3 new_first_pos_orig_su = attribute_math::mix3( bary_weights_orig, - positions_orig_su[loops_orig[looptri_orig.tri[0]].v], - positions_orig_su[loops_orig[looptri_orig.tri[1]].v], - positions_orig_su[loops_orig[looptri_orig.tri[2]].v]); + positions_orig_su[corner_verts_orig[looptri_orig.tri[0]]], + positions_orig_su[corner_verts_orig[looptri_orig.tri[1]]], + positions_orig_su[corner_verts_orig[looptri_orig.tri[2]]]); const float3 old_first_pos_orig_cu = self_->initial_positions_cu_[first_point_i]; const float3 new_first_pos_orig_cu = math::transform_point(transforms_.surface_to_curves, new_first_pos_orig_su); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index f4838823b35..31f0af2c489 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -414,7 +414,7 @@ struct ProjPaintState { blender::Span vert_normals; blender::Span edges_eval; blender::Span polys_eval; - blender::Span loops_eval; + blender::Span corner_verts_eval; const bool *select_poly_eval; const int *material_indices; const bool *sharp_faces_eval; @@ -508,8 +508,8 @@ struct VertSeam { * \{ */ #define PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) \ - int(ps->loops_eval[lt->tri[0]].v), int(ps->loops_eval[lt->tri[1]].v), \ - int(ps->loops_eval[lt->tri[2]].v), + ps->corner_verts_eval[lt->tri[0]], ps->corner_verts_eval[lt->tri[1]], \ + ps->corner_verts_eval[lt->tri[2]], #define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \ uvlayer[lt->poly][lt->tri[0]], uvlayer[lt->poly][lt->tri[1]], uvlayer[lt->poly][lt->tri[2]], @@ -674,9 +674,9 @@ static int project_paint_PickFace(const ProjPaintState *ps, const float pt[2], f const int tri_index = POINTER_AS_INT(node->link); const MLoopTri *lt = &ps->looptris_eval[tri_index]; const float *vtri_ss[3] = { - ps->screenCoords[ps->loops_eval[lt->tri[0]].v], - ps->screenCoords[ps->loops_eval[lt->tri[1]].v], - ps->screenCoords[ps->loops_eval[lt->tri[2]].v], + ps->screenCoords[ps->corner_verts_eval[lt->tri[0]]], + ps->screenCoords[ps->corner_verts_eval[lt->tri[1]]], + ps->screenCoords[ps->corner_verts_eval[lt->tri[2]]], }; if (isect_point_tri_v2(pt, UNPACK3(vtri_ss))) { @@ -916,17 +916,17 @@ static bool project_bucket_point_occluded(const ProjPaintState *ps, if (orig_face != tri_index) { const MLoopTri *lt = &ps->looptris_eval[tri_index]; const float *vtri_ss[3] = { - ps->screenCoords[ps->loops_eval[lt->tri[0]].v], - ps->screenCoords[ps->loops_eval[lt->tri[1]].v], - ps->screenCoords[ps->loops_eval[lt->tri[2]].v], + ps->screenCoords[ps->corner_verts_eval[lt->tri[0]]], + ps->screenCoords[ps->corner_verts_eval[lt->tri[1]]], + ps->screenCoords[ps->corner_verts_eval[lt->tri[2]]], }; float w[3]; if (do_clip) { const float *vtri_co[3] = { - ps->vert_positions_eval[ps->loops_eval[lt->tri[0]].v], - ps->vert_positions_eval[ps->loops_eval[lt->tri[1]].v], - ps->vert_positions_eval[ps->loops_eval[lt->tri[2]].v], + ps->vert_positions_eval[ps->corner_verts_eval[lt->tri[0]]], + ps->vert_positions_eval[ps->corner_verts_eval[lt->tri[1]]], + ps->vert_positions_eval[ps->corner_verts_eval[lt->tri[2]]], }; isect_ret = project_paint_occlude_ptv_clip( pixelScreenCo, UNPACK3(vtri_ss), UNPACK3(vtri_co), w, ps->is_ortho, ps->rv3d); @@ -1143,8 +1143,8 @@ static bool check_seam(const ProjPaintState *ps, const MLoopTri *orig_lt = &ps->looptris_eval[orig_face]; const float *orig_lt_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, orig_lt)}; /* vert indices from face vert order indices */ - const uint i1 = ps->loops_eval[orig_lt->tri[orig_i1_fidx]].v; - const uint i2 = ps->loops_eval[orig_lt->tri[orig_i2_fidx]].v; + const uint i1 = ps->corner_verts_eval[orig_lt->tri[orig_i1_fidx]]; + const uint i2 = ps->corner_verts_eval[orig_lt->tri[orig_i2_fidx]]; LinkNode *node; /* index in face */ int i1_fidx = -1, i2_fidx = -1; @@ -1329,8 +1329,8 @@ static void uv_image_outset(const ProjPaintState *ps, fidx[1] = (fidx[0] == 2) ? 0 : fidx[0] + 1; - vert[0] = ps->loops_eval[loop_index].v; - vert[1] = ps->loops_eval[ltri->tri[fidx[1]]].v; + vert[0] = ps->corner_verts_eval[loop_index]; + vert[1] = ps->corner_verts_eval[ltri->tri[fidx[1]]]; for (uint i = 0; i < 2; i++) { VertSeam *seam; @@ -1415,7 +1415,7 @@ static void insert_seam_vert_array(const ProjPaintState *ps, copy_v2_v2(vseam[1].uv, lt_tri_uv[fidx[1]]); for (uint i = 0; i < 2; i++) { - uint vert = ps->loops_eval[lt->tri[fidx[i]]].v; + const int vert = ps->corner_verts_eval[lt->tri[fidx[i]]]; ListBase *list = &ps->vertSeams[vert]; VertSeam *item = static_cast(list->first); @@ -1454,8 +1454,8 @@ static void project_face_seams_init(const ProjPaintState *ps, } do { - if (init_all || (ps->loops_eval[lt->tri[fidx[0]]].v == vert_index) || - (ps->loops_eval[lt->tri[fidx[1]]].v == vert_index)) { + if (init_all || (ps->corner_verts_eval[lt->tri[fidx[0]]] == vert_index) || + (ps->corner_verts_eval[lt->tri[fidx[1]]] == vert_index)) { if ((ps->faceSeamFlags[tri_index] & (PROJ_FACE_SEAM0 << fidx[0] | PROJ_FACE_NOSEAM0 << fidx[0])) == 0) { if (check_seam(ps, tri_index, fidx[0], fidx[1], &other_face, &other_fidx)) { @@ -1502,7 +1502,7 @@ static void project_face_seams_init(const ProjPaintState *ps, continue; } - vert = ps->loops_eval[lt->tri[fidx[i]]].v; + vert = ps->corner_verts_eval[lt->tri[fidx[i]]]; for (node = ps->vertFaces[vert]; node; node = node->next) { const int tri = POINTER_AS_INT(node->link); @@ -4072,7 +4072,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p ps->vert_normals = ps->me_eval->vert_normals(); ps->edges_eval = ps->me_eval->edges(); ps->polys_eval = ps->me_eval->polys(); - ps->loops_eval = ps->me_eval->loops(); + ps->corner_verts_eval = ps->me_eval->corner_verts(); 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( @@ -4391,7 +4391,8 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps, int poly_loops = poly.totloop; prev_poly = looptris[tri_index].poly; for (iloop = 0; iloop < poly_loops; iloop++) { - if (!(ps->vertFlags[ps->loops_eval[poly.loopstart + iloop].v] & PROJ_VERT_CULL)) { + if (!(ps->vertFlags[ps->corner_verts_eval[poly.loopstart + iloop]] & + PROJ_VERT_CULL)) { culled = false; break; } diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index a81838af5a4..64aa82cb20a 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -1243,15 +1243,15 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Write the front face triangle indices. */ blender::MutableSpan polys = trim_operation->mesh->polys_for_write(); - blender::MutableSpan loops = trim_operation->mesh->loops_for_write(); + blender::MutableSpan corner_verts = trim_operation->mesh->corner_verts_for_write(); int poly_index = 0; int loop_index = 0; for (int i = 0; i < tot_tris_face; i++) { polys[poly_index].loopstart = loop_index; polys[poly_index].totloop = 3; - loops[loop_index + 0].v = r_tris[i][0]; - loops[loop_index + 1].v = r_tris[i][1]; - loops[loop_index + 2].v = r_tris[i][2]; + corner_verts[loop_index + 0] = r_tris[i][0]; + corner_verts[loop_index + 1] = r_tris[i][1]; + corner_verts[loop_index + 2] = r_tris[i][2]; poly_index++; loop_index += 3; } @@ -1260,9 +1260,9 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex for (int i = 0; i < tot_tris_face; i++) { polys[poly_index].loopstart = loop_index; polys[poly_index].totloop = 3; - loops[loop_index + 0].v = r_tris[i][0] + tot_screen_points; - loops[loop_index + 1].v = r_tris[i][1] + tot_screen_points; - loops[loop_index + 2].v = r_tris[i][2] + tot_screen_points; + corner_verts[loop_index + 0] = r_tris[i][0] + tot_screen_points; + corner_verts[loop_index + 1] = r_tris[i][1] + tot_screen_points; + corner_verts[loop_index + 2] = r_tris[i][2] + tot_screen_points; poly_index++; loop_index += 3; } @@ -1278,9 +1278,9 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex if (next_index >= tot_screen_points) { next_index = 0; } - loops[loop_index + 0].v = next_index + tot_screen_points; - loops[loop_index + 1].v = next_index; - loops[loop_index + 2].v = current_index; + corner_verts[loop_index + 0] = next_index + tot_screen_points; + corner_verts[loop_index + 1] = next_index; + corner_verts[loop_index + 2] = current_index; poly_index++; loop_index += 3; } @@ -1293,9 +1293,9 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex if (next_index >= tot_screen_points) { next_index = 0; } - loops[loop_index + 0].v = current_index; - loops[loop_index + 1].v = current_index + tot_screen_points; - loops[loop_index + 2].v = next_index + tot_screen_points; + corner_verts[loop_index + 0] = current_index; + corner_verts[loop_index + 1] = current_index + tot_screen_points; + corner_verts[loop_index + 2] = next_index + tot_screen_points; poly_index++; loop_index += 3; } diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 4953ab84687..ba9a1c75446 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -274,7 +274,7 @@ static void imapaint_pick_uv( const int tottri = BKE_mesh_runtime_looptri_len(me_eval); const float(*positions)[3] = BKE_mesh_vert_positions(me_eval); - const MLoop *mloop = BKE_mesh_loops(me_eval); + const int *corner_verts = BKE_mesh_corner_verts(me_eval); const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); /* get the needed opengl matrices */ @@ -302,7 +302,7 @@ static void imapaint_pick_uv( float tri_co[3][3]; for (int j = 3; j--;) { - copy_v3_v3(tri_co[j], positions[mloop[lt->tri[j]].v]); + copy_v3_v3(tri_co[j], positions[corner_verts[lt->tri[j]]]); } if (mode == PAINT_CANVAS_SOURCE_MATERIAL) { diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 70ebd7fc077..36074b9c0e5 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -1241,7 +1241,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) Mesh *me = (Mesh *)ob->data; const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); if (gmap->vert_to_loop == nullptr) { gmap->vert_map_mem = nullptr; @@ -1251,14 +1251,14 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) BKE_mesh_vert_loop_map_create(&gmap->vert_to_loop, &gmap->vert_map_mem, polys.data(), - loops.data(), + corner_verts.data(), me->totvert, me->totpoly, me->totloop); BKE_mesh_vert_poly_map_create(&gmap->vert_to_poly, &gmap->poly_map_mem, polys.data(), - loops.data(), + corner_verts.data(), me->totvert, me->totpoly, me->totloop); @@ -1972,7 +1972,8 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : + vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; /* If the vertex is selected */ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) { @@ -1986,8 +1987,8 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, total_hit_loops += poly.totloop; for (int k = 0; k < poly.totloop; k++) { const int l_index = poly.loopstart + k; - const MLoop *ml = &ss->mloop[l_index]; - weight_final += data->wpd->precomputed_weight[ml->v]; + const int vert_i = ss->corner_verts[l_index]; + weight_final += data->wpd->precomputed_weight[vert_i]; } } @@ -2070,7 +2071,8 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : + vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; const float3 &mv_curr = ss->vert_positions[v_index]; @@ -2095,9 +2097,9 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const MPoly &poly = ss->polys[p_index]; - const MLoop *ml_other = &ss->mloop[poly.loopstart]; - for (int k = 0; k < poly.totloop; k++, ml_other++) { - const uint v_other_index = ml_other->v; + for (int k = 0; k < poly.totloop; k++) { + const int other_corner_i = poly.loopstart + k; + const int v_other_index = ss->corner_verts[other_corner_i]; if (v_other_index != v_index) { const float3 &mv_other = ss->vert_positions[v_other_index]; @@ -2180,7 +2182,8 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata, /* NOTE: grids are 1:1 with corners (aka loops). * For multires, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : + vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; /* If the vertex is selected */ @@ -2251,7 +2254,8 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(void *__restrict userdata, 1.0f; if (angle_cos > 0.0 && BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) { - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : + vd.vert_indices[vd.i]; /* If the vertex is selected. */ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) { @@ -3005,7 +3009,7 @@ static void do_vpaint_brush_blur_loops(bContext *C, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; @@ -3064,7 +3068,7 @@ static void do_vpaint_brush_blur_loops(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(ss->mloop[l_index].v == v_index); + BLI_assert(ss->corner_verts[l_index] == v_index); if (!use_face_sel || select_poly[p_index]) { Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ @@ -3150,7 +3154,7 @@ static void do_vpaint_brush_blur_verts(bContext *C, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; @@ -3180,7 +3184,7 @@ static void do_vpaint_brush_blur_verts(bContext *C, total_hit_loops += poly.totloop; for (int k = 0; k < poly.totloop; k++) { const uint l_index = poly.loopstart + k; - const uint v_index = ss->mloop[l_index].v; + const uint v_index = ss->corner_verts[l_index]; Color *col = lcol + v_index; @@ -3211,7 +3215,7 @@ static void do_vpaint_brush_blur_verts(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; - BLI_assert(ss->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index); + BLI_assert(ss->corner_verts[gmap->vert_to_loop[v_index].indices[j]] == v_index); if (!use_face_sel || select_poly[p_index]) { Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ @@ -3304,7 +3308,7 @@ static void do_vpaint_brush_smear(bContext *C, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; const float3 &mv_curr = &ss->vert_positions[v_index]; @@ -3336,13 +3340,13 @@ static void do_vpaint_brush_smear(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(ss->mloop[l_index].v == v_index); + BLI_assert(ss->corner_verts[l_index] == v_index); UNUSED_VARS_NDEBUG(l_index); const MPoly &poly = ss->polys[p_index]; if (!use_face_sel || select_poly[p_index]) { - const MLoop *ml_other = &ss->mloop[poly.loopstart]; - for (int k = 0; k < poly.totloop; k++, ml_other++) { - const uint v_other_index = ml_other->v; + for (int k = 0; k < poly.totloop; k++) { + const int other_corner_i = poly.loopstart + k; + const int v_other_index = ss->corner_verts[other_corner_i]; if (v_other_index != v_index) { const float3 &mv_other = &ss->vert_positions[v_other_index]; @@ -3358,7 +3362,7 @@ static void do_vpaint_brush_smear(bContext *C, int elem_index; if constexpr (domain == ATTR_DOMAIN_POINT) { - elem_index = ml_other->v; + elem_index = v_other_index; } else { elem_index = poly.loopstart + k; @@ -3390,7 +3394,7 @@ static void do_vpaint_brush_smear(bContext *C, else { const int l_index = gmap->vert_to_loop[v_index].indices[j]; elem_index = l_index; - BLI_assert(ss->mloop[l_index].v == v_index); + BLI_assert(ss->corner_verts[l_index] == v_index); } if (!use_face_sel || select_poly[p_index]) { @@ -3468,7 +3472,7 @@ static void calculate_average_color(VPaintData *vpd, BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : vd.vert_indices[vd.i]; if (BKE_brush_curve_strength(brush, 0.0, cache->radius) > 0.0) { /* If the vertex is selected for painting. */ @@ -3592,7 +3596,7 @@ static void vpaint_do_draw(bContext *C, /* NOTE: Grids are 1:1 with corners (aka loops). * For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; @@ -3648,7 +3652,7 @@ static void vpaint_do_draw(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(ss->mloop[l_index].v == v_index); + BLI_assert(ss->corner_verts[l_index] == v_index); if (!use_face_sel || select_poly[p_index]) { Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */ @@ -4120,7 +4124,7 @@ static void fill_mesh_face_or_corner_attribute(Mesh &mesh, ".select_poly", ATTR_DOMAIN_FACE, false); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); for (const int i : polys.index_range()) { if (use_face_sel && !select_poly[i]) { @@ -4130,7 +4134,7 @@ static void fill_mesh_face_or_corner_attribute(Mesh &mesh, int j = 0; do { - uint vidx = loops[poly.loopstart + j].v; + const int vidx = corner_verts[poly.loopstart + j]; if (!(use_vert_sel && !(select_vert[vidx]))) { if (domain == ATTR_DOMAIN_CORNER) { diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc index e0a0b8a5be8..46540486600 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc @@ -318,7 +318,7 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, ED_view3d_viewcontext_init(C, &vc, depsgraph); me = BKE_mesh_from_object(vc.obact); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); const MDeformVert *dverts = BKE_mesh_deform_verts(me); if (me && dverts && vc.v3d && vc.rv3d && me->vertex_group_names.first) { @@ -348,7 +348,7 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, uint fidx = poly.totloop - 1; do { - const MDeformVert *dvert = &dverts[loops[poly.loopstart + fidx].v]; + const MDeformVert *dvert = &dverts[corner_verts[poly.loopstart + fidx]]; found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups); } while (fidx--); } @@ -446,7 +446,7 @@ static bool weight_paint_set(Object *ob, float paintweight) const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); if (me->totpoly == 0 || dvert == nullptr) { @@ -477,7 +477,7 @@ static bool weight_paint_set(Object *ob, float paintweight) } do { - uint vidx = loops[poly.loopstart + fidx].v; + const int vidx = corner_verts[poly.loopstart + fidx]; if (!dvert[vidx].flag) { if ((paint_selmode == SCE_SELECT_VERTEX) && !(select_vert && select_vert[vidx])) { diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 668fc4312ff..65dc800e1f6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -727,8 +727,7 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss for (int i = 0; i < vert_map->count; i++) { const MPoly &poly = ss->polys[vert_map->indices[i]]; for (int l = 0; l < poly.totloop; l++) { - const MLoop *loop = &ss->mloop[poly.loopstart + l]; - if (loop->v == v2) { + if (ss->corner_verts[poly.loopstart + l] == v2) { if (p1 == -1) { p1 = vert_map->indices[i]; break; @@ -769,7 +768,7 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, PBVHVertRef vertex) coord.y = vertex_index / key->grid_size; int v1, v2; const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get( - ss->subdiv_ccg, &coord, ss->mloop, ss->polys, &v1, &v2); + ss->subdiv_ccg, &coord, ss->corner_verts, ss->polys, &v1, &v2); switch (adjacency) { case SUBDIV_CCG_ADJACENT_VERTEX: return sculpt_check_unique_face_set_in_base_mesh(ss, v1); @@ -890,7 +889,7 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, } const MPoly &poly = ss->polys[vert_map->indices[i]]; int f_adj_v[2]; - if (poly_get_adj_loops_from_vert(&poly, ss->mloop, vertex.i, f_adj_v) != -1) { + if (poly_get_adj_loops_from_vert(&poly, ss->corner_verts, vertex.i, f_adj_v) != -1) { for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { if (f_adj_v[j] != vertex.i) { sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(f_adj_v[j]), f_adj_v[j]); @@ -1004,7 +1003,7 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const PBVHVertRef vertex coord.y = vertex_index / key->grid_size; int v1, v2; const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get( - ss->subdiv_ccg, &coord, ss->mloop, ss->polys, &v1, &v2); + ss->subdiv_ccg, &coord, ss->corner_verts, ss->polys, &v1, &v2); switch (adjacency) { case SUBDIV_CCG_ADJACENT_VERTEX: return sculpt_check_boundary_vertex_in_base_mesh(ss, v1); @@ -6196,6 +6195,7 @@ struct SculptTopologyIDFloodFillData { void SCULPT_boundary_info_ensure(Object *object) { + using namespace blender; SculptSession *ss = object->sculpt; if (ss->vertex_info.boundary) { return; @@ -6204,7 +6204,7 @@ void SCULPT_boundary_info_ensure(Object *object) Mesh *base_mesh = BKE_mesh_from_object(object); const blender::Span edges = base_mesh->edges(); const blender::Span polys = base_mesh->polys(); - const blender::Span loops = base_mesh->loops(); + const Span corner_edges = base_mesh->corner_edges(); ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info"); int *adjacent_faces_edge_count = static_cast( @@ -6213,8 +6213,8 @@ void SCULPT_boundary_info_ensure(Object *object) for (const int p : polys.index_range()) { const MPoly &poly = polys[p]; for (int l = 0; l < poly.totloop; l++) { - const MLoop *loop = &loops[l + poly.loopstart]; - adjacent_faces_edge_count[loop->e]++; + const int edge_i = corner_edges[poly.loopstart + l]; + adjacent_faces_edge_count[edge_i]++; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc b/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc index ca7684fce6d..3e914f0fa76 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc @@ -326,7 +326,7 @@ static bool dyntopo_supports_layer(const CustomDataLayer &layer, const int elem_ return BM_attribute_stored_in_bmesh_builtin(layer.name); } /* Some layers just encode #Mesh topology or are handled as special cases for dyntopo. */ - return ELEM(layer.type, CD_MEDGE, CD_MPOLY, CD_MLOOP, CD_PAINT_MASK, CD_ORIGINDEX); + return ELEM(layer.type, CD_MEDGE, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX); } static bool dyntopo_supports_customdata_layers(const blender::Span layers, diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index a8f2634151f..c575fe71551 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -148,8 +148,8 @@ static bool sculpt_expand_is_face_in_active_component(SculptSession *ss, ExpandCache *expand_cache, const int f) { - const MLoop *loop = &ss->mloop[ss->polys[f].loopstart]; - return sculpt_expand_is_vert_in_active_component(ss, expand_cache, BKE_pbvh_make_vref(loop->v)); + const int vert = ss->corner_verts[ss->polys[f].loopstart]; + return sculpt_expand_is_vert_in_active_component(ss, expand_cache, BKE_pbvh_make_vref(vert)); } /** @@ -714,7 +714,7 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR for (int j = 0; j < ss->pmap[v_next_i].count; j++) { const MPoly &poly = ss->polys[ss->pmap[v_next_i].indices[j]]; for (int l = 0; l < poly.totloop; l++) { - const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(ss->mloop[poly.loopstart + l].v); + const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(ss->corner_verts[poly.loopstart + l]); if (BLI_BITMAP_TEST(visited_verts, neighbor_v.i)) { continue; } @@ -810,14 +810,14 @@ static void sculpt_expand_grids_to_faces_falloff(SculptSession *ss, static void sculpt_expand_vertex_to_faces_falloff(Mesh *mesh, ExpandCache *expand_cache) { const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); for (const int p : polys.index_range()) { const MPoly &poly = polys[p]; float accum = 0.0f; for (int l = 0; l < poly.totloop; l++) { - const MLoop *loop = &loops[l + poly.loopstart]; - accum += expand_cache->vert_falloff[loop->v]; + const int vert = corner_verts[poly.loopstart + l]; + accum += expand_cache->vert_falloff[vert]; } expand_cache->face_falloff[p] = accum / poly.totloop; } @@ -1119,8 +1119,8 @@ static void sculpt_expand_snap_initialize_from_enabled(SculptSession *ss, const MPoly &poly = ss->polys[p]; bool any_disabled = false; for (int l = 0; l < poly.totloop; l++) { - const MLoop *loop = &ss->mloop[l + poly.loopstart]; - if (!BLI_BITMAP_TEST(enabled_verts, loop->v)) { + const int vert = ss->corner_verts[l + poly.loopstart]; + if (!BLI_BITMAP_TEST(enabled_verts, vert)) { any_disabled = true; break; } @@ -1988,7 +1988,7 @@ static void sculpt_expand_delete_face_set_id(int *r_face_sets, const int totface = ss->totfaces; MeshElemMap *pmap = ss->pmap; const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); /* Check that all the face sets IDs in the mesh are not equal to `delete_id` * before attempting to delete it. */ @@ -2025,8 +2025,8 @@ static void sculpt_expand_delete_face_set_id(int *r_face_sets, int other_id = delete_id; const MPoly &c_poly = polys[f_index]; for (int l = 0; l < c_poly.totloop; l++) { - const MLoop *c_loop = &loops[c_poly.loopstart + l]; - const MeshElemMap *vert_map = &pmap[c_loop->v]; + const int vert = corner_verts[c_poly.loopstart + l]; + const MeshElemMap *vert_map = &pmap[vert]; for (int i = 0; i < vert_map->count; i++) { const int neighbor_face_index = vert_map->indices[i]; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 374d8e6f7d9..f0e51122d63 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -129,7 +129,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, const Span positions( reinterpret_cast(SCULPT_mesh_deformed_positions_get(ss)), SCULPT_vertex_count_get(ss)); - const Span loops(ss->mloop, data->me->totloop); + const Span corner_verts(ss->corner_verts, data->me->totloop); AutomaskingNodeData automask_data; SCULPT_automasking_node_begin( data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]); @@ -144,7 +144,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, const MPoly &poly = ss->polys[vert_map->indices[j]]; const float3 poly_center = bke::mesh::poly_center_calc( - positions, loops.slice(poly.loopstart, poly.totloop)); + positions, corner_verts.slice(poly.loopstart, poly.totloop)); if (!sculpt_brush_test_sq_fn(&test, poly_center)) { continue; @@ -552,7 +552,7 @@ static void sculpt_face_sets_init_flood_fill(Object *ob, const FaceSetsFloodFill const Span edges = mesh->edges(); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_edges = mesh->corner_edges(); if (!ss->epmap) { BKE_mesh_edge_poly_map_create(&ss->epmap, @@ -560,8 +560,8 @@ static void sculpt_face_sets_init_flood_fill(Object *ob, const FaceSetsFloodFill edges.size(), polys.data(), polys.size(), - loops.data(), - loops.size()); + corner_edges.data(), + corner_edges.size()); } int next_face_set = 1; @@ -581,8 +581,7 @@ static void sculpt_face_sets_init_flood_fill(Object *ob, const FaceSetsFloodFill const MPoly &poly = polys[poly_i]; queue.pop(); - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - const int edge_i = loop.e; + for (const int edge_i : corner_edges.slice(poly.loopstart, poly.totloop)) { const Span neighbor_polys(ss->epmap[edge_i].indices, ss->epmap[edge_i].count); for (const int neighbor_i : neighbor_polys) { if (neighbor_i == poly_i) { @@ -1110,18 +1109,18 @@ static void sculpt_face_set_grow(Object *ob, const int active_face_set_id, const bool modify_hidden) { + using namespace blender; Mesh *mesh = BKE_mesh_from_object(ob); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); for (const int p : polys.index_range()) { if (!modify_hidden && prev_face_sets[p] <= 0) { continue; } const MPoly &c_poly = polys[p]; - for (int l = 0; l < c_poly.totloop; l++) { - const MLoop *c_loop = &loops[c_poly.loopstart + l]; - const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; + for (const int vert : corner_verts.slice(c_poly.loopstart, c_poly.totloop)) { + const MeshElemMap *vert_map = &ss->pmap[vert]; for (int i = 0; i < vert_map->count; i++) { const int neighbor_face_index = vert_map->indices[i]; if (neighbor_face_index == p) { @@ -1141,18 +1140,18 @@ static void sculpt_face_set_shrink(Object *ob, const int active_face_set_id, const bool modify_hidden) { + using namespace blender; Mesh *mesh = BKE_mesh_from_object(ob); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); for (const int p : polys.index_range()) { if (!modify_hidden && prev_face_sets[p] <= 0) { continue; } if (abs(prev_face_sets[p]) == active_face_set_id) { const MPoly &c_poly = polys[p]; - for (int l = 0; l < c_poly.totloop; l++) { - const MLoop *c_loop = &loops[c_poly.loopstart + l]; - const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; + for (const int vert_i : corner_verts.slice(c_poly.loopstart, c_poly.totloop)) { + const MeshElemMap *vert_map = &ss->pmap[vert_i]; for (int i = 0; i < vert_map->count; i++) { const int neighbor_face_index = vert_map->indices[i]; if (neighbor_face_index == p) { diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc index 33fc931fca8..7a6f08f5f86 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc @@ -89,7 +89,8 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, float(*vert_positions)[3] = SCULPT_mesh_deformed_positions_get(ss); const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); + const blender::Span corner_edges = mesh->corner_edges(); float *dists = static_cast(MEM_malloc_arrayN(totvert, sizeof(float), __func__)); BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag"); @@ -100,8 +101,8 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, edges.size(), polys.data(), polys.size(), - loops.data(), - loops.size()); + corner_edges.data(), + corner_edges.size()); } if (!ss->vemap) { BKE_mesh_vert_edge_map_create( @@ -183,8 +184,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, } for (int loop_index = 0; loop_index < polys[poly].totloop; loop_index++) { - const MLoop *mloop = &loops[loop_index + polys[poly].loopstart]; - const int v_other = mloop->v; + const int v_other = corner_verts[loop_index + polys[poly].loopstart]; if (ELEM(v_other, v1, v2)) { continue; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index e0c2a6852af..0673a5acced 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -165,16 +165,11 @@ static std::unique_ptr build_mesh_debug_columns(const Mesh &mesh, return {}; } case ATTR_DOMAIN_CORNER: { - const Span loops = mesh.loops(); if (name == "Vertex") { - return std::make_unique( - name, - VArray::ForFunc(loops.size(), [loops](int64_t index) { return loops[index].v; })); + return std::make_unique(name, VArray::ForSpan(mesh.corner_verts())); } if (name == "Edge") { - return std::make_unique( - name, - VArray::ForFunc(loops.size(), [loops](int64_t index) { return loops[index].e; })); + return std::make_unique(name, VArray::ForSpan(mesh.corner_edges())); } return {}; } diff --git a/source/blender/editors/space_view3d/drawobject.cc b/source/blender/editors/space_view3d/drawobject.cc index 835b2d6d0d0..2754ffa7651 100644 --- a/source/blender/editors/space_view3d/drawobject.cc +++ b/source/blender/editors/space_view3d/drawobject.cc @@ -71,13 +71,13 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, const float(*positions)[3] = BKE_mesh_vert_positions(me); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); const blender::Span looptris = me->looptris(); facemap_data = static_cast(CustomData_get_layer(&me->pdata, CD_FACEMAP)); /* Make a batch and free it each time for now. */ - const int looptris_len = poly_to_tri_count(polys.size(), loops.size()); + const int looptris_len = poly_to_tri_count(polys.size(), corner_verts.size()); const int vbo_len_capacity = looptris_len * 3; int vbo_len_used = 0; @@ -97,11 +97,11 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, if (facemap_data[i] == facemap) { for (int j = 2; j < poly.totloop; j++) { copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), - positions[loops[looptris[tri_index].tri[0]].v]); + positions[corner_verts[looptris[tri_index].tri[0]]]); copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), - positions[loops[looptris[tri_index].tri[1]].v]); + positions[corner_verts[looptris[tri_index].tri[1]]]); copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), - positions[loops[looptris[tri_index].tri[2]].v]); + positions[corner_verts[looptris[tri_index].tri[2]]]); vbo_len_used += 3; tri_index++; } diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 394779865f3..0c64183be15 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -243,7 +243,7 @@ static void snap_object_data_mesh_get(SnapObjectContext *sctx, { const Span vert_positions = me_eval->vert_positions(); const Span polys = me_eval->polys(); - const Span loops = me_eval->loops(); + const Span corner_verts = me_eval->corner_verts(); if (ob_eval->type == OB_MESH) { /* Any existing #SnapData_EditMesh is now invalid. */ @@ -256,11 +256,11 @@ static void snap_object_data_mesh_get(SnapObjectContext *sctx, BLI_assert(reinterpret_cast(r_treedata->vert_positions) == vert_positions.data()); - BLI_assert(r_treedata->loop == loops.data()); + BLI_assert(r_treedata->corner_verts == corner_verts.data()); BLI_assert(!polys.data() || r_treedata->looptri); BLI_assert(!r_treedata->tree || r_treedata->looptri); - UNUSED_VARS_NDEBUG(vert_positions, polys, loops); + UNUSED_VARS_NDEBUG(vert_positions, polys, corner_verts); } /* Searches for the #Mesh_Runtime associated with the object that is most likely to be updated due @@ -624,9 +624,9 @@ static void mesh_looptri_raycast_backface_culling_cb(void *userdata, const float(*vert_positions)[3] = data->vert_positions; const MLoopTri *lt = &data->looptri[index]; const float *vtri_co[3] = { - vert_positions[data->loop[lt->tri[0]].v], - vert_positions[data->loop[lt->tri[1]].v], - vert_positions[data->loop[lt->tri[2]].v], + vert_positions[data->corner_verts[lt->tri[0]]], + vert_positions[data->corner_verts[lt->tri[1]]], + vert_positions[data->corner_verts[lt->tri[2]]], }; float dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(vtri_co)); @@ -1429,7 +1429,8 @@ struct Nearest2dUserData { const float (*vert_positions)[3]; const blender::float3 *vert_normals; const MEdge *edges; /* only used for #BVHTreeFromMeshEdges */ - const MLoop *loop; + const int *corner_verts; + const int *corner_edges; const MLoopTri *looptris; }; }; @@ -1480,14 +1481,15 @@ static void cb_bedge_verts_get(const int index, const Nearest2dUserData *data, i static void cb_mlooptri_edges_get(const int index, const Nearest2dUserData *data, int r_v_index[3]) { const MEdge *edges = data->edges; - const MLoop *mloop = data->loop; + const int *corner_verts = data->corner_verts; + const int *corner_edges = data->corner_edges; const MLoopTri *lt = &data->looptris[index]; for (int j = 2, j_next = 0; j_next < 3; j = j_next++) { - const MEdge *edge = &edges[mloop[lt->tri[j]].e]; - const uint tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v}; + const MEdge *edge = &edges[corner_edges[lt->tri[j]]]; + const int tri_edge[2] = {corner_verts[lt->tri[j]], corner_verts[lt->tri[j_next]]}; if (ELEM(edge->v1, tri_edge[0], tri_edge[1]) && ELEM(edge->v2, tri_edge[0], tri_edge[1])) { // printf("real edge found\n"); - r_v_index[j] = mloop[lt->tri[j]].e; + r_v_index[j] = corner_edges[lt->tri[j]]; } else { r_v_index[j] = -1; @@ -1497,12 +1499,12 @@ static void cb_mlooptri_edges_get(const int index, const Nearest2dUserData *data static void cb_mlooptri_verts_get(const int index, const Nearest2dUserData *data, int r_v_index[3]) { - const MLoop *loop = data->loop; + const int *corner_verts = data->corner_verts; const MLoopTri *looptri = &data->looptris[index]; - r_v_index[0] = loop[looptri->tri[0]].v; - r_v_index[1] = loop[looptri->tri[1]].v; - r_v_index[2] = loop[looptri->tri[2]].v; + r_v_index[0] = corner_verts[looptri->tri[0]]; + r_v_index[1] = corner_verts[looptri->tri[1]]; + r_v_index[2] = corner_verts[looptri->tri[2]]; } static bool test_projected_vert_dist(const DistProjectedAABBPrecalc *precalc, @@ -1718,7 +1720,8 @@ static void nearest2d_data_init_mesh(const Mesh *mesh, r_nearest2d->vert_positions = BKE_mesh_vert_positions(mesh); r_nearest2d->vert_normals = mesh->vert_normals().data(); r_nearest2d->edges = mesh->edges().data(); - r_nearest2d->loop = mesh->loops().data(); + r_nearest2d->corner_verts = mesh->corner_verts().data(); + r_nearest2d->corner_edges = mesh->corner_edges().data(); r_nearest2d->looptris = mesh->looptris().data(); r_nearest2d->is_persp = is_persp; @@ -1783,13 +1786,14 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx, &nearest2d); const MPoly &poly = mesh->polys()[sctx->ret.index]; - const MLoop *ml = &nearest2d.loop[poly.loopstart]; + if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { elem = SCE_SNAP_MODE_EDGE; BLI_assert(nearest2d.edges != nullptr); - for (int i = poly.totloop; i--; ml++) { + const int *poly_edges = &nearest2d.corner_edges[poly.loopstart]; + for (int i = poly.totloop; i--;) { cb_snap_edge(&nearest2d, - int(ml->e), + poly_edges[i], &neasrest_precalc, clip_planes_local, sctx->runtime.clip_plane_len, @@ -1798,9 +1802,10 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx, } else { elem = SCE_SNAP_MODE_VERTEX; - for (int i = poly.totloop; i--; ml++) { + const int *poly_verts = &nearest2d.corner_verts[poly.loopstart]; + for (int i = poly.totloop; i--;) { cb_snap_vert(&nearest2d, - int(ml->v), + poly_verts[i], &neasrest_precalc, clip_planes_local, sctx->runtime.clip_plane_len, diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 6f9276c94ed..9666deeba74 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -639,7 +639,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, const float(*subsurfedPositions)[3] = BKE_mesh_vert_positions(subdiv_mesh); const blender::Span subsurf_edges = subdiv_mesh->edges(); const blender::Span subsurf_polys = subdiv_mesh->polys(); - const blender::Span subsurf_loops = subdiv_mesh->loops(); + const blender::Span subsurf_corner_verts = subdiv_mesh->corner_verts(); const int *origVertIndices = static_cast( CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX)); @@ -691,32 +691,52 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, } } - const MLoop *mloop = &subsurf_loops[poly.loopstart]; + const int *poly_corner_verts = &subsurf_corner_verts[poly.loopstart]; /* We will not check for v4 here. Sub-surface faces always have 4 vertices. */ BLI_assert(poly.totloop == 4); key = (ParamKey)i; - vkeys[0] = (ParamKey)mloop[0].v; - vkeys[1] = (ParamKey)mloop[1].v; - vkeys[2] = (ParamKey)mloop[2].v; - vkeys[3] = (ParamKey)mloop[3].v; + vkeys[0] = (ParamKey)poly_corner_verts[0]; + vkeys[1] = (ParamKey)poly_corner_verts[1]; + vkeys[2] = (ParamKey)poly_corner_verts[2]; + vkeys[3] = (ParamKey)poly_corner_verts[3]; - co[0] = subsurfedPositions[mloop[0].v]; - co[1] = subsurfedPositions[mloop[1].v]; - co[2] = subsurfedPositions[mloop[2].v]; - co[3] = subsurfedPositions[mloop[3].v]; + co[0] = subsurfedPositions[poly_corner_verts[0]]; + co[1] = subsurfedPositions[poly_corner_verts[1]]; + co[2] = subsurfedPositions[poly_corner_verts[2]]; + co[3] = subsurfedPositions[poly_corner_verts[3]]; /* This is where all the magic is done. * If the vertex exists in the, we pass the original uv pointer to the solver, thus * flushing the solution to the edit mesh. */ - texface_from_original_index( - scene, offsets, origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0]); - texface_from_original_index( - scene, offsets, origFace, origVertIndices[mloop[1].v], &uv[1], &pin[1], &select[1]); - texface_from_original_index( - scene, offsets, origFace, origVertIndices[mloop[2].v], &uv[2], &pin[2], &select[2]); - texface_from_original_index( - scene, offsets, origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3]); + texface_from_original_index(scene, + offsets, + origFace, + origVertIndices[poly_corner_verts[0]], + &uv[0], + &pin[0], + &select[0]); + texface_from_original_index(scene, + offsets, + origFace, + origVertIndices[poly_corner_verts[1]], + &uv[1], + &pin[1], + &select[1]); + texface_from_original_index(scene, + offsets, + origFace, + origVertIndices[poly_corner_verts[2]], + &uv[2], + &pin[2], + &select[2]); + texface_from_original_index(scene, + offsets, + origFace, + origVertIndices[poly_corner_verts[3]], + &uv[3], + &pin[3], + &select[3]); blender::geometry::uv_parametrizer_face_add(handle, key, 4, vkeys, co, uv, pin, select); } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 3b9670a9d9b..c9c65150a13 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -385,18 +385,19 @@ int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3 static bool testEdgeMark(Mesh *me, const FreestyleEdge *fed, const MLoopTri *lt, int i) { const Span edges = me->edges(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); + const Span corner_edges = me->corner_edges(); - const MLoop *mloop = &loops[lt->tri[i]]; - const MLoop *mloop_next = &loops[lt->tri[(i + 1) % 3]]; - const MEdge *edge = &edges[mloop->e]; + const int corner = lt->tri[i]; + const int corner_next = lt->tri[(i + 1) % 3]; + const MEdge *edge = &edges[corner_edges[corner]]; - if (!ELEM(mloop_next->v, edge->v1, edge->v2)) { + if (!ELEM(corner_verts[corner_next], edge->v1, edge->v2)) { /* Not an edge in the original mesh before triangulation. */ return false; } - return (fed[mloop->e].flag & FREESTYLE_EDGE_MARK) != 0; + return (fed[corner_edges[corner]].flag & FREESTYLE_EDGE_MARK) != 0; } void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) @@ -406,12 +407,12 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) const Span vert_positions = me->vert_positions(); const Span mesh_polys = me->polys(); - const Span mesh_loops = me->loops(); + const Span corner_verts = me->corner_verts(); // Compute loop triangles int tottri = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *mlooptri = (MLoopTri *)MEM_malloc_arrayN(tottri, sizeof(*mlooptri), __func__); - blender::bke::mesh::looptris_calc(vert_positions, mesh_polys, mesh_loops, {mlooptri, tottri}); + blender::bke::mesh::looptris_calc(vert_positions, mesh_polys, corner_verts, {mlooptri, tottri}); // Compute loop normals BKE_mesh_calc_normals_split(me); @@ -448,9 +449,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) for (int a = 0; a < tottri; a++) { const MLoopTri *lt = &mlooptri[a]; - copy_v3_v3(v1, vert_positions[mesh_loops[lt->tri[0]].v]); - copy_v3_v3(v2, vert_positions[mesh_loops[lt->tri[1]].v]); - copy_v3_v3(v3, vert_positions[mesh_loops[lt->tri[2]].v]); + copy_v3_v3(v1, vert_positions[corner_verts[lt->tri[0]]]); + copy_v3_v3(v2, vert_positions[corner_verts[lt->tri[1]]]); + copy_v3_v3(v3, vert_positions[corner_verts[lt->tri[2]]]); mul_m4_v3(obmat, v1); mul_m4_v3(obmat, v2); @@ -523,9 +524,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) const MLoopTri *lt = &mlooptri[a]; Material *mat = BKE_object_material_get(ob, material_indices[lt->poly] + 1); - copy_v3_v3(v1, vert_positions[mesh_loops[lt->tri[0]].v]); - copy_v3_v3(v2, vert_positions[mesh_loops[lt->tri[1]].v]); - copy_v3_v3(v3, vert_positions[mesh_loops[lt->tri[2]].v]); + copy_v3_v3(v1, vert_positions[corner_verts[lt->tri[0]]]); + copy_v3_v3(v2, vert_positions[corner_verts[lt->tri[1]]]); + copy_v3_v3(v3, vert_positions[corner_verts[lt->tri[2]]]); mul_m4_v3(obmat, v1); mul_m4_v3(obmat, v2); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 9cad3c1eb72..5c3d527d2bc 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -587,8 +587,10 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) &mesh->edata, CD_MEDGE, CD_SET_DEFAULT, mesh->totedge); MPoly *polys = (MPoly *)CustomData_add_layer( &mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, mesh->totpoly); - MLoop *loops = (MLoop *)CustomData_add_layer( - &mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, mesh->totloop); + int *corner_verts = (int *)CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert"); + int *corner_edges = (int *)CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert"); int *material_indices = (int *)CustomData_add_layer_named( &mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totpoly, "material_index"); blender::float2 *loopsuv[2] = {nullptr}; @@ -718,26 +720,27 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) bool is_odd = n % 2; // loops if (is_odd) { - loops[0].v = vertex_index - 1; - loops[0].e = edge_index - 2; + corner_verts[0] = vertex_index - 1; + corner_edges[0] = edge_index - 2; - loops[1].v = vertex_index - 3; - loops[1].e = edge_index - 3; + corner_verts[1] = vertex_index - 3; + corner_edges[1] = edge_index - 3; - loops[2].v = vertex_index - 2; - loops[2].e = edge_index - 1; + corner_verts[2] = vertex_index - 2; + corner_edges[2] = edge_index - 1; } else { - loops[0].v = vertex_index - 1; - loops[0].e = edge_index - 1; + corner_verts[0] = vertex_index - 1; + corner_edges[0] = edge_index - 1; - loops[1].v = vertex_index - 2; - loops[1].e = edge_index - 3; + corner_verts[1] = vertex_index - 2; + corner_edges[1] = edge_index - 3; - loops[2].v = vertex_index - 3; - loops[2].e = edge_index - 2; + corner_verts[2] = vertex_index - 3; + corner_edges[2] = edge_index - 2; } - loops += 3; + corner_verts += 3; + corner_edges += 3; loop_index += 3; // UV diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index ec066307f76..fe9f4d15056 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -252,7 +252,7 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, /* Find faces that the passed in uvs belong to. */ const Span surface_positions = inputs.surface->vert_positions(); - const Span surface_loops = inputs.surface->loops(); + const Span surface_corner_verts = inputs.surface->corner_verts(); for (const int i : inputs.uvs.index_range()) { const float2 &uv = inputs.uvs[i]; const ReverseUVSampler::Result result = inputs.reverse_uv_sampler->sample(uv); @@ -265,9 +265,9 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, looptris.append(&looptri); const float3 root_position_su = attribute_math::mix3( result.bary_weights, - surface_positions[surface_loops[looptri.tri[0]].v], - surface_positions[surface_loops[looptri.tri[1]].v], - surface_positions[surface_loops[looptri.tri[2]].v]); + surface_positions[surface_corner_verts[looptri.tri[0]]], + surface_positions[surface_corner_verts[looptri.tri[1]]], + surface_positions[surface_corner_verts[looptri.tri[2]]]); root_positions_cu.append( math::transform_point(inputs.transforms->surface_to_curves, root_position_su)); used_uvs.append(uv); diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index ebd2883abdc..6a494da82f5 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -115,7 +115,8 @@ struct WeldLoopOfPolyIter { int loop_start; int loop_end; Span wloop; - Span mloop; + Span corner_verts; + Span corner_edges; Span loop_map; /* Weld group. */ int *group; @@ -138,7 +139,8 @@ struct WeldLoopOfPolyIter { static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter &iter, const WeldPoly &wp, Span wloop, - Span mloop, + const Span corner_verts, + const Span corner_edges, Span loop_map, int *group_buffer); @@ -159,21 +161,27 @@ static void weld_assert_edge_kill_len(Span wedge, const int supposed_k } static void weld_assert_poly_and_loop_kill_len(WeldMesh *weld_mesh, - Span mloop, + const Span corner_verts, + const Span corner_edges, Span polys, const int supposed_poly_kill_len, const int supposed_loop_kill_len) { int poly_kills = 0; - int loop_kills = mloop.size(); + int loop_kills = corner_verts.size(); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; int poly_ctx = weld_mesh->poly_map[i]; if (poly_ctx != OUT_OF_CONTEXT) { const WeldPoly *wp = &weld_mesh->wpoly[poly_ctx]; WeldLoopOfPolyIter iter; - if (!weld_iter_loop_of_poly_begin( - iter, *wp, weld_mesh->wloop, mloop, weld_mesh->loop_map, nullptr)) { + if (!weld_iter_loop_of_poly_begin(iter, + *wp, + weld_mesh->wloop, + corner_verts, + corner_edges, + weld_mesh->loop_map, + nullptr)) { poly_kills++; continue; } @@ -245,13 +253,15 @@ static void weld_assert_poly_and_loop_kill_len(WeldMesh *weld_mesh, static void weld_assert_poly_no_vert_repetition(const WeldPoly &wp, Span wloop, - Span mloop, + const Span corner_verts, + const Span corner_edges, Span loop_map) { const int loop_len = wp.loop_len; Array verts(loop_len); WeldLoopOfPolyIter iter; - if (!weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { + if (!weld_iter_loop_of_poly_begin( + iter, wp, wloop, corner_verts, corner_edges, loop_map, nullptr)) { return; } else { @@ -672,7 +682,8 @@ static void weld_edge_groups_setup(const int edges_len, static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter &iter, const WeldPoly &wp, Span wloop, - Span mloop, + const Span corner_verts, + const Span corner_edges, Span loop_map, int *group_buffer) { @@ -683,7 +694,8 @@ static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter &iter, iter.loop_start = wp.loop_start; iter.loop_end = wp.loop_end; iter.wloop = wloop; - iter.mloop = mloop; + iter.corner_verts = corner_verts; + iter.corner_edges = corner_edges; iter.loop_map = loop_map; iter.group = group_buffer; @@ -756,12 +768,11 @@ static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter &iter) iter.type = 1; } else { - const MLoop &ml = iter.mloop[l]; #ifdef USE_WELD_DEBUG - BLI_assert(uint(iter.v) != ml.v); + BLI_assert(iter.v != iter.corner_verts[l]); #endif - iter.v = ml.v; - iter.e = ml.e; + iter.v = iter.corner_verts[l]; + iter.e = iter.corner_edges[l]; iter.type = 0; } if (iter.group) { @@ -780,20 +791,21 @@ static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter &iter) * \return r_weld_mesh: Loop and poly members will be allocated here. */ static void weld_poly_loop_ctx_alloc(Span polys, - Span mloop, + const Span corner_verts, + const Span corner_edges, Span vert_dest_map, Span edge_dest_map, WeldMesh *r_weld_mesh) { /* Loop/Poly Context. */ - Array loop_map(mloop.size()); + Array loop_map(corner_verts.size()); Array poly_map(polys.size()); int wloop_len = 0; int wpoly_len = 0; int max_ctx_poly_len = 4; Vector wloop; - wloop.reserve(mloop.size()); + wloop.reserve(corner_verts.size()); Vector wpoly; wpoly.reserve(polys.size()); @@ -806,9 +818,9 @@ static void weld_poly_loop_ctx_alloc(Span polys, const int totloop = poly.totloop; int prev_wloop_len = wloop_len; - for (const int i_loop : mloop.index_range().slice(loopstart, totloop)) { - int v = mloop[i_loop].v; - int e = mloop[i_loop].e; + for (const int i_loop : IndexRange(loopstart, totloop)) { + int v = corner_verts[i_loop]; + int e = corner_edges[i_loop]; int v_dest = vert_dest_map[v]; int e_dest = edge_dest_map[e]; bool is_vert_ctx = v_dest != OUT_OF_CONTEXT; @@ -866,7 +878,8 @@ static void weld_poly_loop_ctx_alloc(Span polys, static void weld_poly_split_recursive(Span vert_dest_map, #ifdef USE_WELD_DEBUG - const Span mloop, + const Span corner_verts, + const Span corner_edges, #endif int ctx_verts_len, WeldPoly *r_wp, @@ -966,7 +979,8 @@ static void weld_poly_split_recursive(Span vert_dest_map, r_weld_mesh->wpoly_new_len++; weld_poly_split_recursive(vert_dest_map, #ifdef USE_WELD_DEBUG - mloop, + corner_verts, + corner_edges, #endif ctx_verts_len, new_wp, @@ -1003,7 +1017,8 @@ static void weld_poly_split_recursive(Span vert_dest_map, *r_loop_kill += loop_kill; #ifdef USE_WELD_DEBUG - weld_assert_poly_no_vert_repetition(*r_wp, wloop, mloop, r_weld_mesh->loop_map); + weld_assert_poly_no_vert_repetition( + *r_wp, wloop, corner_verts, corner_edges, r_weld_mesh->loop_map); #endif } @@ -1018,7 +1033,8 @@ static void weld_poly_split_recursive(Span vert_dest_map, */ static void weld_poly_loop_ctx_setup_collapsed_and_split( #ifdef USE_WELD_DEBUG - Span mloop, + const Span corner_verts, + const Span corner_edges, Span polys, #endif Span vert_dest_map, @@ -1271,7 +1287,8 @@ static int poly_find_doubles(const OffsetIndices poly_corners_offsets, return doubles_buffer_num - (r_doubles_offsets.size() - 1); } -static void weld_poly_find_doubles(Span mloop, +static void weld_poly_find_doubles(const Span corner_verts, + const Span corner_edges, #ifdef USE_WELD_DEBUG const Span polys, #endif @@ -1289,14 +1306,15 @@ static void weld_poly_find_doubles(Span mloop, const int poly_len = r_weld_mesh->wpoly.size(); Array poly_offs(poly_len + 1); - Vector corner_edges; - corner_edges.reserve(mloop.size() - r_weld_mesh->loop_kill_len); + Vector new_corner_edges; + new_corner_edges.reserve(corner_verts.size() - r_weld_mesh->loop_kill_len); for (const WeldPoly &wp : r_weld_mesh->wpoly) { - poly_offs[poly_index++] = corner_edges.size(); + poly_offs[poly_index++] = new_corner_edges.size(); WeldLoopOfPolyIter iter; - if (!weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { + if (!weld_iter_loop_of_poly_begin( + iter, wp, wloop, corner_verts, corner_edges, loop_map, nullptr)) { continue; } @@ -1305,17 +1323,17 @@ static void weld_poly_find_doubles(Span mloop, } while (weld_iter_loop_of_poly_next(iter)) { - corner_edges.append(iter.e); + new_corner_edges.append(iter.e); } } - poly_offs[poly_len] = corner_edges.size(); + poly_offs[poly_len] = new_corner_edges.size(); Vector doubles_offsets; Array doubles_buffer; const int doubles_num = poly_find_doubles(OffsetIndices(poly_offs), poly_len, - corner_edges, + new_corner_edges, medge_len, doubles_offsets, doubles_buffer); @@ -1361,7 +1379,8 @@ static void weld_mesh_context_create(const Mesh &mesh, { const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); + const Span corner_edges = mesh.corner_edges(); Vector wvert = weld_vert_ctx_alloc_and_setup(vert_dest_map, vert_kill_len); r_weld_mesh->vert_kill_len = vert_kill_len; @@ -1377,18 +1396,21 @@ static void weld_mesh_context_create(const Mesh &mesh, wedge, &r_weld_mesh->edge_kill_len); - weld_poly_loop_ctx_alloc(polys, loops, vert_dest_map, edge_dest_map, r_weld_mesh); + weld_poly_loop_ctx_alloc( + polys, corner_verts, corner_edges, vert_dest_map, edge_dest_map, r_weld_mesh); weld_poly_loop_ctx_setup_collapsed_and_split( #ifdef USE_WELD_DEBUG - loops, + corner_verts, + corner_edges, polys, #endif vert_dest_map, wedge.size() - r_weld_mesh->edge_kill_len, r_weld_mesh); - weld_poly_find_doubles(loops, + weld_poly_find_doubles(corner_verts, + corner_edges, #ifdef USE_WELD_DEBUG polys, #endif @@ -1512,7 +1534,8 @@ static Mesh *create_merged_mesh(const Mesh &mesh, const int removed_vertex_count) { const Span src_polys = mesh.polys(); - const Span src_loops = mesh.loops(); + const Span src_corner_verts = mesh.corner_verts(); + const Span src_corner_edges = mesh.corner_edges(); const int totvert = mesh.totvert; const int totedge = mesh.totedge; @@ -1525,14 +1548,15 @@ static Mesh *create_merged_mesh(const Mesh &mesh, const int result_nverts = totvert - weld_mesh.vert_kill_len; const int result_nedges = totedge - weld_mesh.edge_kill_len; - const int result_nloops = src_loops.size() - weld_mesh.loop_kill_len; + const int result_nloops = src_corner_verts.size() - weld_mesh.loop_kill_len; const int result_npolys = src_polys.size() - weld_mesh.poly_kill_len + weld_mesh.wpoly_new_len; Mesh *result = BKE_mesh_new_nomain_from_template( &mesh, result_nverts, result_nedges, result_nloops, result_npolys); MutableSpan dst_edges = result->edges_for_write(); MutableSpan dst_polys = result->polys_for_write(); - MutableSpan dst_loops = result->loops_for_write(); + MutableSpan dst_corner_verts = result->corner_verts_for_write(); + MutableSpan dst_corner_edges = result->corner_edges_for_write(); /* Vertices. */ @@ -1620,7 +1644,6 @@ static Mesh *create_merged_mesh(const Mesh &mesh, /* Polys/Loops. */ - MLoop *r_ml = dst_loops.data(); int r_i = 0; int loop_cur = 0; Array group_buffer(weld_mesh.max_poly_len); @@ -1631,17 +1654,21 @@ static Mesh *create_merged_mesh(const Mesh &mesh, if (poly_ctx == OUT_OF_CONTEXT) { int mp_loop_len = poly.totloop; CustomData_copy_data(&mesh.ldata, &result->ldata, poly.loopstart, loop_cur, mp_loop_len); - loop_cur += mp_loop_len; - for (; mp_loop_len--; r_ml++) { - r_ml->v = vert_final_map[r_ml->v]; - r_ml->e = edge_final_map[r_ml->e]; + for (; mp_loop_len--; loop_cur++) { + dst_corner_verts[loop_cur] = vert_final_map[dst_corner_verts[loop_cur]]; + dst_corner_edges[loop_cur] = edge_final_map[dst_corner_edges[loop_cur]]; } } else { const WeldPoly &wp = weld_mesh.wpoly[poly_ctx]; WeldLoopOfPolyIter iter; - if (!weld_iter_loop_of_poly_begin( - iter, wp, weld_mesh.wloop, src_loops, weld_mesh.loop_map, group_buffer.data())) { + if (!weld_iter_loop_of_poly_begin(iter, + wp, + weld_mesh.wloop, + src_corner_verts, + src_corner_edges, + weld_mesh.loop_map, + group_buffer.data())) { continue; } @@ -1651,11 +1678,8 @@ static Mesh *create_merged_mesh(const Mesh &mesh, while (weld_iter_loop_of_poly_next(iter)) { customdata_weld( &mesh.ldata, &result->ldata, group_buffer.data(), iter.group_len, loop_cur); - int v = vert_final_map[iter.v]; - int e = edge_final_map[iter.e]; - r_ml->v = v; - r_ml->e = e; - r_ml++; + dst_corner_verts[loop_cur] = vert_final_map[iter.v]; + dst_corner_edges[loop_cur] = edge_final_map[iter.e]; loop_cur++; } } @@ -1671,8 +1695,13 @@ static Mesh *create_merged_mesh(const Mesh &mesh, const WeldPoly &wp = weld_mesh.wpoly[i]; const int loop_start = loop_cur; WeldLoopOfPolyIter iter; - if (!weld_iter_loop_of_poly_begin( - iter, wp, weld_mesh.wloop, src_loops, weld_mesh.loop_map, group_buffer.data())) { + if (!weld_iter_loop_of_poly_begin(iter, + wp, + weld_mesh.wloop, + src_corner_verts, + src_corner_edges, + weld_mesh.loop_map, + group_buffer.data())) { continue; } @@ -1681,11 +1710,8 @@ static Mesh *create_merged_mesh(const Mesh &mesh, } while (weld_iter_loop_of_poly_next(iter)) { customdata_weld(&mesh.ldata, &result->ldata, group_buffer.data(), iter.group_len, loop_cur); - int v = vert_final_map[iter.v]; - int e = edge_final_map[iter.e]; - r_ml->v = v; - r_ml->e = e; - r_ml++; + dst_corner_verts[loop_cur] = vert_final_map[iter.v]; + dst_corner_edges[loop_cur] = edge_final_map[iter.e]; loop_cur++; } diff --git a/source/blender/geometry/intern/mesh_primitive_cuboid.cc b/source/blender/geometry/intern/mesh_primitive_cuboid.cc index 6032b19ac25..cf87607338f 100644 --- a/source/blender/geometry/intern/mesh_primitive_cuboid.cc +++ b/source/blender/geometry/intern/mesh_primitive_cuboid.cc @@ -109,7 +109,7 @@ static void calculate_positions(const CuboidConfig &config, MutableSpan * anti-clockwise. */ static void define_quad(MutableSpan polys, - MutableSpan loops, + MutableSpan corner_verts, const int poly_index, const int loop_index, const int vert_1, @@ -121,19 +121,15 @@ static void define_quad(MutableSpan polys, poly.loopstart = loop_index; poly.totloop = 4; - MLoop &loop_1 = loops[loop_index]; - loop_1.v = vert_1; - MLoop &loop_2 = loops[loop_index + 1]; - loop_2.v = vert_2; - MLoop &loop_3 = loops[loop_index + 2]; - loop_3.v = vert_3; - MLoop &loop_4 = loops[loop_index + 3]; - loop_4.v = vert_4; + corner_verts[loop_index] = vert_1; + corner_verts[loop_index + 1] = vert_2; + corner_verts[loop_index + 2] = vert_3; + corner_verts[loop_index + 3] = vert_4; } static void calculate_polys(const CuboidConfig &config, MutableSpan polys, - MutableSpan loops) + MutableSpan corner_verts) { int loop_index = 0; int poly_index = 0; @@ -152,7 +148,7 @@ static void calculate_polys(const CuboidConfig &config, const int vert_3 = vert_2 + 1; const int vert_4 = vert_1 + 1; - define_quad(polys, loops, poly_index, loop_index, vert_1, vert_2, vert_3, vert_4); + define_quad(polys, corner_verts, poly_index, loop_index, vert_1, vert_2, vert_3, vert_4); loop_index += 4; poly_index++; } @@ -166,7 +162,7 @@ static void calculate_polys(const CuboidConfig &config, for ([[maybe_unused]] const int z : IndexRange(config.edges_z)) { for (const int x : IndexRange(config.edges_x)) { define_quad(polys, - loops, + corner_verts, poly_index, loop_index, vert_1_start + x, @@ -189,7 +185,7 @@ static void calculate_polys(const CuboidConfig &config, for ([[maybe_unused]] const int y : IndexRange(config.edges_y)) { for (const int x : IndexRange(config.edges_x)) { define_quad(polys, - loops, + corner_verts, poly_index, loop_index, vert_1_start + x, @@ -213,7 +209,7 @@ static void calculate_polys(const CuboidConfig &config, } for (const int x : IndexRange(config.edges_x)) { define_quad(polys, - loops, + corner_verts, poly_index, loop_index, vert_1_start + x, @@ -258,7 +254,7 @@ static void calculate_polys(const CuboidConfig &config, vert_3 = vert_2 + 2; } - define_quad(polys, loops, poly_index, loop_index, vert_1, vert_2, vert_3, vert_4); + define_quad(polys, corner_verts, poly_index, loop_index, vert_1, vert_2, vert_3, vert_4); loop_index += 4; poly_index++; } @@ -305,7 +301,7 @@ static void calculate_polys(const CuboidConfig &config, vert_4 = vert_1 + config.verts_x; } - define_quad(polys, loops, poly_index, loop_index, vert_1, vert_4, vert_3, vert_2); + define_quad(polys, corner_verts, poly_index, loop_index, vert_1, vert_4, vert_3, vert_2); loop_index += 4; poly_index++; } @@ -406,12 +402,12 @@ Mesh *create_cuboid_mesh(const float3 &size, Mesh *mesh = BKE_mesh_new_nomain(config.vertex_count, 0, config.loop_count, config.poly_count); MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); BKE_mesh_smooth_flag_set(mesh, false); calculate_positions(config, positions); - calculate_polys(config, polys, loops); + calculate_polys(config, polys, corner_verts); BKE_mesh_calc_edges(mesh, false, false); if (uv_id) { diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index 506f7355111..8148f9a7fc5 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -157,7 +157,7 @@ static void add_new_edges(Mesh &mesh, */ static void merge_edges(const int orig_edge_i, const int new_edge_i, - MutableSpan new_loops, + MutableSpan new_corner_edges, Vector> &edge_to_loop_map, Vector &new_edges, Vector &new_to_old_edges_map) @@ -165,7 +165,7 @@ static void merge_edges(const int orig_edge_i, /* Merge back into the original edge by undoing the topology changes. */ BLI_assert(edge_to_loop_map[new_edge_i].size() == 1); const int loop_i = edge_to_loop_map[new_edge_i][0]; - new_loops[loop_i].e = orig_edge_i; + new_corner_edges[loop_i] = orig_edge_i; /* We are putting the last edge in the location of new_edge in all the maps, to remove * new_edge efficiently. We have to update the topology information for this last edge @@ -174,7 +174,7 @@ static void merge_edges(const int orig_edge_i, if (last_edge_i != new_edge_i) { BLI_assert(edge_to_loop_map[last_edge_i].size() == 1); const int last_edge_loop_i = edge_to_loop_map[last_edge_i][0]; - new_loops[last_edge_loop_i].e = new_edge_i; + new_corner_edges[last_edge_loop_i] = new_edge_i; } /* We can now safely swap-remove. */ @@ -192,7 +192,7 @@ static void merge_edges(const int orig_edge_i, static void swap_vertex_of_edge(MEdge &edge, const int old_vert, const int new_vert, - MutableSpan loops, + MutableSpan corner_verts, const Span connected_loops) { if (edge.v1 == old_vert) { @@ -206,8 +206,8 @@ static void swap_vertex_of_edge(MEdge &edge, } for (const int loop_i : connected_loops) { - if (loops[loop_i].v == old_vert) { - loops[loop_i].v = new_vert; + if (corner_verts[loop_i] == old_vert) { + corner_verts[loop_i] = new_vert; } /* The old vertex is on the loop containing the adjacent edge. Since this function is also * called on the adjacent edge, we don't replace it here. */ @@ -222,7 +222,7 @@ static void split_vertex_per_fan(const int vertex, const Span fan_sizes, const Span> edge_to_loop_map, MutableSpan new_edges, - MutableSpan new_loops, + MutableSpan corner_verts, MutableSpan new_to_old_verts_map) { int fan_start = 0; @@ -234,7 +234,7 @@ static void split_vertex_per_fan(const int vertex, for (const int edge_i : fans.slice(fan_start, fan_sizes[i])) { swap_vertex_of_edge( - new_edges[edge_i], vertex, new_vert_i, new_loops, edge_to_loop_map[edge_i]); + new_edges[edge_i], vertex, new_vert_i, corner_verts, edge_to_loop_map[edge_i]); } fan_start += fan_sizes[i]; } @@ -244,12 +244,16 @@ static void split_vertex_per_fan(const int vertex, * Get the index of the adjacent edge to a loop connected to a vertex. In other words, for the * given polygon return the unique edge connected to the given vertex and not on the given loop. */ -static int adjacent_edge(Span loops, const int loop_i, const MPoly &poly, const int vertex) +static int adjacent_edge(const Span corner_verts, + const Span corner_edges, + const int loop_i, + const MPoly &poly, + const int vertex) { - const int adjacent_loop_i = (loops[loop_i].v == vertex) ? + const int adjacent_loop_i = (corner_verts[loop_i] == vertex) ? bke::mesh_topology::poly_loop_prev(poly, loop_i) : bke::mesh_topology::poly_loop_next(poly, loop_i); - return loops[adjacent_loop_i].e; + return corner_edges[adjacent_loop_i]; } /** @@ -259,7 +263,8 @@ static int adjacent_edge(Span loops, const int loop_i, const MPoly &poly, * be used to retrieve the fans from connected_edges. */ static void calc_vertex_fans(const int vertex, - const Span new_loops, + const Span new_corner_verts, + const Span new_corner_edges, const Span polys, const Span> edge_to_loop_map, const Span loop_to_poly_map, @@ -289,7 +294,7 @@ static void calc_vertex_fans(const int vertex, /* Add adjacent edges to search stack. */ for (const int loop_i : edge_to_loop_map[curr_edge_i]) { const int adjacent_edge_i = adjacent_edge( - new_loops, loop_i, polys[loop_to_poly_map[loop_i]], vertex); + new_corner_verts, new_corner_edges, loop_i, polys[loop_to_poly_map[loop_i]], vertex); /* Find out if this edge was visited already. */ int i = curr_i + 1; @@ -331,7 +336,7 @@ static void calc_vertex_fans(const int vertex, static void split_edge_per_poly(const int edge_i, const int new_edge_start, MutableSpan> edge_to_loop_map, - MutableSpan new_loops, + MutableSpan corner_edges, MutableSpan new_edges, MutableSpan new_to_old_edges_map) { @@ -344,7 +349,7 @@ static void split_edge_per_poly(const int edge_i, new_edges[new_edge_index] = new_edge; new_to_old_edges_map[new_edge_index] = edge_i; edge_to_loop_map[new_edge_index].append({loop_i}); - new_loops[loop_i].e = new_edge_index; + corner_edges[loop_i] = new_edge_index; new_edge_index++; } /* Only the first loop is now connected to this edge. */ @@ -368,7 +373,7 @@ void split_edges(Mesh &mesh, Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges, mesh.totvert); Vector> edge_to_loop_map = bke::mesh_topology::build_edge_to_loop_map_resizable( - mesh.loops(), mesh.totedge); + mesh.corner_edges(), mesh.totedge); Array loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(mesh.polys(), mesh.totloop); @@ -387,7 +392,8 @@ void split_edges(Mesh &mesh, const Span polys = mesh.polys(); - MutableSpan loops = mesh.loops_for_write(); + MutableSpan corner_verts = mesh.corner_verts_for_write(); + MutableSpan corner_edges = mesh.corner_edges_for_write(); Vector new_edges(new_edges_size); new_edges.as_mutable_span().take_front(edges.size()).copy_from(edges); @@ -400,8 +406,12 @@ void split_edges(Mesh &mesh, threading::parallel_for(mask.index_range(), 512, [&](IndexRange range) { for (const int mask_i : range) { const int edge_i = mask[mask_i]; - split_edge_per_poly( - edge_i, edge_offsets[edge_i], edge_to_loop_map, loops, new_edges, new_to_old_edges_map); + split_edge_per_poly(edge_i, + edge_offsets[edge_i], + edge_to_loop_map, + corner_edges, + new_edges, + new_to_old_edges_map); } }); @@ -422,7 +432,8 @@ void split_edges(Mesh &mesh, continue; } calc_vertex_fans(vert, - loops, + corner_verts, + corner_edges, polys, edge_to_loop_map, loop_to_poly_map, @@ -459,7 +470,7 @@ void split_edges(Mesh &mesh, vertex_fan_sizes[vert], edge_to_loop_map, new_edges, - loops, + corner_verts, new_to_old_verts_map); } }); @@ -474,12 +485,14 @@ void split_edges(Mesh &mesh, int end_of_duplicates = start_of_duplicates + num_edge_duplicates[edge] - 1; for (int duplicate = end_of_duplicates; duplicate >= start_of_duplicates; duplicate--) { if (naive_edges_equal(new_edges[edge], new_edges[duplicate])) { - merge_edges(edge, duplicate, loops, edge_to_loop_map, new_edges, new_to_old_edges_map); + merge_edges( + edge, duplicate, corner_edges, edge_to_loop_map, new_edges, new_to_old_edges_map); break; } for (int other = start_of_duplicates; other < duplicate; other++) { if (naive_edges_equal(new_edges[other], new_edges[duplicate])) { - merge_edges(other, duplicate, loops, edge_to_loop_map, new_edges, new_to_old_edges_map); + merge_edges( + other, duplicate, corner_edges, edge_to_loop_map, new_edges, new_to_old_edges_map); break; } } diff --git a/source/blender/geometry/intern/mesh_to_volume.cc b/source/blender/geometry/intern/mesh_to_volume.cc index 5d49f78d4b2..dd6fd27d6c5 100644 --- a/source/blender/geometry/intern/mesh_to_volume.cc +++ b/source/blender/geometry/intern/mesh_to_volume.cc @@ -20,7 +20,7 @@ namespace blender::geometry { class OpenVDBMeshAdapter { private: Span positions_; - Span loops_; + Span corner_verts_; Span looptris_; float4x4 transform_; @@ -34,7 +34,7 @@ class OpenVDBMeshAdapter { OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform) : positions_(mesh.vert_positions()), - loops_(mesh.loops()), + corner_verts_(mesh.corner_verts()), looptris_(mesh.looptris()), transform_(transform) { @@ -62,7 +62,7 @@ void OpenVDBMeshAdapter::getIndexSpacePoint(size_t polygon_index, { const MLoopTri &looptri = looptris_[polygon_index]; const float3 transformed_co = math::transform_point( - transform_, positions_[loops_[looptri.tri[vertex_index]].v]); + transform_, positions_[corner_verts_[looptri.tri[vertex_index]]]); pos = &transformed_co.x; } @@ -145,7 +145,7 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh, } const Span positions = mesh.vert_positions(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span looptris = mesh.looptris(); std::vector points(positions.size()); @@ -161,8 +161,9 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh, threading::parallel_for(looptris.index_range(), 2048, [&](const IndexRange range) { for (const int i : range) { const MLoopTri &loop_tri = looptris[i]; - triangles[i] = openvdb::Vec3I( - loops[loop_tri.tri[0]].v, loops[loop_tri.tri[1]].v, loops[loop_tri.tri[2]].v); + triangles[i] = openvdb::Vec3I(corner_verts[loop_tri.tri[0]], + corner_verts[loop_tri.tri[1]], + corner_verts[loop_tri.tri[2]]); } }); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 3a6b92c6e93..9ff6eacd1cb 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -104,7 +104,8 @@ struct MeshRealizeInfo { Span positions; Span edges; Span polys; - Span loops; + Span corner_verts; + Span corner_edges; /** Maps old material indices to new material indices. */ Array material_index_map; @@ -846,6 +847,8 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate( options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); + attributes_to_propagate.remove(".corner_vert"); + attributes_to_propagate.remove(".corner_edge"); 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; @@ -900,7 +903,8 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, mesh_info.positions = mesh->vert_positions(); mesh_info.edges = mesh->edges(); mesh_info.polys = mesh->polys(); - mesh_info.loops = mesh->loops(); + mesh_info.corner_verts = mesh->corner_verts(); + mesh_info.corner_edges = mesh->corner_edges(); /* Create material index mapping. */ mesh_info.material_index_map.reinitialize(std::max(mesh->totcol, 1)); @@ -946,7 +950,8 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, MutableSpan all_dst_positions, MutableSpan all_dst_edges, MutableSpan all_dst_polys, - MutableSpan all_dst_loops, + MutableSpan all_dst_corner_verts, + MutableSpan all_dst_corner_edges, MutableSpan all_dst_vertex_ids, MutableSpan all_dst_material_indices) { @@ -956,17 +961,19 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, const Span src_positions = mesh_info.positions; const Span src_edges = mesh_info.edges; const Span src_polys = mesh_info.polys; - const Span src_loops = mesh_info.loops; + const Span src_corner_verts = mesh_info.corner_verts; + const Span src_corner_edges = mesh_info.corner_edges; const IndexRange dst_vert_range(task.start_indices.vertex, src_positions.size()); const IndexRange dst_edge_range(task.start_indices.edge, src_edges.size()); const IndexRange dst_poly_range(task.start_indices.poly, src_polys.size()); - const IndexRange dst_loop_range(task.start_indices.loop, src_loops.size()); + const IndexRange dst_loop_range(task.start_indices.loop, src_corner_verts.size()); MutableSpan dst_positions = all_dst_positions.slice(dst_vert_range); MutableSpan dst_edges = all_dst_edges.slice(dst_edge_range); MutableSpan dst_polys = all_dst_polys.slice(dst_poly_range); - MutableSpan dst_loops = all_dst_loops.slice(dst_loop_range); + MutableSpan dst_corner_verts = all_dst_corner_verts.slice(dst_loop_range); + MutableSpan dst_corner_edges = all_dst_corner_edges.slice(dst_loop_range); threading::parallel_for(src_positions.index_range(), 1024, [&](const IndexRange vert_range) { for (const int i : vert_range) { @@ -982,13 +989,14 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, dst_edge.v2 += task.start_indices.vertex; } }); - threading::parallel_for(src_loops.index_range(), 1024, [&](const IndexRange loop_range) { + threading::parallel_for(src_corner_verts.index_range(), 1024, [&](const IndexRange loop_range) { for (const int i : loop_range) { - const MLoop &src_loop = src_loops[i]; - MLoop &dst_loop = dst_loops[i]; - dst_loop = src_loop; - dst_loop.v += task.start_indices.vertex; - dst_loop.e += task.start_indices.edge; + dst_corner_verts[i] = src_corner_verts[i] + task.start_indices.vertex; + } + }); + threading::parallel_for(src_corner_edges.index_range(), 1024, [&](const IndexRange loop_range) { + for (const int i : loop_range) { + dst_corner_edges[i] = src_corner_edges[i] + task.start_indices.edge; } }); threading::parallel_for(src_polys.index_range(), 1024, [&](const IndexRange poly_range) { @@ -1079,7 +1087,8 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, MutableSpan dst_positions = dst_mesh->vert_positions_for_write(); MutableSpan dst_edges = dst_mesh->edges_for_write(); MutableSpan dst_polys = dst_mesh->polys_for_write(); - MutableSpan dst_loops = dst_mesh->loops_for_write(); + MutableSpan dst_corner_verts = dst_mesh->corner_verts_for_write(); + MutableSpan dst_corner_edges = dst_mesh->corner_edges_for_write(); /* Copy settings from the first input geometry set with a mesh. */ const RealizeMeshTask &first_task = tasks.first(); @@ -1128,7 +1137,8 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, dst_positions, dst_edges, dst_polys, - dst_loops, + dst_corner_verts, + dst_corner_edges, vertex_ids.span, material_indices.span); } diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index b9b6b5c2eb5..00c0c06f438 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -1477,7 +1477,8 @@ struct EdgeFeatData { const int *material_indices; blender::Span edges; blender::Span polys; - blender::Span loops; + blender::Span corner_verts; + blender::Span corner_edges; blender::Span looptris; LineartTriangle *tri_array; blender::VArray sharp_edges; @@ -1683,8 +1684,11 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, } int real_edges[3]; - BKE_mesh_looptri_get_real_edges( - e_feat_data->edges.data(), e_feat_data->loops.data(), &looptris[i / 3], real_edges); + BKE_mesh_looptri_get_real_edges(e_feat_data->edges.data(), + e_feat_data->corner_verts.data(), + e_feat_data->corner_edges.data(), + &looptris[i / 3], + real_edges); if (real_edges[i % 3] >= 0) { if (ld->conf.use_crease && ld->conf.sharp_as_crease && @@ -1789,7 +1793,7 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *tri, struct TriData { LineartObjectInfo *ob_info; blender::Span positions; - blender::Span loops; + blender::Span corner_verts; blender::Span looptris; const int *material_indices; LineartVert *vert_arr; @@ -1805,7 +1809,7 @@ static void lineart_load_tri_task(void *__restrict userdata, TriData *tri_task_data = (TriData *)userdata; LineartObjectInfo *ob_info = tri_task_data->ob_info; const blender::Span positions = tri_task_data->positions; - const blender::Span loops = tri_task_data->loops; + const blender::Span corner_verts = tri_task_data->corner_verts; const MLoopTri *looptri = &tri_task_data->looptris[i]; const int *material_indices = tri_task_data->material_indices; LineartVert *vert_arr = tri_task_data->vert_arr; @@ -1813,9 +1817,9 @@ static void lineart_load_tri_task(void *__restrict userdata, tri = (LineartTriangle *)(((uchar *)tri) + tri_task_data->lineart_triangle_size * i); - int v1 = loops[looptri->tri[0]].v; - int v2 = loops[looptri->tri[1]].v; - int v3 = loops[looptri->tri[2]].v; + int v1 = corner_verts[looptri->tri[0]]; + int v2 = corner_verts[looptri->tri[1]]; + int v3 = corner_verts[looptri->tri[2]]; tri->v[0] = &vert_arr[v1]; tri->v[1] = &vert_arr[v2]; @@ -1863,7 +1867,7 @@ static void lineart_load_tri_task(void *__restrict userdata, struct EdgeNeighborData { LineartEdgeNeighbor *edge_nabr; LineartAdjacentEdge *adj_e; - blender::Span loops; + blender::Span corner_verts; blender::Span looptris; }; @@ -1875,11 +1879,11 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata, LineartAdjacentEdge *adj_e = &en_data->adj_e[i]; const MLoopTri *looptri = &en_data->looptris[i / 3]; LineartEdgeNeighbor *edge_nabr = &en_data->edge_nabr[i]; - const blender::Span loops = en_data->loops; + const blender::Span corner_verts = en_data->corner_verts; adj_e->e = i; - adj_e->v1 = loops[looptri->tri[i % 3]].v; - adj_e->v2 = loops[looptri->tri[(i + 1) % 3]].v; + adj_e->v1 = corner_verts[looptri->tri[i % 3]]; + adj_e->v2 = corner_verts[looptri->tri[(i + 1) % 3]]; if (adj_e->v1 > adj_e->v2) { std::swap(adj_e->v1, adj_e->v2); } @@ -1925,7 +1929,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge EdgeNeighborData en_data; en_data.adj_e = adj_e; en_data.edge_nabr = edge_nabr; - en_data.loops = me->loops(); + en_data.corner_verts = me->corner_verts(); en_data.looptris = me->looptris(); BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings); @@ -2066,7 +2070,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, tri_data.ob_info = ob_info; tri_data.positions = me->vert_positions(); tri_data.looptris = looptris; - tri_data.loops = me->loops(); + tri_data.corner_verts = me->corner_verts(); tri_data.material_indices = material_indices; tri_data.vert_arr = la_v_arr; tri_data.tri_arr = la_tri_arr; @@ -2103,7 +2107,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_data.material_indices = material_indices; edge_feat_data.edges = me->edges(); edge_feat_data.polys = me->polys(); - edge_feat_data.loops = me->loops(); + edge_feat_data.corner_verts = me->corner_verts(); + edge_feat_data.corner_edges = me->corner_edges(); edge_feat_data.looptris = looptris; edge_feat_data.sharp_edges = sharp_edges; edge_feat_data.sharp_faces = sharp_faces; diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc index 2c08d0f4061..45a5f1df6a0 100644 --- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc +++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc @@ -147,14 +147,6 @@ bool paint_is_grid_face_hidden(const uint * /*grid_hidden*/, /** \name Stubs of BKE_mesh.h * \{ */ -void BKE_mesh_looptri_get_real_edges(const struct MEdge * /*edges*/, - const struct MLoop * /*loops*/, - const struct MLoopTri * /*looptri*/, - int[3] /*col*/) -{ - BLI_assert_unreachable(); -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index af619db9417..52fc86fd09d 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -177,7 +177,7 @@ void ABCGenericMeshWriter::do_write(HierarchyContext &context) m_custom_data_config.pack_uvs = args_.export_params->packuv; m_custom_data_config.mesh = mesh; m_custom_data_config.polys = mesh->polys_for_write().data(); - m_custom_data_config.mloop = mesh->loops_for_write().data(); + m_custom_data_config.corner_verts = mesh->corner_verts_for_write().data(); m_custom_data_config.totpoly = mesh->totpoly; m_custom_data_config.totloop = mesh->totloop; m_custom_data_config.totvert = mesh->totvert; @@ -450,7 +450,7 @@ static void get_topology(struct Mesh *mesh, bool &r_has_flat_shaded_poly) { const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); const bke::AttributeAccessor attributes = mesh->attributes(); const VArray sharp_faces = attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); @@ -463,7 +463,7 @@ static void get_topology(struct Mesh *mesh, poly_verts.clear(); loop_counts.clear(); - poly_verts.reserve(loops.size()); + poly_verts.reserve(corner_verts.size()); loop_counts.reserve(polys.size()); /* NOTE: data needs to be written in the reverse order. */ @@ -471,10 +471,9 @@ static void get_topology(struct Mesh *mesh, const MPoly &poly = polys[i]; loop_counts.push_back(poly.totloop); - const MLoop *loop = &loops[poly.loopstart + (poly.totloop - 1)]; - - for (int j = 0; j < poly.totloop; j++, loop--) { - poly_verts.push_back(loop->v); + int corner = poly.loopstart + (poly.totloop - 1); + for (int j = 0; j < poly.totloop; j++, corner--) { + poly_verts.push_back(corner_verts[corner]); } } } diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index bf7c1fdea06..f9ae257e1ff 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -58,7 +58,7 @@ static void get_uvs(const CDStreamConfig &config, const int num_poly = config.totpoly; MPoly *polys = config.polys; - MLoop *mloop = config.mloop; + int *corner_verts = config.corner_verts; if (!config.pack_uvs) { int count = 0; @@ -86,18 +86,18 @@ static void get_uvs(const CDStreamConfig &config, for (int i = 0; i < num_poly; i++) { MPoly ¤t_poly = polys[i]; - MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop; + int *poly_verts = corner_verts + current_poly.loopstart + current_poly.totloop; const float2 *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop; for (int j = 0; j < current_poly.totloop; j++) { - looppoly--; + poly_verts--; loopuv--; Imath::V2f uv((*loopuv)[0], (*loopuv)[1]); bool found_same = false; /* Find UV already in uvs array. */ - for (uint32_t uv_idx : idx_map[looppoly->v]) { + for (uint32_t uv_idx : idx_map[*poly_verts]) { if (uvs[uv_idx] == uv) { found_same = true; uvidx.push_back(uv_idx); @@ -108,7 +108,7 @@ static void get_uvs(const CDStreamConfig &config, /* UV doesn't exists for this vertex, add it. */ if (!found_same) { uint32_t uv_idx = idx_count++; - idx_map[looppoly->v].push_back(uv_idx); + idx_map[*poly_verts].push_back(uv_idx); uvidx.push_back(uv_idx); uvs.push_back(uv); } @@ -316,7 +316,7 @@ static void read_uvs(const CDStreamConfig &config, const UInt32ArraySamplePtr &indices) { MPoly *polys = config.polys; - MLoop *mloops = config.mloop; + const int *corner_verts = config.corner_verts; float2 *mloopuvs = static_cast(data); uint uv_index, loop_index, rev_loop_index; @@ -330,7 +330,7 @@ static void read_uvs(const CDStreamConfig &config, for (int f = 0; f < poly.totloop; f++) { rev_loop_index = rev_loop_offset - f; - loop_index = do_uvs_per_loop ? poly.loopstart + f : mloops[rev_loop_index].v; + loop_index = do_uvs_per_loop ? poly.loopstart + f : corner_verts[rev_loop_index]; uv_index = (*indices)[loop_index]; const Imath::V2f &uv = (*uvs)[uv_index]; @@ -412,7 +412,7 @@ static void read_custom_data_mcols(const std::string &iobject_full_name, config.mesh, prop_header.getName().c_str(), CD_PROP_BYTE_COLOR); MCol *cfaces = static_cast(cd_data); const MPoly *polys = config.polys; - MLoop *mloops = config.mloop; + const int *corner_verts = config.corner_verts; size_t face_index = 0; size_t color_index; @@ -427,13 +427,13 @@ static void read_custom_data_mcols(const std::string &iobject_full_name, for (int i = 0; i < config.totpoly; i++) { const MPoly &poly = polys[i]; MCol *cface = &cfaces[poly.loopstart + poly.totloop]; - MLoop *mloop = &mloops[poly.loopstart + poly.totloop]; + const int *poly_verts = &corner_verts[poly.loopstart + poly.totloop]; for (int j = 0; j < poly.totloop; j++, face_index++) { cface--; - mloop--; + poly_verts--; - color_index = is_facevarying ? face_index : mloop->v; + color_index = is_facevarying ? face_index : *poly_verts; if (use_dual_indexing) { color_index = (*indices)[color_index]; } diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h index 17ec872b989..4e011393e36 100644 --- a/source/blender/io/alembic/intern/abc_customdata.h +++ b/source/blender/io/alembic/intern/abc_customdata.h @@ -16,7 +16,6 @@ #include "BLI_math_vector_types.hh" struct CustomData; -struct MLoop; struct MPoly; struct Mesh; @@ -30,7 +29,7 @@ struct UVSample { }; struct CDStreamConfig { - MLoop *mloop; + int *corner_verts; int totloop; MPoly *polys; @@ -73,7 +72,7 @@ struct CDStreamConfig { std::map abc_vertex_colors; CDStreamConfig() - : mloop(NULL), + : corner_verts(NULL), totloop(0), polys(NULL), totpoly(0), diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index ed9de7ea227..f4190f3d40e 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -176,7 +176,7 @@ void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySa static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) { MPoly *polys = config.polys; - MLoop *mloops = config.mloop; + int *corner_verts = config.corner_verts; float2 *mloopuvs = config.mloopuv; const Int32ArraySamplePtr &face_indices = mesh_data.face_indices; @@ -209,18 +209,18 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) uint last_vertex_index = 0; for (int f = 0; f < face_size; f++, loop_index++, rev_loop_index--) { - MLoop &loop = mloops[rev_loop_index]; - loop.v = (*face_indices)[loop_index]; + const int vert = (*face_indices)[loop_index]; + corner_verts[rev_loop_index] = vert; - if (f > 0 && loop.v == last_vertex_index) { + if (f > 0 && vert == last_vertex_index) { /* This face is invalid, as it has consecutive loops from the same vertex. This is caused * by invalid geometry in the Alembic file, such as in #76514. */ seen_invalid_geometry = true; } - last_vertex_index = loop.v; + last_vertex_index = vert; if (do_uvs) { - uv_index = (*uvs_indices)[do_uvs_per_loop ? loop_index : loop.v]; + uv_index = (*uvs_indices)[do_uvs_per_loop ? loop_index : last_vertex_index]; /* Some Alembic files are broken (or at least export UVs in a way we don't expect). */ if (uv_index >= uvs_size) { @@ -517,7 +517,7 @@ CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation) CDStreamConfig config; config.mesh = mesh; config.positions = mesh->vert_positions_for_write().data(); - config.mloop = mesh->loops_for_write().data(); + config.corner_verts = mesh->corner_verts_for_write().data(); config.polys = mesh->polys_for_write().data(); config.totvert = mesh->totvert; config.totloop = mesh->totloop; diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 59038c41863..04340a04f93 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -328,7 +328,7 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, std::vector &norind) { const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); std::vector vcount_list; @@ -415,11 +415,11 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, int loop_count = poly->totloop; if (material_indices[i] == material_index) { - const MLoop *l = &loops[poly->loopstart]; BCPolygonNormalsIndices normal_indices = norind[i]; for (int j = 0; j < loop_count; j++) { - primitive_list->appendValues(l[j].v); + const int vert = corner_verts[poly->loopstart + j]; + primitive_list->appendValues(vert); primitive_list->appendValues(normal_indices[j]); if (has_uvs) { primitive_list->appendValues(texindex + j); @@ -622,7 +622,7 @@ void GeometryExporter::create_normals(std::vector &normals, const Span positions = me->vert_positions(); const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me); const Span polys = me->polys(); - const Span loops = me->loops(); + const Span corner_verts = me->corner_verts(); const float(*lnors)[3] = nullptr; bool use_custom_normals = false; @@ -644,7 +644,7 @@ void GeometryExporter::create_normals(std::vector &normals, /* For flat faces use face normal as vertex normal: */ const float3 vector = blender::bke::mesh::poly_normal_calc( - positions, loops.slice(poly->loopstart, poly->totloop)); + positions, corner_verts.slice(poly->loopstart, poly->totloop)); Normal n = {vector[0], vector[1], vector[2]}; normals.push_back(n); @@ -661,7 +661,7 @@ void GeometryExporter::create_normals(std::vector &normals, normalize_v3_v3(normalized, lnors[loop_idx]); } else { - copy_v3_v3(normalized, vert_normals[loops[loop_index].v]); + copy_v3_v3(normalized, vert_normals[corner_verts[loop_index]]); normalize_v3(normalized); } Normal n = {normalized[0], normalized[1], normalized[2]}; diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 5d88c6fd0c0..8c289e55157 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -210,7 +210,7 @@ MeshImporter::MeshImporter(UnitConverter *unitconv, } bool MeshImporter::set_poly_indices( - MPoly *poly, MLoop *mloop, int loop_index, const uint *indices, int loop_count) + MPoly *poly, int *poly_verts, int loop_index, const uint *indices, int loop_count) { poly->loopstart = loop_index; poly->totloop = loop_count; @@ -227,8 +227,8 @@ bool MeshImporter::set_poly_indices( } } - mloop->v = indices[index]; - mloop++; + *poly_verts = indices[index]; + poly_verts++; } return broken_loop; } @@ -456,7 +456,8 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) me->totpoly = total_poly_count; me->totloop = total_loop_count; CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, me->totpoly); - CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, me->totloop); + CustomData_add_layer_named( + &me->ldata, CD_PROP_INT32, CD_SET_DEFAULT, me->totloop, ".corner_vert"); uint totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount(); for (int i = 0; i < totuvset; i++) { @@ -608,8 +609,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, VCOLDataWrapper vcol(collada_mesh->getColors()); MutableSpan polys = me->polys_for_write(); - MutableSpan loops = me->loops_for_write(); - MLoop *mloop = loops.data(); + MutableSpan corner_verts = me->corner_verts_for_write(); int poly_index = 0; int loop_index = 0; @@ -659,7 +659,11 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, /* For each triangle store indices of its 3 vertices */ uint triangle_vertex_indices[3] = { first_vertex, position_indices[1], position_indices[2]}; - set_poly_indices(&polys[poly_index], mloop, loop_index, triangle_vertex_indices, 3); + set_poly_indices(&polys[poly_index], + &corner_verts[loop_index], + loop_index, + triangle_vertex_indices, + 3); if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */ /* The same for vertices normals. */ @@ -668,7 +672,6 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, normal_indices++; } - mloop += 3; poly_index++; loop_index += 3; prim.totpoly++; @@ -703,7 +706,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, } bool broken_loop = set_poly_indices( - &polys[poly_index], mloop, loop_index, position_indices, vcount); + &polys[poly_index], &corner_verts[loop_index], loop_index, position_indices, vcount); if (broken_loop) { invalid_loop_holes += 1; } @@ -768,7 +771,6 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, } poly_index++; - mloop += vcount; loop_index += vcount; start_index += vcount; prim.totpoly++; @@ -890,8 +892,8 @@ std::string *MeshImporter::get_geometry_name(const std::string &mesh_name) static bool bc_has_out_of_bound_indices(Mesh *me) { - for (const MLoop &loop : me->loops()) { - if (loop.v >= me->totvert) { + for (const int vert_i : me->corner_verts()) { + if (vert_i >= me->totvert) { return true; } } @@ -1154,7 +1156,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom) * BKE_mesh_set_custom_normals()'s internals expect me->medge to be populated * and for the MLoops to have correct edge indices. */ if (use_custom_normals && !loop_normals.is_empty()) { - /* BKE_mesh_set_custom_normals()'s internals also expect that each MLoop + /* BKE_mesh_set_custom_normals()'s internals also expect that each corner * has a valid vertex index, which may not be the case due to the existing * logic in read_polys(). This check isn't necessary in the no-custom-normals * case because the invalid MLoops get stripped in a later step. */ diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h index 3d815a025ec..e34a9e322fb 100644 --- a/source/blender/io/collada/MeshImporter.h +++ b/source/blender/io/collada/MeshImporter.h @@ -93,7 +93,7 @@ class MeshImporter : public MeshImporterBase { std::multimap materials_mapped_to_geom; bool set_poly_indices( - MPoly *poly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count); + MPoly *poly, int *poly_verts, int loop_index, const unsigned int *indices, int loop_count); void set_face_uv(blender::float2 *mloopuv, UVDataWrapper &uvs, diff --git a/source/blender/io/ply/exporter/ply_export_load_plydata.cc b/source/blender/io/ply/exporter/ply_export_load_plydata.cc index 233f4a25809..b2139f6d8e3 100644 --- a/source/blender/io/ply/exporter/ply_export_load_plydata.cc +++ b/source/blender/io/ply/exporter/ply_export_load_plydata.cc @@ -124,11 +124,12 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams plyData.face_vertices.reserve(mesh->totloop); plyData.face_sizes.reserve(mesh->totpoly); int loop_offset = 0; - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); for (const MPoly &poly : mesh->polys()) { - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); + const Span mesh_poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + Array poly_verts(mesh_poly_verts.size()); - for (int i = 0; i < poly_loops.size(); ++i) { + for (int i = 0; i < mesh_poly_verts.size(); ++i) { float2 uv; if (export_params.export_uv && uv_map != nullptr) { uv = uv_map[i + loop_offset]; @@ -136,7 +137,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams else { uv = {0, 0}; } - UV_vertex_key key = UV_vertex_key(uv, poly_loops[i].v); + UV_vertex_key key = UV_vertex_key(uv, mesh_poly_verts[i]); int ply_vertex_index = vertex_map.lookup(key); plyData.face_vertices.append(ply_vertex_index + vertex_offset); } @@ -229,7 +230,7 @@ void generate_vertex_map(const Mesh *mesh, { const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); const int totvert = mesh->totvert; r_map.reserve(totvert); @@ -246,7 +247,7 @@ void generate_vertex_map(const Mesh *mesh, UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(polys.data(), nullptr, nullptr, - loops.data(), + corner_verts.data(), reinterpret_cast(uv_map), uint(polys.size()), totvert, diff --git a/source/blender/io/ply/importer/ply_import_mesh.cc b/source/blender/io/ply/importer/ply_import_mesh.cc index efefebb6930..541796ed83b 100644 --- a/source/blender/io/ply/importer/ply_import_mesh.cc +++ b/source/blender/io/ply/importer/ply_import_mesh.cc @@ -54,9 +54,10 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams ¶ mesh->totpoly = int(data.face_sizes.size()); mesh->totloop = int(data.face_vertices.size()); CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, mesh->totpoly); - CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, mesh->totloop); + CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_vert"); MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); /* Fill in face data. */ uint32_t offset = 0; @@ -70,7 +71,7 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams ¶ fprintf(stderr, "Invalid PLY vertex index in face %i loop %i: %u\n", i, j, v); v = 0; } - loops[offset + j].v = v; + corner_verts[offset + j] = data.face_vertices[offset + j]; } offset += size; } diff --git a/source/blender/io/stl/importer/stl_import_mesh.cc b/source/blender/io/stl/importer/stl_import_mesh.cc index 2a7b074b094..39a24c2c13a 100644 --- a/source/blender/io/stl/importer/stl_import_mesh.cc +++ b/source/blender/io/stl/importer/stl_import_mesh.cc @@ -83,17 +83,18 @@ Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name) mesh->totpoly = tris_.size(); mesh->totloop = tris_.size() * 3; CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, mesh->totpoly); - CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, mesh->totloop); + CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert"); MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); threading::parallel_for(tris_.index_range(), 2048, [&](IndexRange tris_range) { for (const int i : tris_range) { polys[i].loopstart = 3 * i; polys[i].totloop = 3; - loops[3 * i].v = tris_[i].v1; - loops[3 * i + 1].v = tris_[i].v2; - loops[3 * i + 2].v = tris_[i].v3; + corner_verts[3 * i] = tris_[i].v1; + corner_verts[3 * i + 1] = tris_[i].v2; + corner_verts[3 * i + 2] = tris_[i].v3; } }); diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 79446728acb..4716597dcb9 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -263,7 +263,7 @@ bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double mot void USDMeshReader::read_mpolys(Mesh *mesh) { MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); int loop_index = 0; @@ -280,12 +280,12 @@ void USDMeshReader::read_mpolys(Mesh *mesh) if (is_left_handed_) { int loop_end_index = loop_index + (face_size - 1); for (int f = 0; f < face_size; ++f, ++loop_index) { - loops[loop_index].v = face_indices_[loop_end_index - f]; + corner_verts[loop_index] = face_indices_[loop_end_index - f]; } } else { for (int f = 0; f < face_size; ++f, ++loop_index) { - loops[loop_index].v = face_indices_[loop_index]; + corner_verts[loop_index] = face_indices_[loop_index]; } } } @@ -351,7 +351,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo } } - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); for (int i = 0; i < face_counts_.size(); i++) { const int face_size = face_counts_[i]; @@ -387,7 +387,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo /* For Vertex interpolation, use the vertex index. */ int usd_uv_index = sample.interpolation == pxr::UsdGeomTokens->vertex ? - loops[loop_index].v : + corner_verts[loop_index] : loop_index; if (usd_uv_index >= sample.uvs.size()) { @@ -468,7 +468,7 @@ void USDMeshReader::read_colors(Mesh *mesh, const double motionSampleTime) MLoopCol *colors = static_cast(cd_ptr); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; for (int j = 0; j < poly.totloop; ++j) { @@ -478,7 +478,7 @@ void USDMeshReader::read_colors(Mesh *mesh, const double motionSampleTime) int usd_index = 0; if (interp == pxr::UsdGeomTokens->vertex) { - usd_index = loops[loop_index].v; + usd_index = corner_verts[loop_index]; } else if (interp == pxr::UsdGeomTokens->faceVarying) { usd_index = poly.loopstart; diff --git a/source/blender/io/usd/intern/usd_reader_shape.cc b/source/blender/io/usd/intern/usd_reader_shape.cc index 58ef6d5cd36..fe661b5acab 100644 --- a/source/blender/io/usd/intern/usd_reader_shape.cc +++ b/source/blender/io/usd/intern/usd_reader_shape.cc @@ -143,7 +143,7 @@ Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh, } MutableSpan polys = active_mesh->polys_for_write(); - MutableSpan loops = active_mesh->loops_for_write(); + MutableSpan corner_verts = active_mesh->corner_verts_for_write(); /* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */ BKE_mesh_smooth_flag_set(active_mesh, !prim_.IsA()); @@ -157,7 +157,7 @@ Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh, poly.totloop = face_size; for (int f = 0; f < face_size; ++f, ++loop_index) { - loops[loop_index].v = face_indices[loop_index]; + corner_verts[loop_index] = face_indices[loop_index]; } } diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index b71997df8ef..6a0d41238f3 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -288,13 +288,13 @@ static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data) usd_mesh_data.face_indices.reserve(mesh->totloop); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; usd_mesh_data.face_vertex_counts.push_back(poly.totloop); - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - usd_mesh_data.face_indices.push_back(loop.v); + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + usd_mesh_data.face_indices.push_back(vert); } } } @@ -427,7 +427,7 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_ const float(*lnors)[3] = static_cast( CustomData_get_layer(&mesh->ldata, CD_NORMAL)); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); pxr::VtVec3fArray loop_normals; loop_normals.reserve(mesh->totloop); @@ -457,8 +457,8 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_ } else { /* Smooth shaded, use individual vert normals. */ - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - loop_normals.push_back(pxr::GfVec3f(&vert_normals[loop.v].x)); + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + loop_normals.push_back(pxr::GfVec3f(&vert_normals[vert].x)); } } } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 8ae878f2222..23737a5c068 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -348,7 +348,7 @@ void OBJWriter::write_poly_elements(FormatHandler &fh, int prev_i = obj_mesh_data.remap_poly_index(idx - 1); int i = obj_mesh_data.remap_poly_index(idx); - Vector poly_vertex_indices = obj_mesh_data.calc_poly_vertex_indices(i); + Span poly_vertex_indices = obj_mesh_data.calc_poly_vertex_indices(i); Span poly_uv_indices = obj_mesh_data.calc_poly_uv_indices(i); Vector poly_normal_indices = obj_mesh_data.calc_poly_normal_indices(i); 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 53c82330f74..b9de9e2f1f8 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -43,7 +43,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj mesh_positions_ = export_mesh_->vert_positions(); mesh_edges_ = export_mesh_->edges(); mesh_polys_ = export_mesh_->polys(); - mesh_loops_ = export_mesh_->loops(); + mesh_corner_verts_ = export_mesh_->corner_verts(); sharp_faces_ = export_mesh_->attributes().lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); } @@ -77,7 +77,7 @@ void OBJMesh::set_mesh(Mesh *mesh) mesh_positions_ = mesh->vert_positions(); mesh_edges_ = mesh->edges(); mesh_polys_ = mesh->polys(); - mesh_loops_ = mesh->loops(); + mesh_corner_verts_ = mesh->corner_verts(); sharp_faces_ = export_mesh_->attributes().lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); } @@ -203,8 +203,8 @@ void OBJMesh::calc_smooth_groups(const bool use_bitflags) poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.size(), mesh_polys_.data(), mesh_polys_.size(), - mesh_loops_.data(), - mesh_loops_.size(), + export_mesh_->corner_edges().data(), + export_mesh_->totloop, sharp_edges, sharp_faces, &tot_smooth_groups_, @@ -282,16 +282,10 @@ float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scal return r_coords; } -Vector OBJMesh::calc_poly_vertex_indices(const int poly_index) const +Span OBJMesh::calc_poly_vertex_indices(const int poly_index) const { const MPoly &poly = mesh_polys_[poly_index]; - const MLoop *mloop = &mesh_loops_[poly.loopstart]; - const int totloop = poly.totloop; - Vector r_poly_vertex_indices(totloop); - for (int loop_index = 0; loop_index < totloop; loop_index++) { - r_poly_vertex_indices[loop_index] = mloop[loop_index].v; - } - return r_poly_vertex_indices; + return mesh_corner_verts_.slice(poly.loopstart, poly.totloop); } void OBJMesh::store_uv_coords_and_indices() @@ -312,7 +306,7 @@ void OBJMesh::store_uv_coords_and_indices() mesh_polys_.data(), nullptr, nullptr, - mesh_loops_.data(), + mesh_corner_verts_.data(), reinterpret_cast(uv_map.data()), mesh_polys_.size(), totvert, @@ -363,7 +357,7 @@ float3 OBJMesh::calc_poly_normal(const int poly_index) const { const MPoly &poly = mesh_polys_[poly_index]; float3 r_poly_normal = bke::mesh::poly_normal_calc( - mesh_positions_, mesh_loops_.slice(poly.loopstart, poly.totloop)); + mesh_positions_, mesh_corner_verts_.slice(poly.loopstart, poly.totloop)); mul_m3_v3(world_and_axes_normal_transform_, r_poly_normal); normalize_v3(r_poly_normal); return r_poly_normal; @@ -477,9 +471,8 @@ int16_t OBJMesh::get_poly_deform_group_index(const int poly_index, group_weights.fill(0); bool found_any_group = false; const MPoly &poly = mesh_polys_[poly_index]; - const MLoop *mloop = &mesh_loops_[poly.loopstart]; - for (int loop_i = 0; loop_i < poly.totloop; ++loop_i, ++mloop) { - const MDeformVert &dv = dverts[mloop->v]; + for (const int vert : mesh_corner_verts_.slice(poly.loopstart, poly.totloop)) { + const MDeformVert &dv = dverts[vert]; for (int weight_i = 0; weight_i < dv.totweight; ++weight_i) { const auto group = dv.dw[weight_i].def_nr; if (group < group_weights.size()) { 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 21d212f5575..a90f6e3c3fd 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -40,7 +40,7 @@ class OBJMesh : NonCopyable { Span mesh_positions_; Span mesh_edges_; Span mesh_polys_; - Span mesh_loops_; + Span mesh_corner_verts_; VArray sharp_faces_; /** @@ -153,7 +153,7 @@ class OBJMesh : NonCopyable { /** * Calculate vertex indices of all vertices of the polygon at the given index. */ - Vector calc_poly_vertex_indices(int poly_index) const; + Span calc_poly_vertex_indices(int poly_index) const; /** * Calculate UV vertex coordinates of an Object. * Stores the coordinates and UV vertex indices in the member variables. 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 5a24020d0e4..ee53dc32bf6 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -184,7 +184,7 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) } MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_only_span("material_index", ATTR_DOMAIN_FACE); @@ -215,9 +215,9 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) for (int idx = 0; idx < curr_face.corner_count_; ++idx) { const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx]; - MLoop &mloop = loops[tot_loop_idx]; + corner_verts[tot_loop_idx] = mesh_geometry_.global_to_local_vertices_.lookup_default( + curr_corner.vert_index, 0); tot_loop_idx++; - mloop.v = mesh_geometry_.global_to_local_vertices_.lookup_default(curr_corner.vert_index, 0); /* Setup vertex group data, if needed. */ if (dverts.is_empty()) { @@ -226,7 +226,8 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) const int group_index = curr_face.vertex_group_index; /* Note: face might not belong to any group */ if (group_index >= 0 || 1) { - MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index); + MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[corner_verts[tot_loop_idx]], + group_index); dw->weight = 1.0f; } } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh index 60c9b7d7764..d8ac3191401 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh @@ -41,7 +41,7 @@ struct GlobalVertices { }; /** - * A face's corner in an OBJ file. In Blender, it translates to a mloop vertex. + * A face's corner in an OBJ file. In Blender, it translates to a corner vertex. */ struct PolyCorner { /* These indices range from zero to total vertices in the OBJ file. */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 3d5cd273eda..93588519a06 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -191,7 +191,6 @@ typedef enum eCustomDataType { // #define CD_MASK_RECAST (1 << CD_RECAST) /* DEPRECATED */ #define CD_MASK_MPOLY (1 << CD_MPOLY) -#define CD_MASK_MLOOP (1 << CD_MLOOP) #define CD_MASK_SHAPE_KEYINDEX (1 << CD_SHAPE_KEYINDEX) #define CD_MASK_SHAPEKEY (1 << CD_SHAPEKEY) #define CD_MASK_BWEIGHT (1 << CD_BWEIGHT) diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 87c21447fa4..67c1606be94 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -71,7 +71,7 @@ typedef struct Mesh { int totedge; /** The number of polygons/faces (#MPoly) in the mesh, and the size of #pdata. */ int totpoly; - /** The number of face corners (#MLoop) in the mesh, and the size of #ldata. */ + /** The number of face corners in the mesh, and the size of #ldata. */ int totloop; CustomData vdata, edata, pdata, ldata; @@ -226,8 +226,9 @@ typedef struct Mesh { blender::MutableSpan vert_positions_for_write(); /** * Array of edges, containing vertex indices. For simple triangle or quad meshes, edges could be - * calculated from the #MPoly and #MLoop arrays, however, edges need to be stored explicitly to - * edge domain attributes and to support loose edges that aren't connected to faces. + * calculated from the #MPoly and "corner edge" arrays, however, edges need to be stored + * explicitly to edge domain attributes and to support loose edges that aren't connected to + * faces. */ blender::Span edges() const; /** Write access to edge data. */ @@ -238,13 +239,28 @@ typedef struct Mesh { blender::Span polys() const; /** Write access to polygon data. */ blender::MutableSpan polys_for_write(); + /** - * Mesh face corners that "loop" around each face, storing the vertex index and the index of the - * subsequent edge. + * Array of vertices for every face corner, stored in the ".corner_vert" integer attribute. + * For example, the vertices in a face can be retrieved with the #slice method: + * \code{.cc} + * const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + * \endcode + * Such a span can often be passed as an argument in lieu of a polygon and the entire corner + * verts array. */ - blender::Span loops() const; - /** Write access to loop data. */ - blender::MutableSpan loops_for_write(); + blender::Span corner_verts() const; + /** Write access to the #corner_verts data. */ + blender::MutableSpan corner_verts_for_write(); + + /** + * Array of edges following every face corner traveling around each face, stored in the + * ".corner_edge" attribute. The array sliced the same way as the #corner_verts data. The edge + * previous to a corner must be accessed with the index of the previous face corner. + */ + blender::Span corner_edges() const; + /** Write access to the #corner_edges data. */ + blender::MutableSpan corner_edges_for_write(); blender::bke::AttributeAccessor attributes() const; blender::bke::MutableAttributeAccessor attributes_for_write(); diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index e2bfef9629d..4410e670b88 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -52,7 +52,8 @@ enum { /** * Mesh Faces. - * This only stores the polygon size & flags, the vertex & edge indices are stored in the #MLoop. + * This only stores the polygon size & flags, the vertex & edge indices are stored in the "corner + * edges" array. * * Typically accessed with #Mesh.polys(). */ @@ -78,19 +79,6 @@ enum { }; #endif -/** - * Mesh Face Corners. - * "Loop" is an internal name for the corner of a polygon (#MPoly). - * - * Typically accessed with #Mesh.loops(). - */ -typedef struct MLoop { - /** Vertex index. */ - unsigned int v; - /** Edge index into an #MEdge array. */ - unsigned int e; -} MLoop; - /** \} */ /* -------------------------------------------------------------------- */ @@ -126,7 +114,7 @@ enum { /** * #MLoopTri's are lightweight triangulation data, * for functionality that doesn't support ngons (#MPoly). - * This is cache data created from (#MPoly, #MLoop & position arrays). + * This is cache data created from (#MPoly, corner vert & position arrays). * There is no attempt to maintain this data's validity over time, * any changes to the underlying mesh invalidate the #MLoopTri array, * which will need to be re-calculated. @@ -153,9 +141,9 @@ enum { * * // access vertex locations. * float *vtri_co[3] = { - * positions[mloop[lt->tri[0]].v], - * positions[mloop[lt->tri[1]].v], - * positions[mloop[lt->tri[2]].v], + * positions[corner_verts[lt->tri[0]]], + * positions[corner_verts[lt->tri[1]]], + * positions[corner_verts[lt->tri[2]]], * }; * * // access UV coordinates (works for all loop data, vertex colors... etc). @@ -179,10 +167,10 @@ enum { * int j, lt_tot = ME_POLY_TRI_TOT(poly); * * for (j = 0; j < lt_tot; j++, lt++) { - * unsigned int vtri[3] = { - * mloop[lt->tri[0]].v, - * mloop[lt->tri[1]].v, - * mloop[lt->tri[2]].v, + * int vtri[3] = { + * corner_verts[lt->tri[0]], + * corner_verts[lt->tri[1]], + * corner_verts[lt->tri[2]], * }; * printf("tri %u %u %u\n", vtri[0], vtri[1], vtri[2]); * }; @@ -191,16 +179,16 @@ enum { * It may also be useful to check whether or not two vertices of a triangle * form an edge in the underlying mesh. * - * This can be done by checking the edge of the referenced loop (#MLoop.e), - * the winding of the #MLoopTri and the #MLoop's will always match, + * This can be done by checking the edge of the referenced corner, + * the winding of the #MLoopTri and the corners's will always match, * however the order of vertices in the edge is undefined. * * \code{.c} * // print real edges from an MLoopTri: lt * int j, j_next; * for (j = 2, j_next = 0; j_next < 3; j = j_next++) { - * MEdge *ed = &medge[mloop[lt->tri[j]].e]; - * unsigned int tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v}; + * MEdge *ed = &medge[corner_edges[lt->tri[j]]]; + * unsigned int tri_edge[2] = {corner_verts[lt->tri[j]], corner_verts[lt->tri[j_next]]}; * * if (((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) || * ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0]))) @@ -410,10 +398,9 @@ enum { /** \name Utility Macros * \{ */ -#define ME_POLY_LOOP_PREV(mloop, poly, i) \ - (&(mloop)[(poly)->loopstart + (((i) + (poly)->totloop - 1) % (poly)->totloop)]) -#define ME_POLY_LOOP_NEXT(mloop, poly, i) \ - (&(mloop)[(poly)->loopstart + (((i) + 1) % (poly)->totloop)]) +#define ME_POLY_LOOP_PREV(poly, i) \ + ((poly)->loopstart + (((i) + (poly)->totloop - 1) % (poly)->totloop)) +#define ME_POLY_LOOP_NEXT(poly, i) ((poly)->loopstart + (((i) + 1) % (poly)->totloop)) /** Number of tri's that make up this polygon once tessellated. */ #define ME_POLY_TRI_TOT(poly) ((poly)->totloop - 2) @@ -452,12 +439,10 @@ enum { MLOOPUV_PINNED = (1 << 2), }; -#endif - /** * Deprecated mesh vertex data structure. Now stored with generic attributes. */ -#ifdef DNA_DEPRECATED_ALLOW + typedef struct MVert { float co_legacy[3]; /** @@ -479,11 +464,24 @@ enum { /** Deprecated hide status. Now stored in ".hide_vert" attribute. */ ME_HIDE = (1 << 4), }; + +/** + * Mesh Face Corners. + * Deprecated storage for the vertex of a face corner and the following edge. + * Replaced by the "corner_verts" and "corner_edges" arrays. + */ +typedef struct MLoop { + /** Vertex index. */ + unsigned int v; + /** Edge index into an #MEdge array. */ + unsigned int e; +} MLoop; + #endif /** - * Used in Blender pre 2.63, See #MLoop, #MPoly for face data stored in the blend file. - * Use for reading old files and in a handful of cases which should be removed eventually. + * Used in Blender pre 2.63, See #Mesh::corner_verts(), #MPoly for face data stored in the blend + * file. Use for reading old files and in a handful of cases which should be removed eventually. */ typedef struct MFace { unsigned int v1, v2, v3, v4; diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 0cdf3c4b590..e41c3e7179d 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -395,8 +395,8 @@ static int rna_MeshPolygon_index_get(PointerRNA *ptr) static int rna_MeshLoop_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); - const MLoop *mloop = (MLoop *)ptr->data; - const int index = (int)(mloop - BKE_mesh_loops(mesh)); + const int *corner_vert = (const int *)ptr->data; + const int index = (int)(corner_vert - BKE_mesh_corner_verts(mesh)); BLI_assert(index >= 0); BLI_assert(index < mesh->totloop); return index; @@ -560,6 +560,30 @@ static void rna_MEdge_crease_set(PointerRNA *ptr, float value) values[index] = clamp_f(value, 0.0f, 1.0f); } +static int rna_MeshLoop_vertex_index_get(PointerRNA *ptr) +{ + return *(int *)ptr->data; +} + +static void rna_MeshLoop_vertex_index_set(PointerRNA *ptr, int value) +{ + *(int *)ptr->data = value; +} + +static int rna_MeshLoop_edge_index_get(PointerRNA *ptr) +{ + const Mesh *me = rna_mesh(ptr); + const int index = rna_MeshLoop_index_get(ptr); + return BKE_mesh_corner_edges(me)[index]; +} + +static void rna_MeshLoop_edge_index_set(PointerRNA *ptr, int value) +{ + Mesh *me = rna_mesh(ptr); + const int index = rna_MeshLoop_index_get(ptr); + BKE_mesh_corner_edges_for_write(me)[index] = value; +} + static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); @@ -629,9 +653,9 @@ static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values) Mesh *me = rna_mesh(ptr); MPoly *poly = (MPoly *)ptr->data; const float(*positions)[3] = BKE_mesh_vert_positions(me); - const MLoop *loops = BKE_mesh_loops(me); + const int *corner_verts = BKE_mesh_corner_verts(me); BKE_mesh_calc_poly_normal( - &loops[poly->loopstart], poly->totloop, positions, me->totvert, values); + &corner_verts[poly->loopstart], poly->totloop, positions, me->totvert, values); } static bool rna_MeshPolygon_hide_get(PointerRNA *ptr) @@ -733,9 +757,9 @@ static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values) Mesh *me = rna_mesh(ptr); MPoly *poly = (MPoly *)ptr->data; const float(*positions)[3] = BKE_mesh_vert_positions(me); - const MLoop *loops = BKE_mesh_loops(me); + const int *corner_verts = BKE_mesh_corner_verts(me); BKE_mesh_calc_poly_center( - &loops[poly->loopstart], poly->totloop, positions, me->totvert, values); + &corner_verts[poly->loopstart], poly->totloop, positions, me->totvert, values); } static float rna_MeshPolygon_area_get(PointerRNA *ptr) @@ -743,15 +767,17 @@ static float rna_MeshPolygon_area_get(PointerRNA *ptr) Mesh *me = (Mesh *)ptr->owner_id; MPoly *poly = (MPoly *)ptr->data; const float(*positions)[3] = BKE_mesh_vert_positions(me); - const MLoop *loops = BKE_mesh_loops(me); - return BKE_mesh_calc_poly_area(&loops[poly->loopstart], poly->totloop, positions, me->totvert); + const int *corner_verts = BKE_mesh_corner_verts(me); + return BKE_mesh_calc_poly_area( + &corner_verts[poly->loopstart], poly->totloop, positions, me->totvert); } static void rna_MeshPolygon_flip(ID *id, MPoly *poly) { Mesh *me = (Mesh *)id; - MLoop *loops = BKE_mesh_loops_for_write(me); - BKE_mesh_polygon_flip(poly, loops, &me->ldata, me->totloop); + int *corner_verts = BKE_mesh_corner_verts_for_write(me); + int *corner_edges = BKE_mesh_corner_edges_for_write(me); + BKE_mesh_polygon_flip(poly, corner_verts, corner_edges, &me->ldata, me->totloop); BKE_mesh_tessface_clear(me); BKE_mesh_runtime_clear_geometry(me); } @@ -759,11 +785,11 @@ static void rna_MeshPolygon_flip(ID *id, MPoly *poly) static void rna_MeshLoopTriangle_verts_get(PointerRNA *ptr, int *values) { Mesh *me = rna_mesh(ptr); - const MLoop *loops = BKE_mesh_loops(me); + const int *corner_verts = BKE_mesh_corner_verts(me); MLoopTri *lt = (MLoopTri *)ptr->data; - values[0] = loops[lt->tri[0]].v; - values[1] = loops[lt->tri[1]].v; - values[2] = loops[lt->tri[2]].v; + values[0] = corner_verts[lt->tri[0]]; + values[1] = corner_verts[lt->tri[1]]; + values[2] = corner_verts[lt->tri[2]]; } static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values) @@ -771,10 +797,10 @@ static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values) Mesh *me = rna_mesh(ptr); MLoopTri *lt = (MLoopTri *)ptr->data; const float(*positions)[3] = BKE_mesh_vert_positions(me); - const MLoop *loops = BKE_mesh_loops(me); - uint v1 = loops[lt->tri[0]].v; - uint v2 = loops[lt->tri[1]].v; - uint v3 = loops[lt->tri[2]].v; + const int *corner_verts = BKE_mesh_corner_verts(me); + const int v1 = corner_verts[lt->tri[0]]; + const int v2 = corner_verts[lt->tri[1]]; + const int v3 = corner_verts[lt->tri[2]]; normal_tri_v3(values, positions[v1], positions[v2], positions[v3]); } @@ -802,10 +828,10 @@ static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr) Mesh *me = rna_mesh(ptr); MLoopTri *lt = (MLoopTri *)ptr->data; const float(*positions)[3] = BKE_mesh_vert_positions(me); - const MLoop *loops = BKE_mesh_loops(me); - uint v1 = loops[lt->tri[0]].v; - uint v2 = loops[lt->tri[1]].v; - uint v3 = loops[lt->tri[2]].v; + const int *corner_verts = BKE_mesh_corner_verts(me); + const int v1 = corner_verts[lt->tri[0]]; + const int v2 = corner_verts[lt->tri[1]]; + const int v3 = corner_verts[lt->tri[2]]; return area_tri_v3(positions[v1], positions[v2], positions[v3]); } @@ -1643,27 +1669,17 @@ static int rna_MeshPoly_vertices_get_length(const PointerRNA *ptr, static void rna_MeshPoly_vertices_get(PointerRNA *ptr, int *values) { - Mesh *me = rna_mesh(ptr); - MPoly *poly = (MPoly *)ptr->data; - const MLoop *loops = BKE_mesh_loops(me); - const MLoop *ml = &loops[poly->loopstart]; - uint i; - for (i = poly->totloop; i > 0; i--, values++, ml++) { - *values = ml->v; - } + const Mesh *me = rna_mesh(ptr); + const MPoly *poly = (const MPoly *)ptr->data; + memcpy(values, BKE_mesh_corner_verts(me) + poly->loopstart, sizeof(int) * poly->totloop); } static void rna_MeshPoly_vertices_set(PointerRNA *ptr, const int *values) { Mesh *me = rna_mesh(ptr); const MPoly *poly = (const MPoly *)ptr->data; - MLoop *loops = BKE_mesh_loops_for_write(me); - - MLoop *ml = &loops[poly->loopstart]; - uint i; - for (i = poly->totloop; i > 0; i--, values++, ml++) { - ml->v = *values; - } + memcpy( + BKE_mesh_corner_verts_for_write(me) + poly->loopstart, values, sizeof(int) * poly->totloop); } /* disabling, some importers don't know the total material count when assigning materials */ @@ -2009,7 +2025,7 @@ static void rna_Mesh_loops_begin(CollectionPropertyIterator *iter, PointerRNA *p { Mesh *mesh = rna_mesh(ptr); rna_iterator_array_begin( - iter, BKE_mesh_loops_for_write(mesh), sizeof(MLoop), mesh->totloop, false, NULL); + iter, BKE_mesh_corner_verts_for_write(mesh), sizeof(int), mesh->totloop, false, NULL); } static int rna_Mesh_loops_length(PointerRNA *ptr) { @@ -2024,7 +2040,7 @@ int rna_Mesh_loops_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) } r_ptr->owner_id = &mesh->id; r_ptr->type = &RNA_MeshLoop; - r_ptr->data = &BKE_mesh_loops_for_write(mesh)[index]; + r_ptr->data = &BKE_mesh_corner_verts_for_write(mesh)[index]; return true; } @@ -2856,17 +2872,18 @@ static void rna_def_mloop(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "MeshLoop", NULL); - RNA_def_struct_sdna(srna, "MLoop"); RNA_def_struct_ui_text(srna, "Mesh Loop", "Loop in a Mesh data-block"); RNA_def_struct_path_func(srna, "rna_MeshLoop_path"); RNA_def_struct_ui_icon(srna, ICON_EDGESEL); prop = RNA_def_property(srna, "vertex_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "v"); + RNA_def_property_int_funcs( + prop, "rna_MeshLoop_vertex_index_get", "rna_MeshLoop_vertex_index_set", false); RNA_def_property_ui_text(prop, "Vertex", "Vertex index"); prop = RNA_def_property(srna, "edge_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "e"); + RNA_def_property_int_funcs( + prop, "rna_MeshLoop_edge_index_get", "rna_MeshLoop_edge_index_set", false); RNA_def_property_ui_text(prop, "Edge", "Edge index"); prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 3699a2ed66d..c24cd7c6d3a 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -98,7 +98,7 @@ static void rna_Mesh_calc_smooth_groups( *r_poly_group = BKE_mesh_calc_smoothgroups(mesh->totedge, BKE_mesh_polys(mesh), mesh->totpoly, - BKE_mesh_loops(mesh), + BKE_mesh_corner_edges(mesh), mesh->totloop, sharp_edges, sharp_faces, @@ -171,8 +171,11 @@ static void rna_Mesh_transform(Mesh *mesh, float mat[16], bool shape_keys) static void rna_Mesh_flip_normals(Mesh *mesh) { - BKE_mesh_polys_flip( - BKE_mesh_polys(mesh), BKE_mesh_loops_for_write(mesh), &mesh->ldata, mesh->totpoly); + BKE_mesh_polys_flip(BKE_mesh_polys(mesh), + BKE_mesh_corner_verts_for_write(mesh), + BKE_mesh_corner_edges_for_write(mesh), + &mesh->ldata, + mesh->totpoly); BKE_mesh_tessface_clear(mesh); BKE_mesh_runtime_clear_geometry(mesh); diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 458983c0ca5..4c76976a792 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -284,11 +284,11 @@ static void mesh_merge_transform(Mesh *result, int *index_orig; int i; MEdge *edge; - MLoop *ml; float(*result_positions)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan result_edges = result->edges_for_write(); blender::MutableSpan result_polys = result->polys_for_write(); - blender::MutableSpan result_loops = result->loops_for_write(); + blender::MutableSpan result_corner_verts = result->corner_verts_for_write(); + blender::MutableSpan result_corner_edges = result->corner_edges_for_write(); CustomData_copy_data(&cap_mesh->vdata, &result->vdata, 0, cap_verts_index, cap_nverts); CustomData_copy_data(&cap_mesh->edata, &result->edata, 0, cap_edges_index, cap_nedges); @@ -327,10 +327,9 @@ static void mesh_merge_transform(Mesh *result, } /* adjust cap loop vertex and edge indices */ - ml = &result_loops[cap_loops_index]; - for (i = 0; i < cap_nloops; i++, ml++) { - ml->v += cap_verts_index; - ml->e += cap_edges_index; + for (i = 0; i < cap_nloops; i++) { + result_corner_verts[cap_loops_index + i] += cap_verts_index; + result_corner_edges[cap_loops_index + i] += cap_edges_index; } const bke::AttributeAccessor cap_attributes = cap_mesh->attributes(); @@ -379,7 +378,6 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } MEdge *edge; - MLoop *ml; int i, j, c, count; float length = amd->length; /* offset matrix */ @@ -557,7 +555,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, float(*result_positions)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan result_edges = result->edges_for_write(); blender::MutableSpan result_polys = result->polys_for_write(); - blender::MutableSpan result_loops = result->loops_for_write(); + blender::MutableSpan result_corner_verts = result->corner_verts_for_write(); + blender::MutableSpan result_corner_edges = result->corner_edges_for_write(); if (use_merge) { /* Will need full_doubles_map for handling merge */ @@ -621,10 +620,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } /* adjust loop vertex and edge indices */ - ml = &result_loops[c * chunk_nloops]; - for (i = 0; i < chunk_nloops; i++, ml++) { - ml->v += c * chunk_nverts; - ml->e += c * chunk_nedges; + const int chunk_corner_start = c * chunk_nloops; + for (i = 0; i < chunk_nloops; i++) { + result_corner_verts[chunk_corner_start + i] += c * chunk_nverts; + result_corner_edges[chunk_corner_start + i] += c * chunk_nedges; } /* Handle merge between chunk n and n-1 */ diff --git a/source/blender/modifiers/intern/MOD_build.cc b/source/blender/modifiers/intern/MOD_build.cc index e4c28530bc1..e0df87ef849 100644 --- a/source/blender/modifiers/intern/MOD_build.cc +++ b/source/blender/modifiers/intern/MOD_build.cc @@ -61,8 +61,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * int faces_dst_num, edges_dst_num, loops_dst_num = 0; float frac; MPoly *mpoly_dst; - MLoop *ml_dst; - const MLoop *ml_src; GHashIterator gh_iter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_int_new("build ve apply gh"); @@ -74,7 +72,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const int vert_src_num = mesh->totvert; const blender::Span edges_src = mesh->edges(); const blender::Span polys_src = mesh->polys(); - const blender::Span loops_src = mesh->loops(); + const blender::Span corner_verts_src = mesh->corner_verts(); + const blender::Span corner_edges_src = mesh->corner_edges(); int *vertMap = static_cast(MEM_malloc_arrayN(vert_src_num, sizeof(int), __func__)); int *edgeMap = static_cast(MEM_malloc_arrayN(edges_src.size(), sizeof(int), __func__)); @@ -97,7 +96,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* if there's at least one face, build based on faces */ if (faces_dst_num) { const MPoly *polys, *poly; - const MLoop *ml, *mloop; uintptr_t hash_num, hash_num_alt; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { @@ -108,15 +106,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * mapped to the new indices */ polys = polys_src.data(); - mloop = loops_src.data(); hash_num = 0; for (i = 0; i < faces_dst_num; i++) { poly = polys + faceMap[i]; - ml = mloop + poly->loopstart; - - for (j = 0; j < poly->totloop; j++, ml++) { + for (j = 0; j < poly->totloop; j++) { + const int vert_i = corner_verts_src[poly->loopstart + j]; void **val_p; - if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(ml->v), &val_p)) { + if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(vert_i), &val_p)) { *val_p = (void *)hash_num; hash_num++; } @@ -200,7 +196,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), loops_dst_num, faces_dst_num); blender::MutableSpan result_edges = result->edges_for_write(); blender::MutableSpan result_polys = result->polys_for_write(); - blender::MutableSpan result_loops = result->loops_for_write(); + blender::MutableSpan result_corner_verts = result->corner_verts_for_write(); + blender::MutableSpan result_corner_edges = result->corner_edges_for_write(); /* copy the vertices across */ GHASH_ITER (gh_iter, vertHash) { @@ -226,7 +223,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } mpoly_dst = result_polys.data(); - ml_dst = result_loops.data(); /* copy the faces across, remapping indices */ k = 0; @@ -243,10 +239,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_copy_data( &mesh->ldata, &result->ldata, source->loopstart, dest->loopstart, dest->totloop); - ml_src = &loops_src[source->loopstart]; - for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) { - ml_dst->v = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(ml_src->v))); - ml_dst->e = POINTER_AS_INT(BLI_ghash_lookup(edgeHash2, POINTER_FROM_INT(ml_src->e))); + for (j = 0; j < source->totloop; j++, k++) { + const int vert_src = corner_verts_src[source->loopstart + j]; + const int edge_src = corner_edges_src[source->loopstart + j]; + result_corner_verts[dest->loopstart + j] = POINTER_AS_INT( + BLI_ghash_lookup(vertHash, POINTER_FROM_INT(vert_src))); + result_corner_edges[dest->loopstart + j] = POINTER_AS_INT( + BLI_ghash_lookup(edgeHash2, POINTER_FROM_INT(edge_src))); } } diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 5f5cbfc342d..788adb5f62f 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -159,11 +159,11 @@ static void deformVerts(ModifierData *md, collmd->mvert_num = mvert_num; { - const MLoop *mloop = BKE_mesh_loops(mesh_src); const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh_src); collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh_src); MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__); - BKE_mesh_runtime_verttri_from_looptri(tri, mloop, looptri, collmd->tri_num); + BKE_mesh_runtime_verttri_from_looptri( + tri, BKE_mesh_corner_verts(mesh_src), looptri, collmd->tri_num); collmd->tri = tri; } diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.cc b/source/blender/modifiers/intern/MOD_correctivesmooth.cc index 7dfbe03ca84..eecaad2e1aa 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.cc +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.cc @@ -129,7 +129,7 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) { const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_edges = mesh->corner_edges(); /* Flag boundary edges so only boundaries are set to 1. */ uint8_t *boundaries = static_cast( @@ -139,7 +139,7 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) const int totloop = polys[i].totloop; int j; for (j = 0; j < totloop; j++) { - uint8_t *e_value = &boundaries[loops[polys[i].loopstart + j].e]; + uint8_t *e_value = &boundaries[corner_edges[polys[i].loopstart + j]]; *e_value |= uint8_t((*e_value) + 1); } } @@ -435,7 +435,7 @@ static void calc_tangent_spaces(const Mesh *mesh, { const uint mvert_num = uint(mesh->totvert); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + blender::Span corner_verts = mesh->corner_verts(); if (r_tangent_weights_per_vertex != nullptr) { copy_vn_fl(r_tangent_weights_per_vertex, int(mvert_num), 0.0f); @@ -443,40 +443,42 @@ static void calc_tangent_spaces(const Mesh *mesh, for (const int64_t i : polys.index_range()) { const MPoly &poly = polys[i]; - const MLoop *l_next = &loops[poly.loopstart]; - const MLoop *l_term = l_next + poly.totloop; - const MLoop *l_prev = l_term - 2; - const MLoop *l_curr = l_term - 1; + int next_corner = poly.loopstart; + int term_corner = next_corner + poly.totloop; + int prev_corner = term_corner - 2; + int curr_corner = term_corner - 1; /* loop directions */ float v_dir_prev[3], v_dir_next[3]; /* needed entering the loop */ - sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]); + sub_v3_v3v3( + v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]); normalize_v3(v_dir_prev); - for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) { - uint l_index = uint(l_curr - loops.data()); - float(*ts)[3] = r_tangent_spaces[l_index]; + for (; next_corner != term_corner; + prev_corner = curr_corner, curr_corner = next_corner, next_corner++) { + float(*ts)[3] = r_tangent_spaces[curr_corner]; /* re-use the previous value */ #if 0 - sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]); + sub_v3_v3v3(v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]); normalize_v3(v_dir_prev); #endif - sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]); + sub_v3_v3v3( + v_dir_next, vertexCos[corner_verts[curr_corner]], vertexCos[corner_verts[next_corner]]); normalize_v3(v_dir_next); if (calc_tangent_loop(v_dir_prev, v_dir_next, ts)) { if (r_tangent_weights != nullptr) { const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev))); - r_tangent_weights[l_index] = weight; - r_tangent_weights_per_vertex[l_curr->v] += weight; + r_tangent_weights[curr_corner] = weight; + r_tangent_weights_per_vertex[corner_verts[curr_corner]] += weight; } } else { if (r_tangent_weights != nullptr) { - r_tangent_weights[l_index] = 0; + r_tangent_weights[curr_corner] = 0; } } @@ -513,34 +515,34 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd, const float (*rest_coords)[3], uint verts_num) { - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); float(*smooth_vertex_coords)[3] = static_cast(MEM_dupallocN(rest_coords)); uint l_index; float(*tangent_spaces)[3][3] = static_cast( - MEM_malloc_arrayN(size_t(loops.size()), sizeof(float[3][3]), __func__)); + MEM_malloc_arrayN(size_t(corner_verts.size()), sizeof(float[3][3]), __func__)); - if (csmd->delta_cache.deltas_num != uint(loops.size())) { + if (csmd->delta_cache.deltas_num != uint(corner_verts.size())) { MEM_SAFE_FREE(csmd->delta_cache.deltas); } /* allocate deltas if they have not yet been allocated, otherwise we will just write over them */ if (!csmd->delta_cache.deltas) { - csmd->delta_cache.deltas_num = uint(loops.size()); + csmd->delta_cache.deltas_num = uint(corner_verts.size()); csmd->delta_cache.deltas = static_cast( - MEM_malloc_arrayN(size_t(loops.size()), sizeof(float[3]), __func__)); + MEM_malloc_arrayN(size_t(corner_verts.size()), sizeof(float[3]), __func__)); } smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, verts_num); calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces, nullptr, nullptr); - copy_vn_fl(&csmd->delta_cache.deltas[0][0], int(loops.size()) * 3, 0.0f); + copy_vn_fl(&csmd->delta_cache.deltas[0][0], int(corner_verts.size()) * 3, 0.0f); - for (l_index = 0; l_index < loops.size(); l_index++) { - const int v_index = int(loops[l_index].v); + for (l_index = 0; l_index < corner_verts.size(); l_index++) { + const int v_index = corner_verts[l_index]; float delta[3]; sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]); @@ -571,7 +573,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) && (((ID *)ob->data)->recalc & ID_RECALC_ALL)); - const blender::Span loops = mesh->loops(); + blender::Span corner_verts = mesh->corner_verts(); bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0; const MDeformVert *dvert = nullptr; @@ -636,7 +638,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, } /* check to see if our deltas are still valid */ - if (!csmd->delta_cache.deltas || (csmd->delta_cache.deltas_num != loops.size()) || + if (!csmd->delta_cache.deltas || (csmd->delta_cache.deltas_num != corner_verts.size()) || force_delta_cache_update) { const float(*rest_coords)[3]; bool is_rest_coords_alloc = false; @@ -689,17 +691,17 @@ static void correctivesmooth_modifier_do(ModifierData *md, const float scale = csmd->scale; float(*tangent_spaces)[3][3] = static_cast( - MEM_malloc_arrayN(size_t(loops.size()), sizeof(float[3][3]), __func__)); + MEM_malloc_arrayN(size_t(corner_verts.size()), sizeof(float[3][3]), __func__)); float *tangent_weights = static_cast( - MEM_malloc_arrayN(size_t(loops.size()), sizeof(float), __func__)); + MEM_malloc_arrayN(size_t(corner_verts.size()), sizeof(float), __func__)); float *tangent_weights_per_vertex = static_cast( MEM_malloc_arrayN(verts_num, sizeof(float), __func__)); calc_tangent_spaces( mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex); - for (const int64_t l_index : loops.index_range()) { - const uint v_index = loops[l_index].v; + for (const int64_t l_index : corner_verts.index_range()) { + const int v_index = corner_verts[l_index]; const float weight = tangent_weights[l_index] / tangent_weights_per_vertex[v_index]; if (UNLIKELY(!(weight > 0.0f))) { /* Catches zero & divide by zero. */ diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index 1d6db98d8fd..52fe7db92d6 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -311,8 +311,11 @@ static void displaceModifier_do(DisplaceModifierData *dmd, CustomData_get_layer_for_write(ldata, CD_NORMAL, mesh->totloop)); vert_clnors = static_cast( MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__)); - BKE_mesh_normals_loop_to_vertex( - verts_num, mesh->loops().data(), mesh->totloop, (const float(*)[3])clnors, vert_clnors); + BKE_mesh_normals_loop_to_vertex(verts_num, + mesh->corner_verts().data(), + mesh->totloop, + (const float(*)[3])clnors, + vert_clnors); } else { direction = MOD_DISP_DIR_NOR; diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.cc b/source/blender/modifiers/intern/MOD_laplaciandeform.cc index bc329d3e5bc..7b5391b8bf9 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.cc +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.cc @@ -140,7 +140,7 @@ static void deleteLaplacianSystem(LaplacianSystem *sys) static void createFaceRingMap(const int mvert_tot, blender::Span looptris, - blender::Span loops, + blender::Span corner_verts, MeshElemMap **r_map, int **r_indices) { @@ -151,7 +151,7 @@ static void createFaceRingMap(const int mvert_tot, for (const int i : looptris.index_range()) { const MLoopTri &mlt = looptris[i]; for (int j = 0; j < 3; j++) { - const uint v_index = loops[mlt.tri[j]].v; + const int v_index = corner_verts[mlt.tri[j]]; map[v_index].count++; indices_num++; } @@ -166,7 +166,7 @@ static void createFaceRingMap(const int mvert_tot, for (const int i : looptris.index_range()) { const MLoopTri &mlt = looptris[i]; for (int j = 0; j < 3; j++) { - const uint v_index = loops[mlt.tri[j]].v; + const int v_index = corner_verts[mlt.tri[j]]; map[v_index].indices[map[v_index].count] = i; map[v_index].count++; } @@ -548,7 +548,7 @@ static void initSystem( } const blender::Span edges = mesh->edges(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); const blender::Span looptris = mesh->looptris(); anchors_num = STACK_SIZE(index_anchors); @@ -562,13 +562,13 @@ static void initSystem( memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * verts_num); lmd->verts_num = verts_num; - createFaceRingMap(mesh->totvert, looptris, loops, &sys->ringf_map, &sys->ringf_indices); + createFaceRingMap(mesh->totvert, looptris, corner_verts, &sys->ringf_map, &sys->ringf_indices); createVertRingMap(mesh->totvert, edges, &sys->ringv_map, &sys->ringv_indices); for (i = 0; i < sys->tris_num; i++) { - sys->tris[i][0] = loops[looptris[i].tri[0]].v; - sys->tris[i][1] = loops[looptris[i].tri[1]].v; - sys->tris[i][2] = loops[looptris[i].tri[2]].v; + sys->tris[i][0] = corner_verts[looptris[i].tri[0]]; + sys->tris[i][1] = corner_verts[looptris[i].tri[1]]; + sys->tris[i][2] = corner_verts[looptris[i].tri[2]]; } } } diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.cc b/source/blender/modifiers/intern/MOD_laplaciansmooth.cc index 7422f8d09bd..5673cfce1f3 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.cc +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.cc @@ -52,9 +52,9 @@ struct LaplacianSystem { /* Pointers to data. */ float (*vertexCos)[3]; - blender::Span polys; - blender::Span loops; blender::Span edges; + blender::Span polys; + blender::Span corner_verts; LinearSolver *context; /* Data. */ @@ -83,7 +83,7 @@ static void delete_laplacian_system(LaplacianSystem *sys) static void memset_laplacian_system(LaplacianSystem *sys, int val) { memset(sys->eweights, val, sizeof(float) * sys->edges.size()); - memset(sys->fweights, val, sizeof(float[3]) * sys->loops.size()); + memset(sys->fweights, val, sizeof(float[3]) * sys->corner_verts.size()); memset(sys->ne_ed_num, val, sizeof(short) * sys->verts_num); memset(sys->ne_fa_num, val, sizeof(short) * sys->verts_num); memset(sys->ring_areas, val, sizeof(float) * sys->verts_num); @@ -113,20 +113,22 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numLoops, in static float compute_volume(const float center[3], float (*vertexCos)[3], const blender::Span polys, - const blender::Span loops) + const blender::Span corner_verts) { float vol = 0.0f; for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - const MLoop *l_first = &loops[poly.loopstart]; - const MLoop *l_prev = l_first + 1; - const MLoop *l_curr = l_first + 2; - const MLoop *l_term = l_first + poly.totloop; + int corner_first = poly.loopstart; + int corner_prev = corner_first + 1; + int corner_curr = corner_first + 2; + int corner_term = corner_first + poly.totloop; - for (; l_curr != l_term; l_prev = l_curr, l_curr++) { - vol += volume_tetrahedron_signed_v3( - center, vertexCos[l_first->v], vertexCos[l_prev->v], vertexCos[l_curr->v]); + for (; corner_curr != corner_term; corner_prev = corner_curr, corner_curr++) { + vol += volume_tetrahedron_signed_v3(center, + vertexCos[corner_verts[corner_first]], + vertexCos[corner_verts[corner_prev]], + vertexCos[corner_verts[corner_curr]]); } } @@ -186,42 +188,44 @@ static void init_laplacian_matrix(LaplacianSystem *sys) sys->eweights[i] = w1; } + const blender::Span corner_verts = sys->corner_verts; + for (const int i : sys->polys.index_range()) { const MPoly &poly = sys->polys[i]; - const MLoop *l_next = &sys->loops[poly.loopstart]; - const MLoop *l_term = l_next + poly.totloop; - const MLoop *l_prev = l_term - 2; - const MLoop *l_curr = l_term - 1; + int corner_next = poly.loopstart; + int corner_term = corner_next + poly.totloop; + int corner_prev = corner_term - 2; + int corner_curr = corner_term - 1; - for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) { - const float *v_prev = sys->vertexCos[l_prev->v]; - const float *v_curr = sys->vertexCos[l_curr->v]; - const float *v_next = sys->vertexCos[l_next->v]; - const uint l_curr_index = l_curr - sys->loops.data(); + for (; corner_next != corner_term; + corner_prev = corner_curr, corner_curr = corner_next, corner_next++) { + const float *v_prev = sys->vertexCos[corner_verts[corner_prev]]; + const float *v_curr = sys->vertexCos[corner_verts[corner_curr]]; + const float *v_next = sys->vertexCos[corner_verts[corner_next]]; - sys->ne_fa_num[l_curr->v] += 1; + sys->ne_fa_num[corner_verts[corner_curr]] += 1; areaf = area_tri_v3(v_prev, v_curr, v_next); if (areaf < sys->min_area) { - sys->zerola[l_curr->v] = true; + sys->zerola[corner_verts[corner_curr]] = true; } - sys->ring_areas[l_prev->v] += areaf; - sys->ring_areas[l_curr->v] += areaf; - sys->ring_areas[l_next->v] += areaf; + sys->ring_areas[corner_verts[corner_prev]] += areaf; + sys->ring_areas[corner_verts[corner_curr]] += areaf; + sys->ring_areas[corner_verts[corner_next]] += areaf; w1 = cotangent_tri_weight_v3(v_curr, v_next, v_prev) / 2.0f; w2 = cotangent_tri_weight_v3(v_next, v_prev, v_curr) / 2.0f; w3 = cotangent_tri_weight_v3(v_prev, v_curr, v_next) / 2.0f; - sys->fweights[l_curr_index][0] += w1; - sys->fweights[l_curr_index][1] += w2; - sys->fweights[l_curr_index][2] += w3; + sys->fweights[corner_curr][0] += w1; + sys->fweights[corner_curr][1] += w2; + sys->fweights[corner_curr][2] += w3; - sys->vweights[l_curr->v] += w2 + w3; - sys->vweights[l_next->v] += w1 + w3; - sys->vweights[l_prev->v] += w1 + w2; + sys->vweights[corner_verts[corner_curr]] += w2 + w3; + sys->vweights[corner_verts[corner_next]] += w1 + w3; + sys->vweights[corner_verts[corner_prev]] += w1 + w2; } } for (i = 0; i < sys->edges.size(); i++) { @@ -241,49 +245,57 @@ static void fill_laplacian_matrix(LaplacianSystem *sys) int i; uint idv1, idv2; + const blender::Span corner_verts = sys->corner_verts; + for (const int i : sys->polys.index_range()) { const MPoly &poly = sys->polys[i]; - const MLoop *l_next = &sys->loops[poly.loopstart]; - const MLoop *l_term = l_next + poly.totloop; - const MLoop *l_prev = l_term - 2; - const MLoop *l_curr = l_term - 1; + int corner_next = poly.loopstart; + int corner_term = corner_next + poly.totloop; + int corner_prev = corner_term - 2; + int corner_curr = corner_term - 1; - for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) { - const uint l_curr_index = l_curr - sys->loops.data(); + for (; corner_next != corner_term; + corner_prev = corner_curr, corner_curr = corner_next, corner_next++) { /* Is ring if number of faces == number of edges around vertex. */ - if (sys->ne_ed_num[l_curr->v] == sys->ne_fa_num[l_curr->v] && - sys->zerola[l_curr->v] == false) { + if (sys->ne_ed_num[corner_verts[corner_curr]] == sys->ne_fa_num[corner_verts[corner_curr]] && + sys->zerola[corner_verts[corner_curr]] == false) { EIG_linear_solver_matrix_add(sys->context, - l_curr->v, - l_next->v, - sys->fweights[l_curr_index][2] * sys->vweights[l_curr->v]); + corner_verts[corner_curr], + corner_verts[corner_next], + sys->fweights[corner_curr][2] * + sys->vweights[corner_verts[corner_curr]]); EIG_linear_solver_matrix_add(sys->context, - l_curr->v, - l_prev->v, - sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]); + corner_verts[corner_curr], + corner_verts[corner_prev], + sys->fweights[corner_curr][1] * + sys->vweights[corner_verts[corner_curr]]); } - if (sys->ne_ed_num[l_next->v] == sys->ne_fa_num[l_next->v] && - sys->zerola[l_next->v] == false) { + if (sys->ne_ed_num[corner_verts[corner_next]] == sys->ne_fa_num[corner_verts[corner_next]] && + sys->zerola[corner_verts[corner_next]] == false) { EIG_linear_solver_matrix_add(sys->context, - l_next->v, - l_curr->v, - sys->fweights[l_curr_index][2] * sys->vweights[l_next->v]); + corner_verts[corner_next], + corner_verts[corner_curr], + sys->fweights[corner_curr][2] * + sys->vweights[corner_verts[corner_next]]); EIG_linear_solver_matrix_add(sys->context, - l_next->v, - l_prev->v, - sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]); + corner_verts[corner_next], + corner_verts[corner_prev], + sys->fweights[corner_curr][0] * + sys->vweights[corner_verts[corner_next]]); } - if (sys->ne_ed_num[l_prev->v] == sys->ne_fa_num[l_prev->v] && - sys->zerola[l_prev->v] == false) { + if (sys->ne_ed_num[corner_verts[corner_prev]] == sys->ne_fa_num[corner_verts[corner_prev]] && + sys->zerola[corner_verts[corner_prev]] == false) { EIG_linear_solver_matrix_add(sys->context, - l_prev->v, - l_curr->v, - sys->fweights[l_curr_index][1] * sys->vweights[l_prev->v]); + corner_verts[corner_prev], + corner_verts[corner_curr], + sys->fweights[corner_curr][1] * + sys->vweights[corner_verts[corner_prev]]); EIG_linear_solver_matrix_add(sys->context, - l_prev->v, - l_next->v, - sys->fweights[l_curr_index][0] * sys->vweights[l_prev->v]); + corner_verts[corner_prev], + corner_verts[corner_next], + sys->fweights[corner_curr][0] * + sys->vweights[corner_verts[corner_prev]]); } } } @@ -310,7 +322,7 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl float vini = 0.0f, vend = 0.0f; if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) { - vini = compute_volume(sys->vert_centroid, sys->vertexCos, sys->polys, sys->loops); + vini = compute_volume(sys->vert_centroid, sys->vertexCos, sys->polys, sys->corner_verts); } for (i = 0; i < sys->verts_num; i++) { if (sys->zerola[i] == false) { @@ -331,7 +343,7 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl } } if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) { - vend = compute_volume(sys->vert_centroid, sys->vertexCos, sys->polys, sys->loops); + vend = compute_volume(sys->vert_centroid, sys->vertexCos, sys->polys, sys->corner_verts); volume_preservation(sys, vini, vend, flag); } } @@ -352,9 +364,9 @@ static void laplaciansmoothModifier_do( return; } - sys->polys = mesh->polys(); - sys->loops = mesh->loops(); sys->edges = mesh->edges(); + sys->polys = mesh->polys(); + sys->corner_verts = mesh->corner_verts(); sys->vertexCos = vertexCos; sys->min_area = 0.00001f; MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index eddd3b09633..2a00e3bd147 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -225,7 +225,7 @@ static void computed_masked_polys(const Mesh *mesh, { BLI_assert(mesh->totvert == vertex_mask.size()); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); r_masked_poly_indices.reserve(mesh->totpoly); r_loop_starts.reserve(mesh->totpoly); @@ -235,9 +235,8 @@ static void computed_masked_polys(const Mesh *mesh, const MPoly &poly_src = polys[i]; bool all_verts_in_mask = true; - Span loops_src = loops.slice(poly_src.loopstart, poly_src.totloop); - for (const MLoop &loop : loops_src) { - if (!vertex_mask[loop.v]) { + for (const int vert_i : corner_verts.slice(poly_src.loopstart, poly_src.totloop)) { + if (!vertex_mask[vert_i]) { all_verts_in_mask = false; break; } @@ -271,7 +270,7 @@ static void compute_interpolated_polys(const Mesh *mesh, r_masked_poly_indices.reserve(r_masked_poly_indices.size() + verts_add_num); r_loop_starts.reserve(r_loop_starts.size() + verts_add_num); const Span polys = mesh->polys(); - const Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); uint edges_add_num = 0; uint polys_add_num = 0; @@ -282,10 +281,10 @@ static void compute_interpolated_polys(const Mesh *mesh, int in_count = 0; int start = -1; int dst_totloop = -1; - const Span loops_src = loops.slice(poly_src.loopstart, poly_src.totloop); - for (const int j : loops_src.index_range()) { - const MLoop &loop = loops_src[j]; - if (vertex_mask[loop.v]) { + const Span poly_verts_src = corner_verts.slice(poly_src.loopstart, poly_src.totloop); + for (const int j : poly_verts_src.index_range()) { + const int vert_i = poly_verts_src[j]; + if (vertex_mask[vert_i]) { in_count++; } else if (start == -1) { @@ -294,11 +293,11 @@ static void compute_interpolated_polys(const Mesh *mesh, } if (0 < in_count && in_count < poly_src.totloop) { /* Ring search starting at a vertex which is not included in the mask. */ - const MLoop *last_loop = &loops_src[start]; - bool v_loop_in_mask_last = vertex_mask[last_loop->v]; - for (const int j : loops_src.index_range()) { - const MLoop &loop = loops_src[(start + 1 + j) % poly_src.totloop]; - const bool v_loop_in_mask = vertex_mask[loop.v]; + int last_corner_vert = corner_verts[start]; + bool v_loop_in_mask_last = vertex_mask[last_corner_vert]; + for (const int j : poly_verts_src.index_range()) { + const int corner_vert = corner_verts[(start + 1 + j) % poly_src.totloop]; + const bool v_loop_in_mask = vertex_mask[corner_vert]; if (v_loop_in_mask && !v_loop_in_mask_last) { dst_totloop = 3; } @@ -315,7 +314,7 @@ static void compute_interpolated_polys(const Mesh *mesh, BLI_assert(dst_totloop > 2); dst_totloop++; } - last_loop = &loop; + last_corner_vert = corner_vert; v_loop_in_mask_last = v_loop_in_mask; } } @@ -446,9 +445,11 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, int polys_masked_num) { const Span src_polys = src_mesh.polys(); - const Span src_loops = src_mesh.loops(); MutableSpan dst_polys = dst_mesh.polys_for_write(); - MutableSpan dst_loops = dst_mesh.loops_for_write(); + const Span src_corner_verts = src_mesh.corner_verts(); + const Span src_corner_edges = src_mesh.corner_edges(); + MutableSpan dst_corner_verts = dst_mesh.corner_verts_for_write(); + MutableSpan dst_corner_edges = dst_mesh.corner_edges_for_write(); for (const int i_dst : IndexRange(polys_masked_num)) { const int i_src = masked_poly_indices[i_dst]; @@ -461,14 +462,11 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1); CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop); - const MLoop *ml_src = src_loops.data() + i_ml_src; - MLoop *ml_dst = dst_loops.data() + i_ml_dst; - mp_dst = mp_src; mp_dst.loopstart = i_ml_dst; for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = vertex_map[ml_src[i].v]; - ml_dst[i].e = edge_map[ml_src[i].e]; + dst_corner_verts[i_ml_dst + i] = vertex_map[src_corner_verts[i_ml_src + i]]; + dst_corner_edges[i_ml_dst + i] = edge_map[src_corner_edges[i_ml_src + i]]; } } } @@ -487,10 +485,12 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, int edges_add_num) { const Span src_polys = src_mesh.polys(); - const Span src_loops = src_mesh.loops(); - MutableSpan dst_edges = dst_mesh.edges_for_write(); MutableSpan dst_polys = dst_mesh.polys_for_write(); - MutableSpan dst_loops = dst_mesh.loops_for_write(); + MutableSpan dst_edges = dst_mesh.edges_for_write(); + const Span src_corner_verts = src_mesh.corner_verts(); + const Span src_corner_edges = src_mesh.corner_edges(); + MutableSpan dst_corner_verts = dst_mesh.corner_verts_for_write(); + MutableSpan dst_corner_edges = dst_mesh.corner_edges_for_write(); int edge_index = dst_mesh.totedge - edges_add_num; int sub_poly_index = 0; @@ -523,9 +523,9 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, /* Ring search starting at a vertex which is not included in the mask. */ int start = -sub_poly_index - 1; bool skip = false; - Span loops_src(&src_loops[i_ml_src], mp_src.totloop); - for (const int j : loops_src.index_range()) { - if (!vertex_mask[loops_src[j].v]) { + Span corner_verts_src(&src_corner_verts[i_ml_src], mp_src.totloop); + for (const int j : corner_verts_src.index_range()) { + if (!vertex_mask[corner_verts_src[j]]) { if (start == -1) { start = j; break; @@ -543,50 +543,52 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, BLI_assert(start >= 0); BLI_assert(edge_index < dst_mesh.totedge); - const MLoop *last_loop = &loops_src[start]; - bool v_loop_in_mask_last = vertex_mask[last_loop->v]; + int last_corner_i = start; + bool v_loop_in_mask_last = vertex_mask[src_corner_verts[last_corner_i]]; int last_index = start; - for (const int j : loops_src.index_range()) { + for (const int j : corner_verts_src.index_range()) { const int index = (start + 1 + j) % mp_src.totloop; - const MLoop &loop = loops_src[index]; - const bool v_loop_in_mask = vertex_mask[loop.v]; + const bool v_loop_in_mask = vertex_mask[src_corner_verts[index]]; if (v_loop_in_mask && !v_loop_in_mask_last) { /* Start new cut. */ - float fac = get_interp_factor_from_vgroup( - dvert, defgrp_index, threshold, last_loop->v, loop.v); + float fac = get_interp_factor_from_vgroup(dvert, + defgrp_index, + threshold, + src_corner_verts[last_corner_i], + src_corner_verts[index]); float weights[2] = {1.0f - fac, fac}; int indices[2] = {i_ml_src + last_index, i_ml_src + index}; CustomData_interp( &src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst); - MLoop &cut_dst_loop = dst_loops[i_ml_dst]; - cut_dst_loop.e = edge_map[last_loop->e]; - cut_dst_loop.v = dst_edges[cut_dst_loop.e].v1; + dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[last_corner_i]]; + dst_corner_verts[i_ml_dst] = dst_edges[dst_corner_edges[i_ml_dst]].v1; i_ml_dst++; CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1); - MLoop &next_dst_loop = dst_loops[i_ml_dst]; - next_dst_loop.v = vertex_map[loop.v]; - next_dst_loop.e = edge_map[loop.e]; + dst_corner_verts[i_ml_dst] = vertex_map[src_corner_verts[index]]; + dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[index]]; i_ml_dst++; } else if (!v_loop_in_mask && v_loop_in_mask_last) { BLI_assert(i_ml_dst != mp_dst.loopstart); /* End active cut. */ - float fac = get_interp_factor_from_vgroup( - dvert, defgrp_index, threshold, last_loop->v, loop.v); + float fac = get_interp_factor_from_vgroup(dvert, + defgrp_index, + threshold, + src_corner_verts[last_corner_i], + src_corner_verts[index]); float weights[2] = {1.0f - fac, fac}; int indices[2] = {i_ml_src + last_index, i_ml_src + index}; CustomData_interp( &src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst); - MLoop &cut_dst_loop = dst_loops[i_ml_dst]; - cut_dst_loop.e = edge_index; - cut_dst_loop.v = dst_edges[edge_map[last_loop->e]].v1; + dst_corner_edges[i_ml_dst] = edge_index; + dst_corner_verts[i_ml_dst] = dst_edges[edge_map[src_corner_edges[last_corner_i]]].v1; i_ml_dst++; /* Create closing edge. */ MEdge &cut_edge = dst_edges[edge_index]; - cut_edge.v1 = dst_loops[mp_dst.loopstart].v; - cut_edge.v2 = cut_dst_loop.v; + cut_edge.v1 = dst_corner_verts[mp_dst.loopstart]; + cut_edge.v2 = dst_corner_verts[i_ml_dst]; BLI_assert(cut_edge.v1 != cut_edge.v2); edge_index++; @@ -597,12 +599,11 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, BLI_assert(i_ml_dst != mp_dst.loopstart); /* Extend active poly. */ CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1); - MLoop &dst_loop = dst_loops[i_ml_dst]; - dst_loop.v = vertex_map[loop.v]; - dst_loop.e = edge_map[loop.e]; + dst_corner_verts[i_ml_dst] = vertex_map[src_corner_verts[index]]; + dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[index]]; i_ml_dst++; } - last_loop = &loop; + last_corner_i = index; last_index = index; v_loop_in_mask_last = v_loop_in_mask; } diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index da1e2c9e703..0fd1e7bebda 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -181,7 +181,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, BKE_mesh_calc_relative_deform( BKE_mesh_polys(me), me->totpoly, - BKE_mesh_loops(me), + BKE_mesh_corner_verts(me), me->totvert, BKE_mesh_vert_positions(me), /* From the original Mesh. */ (const float(*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */ diff --git a/source/blender/modifiers/intern/MOD_multires.cc b/source/blender/modifiers/intern/MOD_multires.cc index 528c5aee889..d2d0e614562 100644 --- a/source/blender/modifiers/intern/MOD_multires.cc +++ b/source/blender/modifiers/intern/MOD_multires.cc @@ -246,7 +246,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * sculpt_session->totpoly = mesh->totpoly; sculpt_session->vert_positions = nullptr; sculpt_session->polys = nullptr; - sculpt_session->mloop = nullptr; + sculpt_session->corner_verts = nullptr; } // BKE_subdiv_stats_print(&subdiv->stats); } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 9cf960af128..267ad8b0b2b 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -125,7 +125,7 @@ static void mix_normals(const float mix_factor, const float mix_limit, const short mix_mode, const int verts_num, - const blender::Span loops, + const blender::Span corner_verts, blender::float3 *nos_old, blender::float3 *nos_new) { @@ -135,12 +135,18 @@ static void mix_normals(const float mix_factor, int i; if (dvert) { - facs = static_cast(MEM_malloc_arrayN(size_t(loops.size()), sizeof(*facs), __func__)); - BKE_defvert_extract_vgroup_to_loopweights( - dvert, defgrp_index, verts_num, loops.data(), loops.size(), use_invert_vgroup, facs); + facs = static_cast( + MEM_malloc_arrayN(size_t(corner_verts.size()), sizeof(*facs), __func__)); + BKE_defvert_extract_vgroup_to_loopweights(dvert, + defgrp_index, + verts_num, + corner_verts.data(), + corner_verts.size(), + use_invert_vgroup, + facs); } - for (i = loops.size(), no_new = nos_new, no_old = nos_old, wfac = facs; i--; + for (i = corner_verts.size(), no_new = nos_new, no_old = nos_old, wfac = facs; i--; no_new++, no_old++, wfac++) { const float fac = facs ? *wfac * mix_factor : mix_factor; @@ -173,14 +179,15 @@ static void mix_normals(const float mix_factor, /* Check poly normals and new loop normals are compatible, otherwise flip polygons * (and invert matching poly normals). */ -static bool polygons_check_flip(blender::MutableSpan loops, +static bool polygons_check_flip(blender::MutableSpan corner_verts, + blender::MutableSpan corner_edges, blender::float3 *nos, CustomData *ldata, const blender::Span polys, float (*poly_normals)[3]) { MDisps *mdisp = static_cast( - CustomData_get_layer_for_write(ldata, CD_MDISPS, loops.size())); + CustomData_get_layer_for_write(ldata, CD_MDISPS, corner_verts.size())); bool flipped = false; for (const int i : polys.index_range()) { @@ -197,8 +204,13 @@ static bool polygons_check_flip(blender::MutableSpan loops, /* If average of new loop normals is opposed to polygon normal, flip polygon. */ if (dot_v3v3(poly_normals[i], norsum) < 0.0f) { - BKE_mesh_polygon_flip_ex( - &poly, loops.data(), ldata, reinterpret_cast(nos), mdisp, true); + BKE_mesh_polygon_flip_ex(&poly, + corner_verts.data(), + corner_edges.data(), + ldata, + reinterpret_cast(nos), + mdisp, + true); negate_v3(poly_normals[i]); flipped = true; } @@ -222,7 +234,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, blender::Span vert_positions, const blender::Span edges, blender::MutableSpan sharp_edges, - blender::MutableSpan loops, + blender::MutableSpan corner_verts, + blender::MutableSpan corner_edges, const blender::Span polys) { Object *ob_target = enmd->target; @@ -231,7 +244,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, float(*cos)[3] = static_cast( MEM_malloc_arrayN(size_t(vert_positions.size()), sizeof(*cos), __func__)); - blender::Array nos(loops.size()); + blender::Array nos(corner_verts.size()); float size[3]; BLI_bitmap *done_verts = BLI_BITMAP_NEW(size_t(vert_positions.size()), __func__); @@ -275,8 +288,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const float n2 = (c * c) / (a * a); /* We reuse cos to now store the ellipsoid-normal of the verts! */ - for (const int64_t i : loops.index_range()) { - const int vidx = loops[i].v; + for (const int64_t i : corner_verts.index_range()) { + const int vidx = corner_verts[i]; float *co = cos[vidx]; if (!BLI_BITMAP_TEST(done_verts, vidx)) { @@ -306,14 +319,17 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, mix_limit, mix_mode, vert_positions.size(), - loops, + corner_verts, loop_normals.data(), nos.data()); } - if (do_polynors_fix && - polygons_check_flip( - loops, nos.data(), &mesh->ldata, polys, BKE_mesh_poly_normals_for_write(mesh))) { + if (do_polynors_fix && polygons_check_flip(corner_verts, + corner_edges, + nos.data(), + &mesh->ldata, + polys, + BKE_mesh_poly_normals_for_write(mesh))) { mesh->runtime->vert_normals_dirty = true; } const bool *sharp_faces = static_cast( @@ -321,7 +337,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, blender::bke::mesh::normals_loop_custom_set(vert_positions, edges, polys, - loops, + corner_verts, + corner_edges, mesh->vert_normals(), mesh->poly_normals(), sharp_faces, @@ -348,7 +365,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const blender::Span positions, const blender::Span edges, blender::MutableSpan sharp_edges, - blender::MutableSpan loops, + blender::MutableSpan corner_verts, + blender::MutableSpan corner_edges, const blender::Span polys) { Object *ob_target = enmd->target; @@ -356,7 +374,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0; const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0; - blender::Array nos(loops.size()); + blender::Array nos(corner_verts.size()); float target_co[3]; int i; @@ -374,7 +392,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, sub_v3_v3v3(no, target_co, enmd->offset); normalize_v3(no); - for (i = loops.size(); i--;) { + for (i = corner_verts.size(); i--;) { copy_v3_v3(nos[i], no); } } @@ -386,8 +404,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, BLI_bitmap *done_verts = BLI_BITMAP_NEW(size_t(positions.size()), __func__); /* We reuse cos to now store the 'to target' normal of the verts! */ - for (const int64_t i : loops.index_range()) { - const int vidx = loops[i].v; + for (const int64_t i : corner_verts.index_range()) { + const int vidx = corner_verts[i]; float *co = cos[vidx]; if (!BLI_BITMAP_TEST(done_verts, vidx)) { @@ -411,14 +429,17 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, mix_limit, mix_mode, positions.size(), - loops, + corner_verts, loop_normals.data(), nos.data()); } - if (do_polynors_fix && - polygons_check_flip( - loops, nos.data(), &mesh->ldata, polys, BKE_mesh_poly_normals_for_write(mesh))) { + if (do_polynors_fix && polygons_check_flip(corner_verts, + corner_edges, + nos.data(), + &mesh->ldata, + polys, + BKE_mesh_poly_normals_for_write(mesh))) { mesh->runtime->vert_normals_dirty = true; } const bool *sharp_faces = static_cast( @@ -426,7 +447,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, blender::bke::mesh::normals_loop_custom_set(positions, edges, polys, - loops, + corner_verts, + corner_edges, mesh->vert_normals(), mesh->poly_normals(), sharp_faces, @@ -501,7 +523,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, const blender::Span positions = result->vert_positions(); const blender::Span edges = result->edges(); const blender::Span polys = result->polys(); - blender::MutableSpan loops = result->loops_for_write(); + blender::MutableSpan corner_verts = result->corner_verts_for_write(); + blender::MutableSpan corner_edges = result->corner_edges_for_write(); int defgrp_index; const MDeformVert *dvert; @@ -515,17 +538,18 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, "sharp_edge", ATTR_DOMAIN_EDGE); short(*clnors)[2] = static_cast( - CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, loops.size())); + CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); if (use_current_clnors) { clnors = static_cast( - CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, loops.size())); - loop_normals.reinitialize(loops.size()); + CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); + loop_normals.reinitialize(corner_verts.size()); const bool *sharp_faces = static_cast( CustomData_get_layer_named(&result->pdata, CD_PROP_BOOL, "sharp_face")); blender::bke::mesh::normals_calc_loop(positions, edges, polys, - loops, + corner_verts, + corner_edges, {}, result->vert_normals(), result->poly_normals(), @@ -540,7 +564,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, if (clnors == nullptr) { clnors = static_cast( - CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, loops.size())); + CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size())); } MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index); @@ -561,7 +585,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, positions, edges, sharp_edges.span, - loops, + corner_verts, + corner_edges, polys); } else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) { @@ -580,7 +605,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, positions, edges, sharp_edges.span, - loops, + corner_verts, + corner_edges, polys); } diff --git a/source/blender/modifiers/intern/MOD_ocean.cc b/source/blender/modifiers/intern/MOD_ocean.cc index b00e6eb10df..fc109f69acd 100644 --- a/source/blender/modifiers/intern/MOD_ocean.cc +++ b/source/blender/modifiers/intern/MOD_ocean.cc @@ -155,7 +155,7 @@ static bool dependsOnNormals(ModifierData *md) struct GenerateOceanGeometryData { float (*vert_positions)[3]; blender::MutableSpan polys; - blender::MutableSpan loops; + blender::MutableSpan corner_verts; float (*mloopuvs)[2]; int res_x, res_y; @@ -191,16 +191,11 @@ static void generate_ocean_geometry_polys(void *__restrict userdata, for (x = 0; x < gogd->res_x; x++) { const int fi = y * gogd->res_x + x; const int vi = y * (gogd->res_x + 1) + x; - MLoop *ml = &gogd->loops[fi * 4]; - ml->v = vi; - ml++; - ml->v = vi + 1; - ml++; - ml->v = vi + 1 + gogd->res_x + 1; - ml++; - ml->v = vi + gogd->res_x + 1; - ml++; + gogd->corner_verts[fi * 4 + 0] = vi; + gogd->corner_verts[fi * 4 + 1] = vi + 1; + gogd->corner_verts[fi * 4 + 2] = vi + 1 + gogd->res_x + 1; + gogd->corner_verts[fi * 4 + 3] = vi + gogd->res_x + 1; gogd->polys[fi].loopstart = fi * 4; gogd->polys[fi].totloop = 4; @@ -268,7 +263,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co gogd.vert_positions = BKE_mesh_vert_positions_for_write(result); gogd.polys = result->polys_for_write(); - gogd.loops = result->loops_for_write(); + gogd.corner_verts = result->corner_verts_for_write(); TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -365,20 +360,26 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes /* Add vertex-colors before displacement: allows lookup based on position. */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { - const blender::Span loops = result->loops(); - MLoopCol *mloopcols = static_cast(CustomData_add_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, loops.size(), omd->foamlayername)); + const blender::Span corner_verts = result->corner_verts(); + MLoopCol *mloopcols = static_cast(CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_SET_DEFAULT, + corner_verts.size(), + omd->foamlayername)); MLoopCol *mloopcols_spray = nullptr; if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) { - mloopcols_spray = static_cast(CustomData_add_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, loops.size(), omd->spraylayername)); + mloopcols_spray = static_cast(CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_SET_DEFAULT, + corner_verts.size(), + omd->spraylayername)); } if (mloopcols) { /* unlikely to fail */ for (const int i : polys.index_range()) { - const MLoop *ml = &loops[polys[i].loopstart]; + const int *corner_vert = &corner_verts[polys[i].loopstart]; MLoopCol *mlcol = &mloopcols[polys[i].loopstart]; MLoopCol *mlcolspray = nullptr; @@ -386,8 +387,8 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes mlcolspray = &mloopcols_spray[polys[i].loopstart]; } - for (j = polys[i].totloop; j--; ml++, mlcol++) { - const float *vco = positions[ml->v]; + for (j = polys[i].totloop; j--; corner_vert++, mlcol++) { + const float *vco = positions[*corner_vert]; const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); float foam; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.cc b/source/blender/modifiers/intern/MOD_particleinstance.cc index c1e07497598..77e756c18cb 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.cc +++ b/source/blender/modifiers/intern/MOD_particleinstance.cc @@ -315,11 +315,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, maxloop, maxpoly); const blender::Span orig_polys = mesh->polys(); - const blender::Span orig_loops = mesh->loops(); + const blender::Span orig_corner_verts = mesh->corner_verts(); + const blender::Span orig_corner_edges = mesh->corner_edges(); float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan edges = result->edges_for_write(); blender::MutableSpan polys = result->polys_for_write(); - blender::MutableSpan loops = result->loops_for_write(); + blender::MutableSpan corner_verts = result->corner_verts_for_write(); + blender::MutableSpan corner_edges = result->corner_edges_for_write(); MLoopCol *mloopcols_index = static_cast(CustomData_get_layer_named_for_write( &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name, result->totloop)); @@ -485,23 +487,23 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * poly.loopstart += p_skip * totloop; { - const MLoop *inML = &orig_loops[in_poly.loopstart]; - MLoop *ml = &loops[poly.loopstart]; + int orig_corner_i = in_poly.loopstart; + int dst_corner_i = poly.loopstart; int j = poly.totloop; CustomData_copy_data(&mesh->ldata, &result->ldata, in_poly.loopstart, poly.loopstart, j); - for (; j; j--, ml++, inML++) { - ml->v = inML->v + (p_skip * totvert); - ml->e = inML->e + (p_skip * totedge); - const int ml_index = (ml - loops.data()); + for (; j; j--, orig_corner_i++, dst_corner_i++) { + corner_verts[dst_corner_i] = orig_corner_verts[orig_corner_i] + (p_skip * totvert); + corner_edges[dst_corner_i] = orig_corner_edges[orig_corner_i] + (p_skip * totedge); + const int vert = corner_verts[orig_corner_i]; if (mloopcols_index != nullptr) { - const int part_index = vert_part_index[ml->v]; - store_float_in_vcol(&mloopcols_index[ml_index], + const int part_index = vert_part_index[vert]; + store_float_in_vcol(&mloopcols_index[dst_corner_i], float(part_index) / float(psys->totpart - 1)); } if (mloopcols_value != nullptr) { - const float part_value = vert_part_value[ml->v]; - store_float_in_vcol(&mloopcols_value[ml_index], part_value); + const float part_value = vert_part_value[vert]; + store_float_in_vcol(&mloopcols_value[dst_corner_i], part_value); } } } diff --git a/source/blender/modifiers/intern/MOD_remesh.cc b/source/blender/modifiers/intern/MOD_remesh.cc index 9d6ca28759f..119c14d824a 100644 --- a/source/blender/modifiers/intern/MOD_remesh.cc +++ b/source/blender/modifiers/intern/MOD_remesh.cc @@ -63,8 +63,8 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) input->co_stride = sizeof(float[3]); input->totco = mesh->totvert; - input->mloop = (DualConLoop)mesh->loops().data(); - input->loop_stride = sizeof(MLoop); + input->mloop = (DualConLoop)mesh->corner_verts().data(); + input->loop_stride = sizeof(int); input->looptri = (DualConTri)mesh->looptris().data(); input->tri_stride = sizeof(MLoopTri); @@ -80,7 +80,7 @@ typedef struct { Mesh *mesh; float (*vert_positions)[3]; MPoly *polys; - MLoop *loops; + int *corner_verts; int curvert, curface; } DualConOutput; @@ -96,7 +96,7 @@ static void *dualcon_alloc_output(int totvert, int totquad) output->mesh = BKE_mesh_new_nomain(totvert, 0, 4 * totquad, totquad); output->vert_positions = BKE_mesh_vert_positions_for_write(output->mesh); output->polys = output->mesh->polys_for_write().data(); - output->loops = output->mesh->loops_for_write().data(); + output->corner_verts = output->mesh->corner_verts_for_write().data(); return output; } @@ -123,9 +123,8 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4]) output->polys[output->curface].loopstart = output->curface * 4; output->polys[output->curface].totloop = 4; - MLoop *mloop = output->loops; for (i = 0; i < 4; i++) { - mloop[output->curface * 4 + i].v = vert_indices[i]; + output->corner_verts[output->curface * 4 + i] = vert_indices[i]; } output->curface++; diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index a3ba9056c55..f6cf87d1720 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -253,7 +253,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uint edge_offset; MPoly *mp_new; - MLoop *ml_new; MEdge *edge_new, *med_new_firstloop; Object *ob_axis = ltmd->ob_axis; @@ -401,12 +400,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const float(*vert_positions_orig)[3] = BKE_mesh_vert_positions(mesh); const blender::Span edges_orig = mesh->edges(); const blender::Span polys_orig = mesh->polys(); - const blender::Span loops_orig = mesh->loops(); + const blender::Span corner_verts_orig = mesh->corner_verts(); + const blender::Span corner_edges_orig = mesh->corner_edges(); float(*vert_positions_new)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan edges_new = result->edges_for_write(); blender::MutableSpan polys_new = result->polys_for_write(); - blender::MutableSpan loops_new = result->loops_for_write(); + blender::MutableSpan corner_verts_new = result->corner_verts_for_write(); + blender::MutableSpan corner_edges_new = result->corner_edges_for_write(); bke::MutableAttributeAccessor attributes = result->attributes_for_write(); bke::SpanAttributeWriter sharp_faces = attributes.lookup_or_add_for_write_span( "sharp_face", ATTR_DOMAIN_FACE); @@ -471,15 +472,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uint loopstart = uint(polys_orig[i].loopstart); uint loopend = loopstart + uint(polys_orig[i].totloop); - const MLoop *ml_orig = &loops_orig[loopstart]; - uint k; - for (k = loopstart; k < loopend; k++, ml_orig++) { - edge_poly_map[ml_orig->e] = uint(i); - vert_loop_map[ml_orig->v] = k; + for (uint k = loopstart; k < loopend; k++) { + const uint vert_i = uint(corner_verts_orig[k]); + const uint edge_i = uint(corner_edges_orig[k]); + edge_poly_map[edge_i] = uint(i); + vert_loop_map[vert_i] = k; /* also order edges based on faces */ - if (edges_new[ml_orig->e].v1 != ml_orig->v) { - std::swap(edges_new[ml_orig->e].v1, edges_new[ml_orig->e].v2); + if (edges_new[edge_i].v1 != vert_i) { + std::swap(edges_new[edge_i].v1, edges_new[edge_i].v2); } } } @@ -827,7 +828,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } mp_new = polys_new.data(); - ml_new = loops_new.data(); + int new_loop_index = 0; med_new_firstloop = edges_new.data(); /* more of an offset in this case */ @@ -889,23 +890,22 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Loop-Custom-Data */ if (has_mloop_orig) { - int l_index = int(ml_new - loops_new.data()); CustomData_copy_data( - &mesh->ldata, &result->ldata, int(mloop_index_orig[0]), l_index + 0, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[0]), new_loop_index + 0, 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, int(mloop_index_orig[1]), l_index + 1, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[1]), new_loop_index + 1, 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, int(mloop_index_orig[1]), l_index + 2, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[1]), new_loop_index + 2, 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, int(mloop_index_orig[0]), l_index + 3, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[0]), new_loop_index + 3, 1); if (mloopuv_layers_tot) { uint uv_lay; const float uv_u_offset_a = float(step) * uv_u_scale; const float uv_u_offset_b = float(step + 1) * uv_u_scale; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - blender::float2 *mluv = &mloopuv_layers[uv_lay][l_index]; + blender::float2 *mluv = &mloopuv_layers[uv_lay][new_loop_index]; mluv[quad_ord[0]][0] += uv_u_offset_a; mluv[quad_ord[1]][0] += uv_u_offset_a; @@ -916,13 +916,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } else { if (mloopuv_layers_tot) { - int l_index = int(ml_new - loops_new.data()); - uint uv_lay; const float uv_u_offset_a = float(step) * uv_u_scale; const float uv_u_offset_b = float(step + 1) * uv_u_scale; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - blender::float2 *mluv = &mloopuv_layers[uv_lay][l_index]; + blender::float2 *mluv = &mloopuv_layers[uv_lay][new_loop_index]; copy_v2_fl2(mluv[quad_ord[0]], uv_u_offset_a, uv_v_offset_a); copy_v2_fl2(mluv[quad_ord[1]], uv_u_offset_a, uv_v_offset_b); @@ -935,16 +933,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Loop-Data */ if (!(close && step == step_last)) { /* regular segments */ - ml_new[quad_ord[0]].v = i1; - ml_new[quad_ord[1]].v = i2; - ml_new[quad_ord[2]].v = i2 + totvert; - ml_new[quad_ord[3]].v = i1 + totvert; + corner_verts_new[new_loop_index + quad_ord[0]] = int(i1); + corner_verts_new[new_loop_index + quad_ord[1]] = int(i2); + corner_verts_new[new_loop_index + quad_ord[2]] = int(i2 + totvert); + corner_verts_new[new_loop_index + quad_ord[3]] = int(i1 + totvert); - ml_new[quad_ord_ofs[0]].e = step == 0 ? i : - (edge_offset + step + (i * (step_tot - 1))) - 1; - ml_new[quad_ord_ofs[1]].e = totedge + i2; - ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1)); - ml_new[quad_ord_ofs[3]].e = totedge + i1; + corner_edges_new[new_loop_index + quad_ord_ofs[0]] = int( + step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1); + corner_edges_new[new_loop_index + quad_ord_ofs[1]] = int(totedge + i2); + corner_edges_new[new_loop_index + quad_ord_ofs[2]] = int(edge_offset + step + + (i * (step_tot - 1))); + corner_edges_new[new_loop_index + quad_ord_ofs[3]] = int(totedge + i1); /* new vertical edge */ if (step) { /* The first set is already done */ @@ -957,19 +956,20 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } else { /* last segment */ - ml_new[quad_ord[0]].v = i1; - ml_new[quad_ord[1]].v = i2; - ml_new[quad_ord[2]].v = med_new_firstloop->v2; - ml_new[quad_ord[3]].v = med_new_firstloop->v1; + corner_verts_new[new_loop_index + quad_ord[0]] = int(i1); + corner_verts_new[new_loop_index + quad_ord[1]] = int(i2); + corner_verts_new[new_loop_index + quad_ord[2]] = int(med_new_firstloop->v2); + corner_verts_new[new_loop_index + quad_ord[3]] = int(med_new_firstloop->v1); - ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1; - ml_new[quad_ord_ofs[1]].e = totedge + i2; - ml_new[quad_ord_ofs[2]].e = i; - ml_new[quad_ord_ofs[3]].e = totedge + i1; + corner_edges_new[new_loop_index + quad_ord_ofs[0]] = int( + (edge_offset + step + (i * (step_tot - 1))) - 1); + corner_edges_new[new_loop_index + quad_ord_ofs[1]] = int(totedge + i2); + corner_edges_new[new_loop_index + quad_ord_ofs[2]] = int(i); + corner_edges_new[new_loop_index + quad_ord_ofs[3]] = int(totedge + i1); } mp_new++; - ml_new += 4; + new_loop_index += 4; mpoly_index++; } diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.cc b/source/blender/modifiers/intern/MOD_solidify_extrude.cc index 6504e3cbc00..c12e25d0d98 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.cc +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.cc @@ -24,10 +24,6 @@ #include "MOD_solidify_util.hh" /* own include */ #include "MOD_util.h" -#ifdef __GNUC__ -# pragma GCC diagnostic error "-Wsign-conversion" -#endif - /* -------------------------------------------------------------------- */ /** \name High Quality Normal Calculation Function * \{ */ @@ -64,7 +60,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const int verts_num = mesh->totvert; const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_edges = mesh->corner_edges(); { EdgeFaceRef *edge_ref_array = MEM_cnew_array(size_t(edges.size()), __func__); @@ -75,11 +71,11 @@ static void mesh_calc_hq_normal(Mesh *mesh, for (const int i : polys.index_range()) { int j; - const MLoop *ml = &loops[polys[i].loopstart]; + for (j = 0; j < polys[i].totloop; j++) { + const int edge_i = corner_edges[polys[i].loopstart + j]; - for (j = 0; j < polys[i].totloop; j++, ml++) { /* --- add edge ref to face --- */ - edge_ref = &edge_ref_array[ml->e]; + edge_ref = &edge_ref_array[edge_i]; if (!edgeref_is_init(edge_ref)) { edge_ref->p1 = i; edge_ref->p2 = -1; @@ -91,7 +87,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, /* 3+ faces using an edge, we can't handle this usefully */ edge_ref->p1 = edge_ref->p2 = -1; #ifdef USE_NONMANIFOLD_WORKAROUND - BLI_BITMAP_ENABLE(edge_tmp_tag, ml->e); + BLI_BITMAP_ENABLE(edge_tmp_tag, edge_i); #endif } /* --- done --- */ @@ -212,7 +208,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const float(*orig_vert_positions)[3] = BKE_mesh_vert_positions(mesh); const blender::Span orig_edges = mesh->edges(); const blender::Span orig_polys = mesh->polys(); - const blender::Span orig_loops = mesh->loops(); + const blender::Span orig_corner_verts = mesh->corner_verts(); + const blender::Span orig_corner_edges = mesh->corner_edges(); if (need_poly_normals) { /* calculate only face normals */ @@ -252,23 +249,26 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const MPoly &poly = orig_polys[i]; int j; - const MLoop *ml = &orig_loops[poly.loopstart]; - const MLoop *ml_prev = ml + (poly.totloop - 1); + int corner_i_prev = poly.loopstart + (poly.totloop - 1); - for (j = 0; j < poly.totloop; j++, ml++) { + for (j = 0; j < poly.totloop; j++) { + const int corner_i = poly.loopstart + j; + const int vert_i = orig_corner_verts[corner_i]; + const int prev_vert_i = orig_corner_verts[corner_i_prev]; /* add edge user */ - eidx = ml_prev->e; + eidx = (int)(orig_corner_edges[corner_i_prev]); if (edge_users[eidx] == INVALID_UNUSED) { edge = &orig_edges[eidx]; - BLI_assert(ELEM(ml_prev->v, edge->v1, edge->v2) && ELEM(ml->v, edge->v1, edge->v2)); - edge_users[eidx] = (ml_prev->v > ml->v) == (edge->v1 < edge->v2) ? uint(i) : - (uint(i) + polys_num); + BLI_assert(ELEM(prev_vert_i, edge->v1, edge->v2) && ELEM(vert_i, edge->v1, edge->v2)); + edge_users[eidx] = (prev_vert_i > vert_i) == (edge->v1 < edge->v2) ? + uint(i) : + (uint(i) + polys_num); edge_order[eidx] = j; } else { edge_users[eidx] = INVALID_PAIR; } - ml_prev = ml; + corner_i_prev = corner_i; } } @@ -333,7 +333,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan edges = result->edges_for_write(); blender::MutableSpan polys = result->polys_for_write(); - blender::MutableSpan loops = result->loops_for_write(); + blender::MutableSpan corner_verts = result->corner_verts_for_write(); + blender::MutableSpan corner_edges = result->corner_edges_for_write(); if (do_shell) { CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, int(verts_num)); @@ -417,13 +418,12 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const int64_t poly_i = polys_num + i; MPoly &poly = polys[poly_i]; const int loop_end = poly.totloop - 1; - MLoop *ml2; - uint e; + int e; int j; - /* reverses the loop direction (MLoop.v as well as custom-data) - * MLoop.e also needs to be corrected too, done in a separate loop below. */ - ml2 = &loops[poly.loopstart + mesh->totloop]; + /* reverses the loop direction (corner verts as well as custom-data) + * Corner edges also need to be corrected too, done in a separate loop below. */ + const int corner_2 = poly.loopstart + mesh->totloop; #if 0 for (j = 0; j < poly.totloop; j++) { CustomData_copy_data(&mesh->ldata, @@ -450,17 +450,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex CLAMP(dst_material_index[poly_i], 0, mat_nr_max); } - e = ml2[0].e; + e = corner_edges[corner_2 + 0]; for (j = 0; j < loop_end; j++) { - ml2[j].e = ml2[j + 1].e; + corner_edges[corner_2 + j] = corner_edges[corner_2 + j + 1]; } - ml2[loop_end].e = e; + corner_edges[corner_2 + loop_end] = e; poly.loopstart += mesh->totloop; for (j = 0; j < poly.totloop; j++) { - ml2[j].e += edges_num; - ml2[j].v += verts_num; + corner_verts[corner_2 + j] += verts_num; + corner_edges[corner_2 + j] += edges_num; } } @@ -516,15 +516,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } for (const int64_t i : orig_polys.index_range()) { const MPoly &poly = orig_polys[i]; - const MLoop *ml = &orig_loops[poly.loopstart]; - const MLoop *ml_prev = ml + (poly.totloop - 1); - - for (uint j = 0; j < poly.totloop; j++, ml++) { + int prev_corner_i = poly.loopstart + poly.totloop - 1; + for (int j = 0; j < poly.totloop; j++) { + const int corner_i = poly.loopstart + j; + const int vert_i = orig_corner_verts[corner_i]; + const int prev_vert_i = orig_corner_verts[prev_corner_i]; /* add edge user */ - eidx = ml_prev->e; - const MEdge *edge = &orig_edges[eidx]; - BLI_assert(ELEM(ml_prev->v, edge->v1, edge->v2) && ELEM(ml->v, edge->v1, edge->v2)); - char flip = char((ml_prev->v > ml->v) == (edge->v1 < edge->v2)); + eidx = orig_corner_edges[prev_corner_i]; + const MEdge *ed = &orig_edges[eidx]; + BLI_assert(ELEM(prev_vert_i, ed->v1, ed->v2) && ELEM(vert_i, ed->v1, ed->v2)); + char flip = char((prev_vert_i > vert_i) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { edge_user_pairs[eidx][flip] = uint(i); } @@ -532,7 +533,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex edge_user_pairs[eidx][0] = INVALID_PAIR; edge_user_pairs[eidx][1] = INVALID_PAIR; } - ml_prev = ml; + prev_corner_i = corner_i; } } const MEdge *edge = orig_edges.data(); @@ -722,14 +723,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex int i_curr = polys[i].totloop - 1; int i_next = 0; - const MLoop *ml = &loops[polys[i].loopstart]; + const int *poly_verts = &corner_verts[polys[i].loopstart]; + const int *poly_edges = &corner_edges[polys[i].loopstart]; - sub_v3_v3v3(nor_prev, vert_positions[ml[i_curr - 1].v], vert_positions[ml[i_curr].v]); + sub_v3_v3v3( + nor_prev, vert_positions[poly_verts[i_curr - 1]], vert_positions[poly_verts[i_curr]]); normalize_v3(nor_prev); while (i_next < polys[i].totloop) { float angle; - sub_v3_v3v3(nor_next, vert_positions[ml[i_curr].v], vert_positions[ml[i_next].v]); + sub_v3_v3v3( + nor_next, vert_positions[poly_verts[i_curr]], vert_positions[poly_verts[i_next]]); normalize_v3(nor_next); angle = angle_normalized_v3v3(nor_prev, nor_next); @@ -738,14 +742,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex angle = FLT_EPSILON; } - vidx = ml[i_curr].v; + vidx = poly_verts[i_curr]; vert_accum[vidx] += angle; #ifdef USE_NONMANIFOLD_WORKAROUND /* skip 3+ face user edges */ if ((check_non_manifold == false) || - LIKELY(!BLI_BITMAP_TEST(edge_tmp_tag, ml[i_curr].e) && - !BLI_BITMAP_TEST(edge_tmp_tag, ml[i_next].e))) { + LIKELY(!BLI_BITMAP_TEST(edge_tmp_tag, poly_edges[i_curr]) && + !BLI_BITMAP_TEST(edge_tmp_tag, poly_edges[i_next]))) { vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_normals[i]) * angle; } @@ -814,15 +818,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } for (const int i : orig_polys.index_range()) { const MPoly &poly = orig_polys[i]; - const MLoop *ml = &orig_loops[poly.loopstart]; - const MLoop *ml_prev = ml + (poly.totloop - 1); + int prev_corner_i = poly.loopstart + poly.totloop - 1; + for (int j = 0; j < poly.totloop; j++) { + const int corner_i = poly.loopstart + j; + const int vert_i = orig_corner_verts[corner_i]; + const int prev_vert_i = orig_corner_verts[prev_corner_i]; - for (int j = 0; j < poly.totloop; j++, ml++) { /* add edge user */ - eidx = ml_prev->e; + eidx = orig_corner_edges[prev_corner_i]; const MEdge *edge = &orig_edges[eidx]; - BLI_assert(ELEM(ml_prev->v, edge->v1, edge->v2) && ELEM(ml->v, edge->v1, edge->v2)); - char flip = char((ml_prev->v > ml->v) == (edge->v1 < edge->v2)); + BLI_assert(ELEM(prev_vert_i, edge->v1, edge->v2) && ELEM(vert_i, edge->v1, edge->v2)); + char flip = char((prev_vert_i > vert_i) == (edge->v1 < edge->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { edge_user_pairs[eidx][flip] = uint(i); } @@ -830,7 +836,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex edge_user_pairs[eidx][0] = INVALID_PAIR; edge_user_pairs[eidx][1] = INVALID_PAIR; } - ml_prev = ml; + prev_corner_i = corner_i; } } const MEdge *edge = orig_edges.data(); @@ -1064,7 +1070,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* faces */ int new_poly_index = int(polys_num * stride); - blender::MutableSpan new_loops = loops.drop_front(loops_num * stride); + blender::MutableSpan new_corner_verts = corner_verts.drop_front(loops_num * stride); + blender::MutableSpan new_corner_edges = corner_edges.drop_front(loops_num * stride); j = 0; for (i = 0; i < newPolys; i++) { uint eidx = new_edge_arr[i]; @@ -1105,35 +1112,35 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex CustomData_copy_data(&mesh->ldata, &result->ldata, k2, int((loops_num * stride) + j + 3), 1); if (flip == false) { - new_loops[j].v = edge.v1; - new_loops[j++].e = eidx; + new_corner_verts[j] = edge.v1; + new_corner_edges[j++] = eidx; - new_loops[j].v = edge.v2; - new_loops[j++].e = (edges_num * stride) + old_vert_arr[edge.v2] + newEdges; + new_corner_verts[j] = edge.v2; + new_corner_edges[j++] = (edges_num * stride) + old_vert_arr[edge.v2] + newEdges; - new_loops[j].v = (do_shell ? edge.v2 : old_vert_arr[edge.v2]) + verts_num; - new_loops[j++].e = (do_shell ? eidx : i) + edges_num; + new_corner_verts[j] = (do_shell ? edge.v2 : old_vert_arr[edge.v2]) + verts_num; + new_corner_edges[j++] = (do_shell ? eidx : i) + edges_num; - new_loops[j].v = (do_shell ? edge.v1 : old_vert_arr[edge.v1]) + verts_num; - new_loops[j++].e = (edges_num * stride) + old_vert_arr[edge.v1] + newEdges; + new_corner_verts[j] = (do_shell ? edge.v1 : old_vert_arr[edge.v1]) + verts_num; + new_corner_edges[j++] = (edges_num * stride) + old_vert_arr[edge.v1] + newEdges; } else { - new_loops[j].v = edge.v2; - new_loops[j++].e = eidx; + new_corner_verts[j] = edge.v2; + new_corner_edges[j++] = eidx; - new_loops[j].v = edge.v1; - new_loops[j++].e = (edges_num * stride) + old_vert_arr[edge.v1] + newEdges; + new_corner_verts[j] = edge.v1; + new_corner_edges[j++] = (edges_num * stride) + old_vert_arr[edge.v1] + newEdges; - new_loops[j].v = (do_shell ? edge.v1 : old_vert_arr[edge.v1]) + verts_num; - new_loops[j++].e = (do_shell ? eidx : i) + edges_num; + new_corner_verts[j] = (do_shell ? edge.v1 : old_vert_arr[edge.v1]) + verts_num; + new_corner_edges[j++] = (do_shell ? eidx : i) + edges_num; - new_loops[j].v = (do_shell ? edge.v2 : old_vert_arr[edge.v2]) + verts_num; - new_loops[j++].e = (edges_num * stride) + old_vert_arr[edge.v2] + newEdges; + new_corner_verts[j] = (do_shell ? edge.v2 : old_vert_arr[edge.v2]) + verts_num; + new_corner_edges[j++] = (edges_num * stride) + old_vert_arr[edge.v2] + newEdges; } if (origindex_edge) { - origindex_edge[new_loops[j - 3].e] = ORIGINDEX_NONE; - origindex_edge[new_loops[j - 1].e] = ORIGINDEX_NONE; + origindex_edge[new_corner_edges[j - 3]] = ORIGINDEX_NONE; + origindex_edge[new_corner_edges[j - 1]] = ORIGINDEX_NONE; } /* use the next material index if option enabled */ @@ -1158,10 +1165,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #ifdef SOLIDIFY_SIDE_NORMALS if (do_side_normals) { normal_quad_v3(nor, - vert_positions[new_loops[j - 4].v], - vert_positions[new_loops[j - 3].v], - vert_positions[new_loops[j - 2].v], - vert_positions[new_loops[j - 1].v]); + vert_positions[new_corner_verts[j - 4]], + vert_positions[new_corner_verts[j - 3]], + vert_positions[new_corner_verts[j - 2]], + vert_positions[new_corner_verts[j - 1]]); add_v3_v3(edge_vert_nos[edge.v1], nor); add_v3_v3(edge_vert_nos[edge.v2], nor); diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc index 5dc456e0e3a..3af2a85ca8f 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc @@ -22,10 +22,6 @@ #include "MOD_solidify_util.hh" /* Own include. */ #include "MOD_util.h" -#ifdef __GNUC__ -# pragma GCC diagnostic error "-Wsign-conversion" -#endif - /* -------------------------------------------------------------------- */ /** \name Local Utilities * \{ */ @@ -189,7 +185,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const float(*orig_vert_positions)[3] = BKE_mesh_vert_positions(mesh); const blender::Span orig_edges = mesh->edges(); const blender::Span orig_polys = mesh->polys(); - const blender::Span orig_loops = mesh->loops(); + const blender::Span orig_corner_verts = mesh->corner_verts(); + const blender::Span orig_corner_edges = mesh->corner_edges(); /* These might be null. */ const float *orig_vert_bweight = static_cast( @@ -222,7 +219,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const MPoly &poly = orig_polys[i]; /* Make normals for faces without area (should really be avoided though). */ if (len_squared_v3(poly_nors[i]) < 0.5f) { - const MEdge *edge = &orig_edges[orig_loops[poly.loopstart].e]; + const MEdge *edge = &orig_edges[orig_corner_edges[poly.loopstart]]; float edgedir[3]; sub_v3_v3v3(edgedir, orig_vert_positions[edge->v2], orig_vert_positions[edge->v1]); if (fabsf(edgedir[2]) < fabsf(edgedir[1])) { @@ -273,9 +270,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, { for (const int64_t i : orig_polys.index_range()) { const MPoly &poly = orig_polys[i]; - const MLoop *ml = &orig_loops[poly.loopstart]; - for (uint j = 0; j < poly.totloop; j++, ml++) { - edge_adj_faces_len[ml->e]++; + for (uint j = 0; j < poly.totloop; j++) { + edge_adj_faces_len[orig_corner_edges[poly.loopstart + j]]++; } } } @@ -323,10 +319,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, { for (const int64_t i : orig_polys.index_range()) { const MPoly &poly = orig_polys[i]; - const MLoop *ml = &orig_loops[poly.loopstart]; - for (uint j = 0; j < poly.totloop; j++, ml++) { - const uint edge = ml->e; - const bool reversed = orig_edges[edge].v2 != ml->v; + for (uint j = 0; j < poly.totloop; j++) { + const int vert = orig_corner_verts[poly.loopstart + j]; + const int edge = orig_corner_edges[poly.loopstart + j]; + const bool reversed = orig_edges[edge].v2 != vert; OldEdgeFaceRef *old_face_edge_ref = edge_adj_faces[edge]; if (old_face_edge_ref == nullptr) { const uint len = edge_adj_faces_len[edge]; @@ -399,8 +395,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint changes = 0; int cur = poly.totloop - 1; for (int next = 0; next < poly.totloop && changes <= 2; next++) { - uint cur_v = vm[orig_loops[poly.loopstart + cur].v]; - uint next_v = vm[orig_loops[poly.loopstart + next].v]; + uint cur_v = vm[orig_corner_verts[poly.loopstart + cur]]; + uint next_v = vm[orig_corner_verts[poly.loopstart + next]]; changes += (ELEM(cur_v, v1, v2) != ELEM(next_v, v1, v2)); cur = next; } @@ -458,7 +454,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!face_singularity[face]) { bool is_singularity = true; for (uint k = 0; k < orig_polys[face].totloop; k++) { - if (vm[orig_loops[uint(orig_polys[face].loopstart) + k].v] != v1) { + if (vm[orig_corner_verts[uint(orig_polys[face].loopstart) + k]] != v1) { is_singularity = false; break; } @@ -626,7 +622,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint face = adj_faces->faces[j]; const int j_loopstart = orig_polys[face].loopstart; const int totloop = orig_polys[face].totloop; - const uint j_first_v = vm[orig_loops[j_loopstart].v]; + const uint j_first_v = vm[orig_corner_verts[j_loopstart]]; for (uint k = j + 1; k < adj_len; k++) { if (orig_polys[adj_faces->faces[k]].totloop != totloop) { continue; @@ -634,9 +630,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Find first face first loop vert in second face loops. */ const int k_loopstart = orig_polys[adj_faces->faces[k]].loopstart; int l; - const MLoop *ml = &orig_loops[k_loopstart]; - for (l = 0; l < totloop && vm[ml->v] != j_first_v; l++, ml++) { - /* Pass. */ + { + const int *corner_vert = &orig_corner_verts[k_loopstart]; + for (l = 0; l < totloop && vm[*corner_vert] != j_first_v; l++, corner_vert++) { + /* Pass. */ + } } if (l == totloop) { continue; @@ -645,17 +643,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const bool reversed = adj_faces->faces_reversed[j] != adj_faces->faces_reversed[k]; const int count_dir = reversed ? -1 : 1; bool has_diff = false; - ml = &orig_loops[j_loopstart]; - for (int m = 0, n = l + totloop; m < totloop && !has_diff; - m++, n += count_dir, ml++) { - has_diff = has_diff || vm[ml->v] != vm[orig_loops[k_loopstart + n % totloop].v]; + for (int m = 0, n = l + totloop; m < totloop && !has_diff; m++, n += count_dir) { + const int vert = orig_corner_verts[j_loopstart + m]; + has_diff = has_diff || + vm[vert] != vm[orig_corner_verts[k_loopstart + n % totloop]]; } /* If the faces are equal, discard one (j). */ if (!has_diff) { - ml = &orig_loops[j_loopstart]; uint del_loops = 0; - for (uint m = 0; m < totloop; m++, ml++) { - const uint e = ml->e; + for (uint m = 0; m < totloop; m++) { + const int e = orig_corner_edges[j_loopstart + m]; OldEdgeFaceRef *e_adj_faces = edge_adj_faces[e]; if (e_adj_faces) { uint face_index = j; @@ -874,11 +871,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, new_edges[j] = edge_data; for (uint k = 0; k < 2; k++) { if (faces[k] != nullptr) { - const MLoop *ml = &orig_loops[faces[k]->face->loopstart]; - for (int l = 0; l < faces[k]->face->totloop; l++, ml++) { - if (edge_adj_faces[ml->e] == edge_adj_faces[i]) { - if (ml->e != i && orig_edge_data_arr[ml->e] == nullptr) { - orig_edge_data_arr[ml->e] = new_edges; + for (int l = 0; l < faces[k]->face->totloop; l++) { + const int edge = orig_corner_edges[faces[k]->face->loopstart + l]; + if (edge_adj_faces[edge] == edge_adj_faces[i]) { + if (edge != i && orig_edge_data_arr[edge] == nullptr) { + orig_edge_data_arr[edge] = new_edges; } faces[k]->link_edges[l] = edge_data; break; @@ -1414,9 +1411,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const MPoly &poly = orig_polys[i]; float scalar_vgroup = 1.0f; int loopend = poly.loopstart + poly.totloop; - const MLoop *ml = &orig_loops[poly.loopstart]; - for (int j = poly.loopstart; j < loopend; j++, ml++) { - const MDeformVert *dv = &dvert[ml->v]; + for (int j = poly.loopstart; j < loopend; j++) { + const int vert = orig_corner_verts[poly.loopstart + j]; + const MDeformVert *dv = &dvert[vert]; if (defgrp_invert) { scalar_vgroup = min_ff(1.0f - BKE_defvert_find_weight(dv, defgrp_index), scalar_vgroup); @@ -1686,17 +1683,19 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) { - const MLoop *ml_next = &orig_loops[face->face->loopstart]; - const MLoop *ml = ml_next + (face->face->totloop - 1); - const MLoop *ml_prev = ml - 1; - for (int m = 0; m < face->face->totloop && vm[ml->v] != i; - m++, ml_next++) { - ml_prev = ml; - ml = ml_next; + int corner_next = face->face->loopstart; + int corner = corner_next + (face->face->totloop - 1); + int corner_prev = corner - 1; + + for (int m = 0; + m < face->face->totloop && vm[orig_corner_verts[corner]] != i; + m++, corner_next++) { + corner_prev = corner; + corner = corner_next; } - angle = angle_v3v3v3(orig_mvert_co[vm[ml_prev->v]], + angle = angle_v3v3v3(orig_mvert_co[vm[orig_corner_verts[corner_prev]]], orig_mvert_co[i], - orig_mvert_co[vm[ml_next->v]]); + orig_mvert_co[vm[orig_corner_verts[corner_next]]]); if (face->reversed) { total_angle_back += angle * ofs * ofs; } @@ -1992,7 +1991,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); blender::MutableSpan edges = result->edges_for_write(); blender::MutableSpan polys = result->polys_for_write(); - blender::MutableSpan loops = result->loops_for_write(); + blender::MutableSpan corner_verts = result->corner_verts_for_write(); + blender::MutableSpan corner_edges = result->corner_edges_for_write(); int *origindex_edge = static_cast( CustomData_get_layer_for_write(&result->edata, CD_ORIGINDEX, result->totedge)); @@ -2323,9 +2323,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint k = 0; g2->valid && k < j; g2++) { if ((do_rim && !g2->is_orig_closed) || (do_shell && g2->split)) { const MPoly *face = g2->edges[0]->faces[0]->face; - const MLoop *ml = &orig_loops[face->loopstart]; - for (int l = 0; l < face->totloop; l++, ml++) { - if (vm[ml->v] == i) { + for (int l = 0; l < face->totloop; l++) { + const int vert = orig_corner_verts[face->loopstart + l]; + if (vm[vert] == i) { loops_data[k] = face->loopstart + l; break; } @@ -2338,16 +2338,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint k = 0; k < j; k++) { CustomData_copy_data( &mesh->ldata, &result->ldata, loops_data[k], int(loop_index), 1); - loops[loop_index].v = edges[edge_index - j + k].v1; - loops[loop_index++].e = edge_index - j + k; + corner_verts[loop_index] = edges[edge_index - j + k].v1; + corner_edges[loop_index++] = edge_index - j + k; } } else { for (uint k = 1; k <= j; k++) { CustomData_copy_data( &mesh->ldata, &result->ldata, loops_data[j - k], int(loop_index), 1); - loops[loop_index].v = edges[edge_index - k].v2; - loops[loop_index++].e = edge_index - k; + corner_verts[loop_index] = edges[edge_index - k].v2; + corner_edges[loop_index++] = edge_index - k; } } MEM_freeN(loops_data); @@ -2396,14 +2396,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, int loop1 = -1; int loop2 = -1; - const MLoop *ml = &orig_loops[face->loopstart]; const uint old_v1 = vm[orig_edges[edge1->old_edge].v1]; const uint old_v2 = vm[orig_edges[edge1->old_edge].v2]; - for (uint j = 0; j < face->totloop; j++, ml++) { - if (vm[ml->v] == old_v1) { + for (uint j = 0; j < face->totloop; j++) { + const int vert = orig_corner_verts[face->loopstart + j]; + if (vm[vert] == old_v1) { loop1 = face->loopstart + int(j); } - else if (vm[ml->v] == old_v2) { + else if (vm[vert] == old_v2) { loop2 = face->loopstart + int(j); } } @@ -2416,8 +2416,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); - loops[loop_index].v = edges[edge1->new_edge].v1; - loops[loop_index++].e = edge1->new_edge; + corner_verts[loop_index] = edges[edge1->new_edge].v1; + corner_edges[loop_index++] = edge1->new_edge; if (!v2_singularity) { open_face_edge_index = edge1->link_edge_groups[1]->open_face_edge; @@ -2426,13 +2426,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); - loops[loop_index].v = edges[edge1->new_edge].v2; + corner_verts[loop_index] = edges[edge1->new_edge].v2; open_face_edge = &edges[open_face_edge_index]; if (ELEM(edges[edge2->new_edge].v2, open_face_edge->v1, open_face_edge->v2)) { - loops[loop_index++].e = open_face_edge_index; + corner_edges[loop_index++] = open_face_edge_index; } else { - loops[loop_index++].e = edge2->link_edge_groups[1]->open_face_edge; + corner_edges[loop_index++] = edge2->link_edge_groups[1]->open_face_edge; } } @@ -2441,8 +2441,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); - loops[loop_index].v = edges[edge2->new_edge].v2; - loops[loop_index++].e = edge2->new_edge; + corner_verts[loop_index] = edges[edge2->new_edge].v2; + corner_edges[loop_index++] = edge2->new_edge; if (!v1_singularity) { open_face_edge_index = edge2->link_edge_groups[0]->open_face_edge; @@ -2451,13 +2451,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); - loops[loop_index].v = edges[edge2->new_edge].v1; + corner_verts[loop_index] = edges[edge2->new_edge].v1; open_face_edge = &edges[open_face_edge_index]; if (ELEM(edges[edge1->new_edge].v1, open_face_edge->v1, open_face_edge->v2)) { - loops[loop_index++].e = open_face_edge_index; + corner_edges[loop_index++] = open_face_edge_index; } else { - loops[loop_index++].e = edge1->link_edge_groups[0]->open_face_edge; + corner_edges[loop_index++] = edge1->link_edge_groups[0]->open_face_edge; } } } @@ -2469,13 +2469,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); - loops[loop_index].v = edges[edge1->new_edge].v1; + corner_verts[loop_index] = edges[edge1->new_edge].v1; open_face_edge = &edges[open_face_edge_index]; if (ELEM(edges[edge2->new_edge].v1, open_face_edge->v1, open_face_edge->v2)) { - loops[loop_index++].e = open_face_edge_index; + corner_edges[loop_index++] = open_face_edge_index; } else { - loops[loop_index++].e = edge2->link_edge_groups[0]->open_face_edge; + corner_edges[loop_index++] = edge2->link_edge_groups[0]->open_face_edge; } } @@ -2484,8 +2484,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); - loops[loop_index].v = edges[edge2->new_edge].v1; - loops[loop_index++].e = edge2->new_edge; + corner_verts[loop_index] = edges[edge2->new_edge].v1; + corner_edges[loop_index++] = edge2->new_edge; if (!v2_singularity) { open_face_edge_index = edge2->link_edge_groups[1]->open_face_edge; @@ -2494,13 +2494,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); - loops[loop_index].v = edges[edge2->new_edge].v2; + corner_verts[loop_index] = edges[edge2->new_edge].v2; open_face_edge = &edges[open_face_edge_index]; if (ELEM(edges[edge1->new_edge].v2, open_face_edge->v1, open_face_edge->v2)) { - loops[loop_index++].e = open_face_edge_index; + corner_edges[loop_index++] = open_face_edge_index; } else { - loops[loop_index++].e = edge1->link_edge_groups[1]->open_face_edge; + corner_edges[loop_index++] = edge1->link_edge_groups[1]->open_face_edge; } } @@ -2509,8 +2509,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); - loops[loop_index].v = edges[edge1->new_edge].v2; - loops[loop_index++].e = edge1->new_edge; + corner_verts[loop_index] = edges[edge1->new_edge].v2; + corner_edges[loop_index++] = edge1->new_edge; } } } @@ -2537,15 +2537,15 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (totloop > 0) { NewEdgeRef *prior_edge = fr->link_edges[totloop - 1]; uint prior_flip = uint(vm[orig_edges[prior_edge->old_edge].v1] == - vm[orig_loops[loopstart + (totloop - 1)].v]); + vm[orig_corner_verts[loopstart + (totloop - 1)]]); for (uint j = 0; j < totloop; j++) { NewEdgeRef *new_edge = fr->link_edges[j]; if (new_edge && new_edge->new_edge != MOD_SOLIDIFY_EMPTY_TAG) { valid_edges++; const uint flip = uint(vm[orig_edges[new_edge->old_edge].v2] == - vm[orig_loops[loopstart + j].v]); - BLI_assert(flip || - vm[orig_edges[new_edge->old_edge].v1] == vm[orig_loops[loopstart + j].v]); + vm[orig_corner_verts[loopstart + j]]); + BLI_assert(flip || vm[orig_edges[new_edge->old_edge].v1] == + vm[orig_corner_verts[loopstart + j]]); /* The vert that's in the current loop. */ const uint new_v1 = new_edge->link_edge_groups[flip]->new_vert; /* The vert that's in the next loop. */ @@ -2592,8 +2592,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } CustomData_copy_data( &mesh->ldata, &result->ldata, int(face_loops[l]), int(loop_index), 1); - loops[loop_index].v = face_verts[l]; - loops[loop_index++].e = face_edges[l]; + corner_verts[loop_index] = face_verts[l]; + corner_edges[loop_index++] = face_edges[l]; } } else { @@ -2601,8 +2601,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint next_l = 0; next_l < k; next_l++) { CustomData_copy_data( &mesh->ldata, &result->ldata, int(face_loops[l]), int(loop_index), 1); - loops[loop_index].v = face_verts[l]; - loops[loop_index++].e = face_edges[next_l]; + corner_verts[loop_index] = face_verts[l]; + corner_edges[loop_index++] = face_edges[next_l]; l = next_l; } } diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.cc b/source/blender/modifiers/intern/MOD_surfacedeform.cc index d13a15e724b..c1ce4e14242 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.cc +++ b/source/blender/modifiers/intern/MOD_surfacedeform.cc @@ -70,7 +70,8 @@ struct SDefBindCalcData { SDefVert *bind_verts; blender::Span edges; blender::Span polys; - blender::Span loops; + blender::Span corner_verts; + blender::Span corner_edges; blender::Span looptris; /** Coordinates to bind to, transformed into local space (compatible with `vertexCos`). */ @@ -290,27 +291,24 @@ static void freeAdjacencyMap(SDefAdjacencyArray *const vert_edges, static int buildAdjacencyMap(const blender::Span polys, const blender::Span edges, - const blender::Span loops, + const blender::Span corner_edges, SDefAdjacencyArray *const vert_edges, SDefAdjacency *adj, SDefEdgePolys *const edge_polys) { - const MLoop *loop; - /* Find polygons adjacent to edges. */ for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - loop = &loops[poly.loopstart]; - - for (int j = 0; j < poly.totloop; j++, loop++) { - if (edge_polys[loop->e].num == 0) { - edge_polys[loop->e].polys[0] = i; - edge_polys[loop->e].polys[1] = -1; - edge_polys[loop->e].num++; + for (int j = 0; j < poly.totloop; j++) { + const int edge_i = corner_edges[poly.loopstart + j]; + if (edge_polys[edge_i].num == 0) { + edge_polys[edge_i].polys[0] = i; + edge_polys[edge_i].polys[1] = -1; + edge_polys[edge_i].num++; } - else if (edge_polys[loop->e].num == 1) { - edge_polys[loop->e].polys[1] = i; - edge_polys[loop->e].num++; + else if (edge_polys[edge_i].num == 1) { + edge_polys[edge_i].polys[1] = i; + edge_polys[edge_i].num++; } else { return MOD_SDEF_BIND_RESULT_NONMANY_ERR; @@ -338,41 +336,42 @@ static int buildAdjacencyMap(const blender::Span polys, } BLI_INLINE void sortPolyVertsEdge(uint *indices, - const MLoop *const loops, + const int *const corner_verts, + const int *const corner_edges, const uint edge, const uint num) { bool found = false; for (int i = 0; i < num; i++) { - if (loops[i].e == edge) { + if (corner_edges[i] == edge) { found = true; } if (found) { - *indices = loops[i].v; + *indices = corner_verts[i]; indices++; } } /* Fill in remaining vertex indices that occur before the edge */ - for (int i = 0; loops[i].e != edge; i++) { - *indices = loops[i].v; + for (int i = 0; corner_edges[i] != edge; i++) { + *indices = corner_verts[i]; indices++; } } BLI_INLINE void sortPolyVertsTri(uint *indices, - const MLoop *const loops, + const int *const corner_verts, const uint loopstart, const uint num) { for (int i = loopstart; i < num; i++) { - *indices = loops[i].v; + *indices = corner_verts[i]; indices++; } for (int i = 0; i < loopstart; i++) { - *indices = loops[i].v; + *indices = corner_verts[i]; indices++; } } @@ -384,7 +383,6 @@ BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3 nearest.index = -1; const MEdge *edge; - const MLoop *loop; float t_point[3]; float max_dist = FLT_MAX; float dist; @@ -396,16 +394,16 @@ BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3 data->treeData->tree, t_point, &nearest, data->treeData->nearest_callback, data->treeData); const MPoly &poly = data->polys[data->looptris[nearest.index].poly]; - loop = &data->loops[poly.loopstart]; - for (int i = 0; i < poly.totloop; i++, loop++) { - edge = &data->edges[loop->e]; + for (int i = 0; i < poly.totloop; i++) { + const int edge_i = data->corner_edges[poly.loopstart + i]; + edge = &data->edges[edge_i]; dist = dist_squared_to_line_segment_v3( point_co, data->targetCos[edge->v1], data->targetCos[edge->v2]); if (dist < max_dist) { max_dist = dist; - index = loop->e; + index = edge_i; } } @@ -488,7 +486,6 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, const SDefEdgePolys *const edge_polys = data->edge_polys; const SDefAdjacency *vedge; - const MLoop *loop; SDefBindWeightData *bwdata; SDefBindPoly *bpoly; @@ -546,7 +543,6 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, /* Copy poly data */ const MPoly &poly = data->polys[bpoly->index]; - loop = &data->loops[poly.loopstart]; bpoly->verts_num = poly.totloop; bpoly->loopstart = poly.loopstart; @@ -567,17 +563,19 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, return nullptr; } - for (int j = 0; j < poly.totloop; j++, loop++) { - copy_v3_v3(bpoly->coords[j], data->targetCos[loop->v]); + for (int j = 0; j < poly.totloop; j++) { + const int vert_i = data->corner_verts[poly.loopstart + j]; + const int edge_i = data->corner_edges[poly.loopstart + j]; + copy_v3_v3(bpoly->coords[j], data->targetCos[vert_i]); /* Find corner and edge indices within poly loop array */ - if (loop->v == nearest) { + if (vert_i == nearest) { bpoly->corner_ind = j; bpoly->edge_vert_inds[0] = (j == 0) ? (poly.totloop - 1) : (j - 1); bpoly->edge_vert_inds[1] = (j == poly.totloop - 1) ? (0) : (j + 1); - bpoly->edge_inds[0] = data->loops[poly.loopstart + bpoly->edge_vert_inds[0]].e; - bpoly->edge_inds[1] = loop->e; + bpoly->edge_inds[0] = data->corner_edges[poly.loopstart + bpoly->edge_vert_inds[0]]; + bpoly->edge_inds[1] = edge_i; } } @@ -1013,8 +1011,6 @@ static void bindVert(void *__restrict userdata, for (int i = 0; i < bwdata->binds_num; bpoly++) { if (bpoly->weight >= FLT_EPSILON) { if (bpoly->inside) { - const MLoop *loop = &data->loops[bpoly->loopstart]; - sdbind->influence = bpoly->weight; sdbind->verts_num = bpoly->verts_num; @@ -1039,9 +1035,10 @@ static void bindVert(void *__restrict userdata, /* Re-project vert based on weights and original poly verts, * to reintroduce poly non-planarity */ zero_v3(point_co_proj); - for (int j = 0; j < bpoly->verts_num; j++, loop++) { + for (int j = 0; j < bpoly->verts_num; j++) { + const int vert_i = data->corner_verts[bpoly->loopstart + j]; madd_v3_v3fl(point_co_proj, bpoly->coords[j], sdbind->vert_weights[j]); - sdbind->vert_inds[j] = loop->v; + sdbind->vert_inds[j] = vert_i; } sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal); @@ -1074,7 +1071,8 @@ static void bindVert(void *__restrict userdata, } sortPolyVertsEdge(sdbind->vert_inds, - &data->loops[bpoly->loopstart], + &data->corner_verts[bpoly->loopstart], + &data->corner_edges[bpoly->loopstart], bpoly->edge_inds[bpoly->dominant_edge], bpoly->verts_num); @@ -1121,7 +1119,7 @@ static void bindVert(void *__restrict userdata, } sortPolyVertsTri(sdbind->vert_inds, - &data->loops[bpoly->loopstart], + &data->corner_verts[bpoly->loopstart], bpoly->edge_vert_inds[0], bpoly->verts_num); @@ -1183,7 +1181,8 @@ static bool surfacedeformBind(Object *ob, const float(*positions)[3] = BKE_mesh_vert_positions(target); const blender::Span edges = target->edges(); const blender::Span polys = target->polys(); - const blender::Span loops = target->loops(); + const blender::Span corner_verts = target->corner_verts(); + const blender::Span corner_edges = target->corner_edges(); uint tedges_num = target->totedge; int adj_result; @@ -1228,7 +1227,7 @@ static bool surfacedeformBind(Object *ob, return false; } - adj_result = buildAdjacencyMap(polys, edges, loops, vert_edges, adj_array, edge_polys); + adj_result = buildAdjacencyMap(polys, edges, corner_edges, vert_edges, adj_array, edge_polys); if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { BKE_modifier_set_error( @@ -1256,7 +1255,8 @@ static bool surfacedeformBind(Object *ob, data.edge_polys = edge_polys; data.polys = polys; data.edges = edges; - data.loops = loops; + data.corner_verts = corner_verts; + data.corner_edges = corner_edges; data.looptris = target->looptris(); data.targetCos = static_cast( MEM_malloc_arrayN(target_verts_num, sizeof(float[3]), "SDefTargetBindVertArray")); diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index a5c15420f28..19f57a6fee1 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -61,6 +61,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, float (*cos)[3], float (*r_texco)[3]) { + using namespace blender; const int verts_num = mesh->totvert; int i; int texmapping = dmd->texmapping; @@ -93,7 +94,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, if (texmapping == MOD_DISP_MAP_UV) { if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__); char uvname[MAX_CUSTOMDATA_LAYER_NAME]; CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, dmd->uvlayer_name, uvname); @@ -107,7 +108,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, do { uint lidx = poly.loopstart + fidx; - uint vidx = loops[lidx].v; + const int vidx = corner_verts[lidx]; if (!BLI_BITMAP_TEST(done, vidx)) { /* remap UVs from [0, 1] to [-1, 1] */ diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index ffaace78131..413774fd208 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -94,6 +94,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, Object *ob, Mesh *mesh) { + using namespace blender; float(*coords)[3], (*co)[3]; int i, verts_num; Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; @@ -182,10 +183,10 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, const blender::Span positions = mesh->vert_positions(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const Span corner_verts = mesh->corner_verts(); - float(*mloop_uv)[2] = static_cast( - CustomData_get_layer_named_for_write(&mesh->ldata, CD_PROP_FLOAT2, uvname, loops.size())); + float(*mloop_uv)[2] = static_cast(CustomData_get_layer_named_for_write( + &mesh->ldata, CD_PROP_FLOAT2, uvname, corner_verts.size())); coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num); @@ -209,7 +210,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = poly.totloop - 1; do { uint lidx = poly.loopstart + fidx; - uint vidx = loops[lidx].v; + const int vidx = corner_verts[lidx]; BLI_uvproject_from_camera( mloop_uv[lidx], coords[vidx], static_cast(projectors[0].uci)); } while (fidx--); @@ -219,7 +220,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = poly.totloop - 1; do { uint lidx = poly.loopstart + fidx; - uint vidx = loops[lidx].v; + const int vidx = corner_verts[lidx]; copy_v2_v2(mloop_uv[lidx], coords[vidx]); } while (fidx--); } @@ -232,7 +233,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, /* get the untransformed face normal */ const blender::float3 face_no = blender::bke::mesh::poly_normal_calc( - positions, loops.slice(poly.loopstart, poly.totloop)); + positions, corner_verts.slice(poly.loopstart, poly.totloop)); /* find the projector which the face points at most directly * (projector normal with largest dot product is best) @@ -252,7 +253,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = poly.totloop - 1; do { uint lidx = poly.loopstart + fidx; - uint vidx = loops[lidx].v; + const int vidx = corner_verts[lidx]; BLI_uvproject_from_camera( mloop_uv[lidx], coords[vidx], static_cast(best_projector->uci)); } while (fidx--); @@ -261,7 +262,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = poly.totloop - 1; do { uint lidx = poly.loopstart + fidx; - uint vidx = loops[lidx].v; + const int vidx = corner_verts[lidx]; mul_v2_project_m4_v3(mloop_uv[lidx], best_projector->projmat, coords[vidx]); } while (fidx--); } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.cc b/source/blender/modifiers/intern/MOD_uvwarp.cc index 0c4c559c69b..562ff538654 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.cc +++ b/source/blender/modifiers/intern/MOD_uvwarp.cc @@ -81,7 +81,7 @@ static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonen struct UVWarpData { blender::Span polys; - blender::Span loops; + blender::Span corner_verts; float (*mloopuv)[2]; const MDeformVert *dvert; @@ -98,7 +98,7 @@ static void uv_warp_compute(void *__restrict userdata, const UVWarpData *data = static_cast(userdata); const MPoly &poly = data->polys[i]; - const MLoop *ml = &data->loops[poly.loopstart]; + const int *poly_verts = &data->corner_verts[poly.loopstart]; float(*mluv)[2] = &data->mloopuv[poly.loopstart]; const MDeformVert *dvert = data->dvert; @@ -109,11 +109,12 @@ static void uv_warp_compute(void *__restrict userdata, int l; if (dvert) { - for (l = 0; l < poly.totloop; l++, ml++, mluv++) { + for (l = 0; l < poly.totloop; l++, mluv++) { + const int vert_i = poly_verts[l]; float uv[2]; const float weight = data->invert_vgroup ? - 1.0f - BKE_defvert_find_weight(&dvert[ml->v], defgrp_index) : - BKE_defvert_find_weight(&dvert[ml->v], defgrp_index); + 1.0f - BKE_defvert_find_weight(&dvert[vert_i], defgrp_index) : + BKE_defvert_find_weight(&dvert[vert_i], defgrp_index); uv_warp_from_mat4_pair(uv, (*mluv), warp_mat); interp_v2_v2v2((*mluv), (*mluv), uv, weight); @@ -192,15 +193,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, umd->uvlayer_name, uvname); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); - float(*mloopuv)[2] = static_cast( - CustomData_get_layer_named_for_write(&mesh->ldata, CD_PROP_FLOAT2, uvname, loops.size())); + float(*mloopuv)[2] = static_cast(CustomData_get_layer_named_for_write( + &mesh->ldata, CD_PROP_FLOAT2, uvname, corner_verts.size())); MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index); UVWarpData data{}; data.polys = polys; - data.loops = loops; + data.corner_verts = corner_verts; data.mloopuv = mloopuv; data.dvert = dvert; data.defgrp_index = defgrp_index; diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 7dbf6ba13e8..fa2147f6615 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -75,7 +75,8 @@ struct WeightedNormalData { blender::Span edges; blender::MutableSpan sharp_edges; - blender::Span loops; + blender::Span corner_verts; + blender::Span corner_edges; blender::Span loop_to_poly; short (*clnors)[2]; bool has_clnors; /* True if clnors already existed, false if we had to create them. */ @@ -187,10 +188,11 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, const blender::Span positions = wn_data->vert_positions; const blender::Span edges = wn_data->edges; const blender::Span polys = wn_data->polys; - const blender::Span loops = wn_data->loops; + const blender::Span corner_verts = wn_data->corner_verts; + const blender::Span corner_edges = wn_data->corner_edges; short(*clnors)[2] = wn_data->clnors; - const Span loop_to_poly = wn_data->loop_to_poly; + const blender::Span loop_to_poly = wn_data->loop_to_poly; const blender::Span poly_normals = wn_data->poly_normals; const int *poly_strength = wn_data->poly_strength; @@ -214,15 +216,16 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, WeightedNormalDataAggregateItem *items_data = nullptr; int items_num = 0; if (keep_sharp) { - BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops.size(), __func__); + BLI_bitmap *done_loops = BLI_BITMAP_NEW(corner_verts.size(), __func__); /* This will give us loop normal spaces, * we do not actually care about computed loop_normals for now... */ - loop_normals.reinitialize(loops.size()); + loop_normals.reinitialize(corner_verts.size()); bke::mesh::normals_calc_loop(positions, edges, polys, - loops, + corner_verts, + corner_edges, loop_to_poly, wn_data->vert_normals, wn_data->poly_normals, @@ -292,7 +295,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, int ml_index = polys[poly_index].loopstart; const int ml_index_end = ml_index + polys[poly_index].totloop; for (; ml_index < ml_index_end; ml_index++) { - const int mv_index = loops[ml_index].v; + const int mv_index = corner_verts[ml_index]; WeightedNormalDataAggregateItem *item_data = keep_sharp ? static_cast( lnors_spacearr.lspacearr[ml_index]->user_data) : @@ -305,12 +308,12 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, break; case MOD_WEIGHTEDNORMAL_MODE_ANGLE: case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE: - for (const int i : loops.index_range()) { + for (int i = 0; i < corner_verts.size(); i++) { const int ml_index = mode_pair[i].index; const float ml_val = mode_pair[i].val; const int poly_index = loop_to_poly[ml_index]; - const int mv_index = loops[ml_index].v; + const int mv_index = corner_verts[ml_index]; WeightedNormalDataAggregateItem *item_data = keep_sharp ? static_cast( lnors_spacearr.lspacearr[ml_index]->user_data) : @@ -336,7 +339,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, * Note that loop_normals is already populated with clnors * (before this modifier is applied, at start of this function), * so no need to recompute them here. */ - for (int ml_index = 0; ml_index < loops.size(); ml_index++) { + for (int ml_index = 0; ml_index < corner_verts.size(); ml_index++) { WeightedNormalDataAggregateItem *item_data = static_cast( lnors_spacearr.lspacearr[ml_index]->user_data); if (!is_zero_v3(item_data->normal)) { @@ -347,7 +350,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, blender::bke::mesh::normals_loop_custom_set(positions, edges, polys, - loops, + corner_verts, + corner_edges, wn_data->vert_normals, poly_normals, wn_data->sharp_faces, @@ -367,15 +371,16 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, * and it makes code simpler & cleaner. */ blender::Array vert_normals(verts_num, float3(0)); - for (int ml_index = 0; ml_index < loops.size(); ml_index++) { - const int mv_index = loops[ml_index].v; + for (int ml_index = 0; ml_index < corner_verts.size(); ml_index++) { + const int mv_index = corner_verts[ml_index]; copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal); } blender::bke::mesh::normals_loop_custom_set_from_verts(positions, edges, polys, - loops, + corner_verts, + corner_edges, wn_data->vert_normals, poly_normals, wn_data->sharp_faces, @@ -384,11 +389,12 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, clnors); } else { - loop_normals.reinitialize(loops.size()); + loop_normals.reinitialize(corner_verts.size()); blender::bke::mesh::normals_calc_loop(positions, edges, polys, - loops, + corner_verts, + corner_edges, loop_to_poly, wn_data->vert_normals, poly_normals, @@ -400,8 +406,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, nullptr, loop_normals); - for (int ml_index = 0; ml_index < loops.size(); ml_index++) { - const int item_index = loops[ml_index].v; + for (int ml_index = 0; ml_index < corner_verts.size(); ml_index++) { + const int item_index = corner_verts[ml_index]; if (!is_zero_v3(items_data[item_index].normal)) { copy_v3_v3(loop_normals[ml_index], items_data[item_index].normal); } @@ -409,7 +415,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, blender::bke::mesh::normals_loop_custom_set(positions, edges, polys, - loops, + corner_verts, + corner_edges, wn_data->vert_normals, poly_normals, wn_data->sharp_faces, @@ -428,7 +435,7 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w { const blender::Span positions = wn_data->vert_positions; const blender::Span polys = wn_data->polys; - const blender::Span loops = wn_data->loops; + const blender::Span corner_verts = wn_data->corner_verts; ModePair *face_area = static_cast( MEM_malloc_arrayN(size_t(polys.size()), sizeof(*face_area), __func__)); @@ -436,7 +443,7 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w ModePair *f_area = face_area; for (const int i : polys.index_range()) { f_area[i].val = blender::bke::mesh::poly_area_calc( - positions, loops.slice(polys[i].loopstart, polys[i].totloop)); + positions, corner_verts.slice(polys[i].loopstart, polys[i].totloop)); f_area[i].index = i; } @@ -450,17 +457,17 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData { const blender::Span positions = wn_data->vert_positions; const blender::Span polys = wn_data->polys; - const blender::Span loops = wn_data->loops; + const blender::Span corner_verts = wn_data->corner_verts; ModePair *corner_angle = static_cast( - MEM_malloc_arrayN(loops.size(), sizeof(*corner_angle), __func__)); + MEM_malloc_arrayN(corner_verts.size(), sizeof(*corner_angle), __func__)); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; float *index_angle = static_cast( MEM_malloc_arrayN(poly.totloop, sizeof(*index_angle), __func__)); blender::bke::mesh::poly_angles_calc( - positions, loops.slice(poly.loopstart, poly.totloop), {index_angle, poly.totloop}); + positions, corner_verts.slice(poly.loopstart, poly.totloop), {index_angle, poly.totloop}); ModePair *c_angl = &corner_angle[poly.loopstart]; float *angl = index_angle; @@ -472,7 +479,7 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData MEM_freeN(index_angle); } - qsort(corner_angle, loops.size(), sizeof(*corner_angle), modepair_cmp_by_val_inverse); + qsort(corner_angle, corner_verts.size(), sizeof(*corner_angle), modepair_cmp_by_val_inverse); wn_data->mode_pair = corner_angle; apply_weights_vertex_normal(wnmd, wn_data); @@ -482,18 +489,18 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD { const blender::Span positions = wn_data->vert_positions; const blender::Span polys = wn_data->polys; - const blender::Span loops = wn_data->loops; + const blender::Span corner_verts = wn_data->corner_verts; ModePair *combined = static_cast( - MEM_malloc_arrayN(loops.size(), sizeof(*combined), __func__)); + MEM_malloc_arrayN(corner_verts.size(), sizeof(*combined), __func__)); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - const blender::Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - const float face_area = blender::bke::mesh::poly_area_calc(positions, poly_loops); + const blender::Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + const float face_area = blender::bke::mesh::poly_area_calc(positions, poly_verts); float *index_angle = static_cast( MEM_malloc_arrayN(size_t(poly.totloop), sizeof(*index_angle), __func__)); - blender::bke::mesh::poly_angles_calc(positions, poly_loops, {index_angle, poly.totloop}); + blender::bke::mesh::poly_angles_calc(positions, poly_verts, {index_angle, poly.totloop}); ModePair *cmbnd = &combined[poly.loopstart]; float *angl = index_angle; @@ -506,7 +513,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD MEM_freeN(index_angle); } - qsort(combined, loops.size(), sizeof(*combined), modepair_cmp_by_val_inverse); + qsort(combined, corner_verts.size(), sizeof(*combined), modepair_cmp_by_val_inverse); wn_data->mode_pair = combined; apply_weights_vertex_normal(wnmd, wn_data); @@ -541,7 +548,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const blender::Span positions = mesh->vert_positions(); const blender::Span edges = mesh->edges(); const blender::Span polys = mesh->polys(); - const blender::Span loops = mesh->loops(); + const blender::Span corner_verts = mesh->corner_verts(); + const blender::Span corner_edges = mesh->corner_edges(); /* Right now: * If weight = 50 then all faces are given equal weight. @@ -568,8 +576,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * it helps when generating clnor spaces and default normals. */ const bool has_clnors = clnors != nullptr; if (!clnors) { - clnors = static_cast( - CustomData_add_layer(&result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, loops.size())); + clnors = static_cast(CustomData_add_layer( + &result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size())); } const MDeformVert *dvert; @@ -591,7 +599,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * wn_data.edges = edges; wn_data.sharp_edges = sharp_edges.span; - wn_data.loops = loops; + wn_data.corner_verts = corner_verts; + wn_data.corner_edges = corner_edges; wn_data.loop_to_poly = loop_to_poly_map; wn_data.clnors = clnors; wn_data.has_clnors = has_clnors; diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 4c2a1336e02..10cc6137926 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -179,34 +179,34 @@ static Array> build_edge_to_edge_by_vert_map(const Span edges } static Array> build_face_to_edge_by_loop_map(const Span polys, - const Span loops, + const Span corner_edges, const int edges_num) { Array> map(edges_num); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - map[loop.e].append(i); + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + map[edge].append(i); } } return map; } static Array> build_face_to_face_by_edge_map(const Span polys, - const Span loops, + const Span corner_edges, const int edges_num, const IndexMask poly_mask) { Array> map(polys.size()); - Array> faces_by_edge = build_face_to_edge_by_loop_map(polys, loops, edges_num); + Array> faces_by_edge = build_face_to_edge_by_loop_map( + polys, corner_edges, edges_num); threading::parallel_for(poly_mask.index_range(), 1024, [&](IndexRange range) { for (const int poly_i : poly_mask.slice(range)) { const MPoly &poly = polys[poly_i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - const int edge_i = loop.e; - if (faces_by_edge[edge_i].size() > 1) { - for (const int neighbor : faces_by_edge[edge_i]) { + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + if (faces_by_edge[edge].size() > 1) { + for (const int neighbor : faces_by_edge[edge]) { if (neighbor != poly_i) { map[poly_i].append(neighbor); } @@ -235,9 +235,8 @@ static Array> create_mesh_map(const Mesh &mesh, } case ATTR_DOMAIN_FACE: { const Span polys = mesh.polys(); - const Span loops = mesh.loops(); const int edges_num = mesh.totedge; - return build_face_to_face_by_edge_map(polys, loops, edges_num, mask); + return build_face_to_face_by_edge_map(polys, mesh.corner_edges(), edges_num, mask); } case ATTR_DOMAIN_CORNER: { return {}; 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 0866074ebab..89d19905e74 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -69,7 +69,8 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) /* NOTE: ConvexHull from Bullet uses a half-edge data structure * for its mesh. To convert that, each half-edge needs to be converted * to a loop and edges need to be created from that. */ - Array mloop_src(loops_num); + Array corner_verts(loops_num); + Array corner_edges(loops_num); uint edge_index = 0; MutableSpan edges = result->edges_for_write(); @@ -78,7 +79,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) int v_to; plConvexHullGetLoop(hull, i, &v_from, &v_to); - mloop_src[i].v = uint(v_from); + corner_verts[i] = v_from; /* Add edges for ascending order loops only. */ if (v_from < v_to) { MEdge &edge = edges[edge_index]; @@ -87,8 +88,8 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) /* Write edge index into both loops that have it. */ int reverse_index = plConvexHullGetReversedLoopIndex(hull, i); - mloop_src[i].e = edge_index; - mloop_src[reverse_index].e = edge_index; + corner_edges[i] = edge_index; + corner_edges[reverse_index] = edge_index; edge_index++; } } @@ -105,8 +106,9 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) Array loops; int j = 0; MutableSpan polys = result->polys_for_write(); - MutableSpan mesh_loops = result->loops_for_write(); - MLoop *loop = mesh_loops.data(); + MutableSpan mesh_corner_verts = result->corner_verts_for_write(); + MutableSpan mesh_corner_edges = result->corner_edges_for_write(); + int dst_corner = 0; for (const int i : IndexRange(faces_num)) { const int len = plConvexHullGetFaceSize(hull, i); @@ -121,10 +123,9 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) face.loopstart = j; face.totloop = len; for (const int k : IndexRange(len)) { - MLoop &src_loop = mloop_src[loops[k]]; - loop->v = src_loop.v; - loop->e = src_loop.e; - loop++; + mesh_corner_verts[dst_corner] = corner_verts[loops[k]]; + mesh_corner_edges[dst_corner] = corner_edges[loops[k]]; + dst_corner++; } j += len; } 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 c64259a8f00..f0e6eafd662 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -83,7 +83,7 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result &result) 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); for (const int i : IndexRange(result.vert.size())) { positions[i] = float3(float(result.vert[i].x), float(result.vert[i].y), 0.0f); @@ -97,7 +97,7 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result &result) polys[i].loopstart = i_loop; polys[i].totloop = result.face[i].size(); for (const int j : result.face[i].index_range()) { - loops[i_loop].v = result.face[i][j]; + corner_verts[i_loop] = result.face[i][j]; i_loop++; } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index f7279cdfe7e..d487085e0f3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -67,11 +67,11 @@ static void deform_curves(const CurvesGeometry &curves, const float4x4 curves_to_surface = math::invert(surface_to_curves); const Span surface_positions_old = surface_mesh_old.vert_positions(); - const Span surface_loops_old = surface_mesh_old.loops(); + const Span surface_corner_verts_old = surface_mesh_old.corner_verts(); const Span surface_looptris_old = surface_mesh_old.looptris(); const Span surface_positions_new = surface_mesh_new.vert_positions(); - const Span surface_loops_new = surface_mesh_new.loops(); + const Span surface_corner_verts_new = surface_mesh_new.corner_verts(); const Span surface_looptris_new = surface_mesh_new.looptris(); const OffsetIndices points_by_curve = curves.points_by_curve(); @@ -102,13 +102,13 @@ static void deform_curves(const CurvesGeometry &curves, const int corner_1_new = looptri_new.tri[1]; const int corner_2_new = looptri_new.tri[2]; - const int vert_0_old = surface_loops_old[corner_0_old].v; - const int vert_1_old = surface_loops_old[corner_1_old].v; - const int vert_2_old = surface_loops_old[corner_2_old].v; + const int vert_0_old = surface_corner_verts_old[corner_0_old]; + const int vert_1_old = surface_corner_verts_old[corner_1_old]; + const int vert_2_old = surface_corner_verts_old[corner_2_old]; - const int vert_0_new = surface_loops_new[corner_0_new].v; - const int vert_1_new = surface_loops_new[corner_1_new].v; - const int vert_2_new = surface_loops_new[corner_2_new].v; + const int vert_0_new = surface_corner_verts_new[corner_0_new]; + const int vert_1_new = surface_corner_verts_new[corner_1_new]; + const int vert_2_new = surface_corner_verts_new[corner_2_new]; const float3 &normal_0_old = corner_normals_old[corner_0_old]; const float3 &normal_1_old = corner_normals_old[corner_1_old]; diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index f89945f89ee..a4db785c644 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -206,27 +206,30 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span new_loop_starts) { const Span src_polys = src_mesh.polys(); - const Span src_loops = src_mesh.loops(); + const Span src_corner_verts = src_mesh.corner_verts(); + const Span src_corner_edges = src_mesh.corner_edges(); MutableSpan dst_polys = dst_mesh.polys_for_write(); - MutableSpan dst_loops = dst_mesh.loops_for_write(); + MutableSpan dst_corner_verts = dst_mesh.corner_verts_for_write(); + MutableSpan dst_corner_edges = dst_mesh.corner_edges_for_write(); threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) { for (const int i_dst : range) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_polys[i_src]; + const int size = mp_src.totloop; + const Span src_poly_verts = src_corner_verts.slice(mp_src.loopstart, size); + const Span src_poly_edges = src_corner_edges.slice(mp_src.loopstart, size); + MPoly &mp_dst = dst_polys[i_dst]; - const int i_ml_src = mp_src.loopstart; - const int i_ml_dst = new_loop_starts[i_dst]; - - const MLoop *ml_src = &src_loops[i_ml_src]; - MLoop *ml_dst = &dst_loops[i_ml_dst]; - mp_dst = mp_src; - mp_dst.loopstart = i_ml_dst; - for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = ml_src[i].v; - ml_dst[i].e = edge_map[ml_src[i].e]; + mp_dst.loopstart = new_loop_starts[i_dst]; + MutableSpan dst_poly_verts = dst_corner_verts.slice(mp_dst.loopstart, size); + MutableSpan dst_poly_edges = dst_corner_edges.slice(mp_dst.loopstart, size); + + dst_poly_verts.copy_from(src_poly_verts); + + for (const int i : IndexRange(size)) { + dst_poly_edges[i] = edge_map[src_poly_edges[i]]; } } }); @@ -239,28 +242,28 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span new_loop_starts) { const Span src_polys = src_mesh.polys(); - const Span src_loops = src_mesh.loops(); + const Span src_corner_verts = src_mesh.corner_verts(); + const Span src_corner_edges = src_mesh.corner_edges(); MutableSpan dst_polys = dst_mesh.polys_for_write(); - MutableSpan dst_loops = dst_mesh.loops_for_write(); + MutableSpan dst_corner_verts = dst_mesh.corner_verts_for_write(); + MutableSpan dst_corner_edges = dst_mesh.corner_edges_for_write(); threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) { for (const int i_dst : range) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_polys[i_src]; + const int size = mp_src.totloop; + const Span src_poly_verts = src_corner_verts.slice(mp_src.loopstart, size); + const Span src_poly_edges = src_corner_edges.slice(mp_src.loopstart, size); + MPoly &mp_dst = dst_polys[i_dst]; - const int i_ml_src = mp_src.loopstart; - const int i_ml_dst = new_loop_starts[i_dst]; - - const MLoop *ml_src = &src_loops[i_ml_src]; - MLoop *ml_dst = &dst_loops[i_ml_dst]; - mp_dst = mp_src; - mp_dst.loopstart = i_ml_dst; - for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = ml_src[i].v; - ml_dst[i].e = ml_src[i].e; - } + mp_dst.loopstart = new_loop_starts[i_dst]; + MutableSpan dst_poly_verts = dst_corner_verts.slice(mp_dst.loopstart, size); + MutableSpan dst_poly_edges = dst_corner_edges.slice(mp_dst.loopstart, size); + + dst_poly_verts.copy_from(src_poly_verts); + dst_poly_edges.copy_from(src_poly_edges); } }); } @@ -273,27 +276,31 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span new_loop_starts) { const Span src_polys = src_mesh.polys(); - const Span src_loops = src_mesh.loops(); + const Span src_corner_verts = src_mesh.corner_verts(); + const Span src_corner_edges = src_mesh.corner_edges(); MutableSpan dst_polys = dst_mesh.polys_for_write(); - MutableSpan dst_loops = dst_mesh.loops_for_write(); + MutableSpan dst_corner_verts = dst_mesh.corner_verts_for_write(); + MutableSpan dst_corner_edges = dst_mesh.corner_edges_for_write(); threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) { for (const int i_dst : range) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_polys[i_src]; + const int size = mp_src.totloop; + const Span src_poly_verts = src_corner_verts.slice(mp_src.loopstart, size); + const Span src_poly_edges = src_corner_edges.slice(mp_src.loopstart, size); + MPoly &mp_dst = dst_polys[i_dst]; - const int i_ml_src = mp_src.loopstart; - const int i_ml_dst = new_loop_starts[i_dst]; - - const MLoop *ml_src = &src_loops[i_ml_src]; - MLoop *ml_dst = &dst_loops[i_ml_dst]; - mp_dst = mp_src; - mp_dst.loopstart = i_ml_dst; - for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = vertex_map[ml_src[i].v]; - ml_dst[i].e = edge_map[ml_src[i].e]; + mp_dst.loopstart = new_loop_starts[i_dst]; + MutableSpan dst_poly_verts = dst_corner_verts.slice(mp_dst.loopstart, size); + MutableSpan dst_poly_edges = dst_corner_edges.slice(mp_dst.loopstart, size); + + for (const int i : IndexRange(size)) { + dst_poly_verts[i] = vertex_map[src_poly_verts[i]]; + } + for (const int i : IndexRange(size)) { + dst_poly_edges[i] = edge_map[src_poly_edges[i]]; } } }); @@ -440,7 +447,7 @@ static void compute_selected_polys_from_vertex_selection(const Mesh &mesh, { BLI_assert(mesh.totvert == vertex_selection.size()); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); @@ -450,9 +457,8 @@ static void compute_selected_polys_from_vertex_selection(const Mesh &mesh, const MPoly &poly_src = polys[i]; bool all_verts_in_selection = true; - const Span poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); - for (const MLoop &loop : poly_loops) { - if (!vertex_selection[loop.v]) { + for (const int vert : corner_verts.slice(poly_src.loopstart, poly_src.totloop)) { + if (!vertex_selection[vert]) { all_verts_in_selection = false; break; } @@ -544,7 +550,7 @@ static void compute_selected_polys_from_edge_selection(const Mesh &mesh, int *r_selected_loops_num) { const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); @@ -554,9 +560,8 @@ static void compute_selected_polys_from_edge_selection(const Mesh &mesh, const MPoly &poly_src = polys[i]; bool all_edges_in_selection = true; - const Span poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); - for (const MLoop &loop : poly_loops) { - if (!edge_selection[loop.e]) { + for (const int edge : corner_edges.slice(poly_src.loopstart, poly_src.totloop)) { + if (!edge_selection[edge]) { all_edges_in_selection = false; break; } @@ -749,7 +754,7 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( BLI_assert(mesh.totpoly == poly_selection.size()); BLI_assert(mesh.totedge == r_edge_map.size()); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); r_edge_map.fill(-1); @@ -767,11 +772,10 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( selected_loops_num += poly_src.totloop; /* Add the vertices and the edges. */ - const Span poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); - for (const MLoop &loop : poly_loops) { + for (const int edge : corner_edges.slice(poly_src.loopstart, poly_src.totloop)) { /* Check first if it has not yet been added. */ - if (r_edge_map[loop.e] == -1) { - r_edge_map[loop.e] = selected_edges_num; + if (r_edge_map[edge] == -1) { + r_edge_map[edge] = selected_edges_num; selected_edges_num++; } } @@ -800,7 +804,8 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, BLI_assert(mesh.totpoly == poly_selection.size()); BLI_assert(mesh.totedge == r_edge_map.size()); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); + const Span corner_edges = mesh.corner_edges(); r_vertex_map.fill(-1); r_edge_map.fill(-1); @@ -820,15 +825,16 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, selected_loops_num += poly_src.totloop; /* Add the vertices and the edges. */ - const Span poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); - for (const MLoop &loop : poly_loops) { + for (const int corner : IndexRange(poly_src.loopstart, poly_src.totloop)) { + const int vert = corner_verts[corner]; + const int edge = corner_edges[corner]; /* Check first if it has not yet been added. */ - if (r_vertex_map[loop.v] == -1) { - r_vertex_map[loop.v] = selected_verts_num; + if (r_vertex_map[vert] == -1) { + r_vertex_map[vert] = selected_verts_num; selected_verts_num++; } - if (r_edge_map[loop.e] == -1) { - r_edge_map[loop.e] = selected_edges_num; + if (r_edge_map[edge] == -1) { + r_edge_map[edge] = selected_edges_num; selected_edges_num++; } } @@ -861,6 +867,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, Map attributes; geometry_set.gather_attributes_for_propagation( {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_MESH, false, propagation_info, attributes); + attributes.remove(".corner_vert"); + attributes.remove(".corner_edge"); switch (mode) { case GEO_NODE_DELETE_GEOMETRY_MODE_ALL: { diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index 3ba718f211a..7344c6d29ce 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -111,7 +111,7 @@ static void sample_mesh_surface(const Mesh &mesh, Vector &r_looptri_indices) { const Span positions = mesh.vert_positions(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span looptris = mesh.looptris(); for (const int looptri_index : looptris.index_range()) { @@ -119,12 +119,9 @@ static void sample_mesh_surface(const Mesh &mesh, const int v0_loop = looptri.tri[0]; const int v1_loop = looptri.tri[1]; const int v2_loop = looptri.tri[2]; - const int v0_index = loops[v0_loop].v; - const int v1_index = loops[v1_loop].v; - const int v2_index = loops[v2_loop].v; - const float3 v0_pos = positions[v0_index]; - const float3 v1_pos = positions[v1_index]; - const float3 v2_pos = positions[v2_index]; + const float3 &v0_pos = positions[corner_verts[v0_loop]]; + const float3 &v1_pos = positions[corner_verts[v1_loop]]; + const float3 &v2_pos = positions[corner_verts[v2_loop]]; float looptri_density_factor = 1.0f; if (!density_factors.is_empty()) { @@ -362,16 +359,16 @@ static void compute_legacy_normal_outputs(const Mesh &mesh, MutableSpan r_normals) { const Span positions = mesh.vert_positions(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span looptris = mesh.looptris(); for (const int i : bary_coords.index_range()) { const int looptri_index = looptri_indices[i]; const MLoopTri &looptri = looptris[looptri_index]; - const int v0_index = loops[looptri.tri[0]].v; - const int v1_index = loops[looptri.tri[1]].v; - const int v2_index = loops[looptri.tri[2]].v; + const int v0_index = corner_verts[looptri.tri[0]]; + const int v1_index = corner_verts[looptri.tri[1]]; + const int v2_index = corner_verts[looptri.tri[2]]; const float3 v0_pos = positions[v0_index]; const float3 v1_pos = positions[v1_index]; const float3 v2_pos = positions[v2_index]; 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 207e30992ef..44f20cbe2be 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -140,6 +140,8 @@ static void transfer_attributes( * Remove anonymous attributes that don't need to be propagated. */ Set attribute_ids = src_attributes.all_ids(); attribute_ids.remove("position"); + attribute_ids.remove(".corner_vert"); + attribute_ids.remove(".corner_edge"); attribute_ids.remove("sharp_face"); attribute_ids.remove_if([&](const AttributeIDRef &id) { return id.is_anonymous() && !propagation_info.propagate(id.anonymous_id()); @@ -209,7 +211,7 @@ static void calc_boundaries(const Mesh &mesh, BLI_assert(r_edge_types.size() == mesh.totedge); const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); r_vertex_types.fill(VertexType::Loose); r_edge_types.fill(EdgeType::Loose); @@ -217,9 +219,8 @@ static void calc_boundaries(const Mesh &mesh, /* Add up the number of polys connected to each edge. */ for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly = polys[i]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - for (const MLoop &loop : poly_loops) { - r_edge_types[loop.e] = get_edge_type_with_added_neighbor(r_edge_types[loop.e]); + for (const int edge_i : corner_edges.slice(poly.loopstart, poly.totloop)) { + r_edge_types[edge_i] = get_edge_type_with_added_neighbor(r_edge_types[edge_i]); } } @@ -312,7 +313,8 @@ static void calc_boundaries(const Mesh &mesh, */ static bool sort_vertex_polys(const Span edges, const Span polys, - const Span loops, + const Span corner_verts, + const Span corner_edges, const int vertex_index, const bool boundary_vertex, const Span edge_types, @@ -329,15 +331,15 @@ static bool sort_vertex_polys(const Span edges, for (const int i : connected_polys.index_range()) { const MPoly &poly = polys[connected_polys[i]]; bool first_edge_done = false; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - if (edges[loop.e].v1 == vertex_index || edges[loop.e].v2 == vertex_index) { + for (const int corner : IndexRange(poly.loopstart, poly.totloop)) { + const int edge = corner_edges[corner]; + if (edges[edge].v1 == vertex_index || edges[edge].v2 == vertex_index) { if (!first_edge_done) { - poly_vertex_corners[i].first = loop_index; + poly_vertex_corners[i].first = corner; first_edge_done = true; } else { - poly_vertex_corners[i].second = loop_index; + poly_vertex_corners[i].second = corner; break; } } @@ -351,17 +353,19 @@ static bool sort_vertex_polys(const Span edges, if (boundary_vertex) { /* Our first polygon needs to be one which has a boundary edge. */ for (const int i : connected_polys.index_range()) { - const MLoop &first_loop = loops[poly_vertex_corners[i].first]; - const MLoop &second_loop = loops[poly_vertex_corners[i].second]; - if (edge_types[first_loop.e] == EdgeType::Boundary && first_loop.v == vertex_index) { - shared_edge_i = second_loop.e; + const int corner_1 = poly_vertex_corners[i].first; + const int corner_2 = poly_vertex_corners[i].second; + if (edge_types[corner_edges[corner_1]] == EdgeType::Boundary && + corner_verts[corner_1] == vertex_index) { + shared_edge_i = corner_edges[corner_2]; r_sorted_corners[0] = poly_vertex_corners[i].first; std::swap(connected_polys[i], connected_polys[0]); std::swap(poly_vertex_corners[i], poly_vertex_corners[0]); break; } - if (edge_types[second_loop.e] == EdgeType::Boundary && second_loop.v == vertex_index) { - shared_edge_i = first_loop.e; + if (edge_types[corner_edges[corner_2]] == EdgeType::Boundary && + corner_verts[corner_2] == vertex_index) { + shared_edge_i = corner_edges[corner_1]; r_sorted_corners[0] = poly_vertex_corners[i].second; std::swap(connected_polys[i], connected_polys[0]); std::swap(poly_vertex_corners[i], poly_vertex_corners[0]); @@ -372,17 +376,17 @@ static bool sort_vertex_polys(const Span edges, /* The rotation is inconsistent between the two polygons on the boundary. Just choose one * of the polygon's orientation. */ for (const int i : connected_polys.index_range()) { - const MLoop &first_loop = loops[poly_vertex_corners[i].first]; - const MLoop &second_loop = loops[poly_vertex_corners[i].second]; - if (edge_types[first_loop.e] == EdgeType::Boundary) { - shared_edge_i = second_loop.e; + const int corner_1 = poly_vertex_corners[i].first; + const int corner_2 = poly_vertex_corners[i].second; + if (edge_types[corner_edges[corner_1]] == EdgeType::Boundary) { + shared_edge_i = corner_edges[corner_2]; r_sorted_corners[0] = poly_vertex_corners[i].first; std::swap(connected_polys[i], connected_polys[0]); std::swap(poly_vertex_corners[i], poly_vertex_corners[0]); break; } - if (edge_types[second_loop.e] == EdgeType::Boundary) { - shared_edge_i = first_loop.e; + if (edge_types[corner_edges[corner_2]] == EdgeType::Boundary) { + shared_edge_i = corner_edges[corner_1]; r_sorted_corners[0] = poly_vertex_corners[i].second; std::swap(connected_polys[i], connected_polys[0]); std::swap(poly_vertex_corners[i], poly_vertex_corners[0]); @@ -393,15 +397,15 @@ static bool sort_vertex_polys(const Span edges, } else { /* Any polygon can be the first. Just need to check the orientation. */ - const MLoop &first_loop = loops[poly_vertex_corners[0].first]; - const MLoop &second_loop = loops[poly_vertex_corners[0].second]; - if (first_loop.v == vertex_index) { - shared_edge_i = second_loop.e; + const int corner_1 = poly_vertex_corners.first().first; + const int corner_2 = poly_vertex_corners.first().second; + if (corner_verts[corner_1] == vertex_index) { + shared_edge_i = corner_edges[corner_2]; r_sorted_corners[0] = poly_vertex_corners[0].first; } else { r_sorted_corners[0] = poly_vertex_corners[0].second; - shared_edge_i = first_loop.e; + shared_edge_i = corner_edges[corner_1]; } } BLI_assert(shared_edge_i != -1); @@ -412,16 +416,17 @@ static bool sort_vertex_polys(const Span edges, /* Look at the other polys to see if it has this shared edge. */ int j = i + 1; for (; j < connected_polys.size(); ++j) { - const MLoop &first_loop = loops[poly_vertex_corners[j].first]; - const MLoop &second_loop = loops[poly_vertex_corners[j].second]; - if (first_loop.e == shared_edge_i) { + const int corner_1 = poly_vertex_corners[j].first; + const int corner_2 = poly_vertex_corners[j].second; + + if (corner_edges[corner_1] == shared_edge_i) { r_sorted_corners[i + 1] = poly_vertex_corners[j].first; - shared_edge_i = second_loop.e; + shared_edge_i = corner_edges[corner_2]; break; } - if (second_loop.e == shared_edge_i) { + if (corner_edges[corner_2] == shared_edge_i) { r_sorted_corners[i + 1] = poly_vertex_corners[j].second; - shared_edge_i = first_loop.e; + shared_edge_i = corner_edges[corner_1]; break; } } @@ -447,17 +452,16 @@ static bool sort_vertex_polys(const Span edges, */ static void boundary_edge_on_poly(const MPoly &poly, const Span edges, - const Span loops, + const Span corner_edges, const int vertex_index, const Span edge_types, int &r_edge) { - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - for (const MLoop &loop : poly_loops) { - if (edge_types[loop.e] == EdgeType::Boundary) { - const MEdge &edge = edges[loop.e]; + for (const int edge_i : corner_edges.slice(poly.loopstart, poly.totloop)) { + if (edge_types[edge_i] == EdgeType::Boundary) { + const MEdge &edge = edges[edge_i]; if (edge.v1 == vertex_index || edge.v2 == vertex_index) { - r_edge = loop.e; + r_edge = edge_i; return; } } @@ -470,7 +474,8 @@ static void boundary_edge_on_poly(const MPoly &poly, */ static void boundary_edges_on_poly(const MPoly &poly, const Span edges, - const Span loops, + const Span corner_verts, + const Span corner_edges, const int vertex_index, const Span edge_types, int &r_edge1, @@ -480,24 +485,24 @@ static void boundary_edges_on_poly(const MPoly &poly, /* This is set to true if the order in which we encounter the two edges is inconsistent with the * orientation of the polygon. */ bool needs_swap = false; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - for (const MLoop &loop : poly_loops) { - if (edge_types[loop.e] == EdgeType::Boundary) { - const MEdge &edge = edges[loop.e]; + for (const int corner : IndexRange(poly.loopstart, poly.totloop)) { + const int edge_i = corner_edges[corner]; + if (edge_types[edge_i] == EdgeType::Boundary) { + const MEdge &edge = edges[edge_i]; if (edge.v1 == vertex_index || edge.v2 == vertex_index) { if (edge1_done) { if (needs_swap) { r_edge2 = r_edge1; - r_edge1 = loop.e; + r_edge1 = edge_i; } else { - r_edge2 = loop.e; + r_edge2 = edge_i; } return; } - r_edge1 = loop.e; + r_edge1 = edge_i; edge1_done = true; - if (loop.v == vertex_index) { + if (corner_verts[corner] == vertex_index) { needs_swap = true; } } @@ -545,7 +550,7 @@ static bool vertex_needs_dissolving(const int vertex, */ static void dissolve_redundant_verts(const Span edges, const Span polys, - const Span loops, + const Span corner_edges, const Span> vert_to_poly_map, MutableSpan vertex_types, MutableSpan old_to_new_edges_map, @@ -562,9 +567,8 @@ static void dissolve_redundant_verts(const Span edges, const int new_edge_index = new_edges.size(); bool edge_created = false; const MPoly &poly = polys[first_poly_index]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - for (const MLoop &loop : poly_loops) { - const MEdge &edge = edges[loop.e]; + for (const int edge_i : corner_edges.slice(poly.loopstart, poly.totloop)) { + const MEdge &edge = edges[edge_i]; const int v1 = edge.v1; const int v2 = edge.v2; bool mark_edge = false; @@ -586,11 +590,11 @@ static void dissolve_redundant_verts(const Span edges, /* The vertex indices in the dual mesh are the polygon indices of the input mesh. */ new_edge.v1 = first_poly_index; new_edge.v2 = second_poly_index; - new_to_old_edges_map.append(loop.e); + new_to_old_edges_map.append(edge_i); new_edges.append(new_edge); edge_created = true; } - old_to_new_edges_map[loop.e] = new_edge_index; + old_to_new_edges_map[edge_i] = new_edge_index; } } } @@ -617,7 +621,8 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, const Span src_positions = src_mesh.vert_positions(); const Span src_edges = src_mesh.edges(); const Span src_polys = src_mesh.polys(); - const Span src_loops = src_mesh.loops(); + const Span src_corner_verts = src_mesh.corner_verts(); + const Span src_corner_edges = src_mesh.corner_edges(); Array vertex_types(src_mesh.totvert); Array edge_types(src_mesh.totedge); @@ -626,7 +631,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, * over in order of their indices, the polygon's indices will be sorted in ascending order. * (This can change once they are sorted using `sort_vertex_polys`). */ Array> vert_to_poly_map = bke::mesh_topology::build_vert_to_poly_map( - src_polys, src_loops, src_positions.size()); + src_polys, src_corner_verts, src_positions.size()); Array> vertex_shared_edges(src_mesh.totvert); Array> vertex_corners(src_mesh.totvert); threading::parallel_for(vert_to_poly_map.index_range(), 512, [&](IndexRange range) { @@ -643,7 +648,8 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, Array shared_edges(loop_indices.size()); vertex_ok = sort_vertex_polys(src_edges, src_polys, - src_loops, + src_corner_verts, + src_corner_edges, i, false, edge_types, @@ -656,7 +662,8 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, Array shared_edges(loop_indices.size() - 1); vertex_ok = sort_vertex_polys(src_edges, src_polys, - src_loops, + src_corner_verts, + src_corner_edges, i, true, edge_types, @@ -678,8 +685,8 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, Vector vert_positions(src_mesh.totpoly); for (const int i : src_polys.index_range()) { const MPoly &poly = src_polys[i]; - vert_positions[i] = bke::mesh::poly_center_calc(src_positions, - src_loops.slice(poly.loopstart, poly.totloop)); + vert_positions[i] = bke::mesh::poly_center_calc( + src_positions, src_corner_verts.slice(poly.loopstart, poly.totloop)); } Array boundary_edge_midpoint_index; @@ -718,7 +725,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, * anything for most meshes. */ dissolve_redundant_verts(src_edges, src_polys, - src_loops, + src_corner_edges, vert_to_poly_map, vertex_types, old_to_new_edges_map, @@ -808,14 +815,20 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, if (loop_indices.size() >= 2) { /* The first boundary edge is at the end of the chain of polygons. */ boundary_edge_on_poly( - src_polys[loop_indices.last()], src_edges, src_loops, i, edge_types, edge1); + src_polys[loop_indices.last()], src_edges, src_corner_edges, i, edge_types, edge1); boundary_edge_on_poly( - src_polys[loop_indices.first()], src_edges, src_loops, i, edge_types, edge2); + src_polys[loop_indices.first()], src_edges, src_corner_edges, i, edge_types, edge2); } else { /* If there is only one polygon both edges are in that polygon. */ - boundary_edges_on_poly( - src_polys[loop_indices[0]], src_edges, src_loops, i, edge_types, edge1, edge2); + boundary_edges_on_poly(src_polys[loop_indices[0]], + src_edges, + src_corner_verts, + src_corner_edges, + i, + edge_types, + edge1, + edge2); } const int last_face_center = loop_indices.last(); @@ -900,7 +913,6 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, mesh_out->vert_positions_for_write().copy_from(vert_positions); MutableSpan dst_edges = mesh_out->edges_for_write(); MutableSpan dst_polys = mesh_out->polys_for_write(); - MutableSpan dst_loops = mesh_out->loops_for_write(); int loop_start = 0; for (const int i : IndexRange(mesh_out->totpoly)) { @@ -908,10 +920,9 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, dst_polys[i].totloop = loop_lengths[i]; loop_start += loop_lengths[i]; } - for (const int i : IndexRange(mesh_out->totloop)) { - dst_loops[i].v = loops[i]; - dst_loops[i].e = loop_edges[i]; - } + mesh_out->corner_verts_for_write().copy_from(loops); + mesh_out->corner_edges_for_write().copy_from(loop_edges); + dst_edges.copy_from(new_edges); return mesh_out; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index d2efdbbddcc..caac413e797 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -389,8 +389,12 @@ static void copy_face_attributes_without_id( const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { - for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_ALL, propagation_info, {"id"})) { + for (auto &attribute : + bke::retrieve_attributes_for_transfer(src_attributes, + dst_attributes, + ATTR_DOMAIN_MASK_ALL, + propagation_info, + {"id", ".corner_vert", ".corner_edge"})) { attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) { using T = decltype(dummy); const Span src = attribute.src.typed(); @@ -484,7 +488,8 @@ static void duplicate_faces(GeometrySet &geometry_set, const Mesh &mesh = *geometry_set.get_mesh_for_read(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); + const Span corner_edges = mesh.corner_edges(); bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator(field_context, polys.size()); @@ -510,11 +515,12 @@ static void duplicate_faces(GeometrySet &geometry_set, Mesh *new_mesh = BKE_mesh_new_nomain(total_loops, total_loops, total_loops, total_polys); MutableSpan new_edges = new_mesh->edges_for_write(); MutableSpan new_polys = new_mesh->polys_for_write(); - MutableSpan new_loops = new_mesh->loops_for_write(); + MutableSpan new_corner_verts = new_mesh->corner_verts_for_write(); + MutableSpan new_corner_edges = new_mesh->corner_edges_for_write(); Array vert_mapping(new_mesh->totvert); Array edge_mapping(new_edges.size()); - Array loop_mapping(new_loops.size()); + Array loop_mapping(total_loops); int poly_index = 0; int loop_index = 0; @@ -526,11 +532,11 @@ static void duplicate_faces(GeometrySet &geometry_set, new_polys[poly_index] = source; new_polys[poly_index].loopstart = loop_index; for (const int i_loops : IndexRange(source.totloop)) { - const MLoop ¤t_loop = loops[source.loopstart + i_loops]; - loop_mapping[loop_index] = source.loopstart + i_loops; - vert_mapping[loop_index] = current_loop.v; - new_edges[loop_index] = edges[current_loop.e]; - edge_mapping[loop_index] = current_loop.e; + const int src_corner = source.loopstart + i_loops; + loop_mapping[loop_index] = src_corner; + vert_mapping[loop_index] = corner_verts[src_corner]; + new_edges[loop_index] = edges[corner_edges[src_corner]]; + edge_mapping[loop_index] = corner_edges[src_corner]; new_edges[loop_index].v1 = loop_index; if (i_loops + 1 != source.totloop) { new_edges[loop_index].v2 = loop_index + 1; @@ -538,8 +544,8 @@ static void duplicate_faces(GeometrySet &geometry_set, else { new_edges[loop_index].v2 = new_polys[poly_index].loopstart; } - new_loops[loop_index].v = loop_index; - new_loops[loop_index].e = loop_index; + new_corner_verts[loop_index] = loop_index; + new_corner_edges[loop_index] = loop_index; loop_index++; } poly_index++; diff --git a/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc b/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc index cc27c4e9fe3..7d6b55a3085 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc @@ -53,10 +53,9 @@ class FaceSetFromBoundariesInput final : public bke::MeshFieldInput { const IndexMask non_boundary_edges = evaluator.get_evaluated_as_mask(0); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); const Array> edge_to_face_map = bke::mesh_topology::build_edge_to_poly_map( - polys, loops, mesh.totedge); + polys, mesh.corner_edges(), mesh.totedge); AtomicDisjointSet islands(polys.size()); for (const int edge : non_boundary_edges) { 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 c1afbf2a0fa..71c3ecbee37 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -230,6 +230,9 @@ static void extrude_mesh_vertices(Mesh &mesh, if (!ELEM(meta_data.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE)) { return true; } + if (ELEM(id.name(), ".corner_vert", ".corner_edge")) { + return true; + } if (meta_data.data_type == CD_PROP_STRING) { return true; } @@ -287,8 +290,10 @@ static void extrude_mesh_vertices(Mesh &mesh, BKE_mesh_runtime_clear_cache(&mesh); } -static void fill_quad_consistent_direction(Span other_poly_loops, - MutableSpan new_loops, +static void fill_quad_consistent_direction(const Span other_poly_verts, + const Span other_poly_edges, + MutableSpan new_corner_verts, + MutableSpan new_corner_edges, const int vert_connected_to_poly_1, const int vert_connected_to_poly_2, const int vert_across_from_poly_1, @@ -300,31 +305,31 @@ static void fill_quad_consistent_direction(Span other_poly_loops, { /* Find the loop on the polygon connected to the new quad that uses the duplicate edge. */ bool start_with_connecting_edge = true; - for (const MLoop &loop : other_poly_loops) { - if (loop.e == edge_connected_to_poly) { - start_with_connecting_edge = loop.v == vert_connected_to_poly_1; + for (const int i : other_poly_edges.index_range()) { + if (other_poly_edges[i] == edge_connected_to_poly) { + start_with_connecting_edge = other_poly_verts[i] == vert_connected_to_poly_1; break; } } if (start_with_connecting_edge) { - new_loops[0].v = vert_connected_to_poly_1; - new_loops[0].e = connecting_edge_1; - new_loops[1].v = vert_across_from_poly_1; - new_loops[1].e = edge_across_from_poly; - new_loops[2].v = vert_across_from_poly_2; - new_loops[2].e = connecting_edge_2; - new_loops[3].v = vert_connected_to_poly_2; - new_loops[3].e = edge_connected_to_poly; + new_corner_verts[0] = vert_connected_to_poly_1; + new_corner_edges[0] = connecting_edge_1; + new_corner_verts[1] = vert_across_from_poly_1; + new_corner_edges[1] = edge_across_from_poly; + new_corner_verts[2] = vert_across_from_poly_2; + new_corner_edges[2] = connecting_edge_2; + new_corner_verts[3] = vert_connected_to_poly_2; + new_corner_edges[3] = edge_connected_to_poly; } else { - new_loops[0].v = vert_connected_to_poly_1; - new_loops[0].e = edge_connected_to_poly; - new_loops[1].v = vert_connected_to_poly_2; - new_loops[1].e = connecting_edge_2; - new_loops[2].v = vert_across_from_poly_2; - new_loops[2].e = edge_across_from_poly; - new_loops[3].v = vert_across_from_poly_1; - new_loops[3].e = connecting_edge_1; + new_corner_verts[0] = vert_connected_to_poly_1; + new_corner_edges[0] = edge_connected_to_poly; + new_corner_verts[1] = vert_connected_to_poly_2; + new_corner_edges[1] = connecting_edge_2; + new_corner_verts[2] = vert_across_from_poly_2; + new_corner_edges[2] = edge_across_from_poly; + new_corner_verts[3] = vert_across_from_poly_1; + new_corner_edges[3] = connecting_edge_1; } } @@ -366,7 +371,7 @@ static void extrude_mesh_edges(Mesh &mesh, } const Array> edge_to_poly_map = bke::mesh_topology::build_edge_to_poly_map( - orig_polys, mesh.loops(), mesh.totedge); + orig_polys, mesh.corner_edges(), mesh.totedge); /* Find the offsets on the vertex domain for translation. This must be done before the mesh's * custom data layers are reallocated, in case the virtual array references one of them. */ @@ -406,8 +411,10 @@ static void extrude_mesh_edges(Mesh &mesh, MutableSpan duplicate_edges = edges.slice(duplicate_edge_range); MutableSpan polys = mesh.polys_for_write(); MutableSpan new_polys = polys.slice(new_poly_range); - MutableSpan loops = mesh.loops_for_write(); - MutableSpan new_loops = loops.slice(new_loop_range); + MutableSpan corner_verts = mesh.corner_verts_for_write(); + MutableSpan new_corner_verts = corner_verts.slice(new_loop_range); + MutableSpan corner_edges = mesh.corner_edges_for_write(); + MutableSpan new_corner_edges = corner_edges.slice(new_loop_range); for (const int i : connect_edges.index_range()) { connect_edges[i] = new_edge(new_vert_indices[i], new_vert_range[i]); @@ -438,13 +445,17 @@ static void extrude_mesh_edges(Mesh &mesh, /* When there was a single polygon connected to the new polygon, we can use the old one to keep * the face direction consistent. When there is more than one connected edge, the new face * direction is totally arbitrary and the only goal for the behavior is to be deterministic. */ - Span connected_poly_loops = {}; + Span connected_poly_verts = {}; + Span connected_poly_edges = {}; if (connected_polys.size() == 1) { const MPoly &connected_poly = polys[connected_polys.first()]; - connected_poly_loops = loops.slice(connected_poly.loopstart, connected_poly.totloop); + connected_poly_verts = corner_verts.slice(connected_poly.loopstart, connected_poly.totloop); + connected_poly_edges = corner_edges.slice(connected_poly.loopstart, connected_poly.totloop); } - fill_quad_consistent_direction(connected_poly_loops, - new_loops.slice(4 * i, 4), + fill_quad_consistent_direction(connected_poly_verts, + connected_poly_edges, + new_corner_verts.slice(4 * i, 4), + new_corner_edges.slice(4 * i, 4), new_vert_indices[extrude_index_1], new_vert_indices[extrude_index_2], new_vert_1, @@ -467,6 +478,9 @@ static void extrude_mesh_edges(Mesh &mesh, if (meta_data.data_type == CD_PROP_STRING) { return true; } + if (ELEM(id.name(), ".corner_vert", ".corner_edge")) { + return true; + } GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( id, meta_data.domain, meta_data.data_type); @@ -534,11 +548,10 @@ static void extrude_mesh_edges(Mesh &mesh, const MPoly &connected_poly = polys[connected_polys[i_connected_poly]]; for (const int i_loop : IndexRange(connected_poly.loopstart, connected_poly.totloop)) { - const MLoop &loop = loops[i_loop]; - if (loop.v == orig_vert_1) { + if (corner_verts[i_loop] == orig_vert_1) { mixer.mix_in(0, data[i_loop]); } - if (loop.v == orig_vert_2) { + if (corner_verts[i_loop] == orig_vert_2) { mixer.mix_in(1, data[i_loop]); } } @@ -550,10 +563,10 @@ static void extrude_mesh_edges(Mesh &mesh, * simpler (though probably slower) to just match the corner data based on the vertex * indices. */ for (const int i : IndexRange(4 * i_edge_selection, 4)) { - if (ELEM(new_loops[i].v, new_vert_1, orig_vert_1)) { + if (ELEM(new_corner_verts[i], new_vert_1, orig_vert_1)) { new_data[i] = side_poly_corner_data.first(); } - else if (ELEM(new_loops[i].v, new_vert_2, orig_vert_2)) { + else if (ELEM(new_corner_verts[i], new_vert_2, orig_vert_2)) { new_data[i] = side_poly_corner_data.last(); } } @@ -629,7 +642,7 @@ static void extrude_mesh_face_regions(Mesh &mesh, const int orig_vert_size = mesh.totvert; const Span orig_edges = mesh.edges(); const Span orig_polys = mesh.polys(); - const Span orig_loops = mesh.loops(); + const Span orig_corner_verts = mesh.corner_verts(); const bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator poly_evaluator{poly_context, mesh.totpoly}; @@ -657,8 +670,8 @@ static void extrude_mesh_face_regions(Mesh &mesh, for (const int i_poly : poly_selection) { const MPoly &poly = orig_polys[i_poly]; const float3 offset = poly_offsets[i_poly]; - for (const MLoop &loop : orig_loops.slice(poly.loopstart, poly.totloop)) { - mixer.mix_in(loop.v, offset); + for (const int vert : orig_corner_verts.slice(poly.loopstart, poly.totloop)) { + mixer.mix_in(vert, offset); } } mixer.finalize(); @@ -666,7 +679,7 @@ static void extrude_mesh_face_regions(Mesh &mesh, /* All of the faces (selected and deselected) connected to each edge. */ const Array> edge_to_poly_map = bke::mesh_topology::build_edge_to_poly_map( - orig_polys, orig_loops, orig_edges.size()); + orig_polys, mesh.corner_edges(), orig_edges.size()); /* All vertices that are connected to the selected polygons. * Start the size at one vert per poly to reduce unnecessary reallocation. */ @@ -674,8 +687,8 @@ static void extrude_mesh_face_regions(Mesh &mesh, all_selected_verts.reserve(orig_polys.size()); for (const int i_poly : poly_selection) { const MPoly &poly = orig_polys[i_poly]; - for (const MLoop &loop : orig_loops.slice(poly.loopstart, poly.totloop)) { - all_selected_verts.add(loop.v); + for (const int vert : orig_corner_verts.slice(poly.loopstart, poly.totloop)) { + all_selected_verts.add(vert); } } @@ -749,7 +762,7 @@ static void extrude_mesh_face_regions(Mesh &mesh, /* Each edge selected for extrusion is extruded into a single face. */ const IndexRange side_poly_range{orig_polys.size(), boundary_edge_indices.size()}; /* The loops that form the new side faces. */ - const IndexRange side_loop_range{orig_loops.size(), side_poly_range.size() * 4}; + const IndexRange side_loop_range{orig_corner_verts.size(), side_poly_range.size() * 4}; expand_mesh(mesh, new_vert_range.size(), @@ -763,8 +776,10 @@ static void extrude_mesh_face_regions(Mesh &mesh, MutableSpan new_inner_edges = edges.slice(new_inner_edge_range); MutableSpan polys = mesh.polys_for_write(); MutableSpan new_polys = polys.slice(side_poly_range); - MutableSpan loops = mesh.loops_for_write(); - MutableSpan new_loops = loops.slice(side_loop_range); + MutableSpan corner_verts = mesh.corner_verts_for_write(); + MutableSpan new_corner_verts = corner_verts.slice(side_loop_range); + MutableSpan corner_edges = mesh.corner_edges_for_write(); + MutableSpan new_corner_edges = corner_edges.slice(side_loop_range); /* Initialize the edges that form the sides of the extrusion. */ for (const int i : connect_edges.index_range()) { @@ -808,20 +823,20 @@ static void extrude_mesh_face_regions(Mesh &mesh, /* Connect the selected faces to the extruded or duplicated edges and the new vertices. */ for (const int i_poly : poly_selection) { const MPoly &poly = polys[i_poly]; - for (MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - const int i_new_vert = new_vert_indices.index_of_try(loop.v); + for (const int corner : IndexRange(poly.loopstart, poly.totloop)) { + const int i_new_vert = new_vert_indices.index_of_try(corner_verts[corner]); if (i_new_vert != -1) { - loop.v = new_vert_range[i_new_vert]; + corner_verts[corner] = new_vert_range[i_new_vert]; } - const int i_boundary_edge = boundary_edge_indices.index_of_try(loop.e); + const int i_boundary_edge = boundary_edge_indices.index_of_try(corner_edges[corner]); if (i_boundary_edge != -1) { - loop.e = boundary_edge_range[i_boundary_edge]; + corner_edges[corner] = boundary_edge_range[i_boundary_edge]; /* Skip the next check, an edge cannot be both a boundary edge and an inner edge. */ continue; } - const int i_new_inner_edge = new_inner_edge_indices.index_of_try(loop.e); + const int i_new_inner_edge = new_inner_edge_indices.index_of_try(corner_edges[corner]); if (i_new_inner_edge != -1) { - loop.e = new_inner_edge_range[i_new_inner_edge]; + corner_edges[corner] = new_inner_edge_range[i_new_inner_edge]; } } } @@ -836,16 +851,19 @@ static void extrude_mesh_face_regions(Mesh &mesh, const MPoly &extrude_poly = polys[edge_extruded_face_indices[i]]; - fill_quad_consistent_direction(loops.slice(extrude_poly.loopstart, extrude_poly.totloop), - new_loops.slice(4 * i, 4), - new_vert_1, - new_vert_2, - new_vert_indices[extrude_index_1], - new_vert_indices[extrude_index_2], - boundary_edge_range[i], - connect_edge_range[extrude_index_1], - boundary_edge_indices[i], - connect_edge_range[extrude_index_2]); + fill_quad_consistent_direction( + corner_verts.slice(extrude_poly.loopstart, extrude_poly.totloop), + corner_edges.slice(extrude_poly.loopstart, extrude_poly.totloop), + new_corner_verts.slice(4 * i, 4), + new_corner_edges.slice(4 * i, 4), + new_vert_1, + new_vert_2, + new_vert_indices[extrude_index_1], + new_vert_indices[extrude_index_2], + boundary_edge_range[i], + connect_edge_range[extrude_index_1], + boundary_edge_indices[i], + connect_edge_range[extrude_index_2]); } /* Create a map of indices in the extruded vertices array to all of the indices of edges @@ -860,6 +878,9 @@ static void extrude_mesh_face_regions(Mesh &mesh, if (meta_data.data_type == CD_PROP_STRING) { return true; } + if (ELEM(id.name(), ".corner_vert", ".corner_edge")) { + return true; + } GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( id, meta_data.domain, meta_data.data_type); @@ -918,10 +939,10 @@ static void extrude_mesh_face_regions(Mesh &mesh, T data_1; T data_2; for (const int i_loop : IndexRange(poly.loopstart, poly.totloop)) { - if (loops[i_loop].v == new_vert_1) { + if (corner_verts[i_loop] == new_vert_1) { data_1 = data[i_loop]; } - if (loops[i_loop].v == new_vert_2) { + if (corner_verts[i_loop] == new_vert_2) { data_2 = data[i_loop]; } } @@ -930,10 +951,10 @@ static void extrude_mesh_face_regions(Mesh &mesh, * simpler (though probably slower) to just match the corner data based on the * vertex indices. */ for (const int i : IndexRange(4 * i_boundary_edge, 4)) { - if (ELEM(new_loops[i].v, new_vert_1, orig_vert_1)) { + if (ELEM(new_corner_verts[i], new_vert_1, orig_vert_1)) { new_data[i] = data_1; } - else if (ELEM(new_loops[i].v, new_vert_2, orig_vert_2)) { + else if (ELEM(new_corner_verts[i], new_vert_2, orig_vert_2)) { new_data[i] = data_2; } } @@ -1038,7 +1059,7 @@ static void extrude_individual_mesh_faces(Mesh &mesh, const int orig_vert_size = mesh.totvert; const int orig_edge_size = mesh.totedge; const Span orig_polys = mesh.polys(); - const Span orig_loops = mesh.loops(); + const Span orig_corner_verts = mesh.corner_verts(); /* Use a mesh for the result of the evaluation because the mesh is reallocated before * the vertices are moved, and the evaluated result might reference an attribute. */ @@ -1069,7 +1090,7 @@ static void extrude_individual_mesh_faces(Mesh &mesh, const IndexRange duplicate_edge_range = connect_edge_range.after(extrude_corner_size); /* Each edge selected for extrusion is extruded into a single face. */ const IndexRange side_poly_range{orig_polys.size(), duplicate_edge_range.size()}; - const IndexRange side_loop_range{orig_loops.size(), side_poly_range.size() * 4}; + const IndexRange side_loop_range{orig_corner_verts.size(), side_poly_range.size() * 4}; expand_mesh(mesh, new_vert_range.size(), @@ -1083,7 +1104,8 @@ static void extrude_individual_mesh_faces(Mesh &mesh, MutableSpan duplicate_edges = edges.slice(duplicate_edge_range); MutableSpan polys = mesh.polys_for_write(); MutableSpan new_polys = polys.slice(side_poly_range); - MutableSpan loops = mesh.loops_for_write(); + MutableSpan corner_verts = mesh.corner_verts_for_write(); + MutableSpan corner_edges = mesh.corner_edges_for_write(); /* For every selected polygon, change it to use the new extruded vertices and the duplicate * edges, and build the faces that form the sides of the extrusion. Build "original index" @@ -1098,15 +1120,16 @@ static void extrude_individual_mesh_faces(Mesh &mesh, const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection); const MPoly &poly = polys[poly_selection[i_selection]]; - MutableSpan poly_loops = loops.slice(poly.loopstart, poly.totloop); + MutableSpan poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + MutableSpan poly_edges = corner_edges.slice(poly.loopstart, poly.totloop); for (const int i : IndexRange(poly.totloop)) { const int i_extrude = extrude_range[i]; - new_vert_indices[i_extrude] = poly_loops[i].v; - duplicate_edge_indices[i_extrude] = poly_loops[i].e; + new_vert_indices[i_extrude] = poly_verts[i]; + duplicate_edge_indices[i_extrude] = poly_edges[i]; - poly_loops[i].v = new_vert_range[i_extrude]; - poly_loops[i].e = duplicate_edge_range[i_extrude]; + poly_verts[i] = new_vert_range[i_extrude]; + poly_edges[i] = duplicate_edge_range[i_extrude]; } for (const int i : IndexRange(poly.totloop)) { @@ -1127,15 +1150,16 @@ static void extrude_individual_mesh_faces(Mesh &mesh, new_polys[i_extrude] = new_poly(side_loop_range[i_extrude * 4], 4); - MutableSpan side_loops = loops.slice(side_loop_range[i_extrude * 4], 4); - side_loops[0].v = new_vert_next; - side_loops[0].e = i_duplicate_edge; - side_loops[1].v = new_vert; - side_loops[1].e = connect_edge_range[i_extrude]; - side_loops[2].v = orig_vert; - side_loops[2].e = orig_edge; - side_loops[3].v = orig_vert_next; - side_loops[3].e = connect_edge_range[i_extrude_next]; + MutableSpan side_poly_verts = corner_verts.slice(side_loop_range[i_extrude * 4], 4); + MutableSpan side_poly_edges = corner_edges.slice(side_loop_range[i_extrude * 4], 4); + side_poly_verts[0] = new_vert_next; + side_poly_edges[0] = i_duplicate_edge; + side_poly_verts[1] = new_vert; + side_poly_edges[1] = connect_edge_range[i_extrude]; + side_poly_verts[2] = orig_vert; + side_poly_edges[2] = orig_edge; + side_poly_verts[3] = orig_vert_next; + side_poly_edges[3] = connect_edge_range[i_extrude_next]; connect_edges[i_extrude] = new_edge(orig_vert, new_vert); } @@ -1148,6 +1172,9 @@ static void extrude_individual_mesh_faces(Mesh &mesh, if (meta_data.data_type == CD_PROP_STRING) { return true; } + if (ELEM(id.name(), ".corner_vert", ".corner_edge")) { + return true; + } GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( id, meta_data.domain, meta_data.data_type); @@ -1170,13 +1197,11 @@ static void extrude_individual_mesh_faces(Mesh &mesh, threading::parallel_for(poly_selection.index_range(), 512, [&](const IndexRange range) { for (const int i_selection : range) { const MPoly &poly = polys[poly_selection[i_selection]]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection); /* For the extruded edges, mix the data from the two neighboring original edges of * the extruded polygon. */ - for (const int i : poly_loops.index_range()) { + for (const int i : IndexRange(poly.totloop)) { const int i_prev = (i == 0) ? poly.totloop - 1 : i - 1; const int i_extrude = extrude_range[i]; const int i_extrude_prev = extrude_range[i_prev]; diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc index 14e2449d80d..0345868e963 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc @@ -30,7 +30,8 @@ static void mesh_flip_faces(Mesh &mesh, const Field &selection_field) const IndexMask selection = evaluator.get_evaluated_as_mask(0); const Span polys = mesh.polys(); - MutableSpan loops = mesh.loops_for_write(); + MutableSpan corner_verts = mesh.corner_verts_for_write(); + MutableSpan corner_edges = mesh.corner_edges_for_write(); threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) { for (const int i : selection.slice(range)) { @@ -38,8 +39,8 @@ static void mesh_flip_faces(Mesh &mesh, const Field &selection_field) for (const int j : IndexRange(poly.size() / 2)) { const int a = poly[j + 1]; const int b = poly.last(j); - std::swap(loops[a].v, loops[b].v); - std::swap(loops[a - 1].e, loops[b].e); + std::swap(corner_verts[a], corner_verts[b]); + std::swap(corner_edges[a - 1], corner_edges[b]); } } }); @@ -53,6 +54,9 @@ static void mesh_flip_faces(Mesh &mesh, const Field &selection_field) if (meta_data.domain != ATTR_DOMAIN_CORNER) { return true; } + if (ELEM(attribute_id.name(), ".corner_vert", ".corner_edge")) { + return true; + } GSpanAttributeWriter attribute = attributes.lookup_for_write_span(attribute_id); attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { using T = decltype(dummy); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc index e2e20237470..850f9db2101 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc @@ -35,15 +35,15 @@ struct EdgeMapEntry { }; static Array create_edge_map(const Span polys, - const Span loops, + const Span corner_edges, const int total_edges) { Array edge_map(total_edges, {0, 0, 0}); for (const int i_poly : polys.index_range()) { const MPoly &poly = polys[i_poly]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - EdgeMapEntry &entry = edge_map[loop.e]; + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + EdgeMapEntry &entry = edge_map[edge]; if (entry.face_count == 0) { entry.face_index_1 = i_poly; } @@ -69,20 +69,21 @@ class AngleFieldInput final : public bke::MeshFieldInput { { const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); - Array edge_map = create_edge_map(polys, loops, mesh.totedge); + const Span corner_verts = mesh.corner_verts(); + const Span corner_edges = mesh.corner_edges(); + Array edge_map = create_edge_map(polys, corner_edges, mesh.totedge); auto angle_fn = - [edge_map = std::move(edge_map), positions, polys, loops](const int i) -> float { + [edge_map = std::move(edge_map), positions, polys, corner_verts](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } const MPoly &poly_1 = polys[edge_map[i].face_index_1]; const MPoly &poly_2 = polys[edge_map[i].face_index_2]; const float3 normal_1 = bke::mesh::poly_normal_calc( - positions, loops.slice(poly_1.loopstart, poly_1.totloop)); + positions, corner_verts.slice(poly_1.loopstart, poly_1.totloop)); const float3 normal_2 = bke::mesh::poly_normal_calc( - positions, loops.slice(poly_2.loopstart, poly_2.totloop)); + positions, corner_verts.slice(poly_2.loopstart, poly_2.totloop)); return angle_normalized_v3v3(normal_1, normal_2); }; @@ -121,11 +122,12 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { const Span positions = mesh.vert_positions(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); - Array edge_map = create_edge_map(polys, loops, mesh.totedge); + const Span corner_verts = mesh.corner_verts(); + const Span corner_edges = mesh.corner_edges(); + Array edge_map = create_edge_map(polys, corner_edges, mesh.totedge); - auto angle_fn = - [edge_map = std::move(edge_map), positions, edges, polys, loops](const int i) -> float { + auto angle_fn = [edge_map = std::move(edge_map), positions, edges, polys, corner_verts]( + const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } @@ -134,9 +136,9 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { /* Find the normals of the 2 polys. */ const float3 poly_1_normal = bke::mesh::poly_normal_calc( - positions, loops.slice(poly_1.loopstart, poly_1.totloop)); + positions, corner_verts.slice(poly_1.loopstart, poly_1.totloop)); const float3 poly_2_normal = bke::mesh::poly_normal_calc( - positions, loops.slice(poly_2.loopstart, poly_2.totloop)); + positions, corner_verts.slice(poly_2.loopstart, poly_2.totloop)); /* Find the centerpoint of the axis edge */ const float3 edge_centerpoint = (positions[edges[i].v1] + positions[edges[i].v2]) * 0.5f; @@ -144,7 +146,7 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { /* Get the centerpoint of poly 2 and subtract the edge centerpoint to get a tangent * normal for poly 2. */ const float3 poly_center_2 = bke::mesh::poly_center_calc( - positions, loops.slice(poly_2.loopstart, poly_2.totloop)); + positions, corner_verts.slice(poly_2.loopstart, poly_2.totloop)); const float3 poly_2_tangent = math::normalize(poly_center_2 - edge_centerpoint); const float concavity = math::dot(poly_1_normal, poly_2_tangent); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc index 9fc5b361b5a..03018baa81a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc @@ -28,10 +28,10 @@ class EdgeNeighborCountFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, const IndexMask /*mask*/) const final { - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); Array face_count(mesh.totedge, 0); - for (const MLoop &loop : loops) { - face_count[loop.e]++; + for (const int edge : corner_edges) { + face_count[edge]++; } return mesh.attributes().adapt_domain( diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc index d8aeac6df8f..4dcf63342e8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc @@ -20,11 +20,11 @@ static VArray construct_face_area_varray(const Mesh &mesh, const eAttrDom { const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); - auto area_fn = [positions, polys, loops](const int i) -> float { + auto area_fn = [positions, polys, corner_verts](const int i) -> float { const MPoly &poly = polys[i]; - return bke::mesh::poly_area_calc(positions, loops.slice(poly.loopstart, poly.totloop)); + return bke::mesh::poly_area_calc(positions, corner_verts.slice(poly.loopstart, poly.totloop)); }; return mesh.attributes().adapt_domain( diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index 71ab9ab3018..d70d0292ae1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -41,7 +41,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput { { const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); const Span poly_normals = mesh.poly_normals(); bke::MeshFieldContext context{mesh, ATTR_DOMAIN_FACE}; @@ -50,20 +50,19 @@ class PlanarFieldInput final : public bke::MeshFieldInput { evaluator.evaluate(); const VArray thresholds = evaluator.get_evaluated(0); - auto planar_fn = [positions, polys, loops, thresholds, poly_normals](const int i) -> bool { + auto planar_fn = + [positions, polys, corner_verts, thresholds, poly_normals](const int i) -> bool { const MPoly &poly = polys[i]; if (poly.totloop <= 3) { return true; } - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); const float3 &reference_normal = poly_normals[i]; float min = FLT_MAX; float max = -FLT_MAX; - for (const int i_loop : poly_loops.index_range()) { - const float3 &vert = positions[poly_loops[i_loop].v]; - float dot = math::dot(reference_normal, vert); + for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) { + float dot = math::dot(reference_normal, positions[vert]); if (dot > max) { max = dot; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc index a4b71941c23..e0fa844a2df 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc @@ -22,18 +22,18 @@ static void node_declare(NodeDeclarationBuilder &b) static VArray construct_neighbor_count_varray(const Mesh &mesh, const eAttrDomain domain) { const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); Array edge_count(mesh.totedge, 0); - for (const MLoop &loop : loops) { - edge_count[loop.e]++; + for (const int edge : corner_edges) { + edge_count[edge]++; } Array poly_count(polys.size(), 0); for (const int poly_index : polys.index_range()) { const MPoly &poly = polys[poly_index]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - poly_count[poly_index] += edge_count[loop.e] - 1; + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { + poly_count[poly_index] += edge_count[edge] - 1; } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc index 2fb8e4f54fa..dd233828d6f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc @@ -67,12 +67,11 @@ class VertexCountFieldInput final : public bke::MeshFieldInput { static VArray construct_face_count_gvarray(const Mesh &mesh, const eAttrDomain domain) { - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); if (domain == ATTR_DOMAIN_POINT) { Array vertices(mesh.totvert, 0); - for (const int i : loops.index_range()) { - int vertex = loops[i].v; - vertices[vertex]++; + for (const int vert : corner_verts) { + vertices[vert]++; } return VArray::ForContainer(std::move(vertices)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc index 90f7677f456..daa7333910e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc @@ -47,11 +47,10 @@ class BoundaryFieldInput final : public bke::MeshFieldInput { Array edge_visited(mesh.totedge, false); Array edge_face_set(mesh.totedge, 0); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); for (const int i : polys.index_range()) { const MPoly &poly = polys[i]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - const int edge = loop.e; + for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) { if (edge_visited[edge]) { if (edge_face_set[edge] != face_set[i]) { /* This edge is connected to two faces on different face sets. */ 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 d85d153972e..328e83612f0 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 @@ -111,7 +111,8 @@ static Mesh *create_circle_mesh(const float radius, 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); + MutableSpan corner_edges = mesh->corner_edges_for_write(); BKE_mesh_smooth_flag_set(mesh, false); /* Assign vertex coordinates. */ @@ -144,13 +145,10 @@ static Mesh *create_circle_mesh(const float radius, if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { MPoly &poly = polys[0]; poly.loopstart = 0; - poly.totloop = loops.size(); + poly.totloop = corner_verts.size(); - for (const int i : IndexRange(verts_num)) { - MLoop &loop = loops[i]; - loop.e = i; - loop.v = i; - } + std::iota(corner_verts.begin(), corner_verts.end(), 0); + std::iota(corner_edges.begin(), corner_edges.end(), 0); } else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { for (const int i : IndexRange(verts_num)) { @@ -158,15 +156,14 @@ static Mesh *create_circle_mesh(const float radius, poly.loopstart = 3 * i; poly.totloop = 3; - MLoop &loop_a = loops[3 * i]; - loop_a.e = i; - loop_a.v = i; - MLoop &loop_b = loops[3 * i + 1]; - loop_b.e = verts_num + ((i + 1) % verts_num); - loop_b.v = (i + 1) % verts_num; - MLoop &loop_c = loops[3 * i + 2]; - loop_c.e = verts_num + i; - loop_c.v = verts_num; + corner_verts[3 * i] = i; + corner_edges[3 * i] = i; + + corner_verts[3 * i + 1] = (i + 1) % verts_num; + corner_edges[3 * i + 1] = verts_num + ((i + 1) % verts_num); + + corner_verts[3 * i + 2] = verts_num; + corner_edges[3 * i + 2] = verts_num + i; } } 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 3145211d1d8..3639a1e069b 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 @@ -365,7 +365,8 @@ static void calculate_cone_edges(const ConeConfig &config, MutableSpan ed } static void calculate_cone_faces(const ConeConfig &config, - MutableSpan loops, + MutableSpan corner_verts, + MutableSpan corner_edges, MutableSpan polys) { int rings_poly_start = 0; @@ -384,14 +385,15 @@ static void calculate_cone_faces(const ConeConfig &config, poly.loopstart = loop_start; poly.totloop = 3; - loops[loop_start + 0].v = config.first_ring_verts_start + i; - loops[loop_start + 0].e = config.first_ring_edges_start + i; + corner_verts[loop_start + 0] = config.first_ring_verts_start + i; + corner_edges[loop_start + 0] = config.first_ring_edges_start + i; - loops[loop_start + 1].v = config.first_ring_verts_start + ((i + 1) % config.circle_segments); - loops[loop_start + 1].e = top_fan_edges_start + ((i + 1) % config.circle_segments); + corner_verts[loop_start + 1] = config.first_ring_verts_start + + ((i + 1) % config.circle_segments); + corner_edges[loop_start + 1] = top_fan_edges_start + ((i + 1) % config.circle_segments); - loops[loop_start + 2].v = top_center_vert; - loops[loop_start + 2].e = top_fan_edges_start + i; + corner_verts[loop_start + 2] = top_center_vert; + corner_edges[loop_start + 2] = top_fan_edges_start + i; } } else if (config.fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { @@ -403,8 +405,8 @@ static void calculate_cone_faces(const ConeConfig &config, poly.loopstart = 0; poly.totloop = config.circle_segments; for (const int i : IndexRange(config.circle_segments)) { - loops[i].v = i; - loops[i].e = i; + corner_verts[i] = i; + corner_edges[i] = i; } } @@ -426,17 +428,17 @@ static void calculate_cone_faces(const ConeConfig &config, poly.loopstart = loop_start; poly.totloop = 4; - loops[loop_start + 0].v = this_ring_vert_start + j; - loops[loop_start + 0].e = ring_connections_start + j; + corner_verts[loop_start + 0] = this_ring_vert_start + j; + corner_edges[loop_start + 0] = ring_connections_start + j; - loops[loop_start + 1].v = next_ring_vert_start + j; - loops[loop_start + 1].e = next_ring_edges_start + j; + corner_verts[loop_start + 1] = next_ring_vert_start + j; + corner_edges[loop_start + 1] = next_ring_edges_start + j; - loops[loop_start + 2].v = next_ring_vert_start + ((j + 1) % config.circle_segments); - loops[loop_start + 2].e = ring_connections_start + ((j + 1) % config.circle_segments); + corner_verts[loop_start + 2] = next_ring_vert_start + ((j + 1) % config.circle_segments); + corner_edges[loop_start + 2] = ring_connections_start + ((j + 1) % config.circle_segments); - loops[loop_start + 3].v = this_ring_vert_start + ((j + 1) % config.circle_segments); - loops[loop_start + 3].e = this_ring_edges_start + j; + corner_verts[loop_start + 3] = this_ring_vert_start + ((j + 1) % config.circle_segments); + corner_edges[loop_start + 3] = this_ring_edges_start + j; } } @@ -452,14 +454,16 @@ static void calculate_cone_faces(const ConeConfig &config, poly.loopstart = loop_start; poly.totloop = 3; - loops[loop_start + 0].v = config.last_ring_verts_start + i; - loops[loop_start + 0].e = config.last_fan_edges_start + i; + corner_verts[loop_start + 0] = config.last_ring_verts_start + i; + corner_edges[loop_start + 0] = config.last_fan_edges_start + i; - loops[loop_start + 1].v = config.last_vert; - loops[loop_start + 1].e = config.last_fan_edges_start + (i + 1) % config.circle_segments; + corner_verts[loop_start + 1] = config.last_vert; + corner_edges[loop_start + 1] = config.last_fan_edges_start + + (i + 1) % config.circle_segments; - loops[loop_start + 2].v = config.last_ring_verts_start + (i + 1) % config.circle_segments; - loops[loop_start + 2].e = config.last_ring_edges_start + i; + corner_verts[loop_start + 2] = config.last_ring_verts_start + + (i + 1) % config.circle_segments; + corner_edges[loop_start + 2] = config.last_ring_edges_start + i; } } else if (config.fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { @@ -470,8 +474,8 @@ static void calculate_cone_faces(const ConeConfig &config, for (const int i : IndexRange(config.circle_segments)) { /* Go backwards to reverse surface normal. */ - loops[bottom_loop_start + i].v = config.last_vert - i; - loops[bottom_loop_start + i].e = config.last_edge - ((i + 1) % config.circle_segments); + corner_verts[bottom_loop_start + i] = config.last_vert - i; + corner_edges[bottom_loop_start + i] = config.last_edge - ((i + 1) % config.circle_segments); } } } @@ -691,12 +695,13 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); + MutableSpan corner_edges = mesh->corner_edges_for_write(); BKE_mesh_smooth_flag_set(mesh, false); calculate_cone_verts(config, positions); calculate_cone_edges(config, edges); - calculate_cone_faces(config, loops, polys); + calculate_cone_faces(config, corner_verts, corner_edges, polys); if (attribute_outputs.uv_map_id) { calculate_cone_uvs(config, mesh, attribute_outputs.uv_map_id.get()); } 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 2d366debda7..10acbb1e4af 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 @@ -16,8 +16,8 @@ namespace blender::nodes { static void calculate_uvs(Mesh *mesh, - Span positions, - Span loops, + const Span positions, + const Span corner_verts, const float size_x, const float size_y, const AttributeIDRef &uv_map_id) @@ -29,9 +29,9 @@ static void calculate_uvs(Mesh *mesh, const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x; const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; - threading::parallel_for(loops.index_range(), 1024, [&](IndexRange range) { + threading::parallel_for(corner_verts.index_range(), 1024, [&](IndexRange range) { for (const int i : range) { - const float3 &co = positions[loops[i].v]; + const float3 &co = positions[corner_verts[i]]; uv_attribute.span[i].x = (co.x + size_x * 0.5f) * dx; uv_attribute.span[i].y = (co.y + size_y * 0.5f) * dy; } @@ -56,7 +56,8 @@ Mesh *create_grid_mesh(const int verts_x, 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); + MutableSpan corner_edges = mesh->corner_edges_for_write(); BKE_mesh_smooth_flag_set(mesh, false); { @@ -125,25 +126,24 @@ Mesh *create_grid_mesh(const int verts_x, poly.totloop = 4; const int vert_index = x * verts_y + y; - MLoop &loop_a = loops[loop_index]; - loop_a.v = vert_index; - loop_a.e = x_edges_start + edges_x * y + x; - MLoop &loop_b = loops[loop_index + 1]; - loop_b.v = vert_index + verts_y; - loop_b.e = y_edges_start + edges_y * (x + 1) + y; - MLoop &loop_c = loops[loop_index + 2]; - loop_c.v = vert_index + verts_y + 1; - loop_c.e = x_edges_start + edges_x * (y + 1) + x; - MLoop &loop_d = loops[loop_index + 3]; - loop_d.v = vert_index + 1; - loop_d.e = y_edges_start + edges_y * x + y; + corner_verts[loop_index] = vert_index; + corner_edges[loop_index] = x_edges_start + edges_x * y + x; + + corner_verts[loop_index + 1] = vert_index + verts_y; + corner_edges[loop_index + 1] = y_edges_start + edges_y * (x + 1) + y; + + corner_verts[loop_index + 2] = vert_index + verts_y + 1; + corner_edges[loop_index + 2] = x_edges_start + edges_x * (y + 1) + x; + + corner_verts[loop_index + 3] = vert_index + 1; + corner_edges[loop_index + 3] = y_edges_start + edges_y * x + y; } }); } }); if (uv_map_id && mesh->totpoly != 0) { - calculate_uvs(mesh, positions, loops, size_x, size_y, uv_map_id); + calculate_uvs(mesh, positions, corner_verts, size_x, size_y, uv_map_id); } mesh->loose_edges_tag_none(); 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 41a48e7bc73..51c5bbce8d3 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 @@ -177,7 +177,8 @@ BLI_NOINLINE static void calculate_sphere_faces(MutableSpan polys, const } } -BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, +BLI_NOINLINE static void calculate_sphere_corners(MutableSpan corner_verts, + MutableSpan corner_edges, const int segments, const int rings) { @@ -191,14 +192,14 @@ BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, const int loop_start = segment * 3; const int segment_next = segment_next_or_first(segment); - loops[loop_start + 0].v = 0; - loops[loop_start + 0].e = segment; + corner_verts[loop_start + 0] = 0; + corner_edges[loop_start + 0] = segment; - loops[loop_start + 1].v = first_vert_ring_start + segment; - loops[loop_start + 1].e = segments + segment; + corner_verts[loop_start + 1] = first_vert_ring_start + segment; + corner_edges[loop_start + 1] = segments + segment; - loops[loop_start + 2].v = first_vert_ring_start + segment_next; - loops[loop_start + 2].e = segment_next; + corner_verts[loop_start + 2] = first_vert_ring_start + segment_next; + corner_edges[loop_start + 2] = segment_next; } const int rings_vert_start = 1; @@ -217,17 +218,17 @@ BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, const int loop_start = ring_loop_start + segment * 4; const int segment_next = segment_next_or_first(segment); - loops[loop_start + 0].v = ring_vert_start + segment; - loops[loop_start + 0].e = ring_vertical_edge_start + segment; + corner_verts[loop_start + 0] = ring_vert_start + segment; + corner_edges[loop_start + 0] = ring_vertical_edge_start + segment; - loops[loop_start + 1].v = next_ring_vert_start + segment; - loops[loop_start + 1].e = next_ring_edge_start + segment; + corner_verts[loop_start + 1] = next_ring_vert_start + segment; + corner_edges[loop_start + 1] = next_ring_edge_start + segment; - loops[loop_start + 2].v = next_ring_vert_start + segment_next; - loops[loop_start + 2].e = ring_vertical_edge_start + segment_next; + corner_verts[loop_start + 2] = next_ring_vert_start + segment_next; + corner_edges[loop_start + 2] = ring_vertical_edge_start + segment_next; - loops[loop_start + 3].v = ring_vert_start + segment_next; - loops[loop_start + 3].e = ring_edge_start + segment; + corner_verts[loop_start + 3] = ring_vert_start + segment_next; + corner_edges[loop_start + 3] = ring_edge_start + segment; } } @@ -241,14 +242,14 @@ BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, const int loop_start = bottom_loop_start + segment * 3; const int segment_next = segment_next_or_first(segment); - loops[loop_start + 0].v = last_vert_index; - loops[loop_start + 0].e = bottom_edge_fan_start + segment_next; + corner_verts[loop_start + 0] = last_vert_index; + corner_edges[loop_start + 0] = bottom_edge_fan_start + segment_next; - loops[loop_start + 1].v = last_vert_ring_start + segment_next; - loops[loop_start + 1].e = last_edge_ring_start + segment; + corner_verts[loop_start + 1] = last_vert_ring_start + segment_next; + corner_edges[loop_start + 1] = last_edge_ring_start + segment; - loops[loop_start + 2].v = last_vert_ring_start + segment; - loops[loop_start + 2].e = bottom_edge_fan_start + segment; + corner_verts[loop_start + 2] = last_vert_ring_start + segment; + corner_edges[loop_start + 2] = bottom_edge_fan_start + segment; } } @@ -314,7 +315,8 @@ static Mesh *create_uv_sphere_mesh(const float radius, 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(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); + MutableSpan corner_edges = mesh->corner_edges_for_write(); BKE_mesh_smooth_flag_set(mesh, false); threading::parallel_invoke( @@ -327,7 +329,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, }, [&]() { calculate_sphere_edge_indices(edges, segments, rings); }, [&]() { calculate_sphere_faces(polys, segments); }, - [&]() { calculate_sphere_corners(loops, segments, rings); }, + [&]() { calculate_sphere_corners(corner_verts, corner_edges, segments, rings); }, [&]() { if (uv_map_id) { calculate_sphere_uvs(mesh, segments, rings, uv_map_id); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc index 2a115560d7e..2e9bd6ec2d7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc @@ -60,8 +60,8 @@ class CornersOfVertInput final : public bke::MeshFieldInput { const IndexMask mask) const final { const IndexRange vert_range(mesh.totvert); - const Span loops = mesh.loops(); - Array> vert_to_loop_map = bke::mesh_topology::build_vert_to_loop_map(loops, + const Span corner_verts = mesh.corner_verts(); + Array> vert_to_loop_map = bke::mesh_topology::build_vert_to_loop_map(corner_verts, mesh.totvert); const bke::MeshFieldContext context{mesh, domain}; @@ -73,7 +73,7 @@ class CornersOfVertInput final : public bke::MeshFieldInput { const VArray indices_in_sort = evaluator.get_evaluated(1); const bke::MeshFieldContext corner_context{mesh, ATTR_DOMAIN_CORNER}; - fn::FieldEvaluator corner_evaluator{corner_context, loops.size()}; + fn::FieldEvaluator corner_evaluator{corner_context, corner_verts.size()}; corner_evaluator.add(sort_weight_); corner_evaluator.evaluate(); const VArray all_sort_weights = corner_evaluator.get_evaluated(0); @@ -172,10 +172,10 @@ class CornersOfVertCountInput final : public bke::MeshFieldInput { if (domain != ATTR_DOMAIN_POINT) { return {}; } - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); Array counts(mesh.totvert, 0); - for (const int i : loops.index_range()) { - counts[loops[i].v]++; + for (const int i : corner_verts.index_range()) { + counts[corner_verts[i]]++; } return VArray::ForContainer(std::move(counts)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc index ecec64c0950..df0b924dfbd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc @@ -25,11 +25,6 @@ static void node_declare(NodeDeclarationBuilder &b) N_("The edge before the corner in the face, in the direction of decreasing indices")); } -static int get_loop_edge(const MLoop &loop) -{ - return loop.e; -} - class CornerNextEdgeFieldInput final : public bke::MeshFieldInput { public: CornerNextEdgeFieldInput() : bke::MeshFieldInput(CPPType::get(), "Corner Next Edge") @@ -44,7 +39,7 @@ class CornerNextEdgeFieldInput final : public bke::MeshFieldInput { if (domain != ATTR_DOMAIN_CORNER) { return {}; } - return VArray::ForDerivedSpan(mesh.loops()); + return VArray::ForSpan(mesh.corner_edges()); } uint64_t hash() const final @@ -81,15 +76,13 @@ class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput { return {}; } const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_edges = mesh.corner_edges(); Array loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(polys, mesh.totloop); return VArray::ForFunc( mesh.totloop, - [polys, loops, loop_to_poly_map = std::move(loop_to_poly_map)](const int corner_i) { - const int poly_i = loop_to_poly_map[corner_i]; - const MPoly &poly = polys[poly_i]; - const int corner_i_prev = bke::mesh_topology::poly_loop_prev(poly, corner_i); - return loops[corner_i_prev].e; + [polys, corner_edges, loop_to_poly_map = std::move(loop_to_poly_map)](const int corner_i) { + const MPoly &poly = polys[loop_to_poly_map[corner_i]]; + return corner_edges[bke::mesh_topology::poly_loop_prev(poly, corner_i)]; }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc index 59ce296b1e7..58f2403338d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc @@ -19,11 +19,6 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("The vertex the corner is attached to")); } -static int get_loop_vert(const MLoop &loop) -{ - return loop.v; -} - class CornerVertFieldInput final : public bke::MeshFieldInput { public: CornerVertFieldInput() : bke::MeshFieldInput(CPPType::get(), "Corner Vertex") @@ -38,7 +33,7 @@ class CornerVertFieldInput final : public bke::MeshFieldInput { if (domain != ATTR_DOMAIN_CORNER) { return {}; } - return VArray::ForDerivedSpan(mesh.loops()); + return VArray::ForSpan(mesh.corner_verts()); } uint64_t hash() const final diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index e8de583d6e6..60a12cdde40 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -165,7 +165,7 @@ static void get_closest_mesh_corners(const Mesh &mesh, { const Span vert_positions = mesh.vert_positions(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); BLI_assert(mesh.totloop > 0); Array poly_indices(positions.size()); @@ -181,8 +181,7 @@ static void get_closest_mesh_corners(const Mesh &mesh, int closest_vert_index = 0; int closest_loop_index = 0; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = loops[loop_index]; - const int vertex_index = loop.v; + const int vertex_index = corner_verts[loop_index]; const float distance_sq = math::distance_squared(position, vert_positions[vertex_index]); if (distance_sq < min_distance_sq) { min_distance_sq = distance_sq; diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc index 819084cb9fa..5d3992bcd76 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc @@ -149,7 +149,7 @@ static float4x4 create_single_axis_transform(const float3 ¢er, using GetVertexIndicesFn = FunctionRef edges, Span polys, - Span loops, + Span corner_verts, int element_index, VectorSet &r_vertex_indices)>; @@ -161,7 +161,7 @@ static void scale_vertex_islands_uniformly(Mesh &mesh, MutableSpan positions = mesh.vert_positions_for_write(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { for (const int island_index : range) { @@ -172,7 +172,7 @@ static void scale_vertex_islands_uniformly(Mesh &mesh, VectorSet vertex_indices; for (const int poly_index : island.element_indices) { - get_vertex_indices(edges, polys, loops, poly_index, vertex_indices); + get_vertex_indices(edges, polys, corner_verts, poly_index, vertex_indices); center += params.centers[poly_index]; scale += params.scales[poly_index]; } @@ -199,7 +199,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, MutableSpan positions = mesh.vert_positions_for_write(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { for (const int island_index : range) { @@ -211,7 +211,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, VectorSet vertex_indices; for (const int poly_index : island.element_indices) { - get_vertex_indices(edges, polys, loops, poly_index, vertex_indices); + get_vertex_indices(edges, polys, corner_verts, poly_index, vertex_indices); center += params.centers[poly_index]; scale += params.scales[poly_index]; axis += params.axis_vectors[poly_index]; @@ -240,19 +240,19 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, static Vector prepare_face_islands(const Mesh &mesh, const IndexMask face_selection) { const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); /* Use the disjoint set data structure to determine which vertices have to be scaled together. */ DisjointSet disjoint_set(mesh.totvert); for (const int poly_index : face_selection) { const MPoly &poly = polys[poly_index]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); + const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); for (const int loop_index : IndexRange(poly.totloop - 1)) { - const int v1 = poly_loops[loop_index].v; - const int v2 = poly_loops[loop_index + 1].v; + const int v1 = poly_verts[loop_index]; + const int v2 = poly_verts[loop_index + 1]; disjoint_set.join(v1, v2); } - disjoint_set.join(poly_loops.first().v, poly_loops.last().v); + disjoint_set.join(poly_verts.first(), poly_verts.last()); } VectorSet island_ids; @@ -263,8 +263,8 @@ static Vector prepare_face_islands(const Mesh &mesh, const IndexM /* Gather all of the face indices in each island into separate vectors. */ for (const int poly_index : face_selection) { const MPoly &poly = polys[poly_index]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - const int island_id = disjoint_set.find_root(poly_loops[0].v); + const Span poly_verts = corner_verts.slice(poly.loopstart, poly.totloop); + const int island_id = disjoint_set.find_root(poly_verts[0]); const int island_index = island_ids.index_of_or_add(island_id); if (island_index == islands.size()) { islands.append_as(); @@ -278,15 +278,12 @@ static Vector prepare_face_islands(const Mesh &mesh, const IndexM static void get_face_verts(const Span /*edges*/, const Span polys, - const Span loops, + const Span corner_verts, int face_index, VectorSet &r_vertex_indices) { const MPoly &poly = polys[face_index]; - const Span poly_loops = loops.slice(poly.loopstart, poly.totloop); - for (const MLoop &loop : poly_loops) { - r_vertex_indices.add(loop.v); - } + r_vertex_indices.add_multiple(corner_verts.slice(poly.loopstart, poly.totloop)); } static AxisScaleParams evaluate_axis_scale_fields(FieldEvaluator &evaluator, @@ -367,7 +364,7 @@ static Vector prepare_edge_islands(const Mesh &mesh, const IndexM static void get_edge_verts(const Span edges, const Span /*polys*/, - const Span /*loops*/, + const Span /*corner_verts*/, int edge_index, VectorSet &r_vertex_indices) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index d6a31c9133e..7f1c7d36a8d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -39,7 +39,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, { const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator face_evaluator{face_context, polys.size()}; @@ -65,10 +65,11 @@ static VArray construct_uv_gvarray(const Mesh &mesh, Array mp_co(poly.totloop); Array mp_uv(poly.totloop); for (const int i : IndexRange(poly.totloop)) { - const MLoop &ml = loops[poly.loopstart + i]; - mp_vkeys[i] = ml.v; - mp_co[i] = positions[ml.v]; - mp_uv[i] = uv[poly.loopstart + i]; + const int corner = poly.loopstart + i; + const int vert = corner_verts[corner]; + mp_vkeys[i] = vert; + mp_co[i] = positions[vert]; + mp_uv[i] = uv[corner]; mp_pin[i] = false; mp_select[i] = false; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 492decd8eb9..98729eb67b6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -65,7 +65,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, const Span positions = mesh.vert_positions(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); - const Span loops = mesh.loops(); + const Span corner_verts = mesh.corner_verts(); bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator face_evaluator{face_context, polys.size()}; @@ -82,7 +82,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, edge_evaluator.evaluate(); const IndexMask seam = edge_evaluator.get_evaluated_as_mask(0); - Array uv(loops.size(), float3(0)); + Array uv(corner_verts.size(), float3(0)); geometry::ParamHandle *handle = geometry::uv_parametrizer_construct_begin(); for (const int poly_index : selection) { @@ -93,10 +93,11 @@ static VArray construct_uv_gvarray(const Mesh &mesh, Array mp_co(poly.totloop); Array mp_uv(poly.totloop); for (const int i : IndexRange(poly.totloop)) { - const MLoop &ml = loops[poly.loopstart + i]; - mp_vkeys[i] = ml.v; - mp_co[i] = positions[ml.v]; - mp_uv[i] = uv[poly.loopstart + i]; + const int corner = poly.loopstart + i; + const int vert = corner_verts[corner]; + mp_vkeys[i] = vert; + mp_co[i] = positions[vert]; + mp_uv[i] = uv[corner]; mp_pin[i] = false; mp_select[i] = false; } 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 77bf69d187c..99311bbd003 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 @@ -125,7 +125,7 @@ static Mesh *create_mesh_from_volume_grids(Span gri BKE_id_material_eval_ensure_default_slot(&mesh->id); MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan polys = mesh->polys_for_write(); - MutableSpan loops = mesh->loops_for_write(); + MutableSpan corner_verts = mesh->corner_verts_for_write(); for (const int i : grids.index_range()) { const bke::OpenVDBMeshData &data = mesh_data[i]; @@ -137,7 +137,7 @@ static Mesh *create_mesh_from_volume_grids(Span gri loop_offsets[i], positions, polys, - loops); + corner_verts); } BKE_mesh_calc_edges(mesh, false, false); diff --git a/source/blender/python/mathutils/mathutils_bvhtree.cc b/source/blender/python/mathutils/mathutils_bvhtree.cc index e9e07a7c248..ecc41aef0dc 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.cc +++ b/source/blender/python/mathutils/mathutils_bvhtree.cc @@ -1111,7 +1111,7 @@ static PyObject *C_BVHTree_FromObject(PyObject * /*cls*/, PyObject *args, PyObje bool free_mesh = false; const MLoopTri *lt; - const MLoop *mloop; + const int *corner_verts; float(*coords)[3] = nullptr; uint(*tris)[3] = nullptr; @@ -1153,7 +1153,7 @@ static PyObject *C_BVHTree_FromObject(PyObject * /*cls*/, PyObject *args, PyObje tris = static_cast(MEM_mallocN(sizeof(*tris) * size_t(tris_len), __func__)); memcpy(coords, BKE_mesh_vert_positions(mesh), sizeof(float[3]) * size_t(mesh->totvert)); - mloop = BKE_mesh_loops(mesh); + corner_verts = BKE_mesh_corner_verts(mesh); } { @@ -1177,9 +1177,9 @@ static PyObject *C_BVHTree_FromObject(PyObject * /*cls*/, PyObject *args, PyObje for (i = 0; i < tris_len; i++, lt++) { float co[3][3]; - tris[i][0] = mloop[lt->tri[0]].v; - tris[i][1] = mloop[lt->tri[1]].v; - tris[i][2] = mloop[lt->tri[2]].v; + tris[i][0] = (uint)corner_verts[lt->tri[0]]; + tris[i][1] = (uint)corner_verts[lt->tri[1]]; + tris[i][2] = (uint)corner_verts[lt->tri[2]]; copy_v3_v3(co[0], coords[tris[i][0]]); copy_v3_v3(co[1], coords[tris[i][1]]); diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index f114f5cd3b9..474ddf73038 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -464,7 +464,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval const blender::Span positions = me->vert_positions(); const blender::Span polys = me->polys(); - const blender::Span loops = me->loops(); + const blender::Span corner_verts = me->corner_verts(); const bke::AttributeAccessor attributes = me->attributes(); const VArray sharp_faces = attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); @@ -480,10 +480,10 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval if (!precomputed_normals.is_empty()) { blender::bke::mesh::looptris_calc_with_normals( - positions, polys, loops, precomputed_normals, {looptri, tottri}); + positions, polys, corner_verts, precomputed_normals, {looptri, tottri}); } else { - blender::bke::mesh::looptris_calc(positions, polys, loops, {looptri, tottri}); + blender::bke::mesh::looptris_calc(positions, polys, corner_verts, {looptri, tottri}); } const TSpace *tspace = nullptr; @@ -505,12 +505,12 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval const MLoopTri *lt = &looptri[i]; const MPoly &poly = polys[lt->poly]; - triangles[i].positions[0] = positions[loops[lt->tri[0]].v]; - triangles[i].positions[1] = positions[loops[lt->tri[1]].v]; - triangles[i].positions[2] = positions[loops[lt->tri[2]].v]; - 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].positions[0] = positions[corner_verts[lt->tri[0]]]; + triangles[i].positions[1] = positions[corner_verts[lt->tri[1]]]; + triangles[i].positions[2] = positions[corner_verts[lt->tri[2]]]; + triangles[i].vert_normals[0] = vert_normals[corner_verts[lt->tri[0]]]; + triangles[i].vert_normals[1] = vert_normals[corner_verts[lt->tri[1]]]; + triangles[i].vert_normals[2] = vert_normals[corner_verts[lt->tri[2]]]; triangles[i].is_smooth = !sharp_faces[lt->poly]; if (tangent) { @@ -527,8 +527,8 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval if (calculate_normal) { if (lt->poly != mpoly_prev) { - no = blender::bke::mesh::poly_normal_calc(positions, - loops.slice(poly.loopstart, poly.totloop)); + no = blender::bke::mesh::poly_normal_calc( + positions, corner_verts.slice(poly.loopstart, poly.totloop)); mpoly_prev = lt->poly; } copy_v3_v3(triangles[i].normal, no); @@ -752,7 +752,7 @@ void RE_bake_pixels_populate(Mesh *me, MLoopTri *looptri = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); blender::bke::mesh::looptris_calc( - me->vert_positions(), me->polys(), me->loops(), {looptri, tottri}); + me->vert_positions(), me->polys(), me->corner_verts(), {looptri, tottri}); const int *material_indices = BKE_mesh_material_indices(me); const int materials_num = targets->materials_num; diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 71fdfd54742..7e4921d6a70 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -65,8 +65,8 @@ struct MResolvePixelData { int verts_num; const MPoly *polys; const int *material_indices; + const int *corner_verts; const bool *sharp_faces; - MLoop *mloop; float (*mloopuv)[2]; float uv_offset[2]; const MLoopTri *mlooptri; @@ -119,7 +119,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, 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; + const int vi = data->corner_verts[data->mlooptri[tri_num].tri[vert_index]]; copy_v3_v3(r_normal, data->vert_normals[vi]); } else { @@ -131,7 +131,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, r_normal, blender::bke::mesh::poly_normal_calc( {reinterpret_cast(data->vert_positions), data->verts_num}, - {&data->mloop[poly.loopstart], poly.totloop})); + {&data->corner_verts[poly.loopstart], poly.totloop})); } } } @@ -480,9 +480,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, const float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); const MPoly *polys = dm->getPolyArray(dm); - MLoop *mloop = dm->getLoopArray(dm); float(*mloopuv)[2] = static_cast(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)); - float *pvtangent = nullptr; + float *pvtangent = NULL; ListBase threads; int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count(); @@ -496,7 +495,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, temp_mesh->totvert * sizeof(float[3])); temp_mesh->edges_for_write().copy_from({dm->getEdgeArray(dm), temp_mesh->totedge}); temp_mesh->polys_for_write().copy_from({dm->getPolyArray(dm), temp_mesh->totpoly}); - temp_mesh->loops_for_write().copy_from({dm->getLoopArray(dm), temp_mesh->totloop}); + temp_mesh->corner_verts_for_write().copy_from({dm->getCornerVertArray(dm), temp_mesh->totloop}); + temp_mesh->corner_edges_for_write().copy_from({dm->getCornerEdgeArray(dm), temp_mesh->totloop}); const blender::Span vert_normals = temp_mesh->vert_normals(); const blender::Span poly_normals = temp_mesh->poly_normals(); @@ -506,7 +506,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, positions, dm->getPolyArray(dm), dm->getNumPolys(dm), - dm->getLoopArray(dm), + dm->getCornerVertArray(dm), dm->getLoopTriArray(dm), dm->getNumLoopTri(dm), static_cast( @@ -565,7 +565,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, handle->data.mloopuv = mloopuv; BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); handle->data.mlooptri = mlooptri; - handle->data.mloop = mloop; + handle->data.corner_verts = dm->getCornerVertArray(dm); handle->data.pvtangent = pvtangent; handle->data.poly_normals = poly_normals.data(); /* don't strictly need this */ handle->data.w = ibuf->x; @@ -721,7 +721,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, * mode = 1: interpolate coord */ static void interp_bilinear_mpoly(DerivedMesh *dm, - MLoop *mloop, + const int *corner_verts, const MPoly &poly, const float u, const float v, @@ -731,23 +731,23 @@ static void interp_bilinear_mpoly(DerivedMesh *dm, float data[4][3]; if (mode == 0) { - dm->getVertNo(dm, mloop[poly.loopstart].v, data[0]); - dm->getVertNo(dm, mloop[poly.loopstart + 1].v, data[1]); - dm->getVertNo(dm, mloop[poly.loopstart + 2].v, data[2]); - dm->getVertNo(dm, mloop[poly.loopstart + 3].v, data[3]); + dm->getVertNo(dm, corner_verts[poly.loopstart], data[0]); + dm->getVertNo(dm, corner_verts[poly.loopstart + 1], data[1]); + dm->getVertNo(dm, corner_verts[poly.loopstart + 2], data[2]); + dm->getVertNo(dm, corner_verts[poly.loopstart + 3], data[3]); } else { - dm->getVertCo(dm, mloop[poly.loopstart].v, data[0]); - dm->getVertCo(dm, mloop[poly.loopstart + 1].v, data[1]); - dm->getVertCo(dm, mloop[poly.loopstart + 2].v, data[2]); - dm->getVertCo(dm, mloop[poly.loopstart + 3].v, data[3]); + dm->getVertCo(dm, corner_verts[poly.loopstart], data[0]); + dm->getVertCo(dm, corner_verts[poly.loopstart + 1], data[1]); + dm->getVertCo(dm, corner_verts[poly.loopstart + 2], data[2]); + dm->getVertCo(dm, corner_verts[poly.loopstart + 3], data[3]); } interp_bilinear_quad_v3(data, u, v, res); } static void interp_barycentric_mlooptri(DerivedMesh *dm, - MLoop *mloop, + const int *corner_verts, const MLoopTri *lt, const float u, const float v, @@ -757,14 +757,14 @@ static void interp_barycentric_mlooptri(DerivedMesh *dm, float data[3][3]; if (mode == 0) { - dm->getVertNo(dm, mloop[lt->tri[0]].v, data[0]); - dm->getVertNo(dm, mloop[lt->tri[1]].v, data[1]); - dm->getVertNo(dm, mloop[lt->tri[2]].v, data[2]); + dm->getVertNo(dm, corner_verts[lt->tri[0]], data[0]); + dm->getVertNo(dm, corner_verts[lt->tri[1]], data[1]); + dm->getVertNo(dm, corner_verts[lt->tri[2]], data[2]); } else { - dm->getVertCo(dm, mloop[lt->tri[0]].v, data[0]); - dm->getVertCo(dm, mloop[lt->tri[1]].v, data[1]); - dm->getVertCo(dm, mloop[lt->tri[2]].v, data[2]); + dm->getVertCo(dm, corner_verts[lt->tri[0]], data[0]); + dm->getVertCo(dm, corner_verts[lt->tri[1]], data[1]); + dm->getVertCo(dm, corner_verts[lt->tri[2]], data[2]); } interp_barycentric_tri_v3(data, u, v, res); @@ -840,7 +840,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, const int y) { const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; - MLoop *mloop = lores_dm->getLoopArray(lores_dm); + const int *corner_verts = lores_dm->getCornerVertArray(lores_dm); const MPoly &poly = lores_dm->getPolyArray(lores_dm)[lt->poly]; float(*mloopuv)[2] = static_cast( lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2)); @@ -884,12 +884,12 @@ static void apply_heights_callback(DerivedMesh *lores_dm, } else { if (poly.totloop == 4) { - interp_bilinear_mpoly(lores_dm, mloop, poly, uv[0], uv[1], 1, p0); - interp_bilinear_mpoly(lores_dm, mloop, poly, uv[0], uv[1], 0, n); + interp_bilinear_mpoly(lores_dm, corner_verts, poly, uv[0], uv[1], 1, p0); + interp_bilinear_mpoly(lores_dm, corner_verts, poly, uv[0], uv[1], 0, n); } else { - interp_barycentric_mlooptri(lores_dm, mloop, lt, uv[0], uv[1], 1, p0); - interp_barycentric_mlooptri(lores_dm, mloop, lt, uv[0], uv[1], 0, n); + interp_barycentric_mlooptri(lores_dm, corner_verts, lt, uv[0], uv[1], 1, p0); + interp_barycentric_mlooptri(lores_dm, corner_verts, lt, uv[0], uv[1], 0, n); } } diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index 12c370131bb..84b337282de 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -55,7 +55,7 @@ class TextureMarginMap { char *mask_; Span polys_; - Span mloop_; + Span corner_edges_; Span mloopuv_; int totedge_; @@ -65,9 +65,14 @@ class TextureMarginMap { const float uv_offset[2], const int totedge, const Span polys, - const Span mloop, + const Span corner_edges, const Span mloopuv) - : w_(w), h_(h), polys_(polys), mloop_(mloop), mloopuv_(mloopuv), totedge_(totedge) + : w_(w), + h_(h), + polys_(polys), + corner_edges_(corner_edges), + mloopuv_(mloopuv), + totedge_(totedge) { copy_v2_v2(uv_offset_, uv_offset); @@ -279,15 +284,16 @@ class TextureMarginMap { void build_tables() { - loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(polys_, mloop_.size()); + loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(polys_, + corner_edges_.size()); - loop_adjacency_map_.resize(mloop_.size(), -1); + loop_adjacency_map_.resize(corner_edges_.size(), -1); Vector tmpmap; tmpmap.resize(totedge_, -1); - for (const int64_t i : mloop_.index_range()) { - int edge = mloop_[i].e; + for (const int64_t i : corner_edges_.index_range()) { + int edge = corner_edges_[i]; if (tmpmap[edge] == -1) { loop_adjacency_map_[i] = -1; tmpmap[edge] = i; @@ -472,14 +478,14 @@ static void generate_margin(ImBuf *ibuf, const Span vert_positions, const int edges_num, const Span polys, - const Span loops, + const Span corner_edges, const Span mloopuv, const float uv_offset[2]) { - Array looptris(poly_to_tri_count(polys.size(), loops.size())); - bke::mesh::looptris_calc(vert_positions, polys, loops, looptris); + Array looptris(poly_to_tri_count(polys.size(), corner_edges.size())); + bke::mesh::looptris_calc(vert_positions, polys, corner_edges, looptris); - TextureMarginMap map(ibuf->x, ibuf->y, uv_offset, edges_num, polys, loops, mloopuv); + TextureMarginMap map(ibuf->x, ibuf->y, uv_offset, edges_num, polys, corner_edges, mloopuv); bool draw_new_mask = false; /* Now the map contains 3 sorts of values: 0xFFFFFFFF for empty pixels, `0x80000000 + polyindex` @@ -559,7 +565,7 @@ void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf, mesh->vert_positions(), mesh->totedge, mesh->polys(), - mesh->loops(), + mesh->corner_edges(), {mloopuv, mesh->totloop}, uv_offset); } @@ -577,7 +583,7 @@ void RE_generate_texturemargin_adjacentfaces_dm( {reinterpret_cast(dm->getVertArray(dm)), dm->getNumVerts(dm)}, dm->getNumEdges(dm), {dm->getPolyArray(dm), dm->getNumPolys(dm)}, - {dm->getLoopArray(dm), dm->getNumLoops(dm)}, + {dm->getCornerEdgeArray(dm), dm->getNumLoops(dm)}, {mloopuv, dm->getNumLoops(dm)}, uv_offset); } diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index d8b9a1955f5..d342c7362bb 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -267,7 +267,7 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, Mesh *mesh, float *data_color) { - const MLoop *mloop = BKE_mesh_loops(mesh); + const int *corner_verts = BKE_mesh_corner_verts(mesh); const int totloop = mesh->totloop; char layername[MAX_CUSTOMDATA_LAYER_NAME]; int i; @@ -288,7 +288,7 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, int *mcorners = MEM_callocN(sizeof(int) * pd->totpoints, "point density corner count"); for (i = 0; i < totloop; i++) { - int v = mloop[i].v; + int v = corner_verts[i]; if (mcorners[v] == 0) { rgb_uchar_to_float(&data_color[v * 3], &mcol[i].r);