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);