Mesh: Replace MPoly struct with offset indices

Implements #95967.

Currently the `MPoly` struct is 12 bytes, and stores the index of a
face's first corner and the number of corners/verts/edges. Polygons
and corners are always created in order by Blender, meaning each
face's corners will be after the previous face's corners. We can take
advantage of this fact and eliminate the redundancy in mesh face
storage by only storing a single integer corner offset for each face.
The size of the face is then encoded by the offset of the next face.
The size of a single integer is 4 bytes, so this reduces memory
usage by 3 times.

The same method is used for `CurvesGeometry`, so Blender already has
an abstraction to simplify using these offsets called `OffsetIndices`.
This class is used to easily retrieve a range of corner indices for
each face. This also gives the opportunity for sharing some logic with
curves.

Another benefit of the change is that the offsets and sizes stored in
`MPoly` can no longer disagree with each other. Storing faces in the
order of their corners can simplify some code too.

Face/polygon variables now use the `IndexRange` type, which comes with
quite a few utilities that can simplify code.

Some:
- The offset integer array has to be one longer than the face count to
  avoid a branch for every face, which means the data is no longer part
  of the mesh's `CustomData`.
- We lose the ability to "reference" an original mesh's offset array
  until more reusable CoW from #104478 is committed. That will be added
  in a separate commit.
- Since they aren't part of `CustomData`, poly offsets often have to be
  copied manually.
- To simplify using `OffsetIndices` in many places, some functions and
  structs in headers were moved to only compile in C++.
- All meshes created by Blender use the same order for faces and face
  corners, but just in case, meshes with mismatched order are fixed by
  versioning code.
- `MeshPolygon.totloop` is no longer editable in RNA. This API break is
  necessary here unfortunately. It should be worth it in 3.6, since
  that's the best way to allow loading meshes from 4.0, which is
  important for an LTS version.

Pull Request: blender/blender#105938
This commit is contained in:
2023-04-04 20:39:28 +02:00
committed by Hans Goudey
parent 17800e0c03
commit 7966cd16d6
209 changed files with 2769 additions and 2983 deletions
+23 -19
View File
@@ -246,11 +246,12 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
if (polys_num == 0) {
return;
}
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
const int *poly_offsets = static_cast<const int *>(b_mesh.polygons[0].ptr.data);
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
for (int j = 0; j < b_poly.totloop; j++) {
*data = get_value_at_index(b_poly.loopstart + j);
const int poly_start = poly_offsets[i];
const int poly_size = poly_offsets[i + 1] - poly_start;
for (int j = 0; j < poly_size; j++) {
*data = get_value_at_index(poly_start + j);
data++;
}
}
@@ -600,7 +601,7 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
if (polys_num == 0) {
return;
}
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
const int *poly_offsets = static_cast<const int *>(b_mesh.polygons[0].ptr.data);
if (!b_mesh.uv_layers.empty()) {
BL::Mesh::uv_layers_iterator l;
@@ -636,9 +637,10 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
float2 *fdata = uv_attr->data_float2();
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
for (int j = 0; j < b_poly.totloop; j++) {
*(fdata++) = get_float2(l->data[b_poly.loopstart + j].uv());
const int poly_start = poly_offsets[i];
const int poly_size = poly_offsets[i + 1] - poly_start;
for (int j = 0; j < poly_size; j++) {
*(fdata++) = get_float2(l->data[poly_start + j].uv());
}
}
}
@@ -910,10 +912,9 @@ static void attr_create_random_per_island(Scene *scene,
else {
const int polys_num = b_mesh.polygons.length();
if (polys_num != 0) {
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
const int *poly_offsets = static_cast<const int *>(b_mesh.polygons[0].ptr.data);
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
const int vert = corner_verts[b_poly.loopstart];
const int vert = corner_verts[poly_offsets[i]];
data[i] = hash_uint_to_float(vertices_sets.find(vert));
}
}
@@ -1000,10 +1001,11 @@ static void create_mesh(Scene *scene,
numtris = numfaces;
}
else {
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
const int *poly_offsets = static_cast<const int *>(b_mesh.polygons[0].ptr.data);
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
numngons += (b_poly.totloop == 4) ? 0 : 1;
const int poly_start = poly_offsets[i];
const int poly_size = poly_offsets[i + 1] - poly_start;
numngons += (poly_size == 4) ? 0 : 1;
}
}
@@ -1132,14 +1134,16 @@ static void create_mesh(Scene *scene,
std::copy(corner_verts, corner_verts + numcorners, subd_face_corners);
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
const int *poly_offsets = static_cast<const int *>(b_mesh.polygons[0].ptr.data);
int ptex_offset = 0;
for (int i = 0; i < numfaces; i++) {
const MPoly &b_poly = polys[i];
subd_start_corner[i] = b_poly.loopstart;
subd_num_corners[i] = b_poly.totloop;
const int poly_start = poly_offsets[i];
const int poly_size = poly_offsets[i + 1] - poly_start;
subd_start_corner[i] = poly_start;
subd_num_corners[i] = poly_size;
subd_ptex_offset[i] = ptex_offset;
const int num_ptex = (b_poly.totloop == 4) ? 1 : b_poly.totloop;
const int num_ptex = (poly_size == 4) ? 1 : poly_size;
ptex_offset += num_ptex;
}
+6 -4
View File
@@ -68,10 +68,10 @@ struct Scene;
/*
* NOTE: all #MFace interfaces now officially operate on tessellated data.
* Also, the #MFace orig-index layer indexes #MPoly, not #MFace.
* Also, the #MFace orig-index layer indexes polys, not #MFace.
*/
/* keep in sync with MFace/MPoly types */
/* keep in sync with MFace type */
typedef struct DMFlagMat {
short mat_nr;
bool sharp;
@@ -90,6 +90,8 @@ struct DerivedMesh {
int needsFree; /* checked on ->release, is set to 0 for cached results */
int deformedOnly; /* set by modifier stack if only deformed from original */
DerivedMeshType type;
/* Always owned by this object. */
int *poly_offsets;
short tangent_mask; /* which tangent layers are calculated */
@@ -113,7 +115,7 @@ struct DerivedMesh {
struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
int *(*getCornerVertArray)(DerivedMesh *dm);
int *(*getCornerEdgeArray)(DerivedMesh *dm);
struct MPoly *(*getPolyArray)(DerivedMesh *dm);
int *(*getPolyArray)(DerivedMesh *dm);
/** Copy all verts/edges/faces from the derived mesh into
* *{vert/edge/face}_r (must point to a buffer large enough)
@@ -122,7 +124,7 @@ struct DerivedMesh {
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge);
void (*copyCornerVertArray)(DerivedMesh *dm, int *r_corner_verts);
void (*copyCornerEdgeArray)(DerivedMesh *dm, int *r_corner_edges);
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly);
void (*copyPolyArray)(DerivedMesh *dm, int *r_poly_offsets);
/** Return a pointer to the entire array of vert/edge/face custom data
* from the derived mesh (this gives a pointer to the actual data, not
+10 -3
View File
@@ -3,6 +3,10 @@
#pragma once
#ifdef __cplusplus
# include "BLI_offset_indices.hh"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -18,7 +22,6 @@ struct ID;
struct ListBase;
struct MDeformVert;
struct MEdge;
struct MPoly;
struct Object;
struct bDeformGroup;
@@ -273,16 +276,20 @@ void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert,
int loops_num,
bool invert_vgroup,
float *r_weights);
#ifdef __cplusplus
void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert,
int defgroup,
int verts_num,
const int *corner_verts,
int loops_num,
const struct MPoly *polys,
int polys_num,
blender::OffsetIndices<int> polys,
bool invert_vgroup,
float *r_weights);
#endif
void BKE_defvert_weight_to_rgb(float r_rgb[3], float weight);
void BKE_defvert_blend_write(struct BlendWriter *writer,
+16 -11
View File
@@ -34,7 +34,6 @@ struct MDisps;
struct MEdge;
struct MFace;
struct MLoopTri;
struct MPoly;
struct Main;
struct MemArena;
struct Mesh;
@@ -142,6 +141,9 @@ void BKE_mesh_copy_parameters_for_eval(struct Mesh *me_dst, const struct Mesh *m
void BKE_mesh_copy_parameters(struct Mesh *me_dst, const struct Mesh *me_src);
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
/** Add poly offsets to describe faces to a new mesh. */
void BKE_mesh_poly_offsets_ensure_alloc(struct Mesh *mesh);
struct Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys_len);
struct Mesh *BKE_mesh_new_nomain_from_template(
const struct Mesh *me_src, int verts_len, int edges_len, int loops_len, int polys_len);
@@ -298,7 +300,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 int *corner_verts,
const struct MPoly *polys,
const int *poly_offsets,
const float (*vert_positions)[3],
int totvert,
int totloop,
@@ -565,24 +567,27 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip);
* \param mloop: the full loops array.
* \param ldata: the loops custom data.
*/
void BKE_mesh_polygon_flip_ex(const struct MPoly *poly,
void BKE_mesh_polygon_flip_ex(int poly_offset,
int poly_size,
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,
void BKE_mesh_polygon_flip(int poly_offset,
int poly_size,
int *corner_verts,
int *corner_edges,
struct CustomData *ldata,
int totloop);
/**
* Flip (invert winding of) all polygons (used to inverse their normals).
*
* \note Invalidates tessellation, caller must handle that.
*/
void BKE_mesh_polys_flip(const struct MPoly *polys,
void BKE_mesh_polys_flip(const int *poly_offsets,
int *corner_verts,
int *corner_edges,
struct CustomData *ldata,
@@ -619,7 +624,7 @@ void BKE_mesh_flush_select_from_verts(struct Mesh *me);
* \param vert_cos_org: reference for the output location.
* \param vert_cos_new: resulting coords.
*/
void BKE_mesh_calc_relative_deform(const struct MPoly *polys,
void BKE_mesh_calc_relative_deform(const int *poly_offsets,
int totpoly,
const int *corner_verts,
int totvert,
@@ -674,7 +679,7 @@ bool BKE_mesh_validate_arrays(struct Mesh *me,
int *corner_verts,
int *corner_edges,
unsigned int totloop,
struct MPoly *polys,
int *poly_offsets,
unsigned int totpoly,
struct MDeformVert *dverts, /* assume totvert length */
bool do_verbose,
@@ -780,13 +785,13 @@ BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh)
return (MEdge *)CustomData_get_layer_for_write(&mesh->edata, CD_MEDGE, mesh->totedge);
}
BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh)
BLI_INLINE const int *BKE_mesh_poly_offsets(const Mesh *mesh)
{
return (const MPoly *)CustomData_get_layer(&mesh->pdata, CD_MPOLY);
return mesh->poly_offset_indices;
}
BLI_INLINE MPoly *BKE_mesh_polys_for_write(Mesh *mesh)
BLI_INLINE int *BKE_mesh_poly_offsets_for_write(Mesh *mesh)
{
return (MPoly *)CustomData_get_layer_for_write(&mesh->pdata, CD_MPOLY, mesh->totpoly);
return mesh->poly_offset_indices;
}
BLI_INLINE const int *BKE_mesh_corner_verts(const Mesh *mesh)
+30 -20
View File
@@ -21,7 +21,7 @@ float3 poly_normal_calc(Span<float3> vert_positions, Span<int> poly_verts);
* Calculate tessellation into #MLoopTri which exist only for this purpose.
*/
void looptris_calc(Span<float3> vert_positions,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
MutableSpan<MLoopTri> looptris);
/**
@@ -32,7 +32,7 @@ void looptris_calc(Span<float3> vert_positions,
* to calculate normals just to use this function.
*/
void looptris_calc_with_normals(Span<float3> vert_positions,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
Span<float3> poly_normals,
MutableSpan<MLoopTri> looptris);
@@ -61,7 +61,7 @@ void poly_angles_calc(Span<float3> vert_positions,
* since they may already be calculated and cached on the mesh.
*/
void normals_calc_polys(Span<float3> vert_positions,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
MutableSpan<float3> poly_normals);
@@ -72,7 +72,7 @@ void normals_calc_polys(Span<float3> vert_positions,
* since they may already be calculated and cached on the mesh.
*/
void normals_calc_poly_vert(Span<float3> vert_positions,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
MutableSpan<float3> poly_normals,
MutableSpan<float3> vert_normals);
@@ -88,7 +88,7 @@ void normals_calc_poly_vert(Span<float3> vert_positions,
*/
void normals_calc_loop(Span<float3> vert_positions,
Span<MEdge> edges,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
Span<int> corner_edges,
Span<int> loop_to_poly_map,
@@ -104,7 +104,7 @@ void normals_calc_loop(Span<float3> vert_positions,
void normals_loop_custom_set(Span<float3> vert_positions,
Span<MEdge> edges,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
@@ -116,7 +116,7 @@ void normals_loop_custom_set(Span<float3> vert_positions,
void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
Span<MEdge> edges,
Span<MPoly> polys,
OffsetIndices<int> polys,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
@@ -134,7 +134,7 @@ void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
*
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void edges_sharp_from_angle_set(Span<MPoly> polys,
void edges_sharp_from_angle_set(OffsetIndices<int> polys,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> poly_normals,
@@ -152,19 +152,19 @@ void edges_sharp_from_angle_set(Span<MPoly> polys,
* Find the index of the next corner in the polygon, looping to the start if necessary.
* The indices are into the entire corners array, not just the polygon's corners.
*/
inline int poly_corner_prev(const MPoly &poly, const int corner)
inline int poly_corner_prev(const IndexRange poly, const int corner)
{
return corner - 1 + (corner == poly.loopstart) * poly.totloop;
return corner - 1 + (corner == poly.start()) * poly.size();
}
/**
* Find the index of the previous corner in the polygon, looping to the end if necessary.
* The indices are into the entire corners array, not just the polygon's corners.
*/
inline int poly_corner_next(const MPoly &poly, const int corner)
inline int poly_corner_next(const IndexRange poly, const int corner)
{
if (corner == poly.loopstart + poly.totloop - 1) {
return poly.loopstart;
if (corner == poly.last()) {
return poly.start();
}
return corner + 1;
}
@@ -173,18 +173,18 @@ inline int poly_corner_next(const MPoly &poly, const int corner)
* Find the index of the corner in the polygon that uses the given vertex.
* The index is into the entire corners array, not just the polygon's corners.
*/
inline int poly_find_corner_from_vert(const MPoly &poly,
inline int poly_find_corner_from_vert(const IndexRange poly,
const Span<int> corner_verts,
const int vert)
{
return poly.loopstart + corner_verts.slice(poly.loopstart, poly.totloop).first_index(vert);
return poly[corner_verts.slice(poly).first_index(vert)];
}
/**
* Return the vertex indices on either side of the given vertex, ordered based on the winding
* direction of the polygon. The vertex must be in the polygon.
*/
inline int2 poly_find_adjecent_verts(const MPoly &poly,
inline int2 poly_find_adjecent_verts(const IndexRange poly,
const Span<int> corner_verts,
const int vert)
{
@@ -235,13 +235,23 @@ inline blender::MutableSpan<MEdge> Mesh::edges_for_write()
return {BKE_mesh_edges_for_write(this), this->totedge};
}
inline blender::Span<MPoly> Mesh::polys() const
inline blender::OffsetIndices<int> Mesh::polys() const
{
return {BKE_mesh_polys(this), this->totpoly};
return blender::Span(BKE_mesh_poly_offsets(this), this->totpoly + 1);
}
inline blender::MutableSpan<MPoly> Mesh::polys_for_write()
inline blender::Span<int> Mesh::poly_offsets() const
{
return {BKE_mesh_polys_for_write(this), this->totpoly};
if (this->totpoly == 0) {
return {};
}
return {BKE_mesh_poly_offsets(this), this->totpoly + 1};
}
inline blender::MutableSpan<int> Mesh::poly_offsets_for_write()
{
if (this->totpoly == 0) {
return {};
}
return {BKE_mesh_poly_offsets_for_write(this), this->totpoly + 1};
}
inline blender::Span<int> Mesh::corner_verts() const
@@ -13,11 +13,9 @@
# include "BLI_resource_scope.hh"
# include "BLI_span.hh"
# include "BLI_vector.hh"
# include "DNA_customdata_types.h"
#endif
#ifdef __cplusplus
extern "C" {
# include "DNA_customdata_types.h"
# include "DNA_meshdata_types.h"
#endif
struct CustomData;
@@ -63,7 +61,8 @@ void BKE_mesh_legacy_bevel_weight_to_layers(struct Mesh *mesh);
/**
* Convert the hidden element attributes to the old flag format for writing.
*/
void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
/**
* Convert the old hide flags (#ME_HIDE) to the hidden element attribute for reading.
* Only add the attributes when there are any elements in each domain hidden.
@@ -73,7 +72,8 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh);
/**
* Convert the selected element attributes to the old flag format for writing.
*/
void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
/**
* Convert the old selection flags (#SELECT/#ME_FACE_SEL) to the selected element attribute for
* reading. Only add the attributes when there are any elements in each domain selected.
@@ -83,7 +83,8 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(struct Mesh *mesh);
/**
* Move material indices from a generic attribute to #MPoly.
*/
void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh);
void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
/**
* Move material indices from the #MPoly struct to a generic attributes.
* Only add the attribute when the indices are not all zero.
@@ -96,7 +97,8 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh);
void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh);
void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_faces_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_faces_to_flags(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
void BKE_mesh_legacy_sharp_faces_from_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh);
@@ -117,10 +119,21 @@ struct MLoop *BKE_mesh_legacy_convert_corners_to_loops(
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write);
#endif
blender::MutableSpan<MPoly> BKE_mesh_legacy_convert_offsets_to_polys(
const Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &poly_layers_to_write);
void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh);
void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh);
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* Recreate #MFace Tessellation.
*
+32 -30
View File
@@ -8,6 +8,7 @@
#ifdef __cplusplus
# include "BLI_array.hh"
# include "BLI_offset_indices.hh"
#endif
#ifdef __cplusplus
@@ -16,7 +17,6 @@ extern "C" {
struct MEdge;
struct MLoopTri;
struct MPoly;
/* UvVertMap */
#define STD_UV_CONNECT_LIMIT 0.0001f
@@ -98,21 +98,27 @@ typedef struct MeshElemMap {
int count;
} MeshElemMap;
#ifdef __cplusplus
/* mapping */
UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *polys,
UvVertMap *BKE_mesh_uv_vert_map_create(blender::OffsetIndices<int> polys,
const bool *hide_poly,
const bool *select_poly,
const int *corner_verts,
const float (*mloopuv)[2],
unsigned int totpoly,
unsigned int totvert,
const float limit[2],
bool selected,
bool use_winding);
#endif
UvMapVert *BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v);
void BKE_mesh_uv_vert_map_free(UvVertMap *vmap);
#ifdef __cplusplus
/**
* Generates a map where the key is the vertex and the value
* is a list of polys that use that vertex as a corner.
@@ -120,11 +126,9 @@ 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,
blender::OffsetIndices<int> polys,
const int *corner_verts,
int totvert,
int totpoly,
int totloop);
int totvert);
/**
* Generates a map where the key is the vertex and the value
* is a list of loops that use that vertex as a corner.
@@ -132,11 +136,12 @@ 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,
blender::OffsetIndices<int> polys,
const int *corner_verts,
int totvert,
int totpoly,
int totloop);
int totvert);
#endif
/**
* Generates a map where the key is the edge and the value
* is a list of looptris that use that edge.
@@ -162,6 +167,9 @@ void BKE_mesh_vert_edge_map_create(
*/
void BKE_mesh_vert_edge_vert_map_create(
MeshElemMap **r_map, int **r_mem, const struct MEdge *edges, int totvert, int totedge);
#ifdef __cplusplus
/**
* Generates a map where the key is the edge and the value is a list of loops that use that edge.
* Loops indices of a same poly are contiguous and in winding order.
@@ -170,8 +178,7 @@ void BKE_mesh_vert_edge_vert_map_create(
void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
int **r_mem,
int totedge,
const struct MPoly *polys,
int totpoly,
blender::OffsetIndices<int> polys,
const int *corner_edges,
int totloop);
/**
@@ -182,8 +189,7 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
int **r_mem,
int totedge,
const struct MPoly *polys,
int totpoly,
blender::OffsetIndices<int> polys,
const int *corner_edges,
int totloop);
/**
@@ -198,7 +204,7 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
*
* \note `totsource` could be `totpoly`,
* `totfinal` could be `tottessface` and `final_origindex` its ORIGINDEX custom-data.
* This would allow an MPoly to loop over its tessfaces.
* This would allow a poly to loop over its tessfaces.
*/
void BKE_mesh_origindex_map_create(
MeshElemMap **r_map, int **r_mem, int totsource, const int *final_origindex, int totfinal);
@@ -208,8 +214,7 @@ void BKE_mesh_origindex_map_create(
*/
void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
int **r_mem,
const struct MPoly *polys,
int polys_num,
blender::OffsetIndices<int> polys,
const struct MLoopTri *looptri,
int looptri_num);
@@ -260,8 +265,7 @@ typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3],
const struct MEdge *edges,
int totedge,
const bool *uv_seams,
const struct MPoly *polys,
int totpoly,
blender::OffsetIndices<int> polys,
const int *corner_verts,
const int *corner_edges,
int totloop,
@@ -279,8 +283,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
const struct MEdge *edges,
int totedge,
const bool *uv_seams,
const struct MPoly *polys,
int totpoly,
blender::OffsetIndices<int> polys,
const int *corner_verts,
const int *corner_edges,
int totloop,
@@ -304,14 +307,15 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
struct MEdge *edges,
int totedge,
const bool *uv_seams,
struct MPoly *polys,
int totpoly,
blender::OffsetIndices<int> polys,
const int *corner_verts,
const int *corner_edges,
int totloop,
const float (*luvs)[2],
MeshIslandStore *r_island_store);
#endif
/**
* Calculate smooth groups from sharp edges.
*
@@ -321,7 +325,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
* Note it's callers's responsibility to MEM_freeN returned array.
*/
int *BKE_mesh_calc_smoothgroups(int totedge,
const struct MPoly *polys,
const int *poly_offsets,
int totpoly,
const int *corner_edges,
int totloop,
@@ -346,19 +350,17 @@ int *BKE_mesh_calc_smoothgroups(int totedge,
#ifdef __cplusplus
# include "DNA_meshdata_types.h" /* MPoly */
namespace blender::bke::mesh_topology {
Array<int> build_loop_to_poly_map(Span<MPoly> polys, int loops_num);
Array<int> build_loop_to_poly_map(OffsetIndices<int> polys);
Array<Vector<int>> build_vert_to_edge_map(Span<MEdge> edges, int verts_num);
Array<Vector<int>> build_vert_to_poly_map(Span<MPoly> polys,
Array<Vector<int>> build_vert_to_poly_map(OffsetIndices<int> polys,
Span<int> corner_verts,
int verts_num);
Array<Vector<int>> build_vert_to_loop_map(Span<int> corner_verts, int verts_num);
Array<Vector<int>> build_edge_to_loop_map(Span<int> corner_edges, int edges_num);
Array<Vector<int, 2>> build_edge_to_poly_map(Span<MPoly> polys,
Array<Vector<int, 2>> build_edge_to_poly_map(OffsetIndices<int> polys,
Span<int> corner_edges,
int edges_num);
Vector<Vector<int>> build_edge_to_loop_map_resizable(Span<int> corner_edges, int edges_num);
+12 -6
View File
@@ -6,6 +6,10 @@
* \ingroup bke
*/
#ifdef __cplusplus
# include "BLI_offset_indices.hh"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -193,6 +197,12 @@ void BKE_mesh_remap_calc_edges_from_mesh(int mode,
struct Mesh *me_dst,
MeshPairRemap *r_map);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
void BKE_mesh_remap_calc_loops_from_mesh(int mode,
const struct SpaceTransform *space_transform,
float max_dist,
@@ -205,8 +215,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode,
const int *corner_verts_dst,
const int *corner_edges_dst,
int numloops_dst,
const struct MPoly *polys_dst,
int numpolys_dst,
const blender::OffsetIndices<int> polys_dst,
struct CustomData *ldata_dst,
bool use_split_nors_dst,
float split_angle_dst,
@@ -224,11 +233,8 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode,
const float (*vert_positions_dst)[3],
int numverts_dst,
const int *corner_verts,
const struct MPoly *polys_dst,
int numpolys_dst,
const blender::OffsetIndices<int> polys_dst,
const struct Mesh *me_src,
struct MeshPairRemap *r_map);
#ifdef __cplusplus
}
#endif
+19 -8
View File
@@ -6,9 +6,11 @@
*/
#ifdef __cplusplus
extern "C" {
# include "BLI_offset_indices.hh"
#endif
#ifdef __cplusplus
struct ReportList;
/**
@@ -25,9 +27,15 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
const float (*loop_normals)[3],
const float (*loopuv)[2],
int numLoops,
const struct MPoly *polys,
int numPolys,
blender::OffsetIndices<int> polys,
struct ReportList *reports);
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* Wrapper around BKE_mesh_calc_loop_tangent_single_ex, which takes care of most boilerplate code.
* \note
@@ -39,12 +47,17 @@ void BKE_mesh_calc_loop_tangent_single(struct Mesh *mesh,
float (*r_looptangents)[4],
struct ReportList *reports);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
/**
* See: #BKE_editmesh_loop_tangent_calc (matching logic).
*/
void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const struct MPoly *polys,
uint polys_len,
blender::OffsetIndices<int> polys,
const int *corner_verts,
const struct MLoopTri *looptri,
uint looptri_len,
@@ -74,7 +87,7 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(struct CustomData *uv_data,
int numLoopData,
const char *layer_name);
#define DM_TANGENT_MASK_ORCO (1 << 9)
# define DM_TANGENT_MASK_ORCO (1 << 9)
/**
* Here we get some useful information such as active uv layer name and
* search if it is already in tangent_names.
@@ -93,6 +106,4 @@ void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData,
char *rren_uv_name,
short *rtangent_mask);
#ifdef __cplusplus
}
#endif
+1 -3
View File
@@ -25,7 +25,6 @@ struct Scene;
struct SubdivCCG;
struct MLoopTri;
struct MPoly;
/**
* Delete mesh mdisps and grid paint masks.
@@ -154,8 +153,7 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float
/**
* Find per-corner coordinate with given per-face UV coord.
*/
int mdisp_rot_face_to_crn(
const struct MPoly *poly, int face_side, float u, float v, float *x, float *y);
int mdisp_rot_face_to_crn(int face_size, int face_side, float u, float v, float *x, float *y);
/* Reshaping, define in multires_reshape.cc */
+1 -1
View File
@@ -579,7 +579,7 @@ typedef struct SculptSession {
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
float (*vert_positions)[3];
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
blender::Span<int> corner_verts;
/* These contain the vertex and poly counts of the final mesh. */
+1 -1
View File
@@ -639,7 +639,7 @@ void psys_calc_dmcache(struct Object *ob,
* This is slow and can be optimized but only for many lookups.
*
* \param mesh_final: Final mesh, it may not have the same topology as original mesh.
* \param mesh_original: Original mesh, use for accessing #MPoly to #MFace mapping.
* \param mesh_original: Original mesh, use for accessing poly to #MFace mapping.
* \param findex_orig: The input tessface index.
* \param fw: Face weights (position of the particle inside the \a findex_orig tessface).
* \param poly_nodes: May be NULL, otherwise an array of linked list,
+11 -3
View File
@@ -10,6 +10,9 @@
#include "BLI_bitmap.h"
#include "BLI_compiler_compat.h"
#include "BLI_ghash.h"
#ifdef __cplusplus
# include "BLI_offset_indices.hh"
#endif
#include "bmesh.h"
@@ -30,7 +33,6 @@ struct CustomData;
struct DMFlagMat;
struct IsectRayPrecalc;
struct MLoopTri;
struct MPoly;
struct Mesh;
struct MeshElemMap;
struct PBVH;
@@ -280,6 +282,9 @@ typedef void (*BKE_pbvh_SearchNearestCallback)(PBVHNode *node, void *data, float
/* Building */
PBVH *BKE_pbvh_new(PBVHType type);
#ifdef __cplusplus
/**
* Do a full rebuild with on Mesh data structure.
*
@@ -288,7 +293,7 @@ PBVH *BKE_pbvh_new(PBVHType type);
*/
void BKE_pbvh_build_mesh(PBVH *pbvh,
struct Mesh *mesh,
const struct MPoly *polys,
blender::OffsetIndices<int> polys,
const int *corner_verts,
float (*vert_positions)[3],
int totvert,
@@ -297,6 +302,9 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
struct CustomData *pdata,
const struct MLoopTri *looptri,
int looptri_num);
#endif
/**
* Do a full rebuild with on Grids data structure.
*/
@@ -735,7 +743,7 @@ typedef struct PBVHFaceIter {
int cd_hide_poly_, cd_face_set_;
bool *hide_poly_;
int *face_sets_;
const struct MPoly *polys_;
const int *poly_offsets_;
const struct MLoopTri *looptri_;
const int *corner_verts_;
int prim_index_;
+1 -2
View File
@@ -30,7 +30,6 @@ struct BVHTree;
struct MDeformVert;
struct Mesh;
struct ModifierEvalContext;
struct MPoly;
struct Object;
struct ShrinkwrapGpencilModifierData;
struct ShrinkwrapModifierData;
@@ -73,7 +72,7 @@ typedef struct ShrinkwrapTreeData {
BVHTree *bvh;
BVHTreeFromMesh treeData;
const struct MPoly *polys;
const int *poly_offsets;
const float (*vert_normals)[3];
const int *corner_edges;
const float (*poly_normals)[3];
+15 -8
View File
@@ -11,6 +11,10 @@
#include "BLI_bitmap.h"
#include "BLI_sys_types.h"
#ifdef __cplusplus
# include "BLI_offset_indices.hh"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -20,7 +24,6 @@ struct CCGFace;
struct CCGKey;
struct DMFlagMat;
struct Mesh;
struct MPoly;
struct Subdiv;
/* --------------------------------------------------------------------
@@ -304,16 +307,20 @@ typedef enum SubdivCCGAdjacencyType {
SUBDIV_CCG_ADJACENT_EDGE,
} SubdivCCGAdjacencyType;
#ifdef __cplusplus
/* Returns if a grid coordinates is adjacent to a coarse mesh edge, vertex or nothing. If it is
* adjacent to an edge, r_v1 and r_v2 will be set to the two vertices of that edge. If it is
* 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 int *corner_verts,
int corners_num,
const struct MPoly *mpoly,
int *r_v1,
int *r_v2);
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
blender::Span<int> corner_verts,
blender::OffsetIndices<int> polys,
int *r_v1,
int *r_v2);
#endif
/* Get array which is indexed by face index and contains index of a first grid of the face.
*
@@ -63,7 +63,7 @@ void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
int poly_offset,
int loop_offset,
MutableSpan<float3> vert_positions,
MutableSpan<MPoly> polys,
MutableSpan<int> poly_offsets,
MutableSpan<int> corner_verts);
#endif
@@ -189,6 +189,7 @@ static CCGFace *_face_new(
byte *userData;
f->numVerts = numVerts;
BLI_assert(numVerts > 2);
f->fHDL = fHDL;
f->flags = 0;
+18 -22
View File
@@ -148,19 +148,13 @@ static int *dm_getCornerEdgeArray(DerivedMesh *dm)
return corner_edges;
}
static MPoly *dm_getPolyArray(DerivedMesh *dm)
static int *dm_getPolyArray(DerivedMesh *dm)
{
MPoly *mpoly = (MPoly *)CustomData_get_layer_for_write(
&dm->polyData, CD_MPOLY, dm->getNumPolys(dm));
if (!mpoly) {
mpoly = (MPoly *)CustomData_add_layer(
&dm->polyData, CD_MPOLY, CD_SET_DEFAULT, dm->getNumPolys(dm));
CustomData_set_layer_flag(&dm->polyData, CD_MPOLY, CD_FLAG_TEMPORARY);
dm->copyPolyArray(dm, mpoly);
if (!dm->poly_offsets) {
dm->poly_offsets = MEM_cnew_array<int>(dm->getNumPolys(dm) + 1, __func__);
dm->copyPolyArray(dm, dm->poly_offsets);
}
return mpoly;
return dm->poly_offsets;
}
void DM_init_funcs(DerivedMesh *dm)
@@ -220,6 +214,7 @@ void DM_from_template(DerivedMesh *dm,
CustomData_copy(&source->faceData, &dm->faceData, mask->fmask, CD_SET_DEFAULT, numTessFaces);
CustomData_copy(&source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
CustomData_copy(&source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
dm->poly_offsets = static_cast<int *>(MEM_dupallocN(source->poly_offsets));
dm->type = type;
dm->numVertData = numVerts;
@@ -235,6 +230,7 @@ void DM_from_template(DerivedMesh *dm,
bool DM_release(DerivedMesh *dm)
{
MEM_SAFE_FREE(dm->poly_offsets);
if (dm->needsFree) {
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
@@ -1835,7 +1831,7 @@ static void mesh_init_origspace(Mesh *mesh)
OrigSpaceLoop *lof_array = (OrigSpaceLoop *)CustomData_get_layer_for_write(
&mesh->ldata, CD_ORIGSPACE_MLOOP, mesh->totloop);
const Span<float3> positions = mesh->vert_positions();
const Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
int j, k;
@@ -1843,11 +1839,11 @@ static void mesh_init_origspace(Mesh *mesh)
blender::Vector<blender::float2, 64> vcos_2d;
for (const int i : polys.index_range()) {
const MPoly &poly = polys[i];
OrigSpaceLoop *lof = lof_array + poly.loopstart;
const blender::IndexRange poly = polys[i];
OrigSpaceLoop *lof = lof_array + poly.start();
if (ELEM(poly.totloop, 3, 4)) {
for (j = 0; j < poly.totloop; j++, lof++) {
if (ELEM(poly.size(), 3, 4)) {
for (j = 0; j < poly.size(); j++, lof++) {
copy_v2_v2(lof->uv, default_osf[j]);
}
}
@@ -1858,14 +1854,14 @@ static void mesh_init_origspace(Mesh *mesh)
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
const float3 p_nor = blender::bke::mesh::poly_normal_calc(
positions, corner_verts.slice(poly.loopstart, poly.totloop));
const float3 p_nor = blender::bke::mesh::poly_normal_calc(positions,
corner_verts.slice(poly));
axis_dominant_v3_to_m3(mat, p_nor);
vcos_2d.resize(poly.totloop);
for (j = 0; j < poly.totloop; j++) {
mul_v3_m3v3(co, mat, positions[corner_verts[poly.loopstart + j]]);
vcos_2d.resize(poly.size());
for (j = 0; j < poly.size(); j++) {
mul_v3_m3v3(co, mat, positions[corner_verts[poly[j]]]);
copy_v2_v2(vcos_2d[j], co);
for (k = 0; k < 2; k++) {
@@ -1893,7 +1889,7 @@ static void mesh_init_origspace(Mesh *mesh)
/* Finally, transform all vcos_2d into ((0, 0), (1, 1))
* square and assign them as origspace. */
for (j = 0; j < poly.totloop; j++, lof++) {
for (j = 0; j < poly.size(); j++, lof++) {
add_v2_v2v2(lof->uv, vcos_2d[j], translate);
mul_v2_v2(lof->uv, scale);
}
+2 -2
View File
@@ -1173,7 +1173,7 @@ static BitVector<> loose_edges_map_get(const Mesh &mesh, int *r_loose_edge_len)
return loose_edges.is_loose_bits;
}
static BitVector<> looptri_no_hidden_map_get(const Span<MPoly> polys,
static BitVector<> looptri_no_hidden_map_get(const blender::OffsetIndices<int> polys,
const VArray<bool> &hide_poly,
const int looptri_len,
int *r_looptri_active_len)
@@ -1186,7 +1186,7 @@ static BitVector<> looptri_no_hidden_map_get(const Span<MPoly> polys,
int looptri_no_hidden_len = 0;
int looptri_index = 0;
for (const int64_t i : polys.index_range()) {
const int triangles_num = ME_POLY_TRI_TOT(&polys[i]);
const int triangles_num = ME_POLY_TRI_TOT(polys[i].size());
if (hide_poly[i]) {
looptri_index += triangles_num;
}
@@ -44,7 +44,6 @@ struct CDDerivedMesh {
MFace *mface;
int *corner_verts;
int *corner_edges;
MPoly *mpoly;
/* Cached */
struct PBVH *pbvh;
@@ -100,10 +99,9 @@ static void cdDM_copyCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges)
memcpy(r_corner_edges, cddm->corner_edges, sizeof(*r_corner_edges) * dm->numLoopData);
}
static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
static void cdDM_copyPolyArray(DerivedMesh *dm, int *r_poly_offsets)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
memcpy(r_poly, cddm->mpoly, sizeof(*r_poly) * dm->numPolyData);
memcpy(r_poly_offsets, dm->poly_offsets, sizeof(int) * (dm->numPolyData + 1));
}
static void cdDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
@@ -213,8 +211,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
&dm->loopData, CD_PROP_INT32, ".corner_vert", mesh->totloop));
cddm->corner_edges = static_cast<int *>(CustomData_get_layer_named_for_write(
&dm->loopData, CD_PROP_INT32, ".corner_edge", mesh->totloop));
cddm->mpoly = static_cast<MPoly *>(
CustomData_get_layer_for_write(&dm->polyData, CD_MPOLY, mesh->totpoly));
dm->poly_offsets = static_cast<int *>(MEM_dupallocN(mesh->poly_offset_indices));
#if 0
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
#else
+18 -19
View File
@@ -1289,7 +1289,7 @@ void cloth_parallel_transport_hair_frame(float mat[3][3],
static bool cloth_add_shear_bend_spring(ClothModifierData *clmd,
LinkNodePair *edgelist,
const blender::Span<int> corner_verts,
const blender::Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
int i,
int j,
int k)
@@ -1307,8 +1307,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd,
return false;
}
spring_verts_ordered_set(
spring, corner_verts[polys[i].loopstart + j], corner_verts[polys[i].loopstart + k]);
spring_verts_ordered_set(spring, corner_verts[polys[i][j]], corner_verts[polys[i][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) *
@@ -1328,7 +1327,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd,
spring->type |= CLOTH_SPRING_TYPE_BENDING;
spring->la = k - j + 1;
spring->lb = polys[i].totloop - k + j + 1;
spring->lb = polys[i].size() - k + j + 1;
spring->pa = static_cast<int *>(MEM_mallocN(sizeof(*spring->pa) * spring->la, "spring poly"));
if (!spring->pa) {
@@ -1340,7 +1339,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd,
return false;
}
tmp_corner = &corner_verts[polys[i].loopstart];
tmp_corner = &corner_verts[polys[i].start()];
for (x = 0; x < spring->la; x++) {
spring->pa[x] = tmp_corner[j + x];
@@ -1350,7 +1349,7 @@ static bool cloth_add_shear_bend_spring(ClothModifierData *clmd,
spring->pb[x] = tmp_corner[x];
}
for (y = k; y < polys[i].totloop; x++, y++) {
for (y = k; y < polys[i].size(); x++, y++) {
spring->pb[x] = tmp_corner[y];
}
@@ -1476,7 +1475,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
uint numpolys = uint(mesh->totpoly);
float shrink_factor;
const blender::Span<MEdge> edges = mesh->edges();
const blender::Span<MPoly> polys = mesh->polys();
const OffsetIndices polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
const Span<int> corner_edges = mesh->corner_edges();
int index2 = 0; /* our second vertex index */
@@ -1671,8 +1670,8 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
for (int i = 0; i < numpolys; i++) {
/* Shear springs. */
/* Triangle faces already have shear springs due to structural geometry. */
if (polys[i].totloop > 3) {
for (int j = 1; j < polys[i].totloop - 1; j++) {
if (polys[i].size() > 3) {
for (int j = 1; j < polys[i].size() - 1; j++) {
if (j > 1) {
if (cloth_add_shear_bend_spring(clmd, edgelist, corner_verts, polys, i, 0, j)) {
shear_springs++;
@@ -1687,7 +1686,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
}
}
for (int k = j + 2; k < polys[i].totloop; k++) {
for (int k = j + 2; k < polys[i].size(); k++) {
if (cloth_add_shear_bend_spring(clmd, edgelist, corner_verts, polys, i, j, k)) {
shear_springs++;
@@ -1705,8 +1704,8 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
/* Angular bending springs along struct springs. */
if (clmd->sim_parms->bending_model == CLOTH_BENDING_ANGULAR) {
for (int j = 0; j < polys[i].totloop; j++) {
const int edge_i = corner_edges[polys[i].loopstart + j];
for (int j = 0; j < polys[i].size(); j++) {
const int edge_i = corner_edges[polys[i][j]];
BendSpringRef *curr_ref = &spring_ref[edge_i];
curr_ref->polys++;
@@ -1720,13 +1719,13 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
spring->type |= CLOTH_SPRING_TYPE_BENDING;
spring->la = polys[curr_ref->index].totloop;
spring->lb = polys[i].totloop;
spring->la = polys[curr_ref->index].size();
spring->lb = polys[i].size();
if (!cloth_bend_set_poly_vert_array(
&spring->pa, spring->la, &corner_verts[polys[curr_ref->index].loopstart]) ||
&spring->pa, spring->la, &corner_verts[polys[curr_ref->index].start()]) ||
!cloth_bend_set_poly_vert_array(
&spring->pb, spring->lb, &corner_verts[polys[i].loopstart])) {
&spring->pb, spring->lb, &corner_verts[polys[i].start()])) {
cloth_free_errorsprings(cloth, edgelist, spring_ref);
return false;
}
@@ -1897,11 +1896,11 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
}
for (int i = 0; i < numpolys; i++) { /* edge springs */
if (polys[i].totloop == 4) {
if (polys[i].size() == 4) {
BLI_edgeset_add(
edgeset, corner_verts[polys[i].loopstart + 0], corner_verts[polys[i].loopstart + 2]);
edgeset, corner_verts[polys[i].start() + 0], corner_verts[polys[i].start() + 2]);
BLI_edgeset_add(
edgeset, corner_verts[polys[i].loopstart + 1], corner_verts[polys[i].loopstart + 3]);
edgeset, corner_verts[polys[i].start() + 1], corner_verts[polys[i].start() + 3]);
}
}
@@ -189,16 +189,16 @@ 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<float3> positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
for (int i = 0; i < me->totpoly; i++) {
const MPoly &poly = polys[i];
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];
const IndexRange poly = polys[i];
const int *corner_vert_next = &corner_verts[poly.start()];
const int *corner_vert_curr = &corner_vert_next[poly.size() - 1];
const int *corner_vert_prev = &corner_vert_next[poly.size() - 2];
for (int j = 0; j < poly.totloop; j++) {
for (int j = 0; j < poly.size(); j++) {
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 */
@@ -30,7 +30,7 @@ static void fill_mesh_topology(const int vert_offset,
MutableSpan<MEdge> edges,
MutableSpan<int> corner_verts,
MutableSpan<int> corner_edges,
MutableSpan<MPoly> polys)
MutableSpan<int> poly_offsets)
{
const int main_segment_num = curves::segments_num(main_point_num, main_cyclic);
const int profile_segment_num = curves::segments_num(profile_point_num, profile_cyclic);
@@ -101,9 +101,7 @@ static void fill_mesh_topology(const int vert_offset,
const int main_edge_start = main_edges_start + main_segment_num * i_profile;
const int next_main_edge_start = main_edges_start + main_segment_num * i_next_profile;
MPoly &poly = polys[ring_poly_offset + i_profile];
poly.loopstart = ring_segment_loop_offset;
poly.totloop = 4;
poly_offsets[ring_poly_offset + i_profile] = ring_segment_loop_offset;
corner_verts[ring_segment_loop_offset] = ring_vert_offset + i_profile;
corner_edges[ring_segment_loop_offset] = ring_edge_start + i_profile;
@@ -125,12 +123,8 @@ static void fill_mesh_topology(const int vert_offset,
const int cap_loop_offset = loop_offset + poly_num * 4;
const int cap_poly_offset = poly_offset + poly_num;
MPoly &poly_start = polys[cap_poly_offset];
poly_start.loopstart = cap_loop_offset;
poly_start.totloop = profile_segment_num;
MPoly &poly_end = polys[cap_poly_offset + 1];
poly_end.loopstart = cap_loop_offset + profile_segment_num;
poly_end.totloop = profile_segment_num;
poly_offsets[cap_poly_offset] = cap_loop_offset;
poly_offsets[cap_poly_offset + 1] = cap_loop_offset + profile_segment_num;
const int last_ring_index = main_point_num - 1;
const int last_ring_vert_offset = vert_offset + profile_point_num * last_ring_index;
@@ -702,7 +696,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
mesh->smoothresh = DEG2RADF(180.0f);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MPoly> polys = mesh->polys_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
MutableSpan<int> corner_edges = mesh->corner_edges_for_write();
MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write();
@@ -720,7 +714,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
edges,
corner_verts,
corner_edges,
polys);
poly_offsets);
});
if (fill_caps) {
@@ -1768,7 +1768,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float[3]), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 24: CD_RECAST */
{sizeof(MRecast), "MRecast", 1, N_("Recast"), nullptr, nullptr, nullptr, nullptr},
/* 25: CD_MPOLY */
/* 25: CD_MPOLY */ /* DEPRECATED */
{sizeof(MPoly), "MPoly", 1, N_("NGon Face"), nullptr, nullptr, nullptr, nullptr, nullptr},
/* 26: CD_MLOOP */ /* DEPRECATED*/
{sizeof(MLoop),
@@ -2029,14 +2029,14 @@ const CustomData_MeshMasks CD_MASK_BAREMESH = {
/*vmask*/ CD_MASK_PROP_FLOAT3,
/*emask*/ CD_MASK_MEDGE,
/*fmask*/ 0,
/*pmask*/ CD_MASK_MPOLY | CD_MASK_FACEMAP,
/*pmask*/ CD_MASK_FACEMAP,
/*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,
/*pmask*/ CD_MASK_FACEMAP | CD_MASK_ORIGINDEX,
/*lmask*/ CD_MASK_PROP_INT32,
};
const CustomData_MeshMasks CD_MASK_MESH = {
@@ -2046,7 +2046,7 @@ const CustomData_MeshMasks CD_MASK_MESH = {
(CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT | CD_MASK_CREASE),
/*fmask*/ 0,
/*pmask*/
(CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
(CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
@@ -2086,8 +2086,8 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
CD_MASK_ORIGSPACE | CD_MASK_TANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_PREVIEW_MCOL |
CD_MASK_PROP_ALL),
/*pmask*/
(CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP |
CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE |
CD_MASK_PROP_ALL),
/*lmask*/
(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 |
@@ -1567,7 +1567,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<MEdge> edges_dst = me_dst->edges();
const blender::Span<MPoly> polys_dst = me_dst->polys();
const blender::OffsetIndices polys_dst = me_dst->polys();
const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
const blender::Span<int> corner_edges_dst = me_dst->corner_edges();
CustomData *ldata_dst = &me_dst->ldata;
@@ -1612,8 +1612,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
corner_verts_dst.data(),
corner_edges_dst.data(),
corner_verts_dst.size(),
polys_dst.data(),
polys_dst.size(),
polys_dst,
ldata_dst,
(me_dst->flag & ME_AUTOSMOOTH) != 0,
me_dst->smoothresh,
@@ -1668,7 +1667,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
const blender::Span<MPoly> polys_dst = me_dst->polys();
const blender::OffsetIndices polys_dst = me_dst->polys();
const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
if (!geom_map_init[PDATA]) {
@@ -1704,8 +1703,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
positions_dst,
num_verts_dst,
corner_verts_dst.data(),
polys_dst.data(),
polys_dst.size(),
polys_dst,
me_src,
&geom_map[PDATA]);
geom_map_init[PDATA] = true;
@@ -1713,14 +1711,13 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (mdef && vg_idx != -1 && !weights[PDATA]) {
weights[PDATA] = static_cast<float *>(
MEM_mallocN(sizeof(*weights[PDATA]) * size_t(polys_dst.size()), __func__));
MEM_mallocN(sizeof(*weights[PDATA]) * polys_dst.size(), __func__));
BKE_defvert_extract_vgroup_to_polyweights(mdef,
vg_idx,
num_verts_dst,
corner_verts_dst.data(),
corner_verts_dst.size(),
polys_dst.data(),
polys_dst.size(),
polys_dst,
invert_vgroup,
weights[PDATA]);
}
+7 -8
View File
@@ -1103,13 +1103,12 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
const int verts_num,
const int *corner_verts,
const int /*loops_num*/,
const MPoly *polys,
const int polys_num,
const blender::OffsetIndices<int> polys,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = polys_num;
int i = polys.size();
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
@@ -1117,21 +1116,21 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const MPoly &poly = polys[i];
const int *corner_vert = &corner_verts[poly.loopstart];
int j = poly.totloop;
const blender::IndexRange poly = polys[i];
const int *corner_vert = &corner_verts[poly.start()];
int j = poly.size();
float w = 0.0f;
for (; j--; corner_vert++) {
w += tmp_weights[*corner_vert];
}
r_weights[i] = w / float(poly.totloop);
r_weights[i] = w / float(poly.size());
}
MEM_freeN(tmp_weights);
}
else {
copy_vn_fl(r_weights, polys_num, 0.0f);
copy_vn_fl(r_weights, polys.size(), 0.0f);
}
}
@@ -1415,7 +1415,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
int numOfEdges = mesh->totedge;
int numOfPolys = mesh->totpoly;
const blender::Span<MEdge> edges = mesh->edges();
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
/* count number of edges per vertex */
@@ -1430,8 +1430,8 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
/* also add number of vertices to temp_data
* to locate points on "mesh edge" */
for (int i = 0; i < numOfPolys; i++) {
for (int j = 0; j < polys[i].totloop; j++) {
temp_data[corner_verts[polys[i].loopstart + j]]++;
for (const int vert : corner_verts.slice(polys[i])) {
temp_data[vert]++;
}
}
@@ -1790,7 +1790,7 @@ struct DynamicPaintModifierApplyData {
float (*vert_positions)[3];
blender::Span<blender::float3> vert_normals;
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
blender::Span<int> corner_verts;
float (*fcolor)[4];
@@ -1859,7 +1859,6 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
const DynamicPaintModifierApplyData *data = static_cast<DynamicPaintModifierApplyData *>(
userdata);
const blender::Span<MPoly> polys = data->polys;
const blender::Span<int> corner_verts = data->corner_verts;
const DynamicPaintSurface *surface = data->surface;
@@ -1869,8 +1868,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
MLoopCol *mloopcol = data->mloopcol;
MLoopCol *mloopcol_wet = data->mloopcol_wet;
for (int j = 0; j < polys[p_index].totloop; j++) {
const int l_index = polys[p_index].loopstart + j;
for (const int l_index : data->polys[p_index]) {
const int v_index = corner_verts[l_index];
/* save layer data to output layer */
@@ -1928,7 +1926,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
/* vertex color paint */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
const blender::Span<MPoly> polys = result->polys();
const blender::OffsetIndices polys = result->polys();
const blender::Span<int> corner_verts = result->corner_verts();
/* paint is stored on dry and wet layers, so mix final color first */
+7 -24
View File
@@ -3234,7 +3234,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
return nullptr;
}
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
blender::MutableSpan<MPoly> polys = me->polys_for_write();
blender::MutableSpan<int> poly_offsets = me->poly_offsets_for_write();
blender::MutableSpan<int> corner_verts = me->corner_verts_for_write();
const bool is_sharp = orgmesh->attributes().lookup_or_default<bool>(
@@ -3325,12 +3325,11 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
int *material_indices = BKE_mesh_material_indices_for_write(me);
/* Loop for triangles. */
for (const int i : polys.index_range()) {
for (const int i : poly_offsets.index_range().drop_back(1)) {
/* Initialize from existing face. */
material_indices[i] = mp_mat_nr;
polys[i].loopstart = i * 3;
polys[i].totloop = 3;
poly_offsets[i] = i * 3;
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);
@@ -3355,7 +3354,6 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
float min[3];
float max[3];
float *co;
MPoly *poly;
int *corner_vert;
int num_verts = 8;
@@ -3370,7 +3368,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<MPoly> polys = result->polys_for_write();
blender::MutableSpan<int> poly_offsets = result->poly_offsets_for_write();
blender::MutableSpan<int> corner_verts = result->corner_verts_for_write();
if (num_verts) {
@@ -3414,57 +3412,42 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
co[1] = max[1];
co[2] = min[2];
poly_offsets.fill(4);
blender::offset_indices::accumulate_counts_to_offsets(poly_offsets);
/* Create faces. */
/* Top side. */
poly = &polys[0];
corner_vert = &corner_verts[0 * 4];
poly->loopstart = 0 * 4;
poly->totloop = 4;
corner_vert[0] = 0;
corner_vert[1] = 1;
corner_vert[2] = 2;
corner_vert[3] = 3;
/* Right side. */
poly = &polys[1];
corner_vert = &corner_verts[1 * 4];
poly->loopstart = 1 * 4;
poly->totloop = 4;
corner_vert[0] = 2;
corner_vert[1] = 1;
corner_vert[2] = 5;
corner_vert[3] = 6;
/* Bottom side. */
poly = &polys[2];
corner_vert = &corner_verts[2 * 4];
poly->loopstart = 2 * 4;
poly->totloop = 4;
corner_vert[0] = 7;
corner_vert[1] = 6;
corner_vert[2] = 5;
corner_vert[3] = 4;
/* Left side. */
poly = &polys[3];
corner_vert = &corner_verts[3 * 4];
poly->loopstart = 3 * 4;
poly->totloop = 4;
corner_vert[0] = 0;
corner_vert[1] = 3;
corner_vert[2] = 7;
corner_vert[3] = 4;
/* Front side. */
poly = &polys[4];
corner_vert = &corner_verts[4 * 4];
poly->loopstart = 4 * 4;
poly->totloop = 4;
corner_vert[0] = 3;
corner_vert[1] = 2;
corner_vert[2] = 6;
corner_vert[3] = 7;
/* Back side. */
poly = &polys[5];
corner_vert = &corner_verts[5 * 4];
poly->loopstart = 5 * 4;
poly->totloop = 4;
corner_vert[0] = 1;
corner_vert[1] = 0;
corner_vert[2] = 4;
@@ -250,7 +250,7 @@ static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray
static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray &varray)
{
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
@@ -260,8 +260,7 @@ static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray
new_varray = VArray<T>::ForFunc(
polys.size(), [polys, varray = varray.typed<bool>()](const int face_index) {
/* A face is selected if all of its corners were selected. */
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
for (const int loop_index : polys[face_index]) {
if (!varray[loop_index]) {
return false;
}
@@ -274,8 +273,7 @@ static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray
polys.size(), [polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
for (const int loop_index : polys[face_index]) {
const T value = varray[loop_index];
mixer.mix_in(0, value);
}
@@ -294,19 +292,19 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_edges = mesh.corner_edges();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
const IndexRange poly = polys[poly_index];
/* For every edge, mix values from the two adjacent corners (the current and next corner). */
for (const int i : IndexRange(poly.totloop)) {
const int next_i = (i + 1) % poly.totloop;
const int loop_i = poly.loopstart + i;
const int next_loop_i = poly.loopstart + next_i;
for (const int i : IndexRange(poly.size())) {
const int next_i = (i + 1) % poly.size();
const int loop_i = poly.start() + i;
const int next_loop_i = poly.start() + next_i;
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]);
@@ -323,17 +321,17 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_edges = mesh.corner_edges();
r_values.fill(true);
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
const IndexRange poly = polys[poly_index];
for (const int i : IndexRange(poly.totloop)) {
const int next_i = (i + 1) % poly.totloop;
const int loop_i = poly.loopstart + i;
const int next_loop_i = poly.loopstart + next_i;
for (const int i : IndexRange(poly.size())) {
const int next_i = (i + 1) % poly.size();
const int loop_i = poly[i];
const int next_loop_i = poly[next_i];
const int edge_index = corner_edges[loop_i];
if (!old_values[loop_i] || !old_values[next_loop_i]) {
@@ -374,15 +372,14 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_verts = mesh.corner_verts();
attribute_math::DefaultMixer<T> 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 vert : corner_verts.slice(poly.loopstart, poly.totloop)) {
for (const int vert : corner_verts.slice(polys[poly_index])) {
mixer.mix_in(vert, value);
}
}
@@ -397,15 +394,14 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> 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 int vert : corner_verts.slice(poly.loopstart, poly.totloop)) {
for (const int vert : corner_verts.slice(polys[poly_index])) {
r_values[vert] = true;
}
}
@@ -433,12 +429,11 @@ void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
for (const int poly_index : range) {
const MPoly &poly = polys[poly_index];
MutableSpan<T> poly_corner_values = r_values.slice(poly.loopstart, poly.totloop);
MutableSpan<T> poly_corner_values = r_values.slice(polys[poly_index]);
poly_corner_values.fill(old_values[poly_index]);
}
});
@@ -463,15 +458,14 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_edges = mesh.corner_edges();
attribute_math::DefaultMixer<T> 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 edge : corner_edges.slice(poly.loopstart, poly.totloop)) {
for (const int edge : corner_edges.slice(polys[poly_index])) {
mixer.mix_in(edge, value);
}
}
@@ -485,15 +479,14 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> 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 int edge : corner_edges.slice(poly.loopstart, poly.totloop)) {
for (const int edge : corner_edges.slice(polys[poly_index])) {
r_values[edge] = true;
}
}
@@ -516,7 +509,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<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_verts = mesh.corner_verts();
GVArray new_varray;
@@ -528,8 +521,7 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &
mesh.totpoly,
[corner_verts, polys, varray = varray.typed<bool>()](const int face_index) {
/* A face is selected if all of its vertices were selected. */
const MPoly &poly = polys[face_index];
for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) {
for (const int vert : corner_verts.slice(polys[face_index])) {
if (!varray[vert]) {
return false;
}
@@ -542,8 +534,7 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &
mesh.totpoly, [corner_verts, polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MPoly &poly = polys[face_index];
for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) {
for (const int vert : corner_verts.slice(polys[face_index])) {
mixer.mix_in(0, varray[vert]);
}
mixer.finalize();
@@ -594,16 +585,16 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_edges = mesh.corner_edges();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
const IndexRange poly = polys[poly_index];
/* For every corner, mix the values from the adjacent edges on the face. */
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
for (const int loop_index : poly) {
const int loop_index_prev = mesh::poly_corner_prev(poly, loop_index);
const int edge = corner_edges[loop_index];
const int edge_prev = corner_edges[loop_index_prev];
@@ -622,15 +613,15 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
const Span<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> 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) {
const MPoly &poly = polys[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const IndexRange poly = polys[poly_index];
for (const int loop_index : poly) {
const int loop_index_prev = mesh::poly_corner_prev(poly, loop_index);
const int edge = corner_edges[loop_index];
const int edge_prev = corner_edges[loop_index_prev];
@@ -713,7 +704,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<MPoly> polys = mesh.polys();
const OffsetIndices polys = mesh.polys();
const Span<int> corner_edges = mesh.corner_edges();
GVArray new_varray;
@@ -724,8 +715,7 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
/* A face is selected if all of its edges are selected. */
new_varray = VArray<bool>::ForFunc(
polys.size(), [corner_edges, polys, varray = varray.typed<T>()](const int face_index) {
const MPoly &poly = polys[face_index];
for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) {
for (const int edge : corner_edges.slice(polys[face_index])) {
if (!varray[edge]) {
return false;
}
@@ -738,8 +728,7 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
polys.size(), [corner_edges, polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MPoly &poly = polys[face_index];
for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) {
for (const int edge : corner_edges.slice(polys[face_index])) {
mixer.mix_in(0, varray[edge]);
}
mixer.finalize();
@@ -2715,7 +2715,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh);
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
const Span<float3> positions = me_eval->vert_positions();
const Span<MPoly> polys = me_eval->polys();
const OffsetIndices polys = me_eval->polys();
const Span<int> corner_verts = me_eval->corner_verts();
int polys_len = me_eval->totpoly;
char element_name[200];
@@ -2756,7 +2756,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
const VArray<int> mesh_material_indices = me_eval->attributes().lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
for (i = 0; i < polys_len; i++) {
const MPoly &poly = polys[i];
const IndexRange poly = polys[i];
/* Find material. */
int mat_idx = 0;
@@ -2776,19 +2776,19 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
gpencil_add_material(bmain, ob_gp, element_name, color, false, true, &mat_idx);
}
bGPDstroke *gps_fill = BKE_gpencil_stroke_add(gpf_fill, mat_idx, poly.totloop, 10, false);
bGPDstroke *gps_fill = BKE_gpencil_stroke_add(gpf_fill, mat_idx, poly.size(), 10, false);
gps_fill->flag |= GP_STROKE_CYCLIC;
/* Create dvert data. */
const Span<MDeformVert> dverts = me_eval->deform_verts();
if (use_vgroups && !dverts.is_empty()) {
gps_fill->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * poly.totloop,
gps_fill->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * poly.size(),
"gp_fill_dverts");
}
/* Add points to strokes. */
for (int j = 0; j < poly.totloop; j++) {
const int vert = corner_verts[poly.loopstart + j];
for (int j = 0; j < poly.size(); j++) {
const int vert = corner_verts[poly[j]];
bGPDspoint *pt = &gps_fill->points[j];
copy_v3_v3(&pt->x, positions[vert]);
@@ -2810,7 +2810,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
}
}
/* If has only 3 points subdivide. */
if (poly.totloop == 3) {
if (poly.size() == 3) {
BKE_gpencil_stroke_subdivide(gpd, gps_fill, 1, GP_SUBDIV_SIMPLE);
}
+1 -1
View File
@@ -2234,7 +2234,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
float(*positions)[3] = static_cast<float(*)[3]>(MEM_dupallocN(BKE_mesh_vert_positions(mesh)));
BKE_keyblock_convert_to_mesh(kb, positions, mesh->totvert);
const blender::Span<MEdge> edges = mesh->edges();
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
const blender::Span<int> corner_edges = mesh->corner_edges();
@@ -1459,8 +1459,8 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
mesh->vert_positions_for_write().copy_from(process.co);
mesh->totpoly = int(process.curindex);
MPoly *polys = static_cast<MPoly *>(
CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CONSTRUCT, mesh->totpoly));
BKE_mesh_poly_offsets_ensure_alloc(mesh);
blender::MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
int *corner_verts = static_cast<int *>(CustomData_add_layer_named(
&mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totpoly * 4, ".corner_vert"));
@@ -1469,8 +1469,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
const int *indices = process.indices[i];
const int count = indices[2] != indices[3] ? 4 : 3;
polys[i].loopstart = loop_offset;
polys[i].totloop = count;
poly_offsets[i] = loop_offset;
corner_verts[loop_offset] = indices[0];
corner_verts[loop_offset + 1] = indices[1];
@@ -1492,6 +1491,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
BKE_mesh_vert_normals_clear_dirty(mesh);
mesh->totloop = loop_offset;
poly_offsets.last() = loop_offset;
BKE_mesh_calc_edges(mesh, false, false);
+50 -21
View File
@@ -156,6 +156,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, alloc_type, mesh_dst->totedge);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, alloc_type, mesh_dst->totloop);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, alloc_type, mesh_dst->totpoly);
mesh_dst->poly_offset_indices = static_cast<int *>(MEM_dupallocN(mesh_src->poly_offset_indices));
if (do_tessface) {
CustomData_copy(&mesh_src->fdata, &mesh_dst->fdata, mask.fmask, alloc_type, mesh_dst->totface);
}
@@ -250,6 +251,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->totpoly = 0;
memset(&mesh->pdata, 0, sizeof(mesh->pdata));
mesh->poly_offset_indices = nullptr;
}
else {
Set<std::string> names_to_skip;
@@ -273,10 +275,15 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
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);
BKE_mesh_legacy_sharp_faces_to_flags(mesh);
MutableSpan<MPoly> legacy_polys = BKE_mesh_legacy_convert_offsets_to_polys(
mesh, temp_arrays_for_legacy_format, poly_layers);
mesh->poly_offset_indices = nullptr;
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh, legacy_polys);
BKE_mesh_legacy_sharp_faces_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
BKE_mesh_legacy_edge_crease_from_layers(mesh);
BKE_mesh_legacy_sharp_edges_to_flags(mesh);
@@ -288,7 +295,7 @@ 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<MEdge *>(mesh->edges().data());
mesh->mpoly = const_cast<MPoly *>(mesh->polys().data());
mesh->mpoly = legacy_polys.data();
mesh->dvert = const_cast<MDeformVert *>(mesh->deform_verts().data());
}
@@ -298,6 +305,12 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip);
if (!BLO_write_is_undo(writer)) {
/* #CustomData expects the layers to be sorted in increasing order based on type. */
std::stable_sort(
poly_layers.begin(),
poly_layers.end(),
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers);
BKE_mesh_legacy_face_set_from_generic(poly_layers);
}
@@ -330,6 +343,10 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
writer, &mesh->ldata, loop_layers, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id);
CustomData_blend_write(
writer, &mesh->pdata, poly_layers, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id);
if (mesh->poly_offset_indices) {
BLO_write_int32_array(writer, mesh->totpoly + 1, mesh->poly_offset_indices);
}
}
static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
@@ -355,6 +372,8 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &mesh->vertex_group_names);
BLO_read_int32_array(reader, mesh->totpoly + 1, &mesh->poly_offset_indices);
CustomData_blend_read(reader, &mesh->vdata, mesh->totvert);
CustomData_blend_read(reader, &mesh->edata, mesh->totedge);
CustomData_blend_read(reader, &mesh->fdata, mesh->totface);
@@ -525,7 +544,7 @@ static int customdata_compare(
{
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_non_generic = CD_MASK_MEDGE | CD_MASK_MDEFORMVERT;
const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic;
/* The uv selection / pin layers are ignored in the comparisons because
@@ -601,18 +620,6 @@ static int customdata_compare(
BLI_edgehash_free(eh, nullptr);
break;
}
case CD_MPOLY: {
MPoly *p1 = (MPoly *)l1->data;
MPoly *p2 = (MPoly *)l2->data;
int ptot = m1->totpoly;
for (j = 0; j < ptot; j++, p1++, p2++) {
if (p1->totloop != p2->totloop) {
return MESHCMP_POLYMISMATCH;
}
}
break;
}
case CD_PROP_BYTE_COLOR: {
MLoopCol *lp1 = (MLoopCol *)l1->data;
MLoopCol *lp2 = (MLoopCol *)l2->data;
@@ -775,6 +782,11 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
return "Number of loops don't match";
}
if (!std::equal(
me1->poly_offsets().begin(), me1->poly_offsets().end(), me2->poly_offsets().begin())) {
return "Face sizes don't match";
}
if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1->totvert, me1, thresh))) {
return cmpcode_to_str(c);
}
@@ -903,6 +915,7 @@ static void mesh_clear_geometry(Mesh *mesh)
CustomData_free(&mesh->fdata, mesh->totface);
CustomData_free(&mesh->ldata, mesh->totloop);
CustomData_free(&mesh->pdata, mesh->totpoly);
MEM_SAFE_FREE(mesh->poly_offset_indices);
MEM_SAFE_FREE(mesh->mselect);
@@ -944,6 +957,23 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
return me;
}
void BKE_mesh_poly_offsets_ensure_alloc(Mesh *mesh)
{
BLI_assert(mesh->poly_offset_indices == nullptr);
if (mesh->totpoly == 0) {
return;
}
if (!mesh->poly_offset_indices) {
mesh->poly_offset_indices = static_cast<int *>(
MEM_malloc_arrayN(mesh->totpoly + 1, sizeof(int), __func__));
}
#ifdef DEBUG
/* Fill offsets with obviously bad values to simplify finding missing initialization. */
mesh->poly_offsets_for_write().fill(-1);
#endif
mesh->poly_offsets_for_write().last() = mesh->totloop;
}
/* Custom data layer functions; those assume that totXXX are set correctly. */
static void mesh_ensure_cdlayers_primary(Mesh *mesh)
{
@@ -962,9 +992,6 @@ static void mesh_ensure_cdlayers_primary(Mesh *mesh)
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);
}
}
Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys_len)
@@ -986,6 +1013,7 @@ Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys
mesh->totpoly = polys_len;
mesh_ensure_cdlayers_primary(mesh);
BKE_mesh_poly_offsets_ensure_alloc(mesh);
return mesh;
}
@@ -1082,6 +1110,7 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
/* The destination mesh should at least have valid primary CD layers,
* even in cases where the source mesh does not. */
mesh_ensure_cdlayers_primary(me_dst);
BKE_mesh_poly_offsets_ensure_alloc(me_dst);
if (do_tessface && !CustomData_get_layer(&me_dst->fdata, CD_MFACE)) {
CustomData_add_layer(&me_dst->fdata, CD_MFACE, CD_SET_DEFAULT, me_dst->totface);
}
@@ -97,10 +97,10 @@ class MeshesToIMeshInfo {
int input_mesh_for_imesh_vert(int imesh_v) const;
int input_mesh_for_imesh_edge(int imesh_e) const;
int input_mesh_for_imesh_face(int imesh_f) const;
const MPoly *input_mpoly_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_orig_mesh_index,
int *r_index_in_orig_mesh) const;
const IndexRange input_mpoly_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_orig_mesh_index,
int *r_index_in_orig_mesh) const;
void input_mvert_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
@@ -136,7 +136,7 @@ int MeshesToIMeshInfo::input_mesh_for_imesh_edge(int imesh_e) const
}
/* Given an index `imesh_f` in the `IMesh`, return the index of the
* input `Mesh` that contained the `MPoly` that it came from. */
* input `Mesh` that contained the polygon that it came from. */
int MeshesToIMeshInfo::input_mesh_for_imesh_face(int imesh_f) const
{
int n = int(mesh_poly_offset.size());
@@ -151,20 +151,20 @@ int MeshesToIMeshInfo::input_mesh_for_imesh_face(int imesh_f) const
/* Given an index of an original face in the `IMesh`, find out the input
* `Mesh` that it came from and return it in `*r_orig_mesh`,
* and also return the index of that `Mesh` in `*r_orig_mesh_index`.
* Finally, return the index of the corresponding `MPoly` in that `Mesh`
* Finally, return the index of the corresponding polygon in that `Mesh`
* in `*r_index_in_orig_mesh`. */
const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_orig_mesh_index,
int *r_index_in_orig_mesh) const
const IndexRange MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_orig_mesh_index,
int *r_index_in_orig_mesh) const
{
int orig_mesh_index = input_mesh_for_imesh_face(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
const Span<MPoly> polys = me->polys();
const OffsetIndices polys = me->polys();
int index_in_mesh = orig_index - mesh_poly_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totpoly);
const MPoly *poly = &polys[index_in_mesh];
const IndexRange poly = polys[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -222,7 +222,7 @@ void MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
* first Mesh. To do this transformation, we also need the transformation
* obmats corresponding to the Meshes, so they are in the `obmats` argument.
* The 'original' indexes in the IMesh are the indexes you get by
* a scheme that offsets each vertex, MEdge, and MPoly index by the sum of the
* a scheme that offsets each vertex, MEdge, and polygon index by the sum of the
* vertices, edges, and polys in the preceding Meshes in the mesh span.
* The `*r_info class` is filled in with information needed to make the
* correspondence between the Mesh MVerts/MPolys and the IMesh Verts/Faces.
@@ -280,10 +280,10 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
const float4x4 inv_target_mat = math::invert(clean_transform(target_transform));
/* For each input `Mesh`, make `Vert`s and `Face`s for the corresponding
* vertices and `MPoly`s, and keep track of the original indices (using the
* vertices and polygons, and keep track of the original indices (using the
* concatenating offset scheme) inside the `Vert`s and `Face`s.
* When making `Face`s, we also put in the original indices for `MEdge`s that
* make up the `MPoly`s using the same scheme. */
* make up the polygons using the same scheme. */
for (int mi : meshes.index_range()) {
const Mesh *me = meshes[mi];
r_info->mesh_vert_offset[mi] = v;
@@ -303,7 +303,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
Vector<Vert *> verts(me->totvert);
const Span<float3> vert_positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
const Span<int> corner_edges = me->corner_edges();
@@ -336,12 +336,13 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
++v;
}
for (const MPoly &poly : polys) {
int flen = poly.totloop;
for (const int poly_i : polys.index_range()) {
const IndexRange poly = polys[poly_i];
int flen = poly.size();
face_vert.resize(flen);
face_edge_orig.resize(flen);
for (int i = 0; i < flen; ++i) {
const int corner_i = poly.loopstart + i;
const int corner_i = poly[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) {
@@ -401,9 +402,6 @@ static void copy_poly_attributes(Mesh *dest_mesh,
const CustomData *source_cd = &orig_me->pdata;
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
const eCustomDataType ty = eCustomDataType(source_cd->layers[source_layer_i].type);
if (ty == CD_MPOLY) {
continue;
}
const char *name = source_cd->layers[source_layer_i].name;
int target_layer_i = CustomData_get_named_layer_index(target_cd, ty, name);
if (target_layer_i != -1) {
@@ -459,7 +457,7 @@ static void copy_edge_attributes(Mesh *dest_mesh,
* Return the number of non-null MLoops filled in.
*/
static int fill_orig_loops(const Face *f,
const MPoly *orig_poly,
const IndexRange orig_poly,
const Mesh *orig_me,
int orig_me_index,
MeshesToIMeshInfo &mim,
@@ -468,7 +466,7 @@ static int fill_orig_loops(const Face *f,
r_orig_loops.fill(-1);
const Span<int> orig_corner_verts = orig_me->corner_verts();
int orig_mplen = orig_poly->totloop;
int orig_mplen = orig_poly.size();
if (f->size() != orig_mplen) {
return 0;
}
@@ -493,7 +491,7 @@ static int fill_orig_loops(const Face *f,
/* Assume all vertices in an mpoly are unique. */
int offset = -1;
for (int i = 0; i < orig_mplen; ++i) {
int loop_i = i + orig_poly->loopstart;
int loop_i = i + orig_poly.start();
if (orig_corner_verts[loop_i] == first_orig_v_in_orig_me) {
offset = i;
break;
@@ -505,7 +503,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 int vert_i = orig_corner_verts[orig_poly->loopstart + orig_mp_loop_index];
const int vert_i = orig_corner_verts[orig_poly.start() + orig_mp_loop_index];
int fv_orig = f->vert[mp_loop_index]->orig;
if (fv_orig != NO_INDEX) {
fv_orig -= orig_me_vert_offset;
@@ -515,7 +513,7 @@ static int fill_orig_loops(const Face *f,
}
if (vert_i == fv_orig) {
const int vert_next =
orig_corner_verts[orig_poly->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
orig_corner_verts[orig_poly.start() + ((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;
@@ -524,7 +522,7 @@ static int fill_orig_loops(const Face *f,
}
}
if (vert_next == fvnext_orig) {
r_orig_loops[mp_loop_index] = orig_poly->loopstart + orig_mp_loop_index;
r_orig_loops[mp_loop_index] = orig_poly.start() + orig_mp_loop_index;
++num_orig_loops_found;
}
}
@@ -532,19 +530,19 @@ static int fill_orig_loops(const Face *f,
return num_orig_loops_found;
}
/* Fill `cos_2d` with the 2d coordinates found by projection MPoly `poly` along
/* Fill `cos_2d` with the 2d coordinates found by projection polygon `poly` along
* its normal. Also fill in r_axis_mat with the matrix that does that projection.
* But before projecting, also transform the 3d coordinate by multiplying by trans_mat.
* `cos_2d` should have room for `poly->totloop` entries. */
* `cos_2d` should have room for `poly.size()` entries. */
static void get_poly2d_cos(const Mesh *me,
const MPoly *poly,
const IndexRange poly,
float (*cos_2d)[2],
const float4x4 &trans_mat,
float r_axis_mat[3][3])
{
const Span<float3> positions = me->vert_positions();
const Span<int> corner_verts = me->corner_verts();
const Span<int> poly_verts = corner_verts.slice(poly->loopstart, poly->totloop);
const Span<int> poly_verts = corner_verts.slice(poly);
/* Project coordinates to 2d in cos_2d, using normal as projection axis. */
const float3 axis_dominant = bke::mesh::poly_normal_calc(positions, poly_verts);
@@ -561,13 +559,13 @@ static void get_poly2d_cos(const Mesh *me,
* Otherwise, interpolate the Loop attributes in the face `orig_poly`. */
static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
const Face *f,
MPoly *poly,
const MPoly *orig_poly,
const IndexRange poly,
const IndexRange orig_poly,
const Mesh *orig_me,
int orig_me_index,
MeshesToIMeshInfo &mim)
{
Array<int> orig_loops(poly->totloop);
Array<int> orig_loops(poly.size());
int norig = fill_orig_loops(f, orig_poly, orig_me, orig_me_index, mim, orig_loops);
/* We may need these arrays if we have to interpolate Loop attributes rather than just copy.
* Right now, trying Array<float[2]> complains, so declare cos_2d a different way. */
@@ -575,22 +573,22 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
Array<float> weights;
Array<const void *> src_blocks_ofs;
float axis_mat[3][3];
if (norig != poly->totloop) {
if (norig != poly.size()) {
/* We will need to interpolate. Make `cos_2d` hold 2d-projected coordinates of `orig_poly`,
* which are transformed into object 0's local space before projecting.
* At this point we cannot yet calculate the interpolation weights, as they depend on
* the coordinate where interpolation is to happen, but we can allocate the needed arrays,
* so they don't have to be allocated per-layer. */
cos_2d = (float(*)[2])BLI_array_alloca(cos_2d, orig_poly->totloop);
weights = Array<float>(orig_poly->totloop);
src_blocks_ofs = Array<const void *>(orig_poly->totloop);
cos_2d = (float(*)[2])BLI_array_alloca(cos_2d, orig_poly.size());
weights = Array<float>(orig_poly.size());
src_blocks_ofs = Array<const void *>(orig_poly.size());
get_poly2d_cos(orig_me, orig_poly, cos_2d, mim.to_target_transform[orig_me_index], axis_mat);
}
CustomData *target_cd = &dest_mesh->ldata;
const Span<float3> dst_positions = dest_mesh->vert_positions();
const Span<int> dst_corner_verts = dest_mesh->corner_verts();
for (int i = 0; i < poly->totloop; ++i) {
int loop_index = poly->loopstart + i;
for (int i = 0; i < poly.size(); ++i) {
int loop_index = poly[i];
int orig_loop_index = norig > 0 ? orig_loops[i] : -1;
const CustomData *source_cd = &orig_me->ldata;
if (orig_loop_index == -1) {
@@ -599,7 +597,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
* 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_corner_verts[loop_index]]);
interp_weights_poly_v2(weights.data(), cos_2d, orig_poly->totloop, co);
interp_weights_poly_v2(weights.data(), cos_2d, orig_poly.size(), co);
}
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
const eCustomDataType ty = eCustomDataType(source_cd->layers[source_layer_i].type);
@@ -628,9 +626,9 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
int source_layer_type_index = source_layer_i - source_cd->typemap[ty];
BLI_assert(target_layer_type_index != -1 && source_layer_type_index >= 0);
const int size = CustomData_sizeof(ty);
for (int j = 0; j < orig_poly->totloop; ++j) {
for (int j = 0; j < orig_poly.size(); ++j) {
const void *layer = CustomData_get_layer_n(source_cd, ty, source_layer_type_index);
src_blocks_ofs[j] = POINTER_OFFSET(layer, size * (orig_poly->loopstart + j));
src_blocks_ofs[j] = POINTER_OFFSET(layer, size * (orig_poly[j]));
}
void *dst_layer = CustomData_get_layer_n_for_write(
target_cd, ty, target_layer_type_index, dest_mesh->totloop);
@@ -639,7 +637,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
src_blocks_ofs.data(),
weights.data(),
nullptr,
orig_poly->totloop,
orig_poly.size(),
dst_block_ofs,
target_layer_i);
}
@@ -723,17 +721,15 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
ATTR_DOMAIN_FACE);
int cur_loop_index = 0;
MutableSpan<int> dst_corner_verts = result->corner_verts_for_write();
MutableSpan<MPoly> dst_polys = result->polys_for_write();
MutableSpan<int> dst_poly_offsets = result->poly_offsets_for_write();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
const Mesh *orig_me;
int index_in_orig_me;
int orig_me_index;
const MPoly *orig_poly = mim.input_mpoly_for_orig_index(
const IndexRange orig_poly = mim.input_mpoly_for_orig_index(
f->orig, &orig_me, &orig_me_index, &index_in_orig_me);
MPoly *poly = &dst_polys[fi];
poly->totloop = f->size();
poly->loopstart = cur_loop_index;
dst_poly_offsets[fi] = cur_loop_index;
for (int j : f->index_range()) {
const Vert *vf = f->vert[j];
const int vfi = im->lookup_vert(vf);
@@ -749,7 +745,13 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
mim.material_remaps[orig_me_index].as_span() :
Span<short>(),
dst_material_indices.span);
copy_or_interp_loop_attributes(result, f, poly, orig_poly, orig_me, orig_me_index, mim);
copy_or_interp_loop_attributes(result,
f,
IndexRange(dst_poly_offsets[fi], f->size()),
orig_poly,
orig_me,
orig_me_index,
mim);
}
dst_material_indices.finish();
@@ -760,16 +762,17 @@ 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 OffsetIndices dst_polys = result->polys();
const Span<int> 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];
const IndexRange poly = dst_polys[fi];
for (int j : f->index_range()) {
if (f->edge_orig[j] != NO_INDEX) {
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_corner_edges[poly.loopstart + j];
int e_index = dst_corner_edges[poly[j]];
copy_edge_attributes(result, orig_me, e_index, index_in_orig_me);
}
}
@@ -831,14 +834,14 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
/* Store intersecting edge indices. */
if (r_intersecting_edges != nullptr) {
const Span<MPoly> polys = result->polys();
const OffsetIndices polys = result->polys();
const Span<int> 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 = corner_edges[poly.loopstart + corner_i];
const IndexRange poly = polys[fi];
for (int i : face.index_range()) {
if (face.is_intersect[i]) {
int e_index = corner_edges[poly[i]];
r_intersecting_edges->append(e_index);
}
}
@@ -95,12 +95,12 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh,
MutableSpan<EdgeMap> edge_maps,
uint32_t parallel_mask)
{
const Span<MPoly> polys = mesh->polys();
const OffsetIndices polys = mesh->polys();
const Span<int> 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) {
const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
for (const int i : polys.index_range()) {
const Span<int> poly_verts = corner_verts.slice(polys[i]);
int vert_prev = poly_verts.last();
for (const int vert : poly_verts) {
/* Can only be the same when the mesh data is invalid. */
@@ -155,16 +155,14 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh,
Span<EdgeMap> edge_maps,
uint32_t parallel_mask)
{
const Span<MPoly> polys = mesh->polys();
const OffsetIndices polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
MutableSpan<int> 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];
const IndexRange corners(poly.loopstart, poly.totloop);
int prev_corner = corners.last();
for (const int next_corner : corners) {
const IndexRange poly = polys[poly_index];
int prev_corner = poly.last();
for (const int next_corner : poly) {
const int vert = corner_verts[next_corner];
const int vert_prev = corner_verts[prev_corner];
@@ -76,18 +76,18 @@ using blender::StringRefNull;
static CLG_LogRef LOG = {"bke.mesh_convert"};
static void poly_edgehash_insert(EdgeHash *ehash, const MPoly *poly, const Span<int> corner_verts)
static void poly_edgehash_insert(EdgeHash *ehash, const Span<int> poly_verts)
{
int i = poly->totloop;
int i = poly_verts.size();
int corner_next = poly->loopstart; /* first loop */
int corner = corner_next + (i - 1); /* last loop */
int next = 0; /* first loop */
int poly_corner = (i - 1); /* last loop */
while (i-- != 0) {
BLI_edgehash_reinsert(ehash, corner_verts[corner], corner_verts[corner_next], nullptr);
BLI_edgehash_reinsert(ehash, poly_verts[poly_corner], poly_verts[next], nullptr);
corner = corner_next;
corner_next++;
poly_corner = next;
next++;
}
}
@@ -98,15 +98,15 @@ static void make_edges_mdata_extend(Mesh &mesh)
{
int totedge = mesh.totedge;
const Span<MPoly> polys = mesh.polys();
const blender::OffsetIndices polys = mesh.polys();
const Span<int> corner_verts = mesh.corner_verts();
MutableSpan<int> 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, corner_verts);
for (const int i : polys.index_range()) {
poly_edgehash_insert(eh, corner_verts.slice(polys[i]));
}
const int totedge_new = BLI_edgehash_len(eh);
@@ -138,11 +138,11 @@ static void make_edges_mdata_extend(Mesh &mesh)
BLI_edgehashIterator_free(ehi);
for (const int i : polys.index_range()) {
const MPoly &poly = polys[i];
int corner = poly.loopstart;
int corner_prev = poly.loopstart + (poly.totloop - 1);
const IndexRange poly = polys[i];
int corner = poly.start();
int corner_prev = poly.start() + (poly.size() - 1);
int j;
for (j = 0; j < poly.totloop; j++, corner++) {
for (j = 0; j < poly.size(); j++, corner++) {
/* lookup hashed edge index */
corner_edges[corner_prev] = POINTER_AS_UINT(
BLI_edgehash_lookup(eh, corner_verts[corner_prev], corner_verts[corner]));
@@ -206,7 +206,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, totloop, totpoly);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MPoly> polys = mesh->polys_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
MutableAttributeAccessor attributes = mesh->attributes_for_write();
@@ -287,8 +287,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
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;
poly_offsets[dst_poly] = dst_loop;
material_indices.span[dst_poly] = dl->col;
if (mloopuv) {
@@ -345,8 +344,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
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;
poly_offsets[dst_poly] = dst_loop;
material_indices.span[dst_poly] = dl->col;
if (mloopuv) {
@@ -470,7 +468,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
{
const Span<float3> positions = me->vert_positions();
const Span<MEdge> mesh_edges = me->edges();
const Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_edges = me->corner_edges();
/* only to detect edge polylines */
@@ -481,10 +479,8 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
/* get boundary edges */
edge_users = (int *)MEM_calloc_arrayN(mesh_edges.size(), sizeof(int), __func__);
for (const int i : polys.index_range()) {
const MPoly &poly = polys[i];
int j;
for (j = 0; j < poly.totloop; j++) {
edge_users[corner_edges[poly.loopstart + j]]++;
for (const int edge : corner_edges.slice(polys[i])) {
edge_users[edge]++;
}
}
@@ -1139,6 +1135,8 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, CD_ASSIGN, mesh_src->totedge);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, CD_ASSIGN, mesh_src->totpoly);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop);
mesh_dst->poly_offset_indices = static_cast<int *>(mesh_src->poly_offset_indices);
mesh_src->poly_offset_indices = nullptr;
/* Make sure active/default color attribute (names) are brought over. */
if (mesh_src->active_color_attribute) {
@@ -117,13 +117,12 @@ float BKE_mesh_calc_poly_area(const int *poly_verts,
float BKE_mesh_calc_area(const Mesh *me)
{
const Span<float3> positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
float total_area = 0.0f;
for (const MPoly &poly : polys) {
total_area += blender::bke::mesh::poly_area_calc(
positions, corner_verts.slice(poly.loopstart, poly.totloop));
for (const int i : polys.index_range()) {
total_area += blender::bke::mesh::poly_area_calc(positions, corner_verts.slice(polys[i]));
}
return total_area;
}
@@ -285,15 +284,14 @@ bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3])
{
int tot = 0;
const Span<float3> positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> 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[corner_verts[j]]);
for (const int i : polys.index_range()) {
for (const int vert : corner_verts.slice(polys[i])) {
add_v3_v3(r_cent, positions[vert]);
}
tot += poly.totloop;
tot += polys[i].size();
}
/* otherwise we get NAN for 0 verts */
if (me->totpoly) {
@@ -320,7 +318,7 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
float total_area = 0.0f;
float poly_cent[3];
const Span<float3> positions = me->vert_positions();
const blender::Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
zero_v3(r_cent);
@@ -328,7 +326,7 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
/* calculate a weighted average of polygon centroids */
for (const int i : polys.index_range()) {
poly_area = blender::bke::mesh::poly_area_centroid_calc(
positions, corner_verts.slice(polys[i].loopstart, polys[i].totloop), poly_cent);
positions, corner_verts.slice(polys[i]), poly_cent);
madd_v3_v3fl(r_cent, poly_cent, poly_area);
total_area += poly_area;
@@ -352,7 +350,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
float total_volume = 0.0f;
float poly_cent[3];
const Span<float3> positions = me->vert_positions();
const blender::Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
/* Use an initial center to avoid numeric instability of geometry far away from the center. */
@@ -364,7 +362,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, corner_verts.slice(polys[i].loopstart, polys[i].totloop), init_cent, poly_cent);
positions, corner_verts.slice(polys[i]), 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);
@@ -535,7 +533,8 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
}
}
void BKE_mesh_polygon_flip_ex(const MPoly *poly,
void BKE_mesh_polygon_flip_ex(const int poly_offset,
const int poly_size,
int *corner_verts,
int *corner_edges,
CustomData *ldata,
@@ -543,8 +542,8 @@ void BKE_mesh_polygon_flip_ex(const MPoly *poly,
MDisps *mdisp,
const bool use_loop_mdisp_flip)
{
int loopstart = poly->loopstart;
int loopend = loopstart + poly->totloop - 1;
int loopstart = poly_offset;
int loopend = loopstart + poly_size - 1;
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(
@@ -585,19 +584,32 @@ void BKE_mesh_polygon_flip_ex(const MPoly *poly,
}
}
void BKE_mesh_polygon_flip(
const MPoly *poly, int *corner_verts, int *corner_edges, CustomData *ldata, const int totloop)
void BKE_mesh_polygon_flip(const int poly_offset,
const int poly_size,
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, corner_verts, corner_edges, ldata, nullptr, mdisp, true);
BKE_mesh_polygon_flip_ex(
poly_offset, poly_size, corner_verts, corner_edges, ldata, nullptr, mdisp, true);
}
void BKE_mesh_polys_flip(
const MPoly *polys, int *corner_verts, int *corner_edges, CustomData *ldata, int totpoly)
const int *poly_offsets, int *corner_verts, int *corner_edges, CustomData *ldata, int totpoly)
{
const blender::OffsetIndices polys(blender::Span(poly_offsets, totpoly + 1));
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], corner_verts, corner_edges, ldata, nullptr, mdisp, true);
for (const int i : polys.index_range()) {
BKE_mesh_polygon_flip_ex(polys[i].start(),
polys[i].size(),
corner_verts,
corner_edges,
ldata,
nullptr,
mdisp,
true);
}
}
@@ -620,7 +632,7 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
}
const VArraySpan<bool> hide_vert_span{hide_vert};
const Span<MEdge> edges = me->edges();
const Span<MPoly> polys = me->polys();
const OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
/* Hide edges when either of their vertices are hidden. */
@@ -636,8 +648,7 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_poly", ATTR_DOMAIN_FACE);
for (const int i : polys.index_range()) {
const MPoly &poly = polys[i];
const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
const Span<int> poly_verts = corner_verts.slice(polys[i]);
hide_poly.span[i] = std::any_of(poly_verts.begin(), poly_verts.end(), [&](const int vert) {
return hide_vert_span[vert];
});
@@ -659,7 +670,7 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
return;
}
const VArraySpan<bool> hide_poly_span{hide_poly};
const Span<MPoly> polys = me->polys();
const OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
const Span<int> corner_edges = me->corner_edges();
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -670,8 +681,7 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
/* Hide all edges or vertices connected to hidden polygons. */
for (const int i : polys.index_range()) {
if (hide_poly_span[i]) {
const MPoly &poly = polys[i];
for (const int corner : IndexRange(poly.loopstart, poly.totloop)) {
for (const int corner : polys[i]) {
hide_vert.span[corner_verts[corner]] = true;
hide_edge.span[corner_edges[corner]] = true;
}
@@ -680,8 +690,7 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
/* Unhide vertices and edges connected to visible polygons. */
for (const int i : polys.index_range()) {
if (!hide_poly_span[i]) {
const MPoly &poly = polys[i];
for (const int corner : IndexRange(poly.loopstart, poly.totloop)) {
for (const int corner : polys[i]) {
hide_vert.span[corner_verts[corner]] = false;
hide_edge.span[corner_edges[corner]] = false;
}
@@ -720,7 +729,7 @@ void BKE_mesh_flush_select_from_polys(Mesh *me)
}
static void mesh_flush_select_from_verts(const Span<MEdge> edges,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<int> corner_verts,
const VArray<bool> &hide_edge,
const VArray<bool> &hide_poly,
@@ -739,8 +748,7 @@ static void mesh_flush_select_from_verts(const Span<MEdge> edges,
/* Select visible faces that have all of their vertices selected. */
for (const int i : polys.index_range()) {
if (!hide_poly[i]) {
const MPoly &poly = polys[i];
const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
const Span<int> poly_verts = corner_verts.slice(polys[i]);
select_poly[i] = std::all_of(
poly_verts.begin(), poly_verts.end(), [&](const int vert) { return select_vert[vert]; });
}
@@ -781,7 +789,7 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
/** \name Mesh Spatial Calculation
* \{ */
void BKE_mesh_calc_relative_deform(const MPoly *polys,
void BKE_mesh_calc_relative_deform(const int *poly_offsets,
const int totpoly,
const int *corner_verts,
const int totvert,
@@ -792,18 +800,20 @@ void BKE_mesh_calc_relative_deform(const MPoly *polys,
const float (*vert_cos_org)[3],
float (*vert_cos_new)[3])
{
const blender::OffsetIndices<int> polys({poly_offsets, totpoly + 1});
int *vert_accum = (int *)MEM_calloc_arrayN(size_t(totvert), sizeof(*vert_accum), __func__);
memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * size_t(totvert));
for (const int i : blender::IndexRange(totpoly)) {
const MPoly &poly = polys[i];
const int *poly_verts = &corner_verts[poly.loopstart];
for (const int i : polys.index_range()) {
const blender::IndexRange poly = polys[i];
const int *poly_verts = &corner_verts[poly.start()];
for (int j = 0; j < poly.totloop; j++) {
const int v_prev = poly_verts[(poly.totloop + (j - 1)) % poly.totloop];
for (int j = 0; j < poly.size(); j++) {
const int v_prev = poly_verts[(poly.size() + (j - 1)) % poly.size()];
const int v_curr = poly_verts[j];
const int v_next = poly_verts[(j + 1) % poly.totloop];
const int v_next = poly_verts[(j + 1) % poly.size()];
float tvec[3];
+5 -11
View File
@@ -202,13 +202,8 @@ class MeshFairingContext : public FairingContext {
polys = mesh->polys();
corner_verts_ = mesh->corner_verts();
corner_edges_ = mesh->corner_edges();
BKE_mesh_vert_loop_map_create(&vlmap_,
&vlmap_mem_,
polys.data(),
corner_verts_.data(),
mesh->totvert,
mesh->totpoly,
mesh->totloop);
BKE_mesh_vert_loop_map_create(
&vlmap_, &vlmap_mem_, polys, corner_verts_.data(), mesh->totvert);
/* Deformation coords. */
co_.reserve(mesh->totvert);
@@ -223,8 +218,7 @@ class MeshFairingContext : public FairingContext {
}
}
loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(polys,
corner_verts_.size());
loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(polys);
}
~MeshFairingContext() override
@@ -239,7 +233,7 @@ class MeshFairingContext : public FairingContext {
{
using namespace blender;
const int vert = corner_verts_[loop];
const MPoly &poly = polys[loop_to_poly_map_[loop]];
const blender::IndexRange poly = polys[loop_to_poly_map_[loop]];
const int2 adjecent_verts = bke::mesh::poly_find_adjecent_verts(poly, corner_verts_, vert);
copy_v3_v3(r_adj_next, co_[adjecent_verts[0]]);
copy_v3_v3(r_adj_prev, co_[adjecent_verts[1]]);
@@ -258,7 +252,7 @@ class MeshFairingContext : public FairingContext {
Mesh *mesh_;
Span<int> corner_verts_;
Span<int> corner_edges_;
Span<MPoly> polys;
blender::OffsetIndices<int> polys;
Span<MEdge> edges_;
Array<int> loop_to_poly_map_;
};
@@ -193,7 +193,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
nullptr;
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
const int *v_index = static_cast<const int *>(
CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX));
@@ -202,7 +202,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
if (v_index || f_index) {
for (const int poly_i : polys.index_range()) {
for (const int vert : corner_verts.slice(polys[poly_i].loopstart, polys[poly_i].totloop)) {
for (const int vert : corner_verts.slice(polys[poly_i])) {
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;
@@ -215,7 +215,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
}
else {
for (const int poly_i : polys.index_range()) {
for (const int vert : corner_verts.slice(polys[poly_i].loopstart, polys[poly_i].totloop)) {
for (const int vert : corner_verts.slice(polys[poly_i])) {
const int v_idx = vert;
const int f_idx = poly_i;
const float *no = loop_normals ? *loop_normals++ : nullptr;
@@ -268,7 +268,7 @@ void BKE_mesh_foreach_mapped_face_center(
}
else {
const blender::Span<float3> positions = mesh->vert_positions();
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
@@ -278,7 +278,7 @@ void BKE_mesh_foreach_mapped_face_center(
if (orig == ORIGINDEX_NONE) {
continue;
}
const Span<int> poly_verts = corner_verts.slice(polys[i].loopstart, polys[i].totloop);
const Span<int> poly_verts = corner_verts.slice(polys[i]);
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_verts);
@@ -291,7 +291,7 @@ void BKE_mesh_foreach_mapped_face_center(
}
else {
for (const int i : polys.index_range()) {
const Span<int> poly_verts = corner_verts.slice(polys[i].loopstart, polys[i].totloop);
const Span<int> poly_verts = corner_verts.slice(polys[i]);
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_verts);
@@ -312,7 +312,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
MeshForeachFlag flag)
{
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
blender::Span<blender::float3> vert_normals;
if (flag & MESH_FOREACH_USE_NORMAL) {
@@ -327,7 +327,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
if (orig == ORIGINDEX_NONE) {
continue;
}
for (const int vert : corner_verts.slice(polys[i].loopstart, polys[i].totloop)) {
for (const int vert : corner_verts.slice(polys[i])) {
if (facedot_tags[vert]) {
func(userData,
orig,
@@ -339,7 +339,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
}
else {
for (const int i : polys.index_range()) {
for (const int vert : corner_verts.slice(polys[i].loopstart, polys[i].totloop)) {
for (const int vert : corner_verts.slice(polys[i])) {
if (facedot_tags[vert]) {
func(userData,
i,
@@ -208,17 +208,16 @@ void BKE_mesh_calc_edges_legacy(Mesh *me)
int totedge = 0;
const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&me->vdata, CD_MVERT)),
me->totvert);
const Span<MPoly> polys = me->polys();
mesh_calc_edges_mdata(
verts.data(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
static_cast<MLoop *>(CustomData_get_layer_for_write(&me->ldata, CD_MLOOP, me->totloop)),
polys.data(),
static_cast<const MPoly *>(CustomData_get_layer(&me->pdata, CD_MPOLY)),
verts.size(),
me->totface,
me->totloop,
polys.size(),
me->totpoly,
&edges,
&totedge);
@@ -964,7 +963,6 @@ static int mesh_tessface_calc(Mesh &mesh,
const int looptri_num = poly_to_tri_count(totpoly, totloop);
const MPoly *poly, *mpoly;
MFace *mface, *mf;
MemArena *arena = nullptr;
int *mface_to_poly_map;
@@ -972,7 +970,7 @@ static int mesh_tessface_calc(Mesh &mesh,
int poly_index, mface_index;
uint j;
mpoly = (const MPoly *)CustomData_get_layer(pdata, CD_MPOLY);
const blender::OffsetIndices polys = mesh.polys();
const Span<int> corner_verts = mesh.corner_verts();
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index"));
@@ -988,10 +986,9 @@ static int mesh_tessface_calc(Mesh &mesh,
lindices = (uint(*)[4])MEM_malloc_arrayN(size_t(looptri_num), sizeof(*lindices), __func__);
mface_index = 0;
poly = mpoly;
for (poly_index = 0; poly_index < totpoly; poly_index++, poly++) {
const uint mp_loopstart = uint(poly->loopstart);
const uint mp_totloop = uint(poly->totloop);
for (poly_index = 0; poly_index < totpoly; poly_index++) {
const uint mp_loopstart = uint(polys[poly_index].start());
const uint mp_totloop = uint(polys[poly_index].size());
uint l1, l2, l3, l4;
uint *lidx;
if (mp_totloop < 3) {
@@ -1220,21 +1217,20 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh)
/** \name Sharp Edge Conversion
* \{ */
void BKE_mesh_legacy_sharp_faces_to_flags(Mesh *mesh)
void BKE_mesh_legacy_sharp_faces_to_flags(Mesh *mesh, blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
MutableSpan<MPoly> polys = mesh->polys_for_write();
if (const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"))) {
threading::parallel_for(polys.index_range(), 4096, [&](const IndexRange range) {
threading::parallel_for(legacy_polys.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(polys[i].flag_legacy, !sharp_faces[i], ME_SMOOTH);
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, !sharp_faces[i], ME_SMOOTH);
}
});
}
else {
for (const int i : polys.index_range()) {
polys[i].flag_legacy |= ME_SMOOTH;
for (const int i : legacy_polys.index_range()) {
legacy_polys[i].flag_legacy |= ME_SMOOTH;
}
}
}
@@ -1243,11 +1239,12 @@ void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
const Span<MPoly> polys = mesh->polys();
MutableAttributeAccessor attributes = mesh->attributes_for_write();
if (attributes.contains("sharp_face")) {
return;
}
const Span<MPoly> polys(static_cast<const MPoly *>(CustomData_get_layer(&mesh->pdata, CD_MPOLY)),
mesh->totpoly);
if (std::any_of(polys.begin(), polys.end(), [](const MPoly &poly) {
return !(poly.flag_legacy & ME_SMOOTH);
})) {
@@ -1520,7 +1517,8 @@ void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
/** \name Hide Attribute and Legacy Flag Conversion
* \{ */
void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
using namespace blender::bke;
@@ -1544,12 +1542,11 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
}
});
MutableSpan<MPoly> polys = mesh->polys_for_write();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(polys[i].flag_legacy, hide_poly[i], ME_HIDE);
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, hide_poly[i], ME_HIDE);
}
});
}
@@ -1591,7 +1588,8 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
hide_edge.finish();
}
const Span<MPoly> polys = mesh->polys();
const Span<MPoly> polys(static_cast<const MPoly *>(CustomData_get_layer(&mesh->pdata, CD_MPOLY)),
mesh->totpoly);
if (std::any_of(polys.begin(), polys.end(), [](const MPoly &poly) {
return poly.flag_legacy & ME_HIDE;
})) {
@@ -1612,17 +1610,17 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
/** \name Material Index Conversion
* \{ */
void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh)
void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
using namespace blender::bke;
const AttributeAccessor attributes = mesh->attributes();
MutableSpan<MPoly> polys = mesh->polys_for_write();
const VArray<int> material_indices = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
polys[i].mat_nr_legacy = material_indices[i];
legacy_polys[i].mat_nr_legacy = material_indices[i];
}
});
}
@@ -1632,10 +1630,11 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh->attributes_for_write();
if (attributes.contains("material_index")) {
if (!mesh->mpoly || attributes.contains("material_index")) {
return;
}
const Span<MPoly> polys = mesh->polys();
const Span<MPoly> polys(static_cast<const MPoly *>(CustomData_get_layer(&mesh->pdata, CD_MPOLY)),
mesh->totpoly);
if (std::any_of(
polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr_legacy != 0; })) {
SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_only_span<int>(
@@ -1849,7 +1848,8 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
/** \name Selection Attribute and Legacy Flag Conversion
* \{ */
void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh)
void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
using namespace blender::bke;
@@ -1873,12 +1873,11 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh)
}
});
MutableSpan<MPoly> polys = mesh->polys_for_write();
const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
".select_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(polys[i].flag_legacy, select_poly[i], ME_FACE_SEL);
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, select_poly[i], ME_FACE_SEL);
}
});
}
@@ -1921,7 +1920,8 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
select_edge.finish();
}
const Span<MPoly> polys = mesh->polys();
const Span<MPoly> polys(static_cast<const MPoly *>(CustomData_get_layer(&mesh->pdata, CD_MPOLY)),
mesh->totpoly);
if (std::any_of(polys.begin(), polys.end(), [](const MPoly &poly) {
return poly.flag_legacy & ME_FACE_SEL;
})) {
@@ -2196,3 +2196,89 @@ void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Poly Offset Conversion
* \{ */
blender::MutableSpan<MPoly> BKE_mesh_legacy_convert_offsets_to_polys(
const Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &poly_layers_to_write)
{
using namespace blender;
const OffsetIndices polys = mesh->polys();
MutableSpan<MPoly> polys_legacy = temp_arrays_for_convert.construct<Array<MPoly>>(mesh->totpoly);
threading::parallel_for(polys_legacy.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
polys_legacy[i].loopstart = polys[i].start();
polys_legacy[i].totloop = polys[i].size();
}
});
CustomDataLayer layer{};
layer.type = CD_MPOLY;
layer.data = polys_legacy.data();
poly_layers_to_write.append(layer);
return polys_legacy;
}
static bool poly_loops_orders_match(const Span<MPoly> polys)
{
for (const int i : polys.index_range().drop_back(1)) {
if (polys[i].loopstart > polys[i + 1].loopstart) {
return false;
}
}
return true;
}
void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh)
{
using namespace blender;
if (mesh->poly_offset_indices) {
return;
}
const Span<MPoly> polys(static_cast<const MPoly *>(CustomData_get_layer(&mesh->pdata, CD_MPOLY)),
mesh->totpoly);
BKE_mesh_poly_offsets_ensure_alloc(mesh);
MutableSpan<int> offsets = mesh->poly_offsets_for_write();
if (poly_loops_orders_match(polys)) {
for (const int i : polys.index_range()) {
offsets[i] = polys[i].loopstart;
}
}
else {
/* Reorder mesh polygons to match the order of their loops. */
Array<int> orig_indices(polys.size());
std::iota(orig_indices.begin(), orig_indices.end(), 0);
std::stable_sort(orig_indices.begin(), orig_indices.end(), [polys](const int a, const int b) {
return polys[a].loopstart < polys[b].loopstart;
});
CustomData old_poly_data = mesh->pdata;
CustomData_reset(&mesh->pdata);
CustomData_copy(&old_poly_data, &mesh->pdata, CD_MASK_MESH.pmask, CD_CONSTRUCT, mesh->totpoly);
int offset = 0;
for (const int i : orig_indices.index_range()) {
offsets[i] = offset;
offset += polys[orig_indices[i]].totloop;
}
threading::parallel_for(orig_indices.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
CustomData_copy_data(&old_poly_data, &mesh->pdata, orig_indices[i], i, 1);
}
});
CustomData_free(&old_poly_data, mesh->totloop);
}
CustomData_free_layers(&mesh->pdata, CD_MPOLY, mesh->totpoly);
}
/** \} */
+76 -118
View File
@@ -21,6 +21,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BLI_memarena.h"
@@ -30,12 +31,11 @@
/** \name Mesh Connectivity Mapping
* \{ */
UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *polys,
UvVertMap *BKE_mesh_uv_vert_map_create(const blender::OffsetIndices<int> polys,
const bool *hide_poly,
const bool *select_poly,
const int *corner_verts,
const float (*mloopuv)[2],
uint totpoly,
uint totvert,
const float limit[2],
const bool selected,
@@ -52,10 +52,9 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *polys,
totuv = 0;
/* generate UvMapVert array */
for (const int64_t a : blender::IndexRange(totpoly)) {
const MPoly &poly = polys[a];
for (const int64_t a : polys.index_range()) {
if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {
totuv += poly.totloop;
totuv += int(polys[a].size());
}
}
@@ -74,29 +73,30 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *polys,
bool *winding = nullptr;
if (use_winding) {
winding = static_cast<bool *>(MEM_callocN(sizeof(*winding) * totpoly, "winding"));
winding = static_cast<bool *>(
MEM_calloc_arrayN(sizeof(*winding), size_t(polys.size()), "winding"));
}
for (const int64_t a : blender::IndexRange(totpoly)) {
const MPoly &poly = polys[a];
for (const int64_t a : polys.index_range()) {
const blender::IndexRange poly = polys[a];
if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {
float(*tf_uv)[2] = nullptr;
if (use_winding) {
tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, size_t(poly.totloop));
tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, size_t(poly.size()));
}
nverts = poly.totloop;
nverts = int(poly.size());
for (i = 0; i < nverts; i++) {
buf->loop_of_poly_index = ushort(i);
buf->poly_index = uint(a);
buf->separate = false;
buf->next = vmap->vert[corner_verts[poly.loopstart + i]];
vmap->vert[corner_verts[poly.loopstart + i]] = buf;
buf->next = vmap->vert[corner_verts[poly[i]]];
vmap->vert[corner_verts[poly[i]]] = buf;
if (use_winding) {
copy_v2_v2(tf_uv[i], mloopuv[poly.loopstart + i]);
copy_v2_v2(tf_uv[i], mloopuv[poly[i]]);
}
buf++;
@@ -121,14 +121,14 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *polys,
v->next = newvlist;
newvlist = v;
uv = mloopuv[polys[v->poly_index].loopstart + v->loop_of_poly_index];
uv = mloopuv[polys[v->poly_index].start() + v->loop_of_poly_index];
lastv = nullptr;
iterv = vlist;
while (iterv) {
next = iterv->next;
uv2 = mloopuv[polys[iterv->poly_index].loopstart + iterv->loop_of_poly_index];
uv2 = mloopuv[polys[iterv->poly_index].start() + iterv->loop_of_poly_index];
sub_v2_v2v2(uvdiff, uv2, uv);
if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] &&
@@ -191,31 +191,26 @@ 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 blender::OffsetIndices<int> polys,
const int *corner_verts,
int totvert,
int totpoly,
int totloop,
const bool do_loops)
{
MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totvert), __func__);
int *indices, *index_iter;
int i, j;
indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totloop), __func__));
indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(polys.total_size()), __func__));
index_iter = indices;
/* Count number of polys for each vertex */
for (i = 0; i < totpoly; i++) {
const MPoly &poly = polys[i];
for (j = 0; j < poly.totloop; j++) {
map[corner_verts[poly.loopstart + j]].count++;
for (const int64_t i : polys.index_range()) {
for (const int64_t corner : polys[i]) {
map[corner_verts[corner]].count++;
}
}
/* Assign indices mem */
for (i = 0; i < totvert; i++) {
for (int64_t i = 0; i < totvert; i++) {
map[i].indices = index_iter;
index_iter += map[i].count;
@@ -224,13 +219,11 @@ static void mesh_vert_poly_or_loop_map_create(MeshElemMap **r_map,
}
/* Find the users */
for (i = 0; i < totpoly; i++) {
const MPoly &poly = polys[i];
for (const int64_t i : polys.index_range()) {
for (const int64_t corner : polys[i]) {
const int v = corner_verts[corner];
for (j = 0; j < poly.totloop; j++) {
const int v = corner_verts[poly.loopstart + j];
map[v].indices[map[v].count] = do_loops ? poly.loopstart + j : i;
map[v].indices[map[v].count] = do_loops ? int(corner) : int(i);
map[v].count++;
}
}
@@ -241,26 +234,20 @@ 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 blender::OffsetIndices<int> polys,
const int *corner_verts,
int totvert,
int totpoly,
int totloop)
int totvert)
{
mesh_vert_poly_or_loop_map_create(
r_map, r_mem, polys, corner_verts, totvert, totpoly, totloop, false);
mesh_vert_poly_or_loop_map_create(r_map, r_mem, polys, corner_verts, totvert, false);
}
void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map,
int **r_mem,
const MPoly *polys,
const blender::OffsetIndices<int> polys,
const int *corner_verts,
int totvert,
int totpoly,
int totloop)
int totvert)
{
mesh_vert_poly_or_loop_map_create(
r_map, r_mem, polys, corner_verts, totvert, totpoly, totloop, true);
mesh_vert_poly_or_loop_map_create(r_map, r_mem, polys, corner_verts, totvert, true);
}
void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
@@ -387,8 +374,7 @@ void BKE_mesh_vert_edge_vert_map_create(
void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
int **r_mem,
const int totedge,
const MPoly *polys,
const int totpoly,
const blender::OffsetIndices<int> polys,
const int *corner_edges,
const int totloop)
{
@@ -413,17 +399,15 @@ 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];
for (const int64_t i : polys.index_range()) {
MeshElemMap *map_ele;
const int max_loop = poly.loopstart + poly.totloop;
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;
for (const int64_t corner : polys[i]) {
map_ele = &map[corner_edges[corner]];
map_ele->indices[map_ele->count++] = int(corner);
map_ele->indices[map_ele->count++] = int(corner) + 1;
}
/* last edge/loop of poly, must point back to first loop! */
map_ele->indices[map_ele->count - 1] = poly.loopstart;
map_ele->indices[map_ele->count - 1] = int(polys[i].start());
}
*r_map = map;
@@ -433,8 +417,7 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
int **r_mem,
const int totedge,
const MPoly *polys,
const int totpoly,
const blender::OffsetIndices<int> polys,
const int *corner_edges,
const int totloop)
{
@@ -458,10 +441,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];
for (int j = 0; j < poly.totloop; j++) {
const int edge_i = corner_edges[poly.loopstart + j];
for (const int64_t i : polys.index_range()) {
for (const int64_t corner : polys[i]) {
const int edge_i = corner_edges[corner];
MeshElemMap *map_ele = &map[edge_i];
map_ele->indices[map_ele->count++] = int(i);
}
@@ -514,25 +496,23 @@ void BKE_mesh_origindex_map_create(MeshElemMap **r_map,
void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
int **r_mem,
const MPoly *polys,
const int polys_num,
const blender::OffsetIndices<int> polys,
const MLoopTri *looptri,
const int looptri_num)
{
MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(polys_num), __func__);
MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(polys.size()), __func__);
int *indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(looptri_num), __func__));
int *index_step;
int i;
/* create offsets */
index_step = indices;
for (i = 0; i < polys_num; i++) {
for (const int64_t i : polys.index_range()) {
map[i].indices = index_step;
index_step += ME_POLY_TRI_TOT(&polys[i]);
index_step += ME_POLY_TRI_TOT(polys[i].size());
}
/* assign poly-tessface users */
for (i = 0; i < looptri_num; i++) {
for (int i = 0; i < looptri_num; i++) {
MeshElemMap *map_ele = &map[looptri[i].poly];
map_ele->indices[map_ele->count++] = i;
}
@@ -543,13 +523,12 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
namespace blender::bke::mesh_topology {
Array<int> build_loop_to_poly_map(const Span<MPoly> polys, const int loops_num)
Array<int> build_loop_to_poly_map(const OffsetIndices<int> polys)
{
Array<int> map(loops_num);
Array<int> map(polys.total_size());
threading::parallel_for(polys.index_range(), 1024, [&](IndexRange range) {
for (const int64_t poly_i : range) {
const MPoly &poly = polys[poly_i];
map.as_mutable_span().slice(poly.loopstart, poly.totloop).fill(int(poly_i));
map.as_mutable_span().slice(polys[poly_i]).fill(int(poly_i));
}
});
return map;
@@ -565,14 +544,13 @@ Array<Vector<int>> build_vert_to_edge_map(const Span<MEdge> edges, const int ver
return map;
}
Array<Vector<int>> build_vert_to_poly_map(const Span<MPoly> polys,
Array<Vector<int>> build_vert_to_poly_map(const OffsetIndices<int> polys,
const Span<int> corner_verts,
int verts_num)
{
Array<Vector<int>> map(verts_num);
for (const int64_t i : polys.index_range()) {
const MPoly &poly = polys[i];
for (const int64_t vert_i : corner_verts.slice(poly.loopstart, poly.totloop)) {
for (const int64_t vert_i : corner_verts.slice(polys[i])) {
map[int(vert_i)].append(int(i));
}
}
@@ -597,14 +575,13 @@ Array<Vector<int>> build_edge_to_loop_map(const Span<int> corner_edges, const in
return map;
}
Array<Vector<int, 2>> build_edge_to_poly_map(const Span<MPoly> polys,
Array<Vector<int, 2>> build_edge_to_poly_map(const OffsetIndices<int> polys,
const Span<int> corner_edges,
const int edges_num)
{
Array<Vector<int, 2>> map(edges_num);
for (const int64_t i : polys.index_range()) {
const MPoly &poly = polys[i];
for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) {
for (const int edge : corner_edges.slice(polys[i])) {
map[edge].append(int(i));
}
}
@@ -642,7 +619,7 @@ using MeshRemap_CheckIslandBoundary =
const MeshElemMap &edge_poly_map_elem)>;
static void poly_edge_loop_islands_calc(const int totedge,
const blender::Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const blender::Span<int> corner_edges,
MeshElemMap *edge_poly_map,
const bool use_bitflags,
@@ -689,8 +666,7 @@ static void poly_edge_loop_islands_calc(const int totedge,
BKE_mesh_edge_poly_map_create(&edge_poly_map,
&edge_poly_mem,
totedge,
polys.data(),
int(polys.size()),
polys,
corner_edges.data(),
int(corner_edges.size()));
}
@@ -727,7 +703,7 @@ static void poly_edge_loop_islands_calc(const int totedge,
poly = poly_stack[ps_curr_idx++];
BLI_assert(poly_groups[poly] == poly_group_id);
for (const int64_t loop : blender::IndexRange(polys[poly].loopstart, polys[poly].totloop)) {
for (const int64_t loop : polys[poly]) {
const int edge = corner_edges[loop];
/* loop over poly users */
const MeshElemMap &map_ele = edge_poly_map[edge];
@@ -832,7 +808,7 @@ static void poly_edge_loop_islands_calc(const int totedge,
}
int *BKE_mesh_calc_smoothgroups(const int totedge,
const MPoly *polys,
const int *poly_offsets,
const int totpoly,
const int *corner_edges,
const int totloop,
@@ -864,7 +840,7 @@ int *BKE_mesh_calc_smoothgroups(const int totedge,
};
poly_edge_loop_islands_calc(totedge,
{polys, totpoly},
blender::Span(poly_offsets, totpoly + 1),
{corner_edges, totloop},
nullptr,
use_bitflags,
@@ -994,8 +970,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
static bool mesh_calc_islands_loop_poly_uv(const int totedge,
const bool *uv_seams,
const MPoly *polys,
const int totpoly,
const blender::OffsetIndices<int> polys,
const int *corner_verts,
const int *corner_edges,
const int totloop,
@@ -1025,18 +1000,18 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge,
int *edge_innercut_indices = nullptr;
int num_einnercuts = 0;
int grp_idx, p_idx, pl_idx, l_idx;
int grp_idx;
BKE_mesh_loop_islands_clear(r_island_store);
BKE_mesh_loop_islands_init(
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, corner_edges, totloop);
&edge_poly_map, &edge_poly_mem, totedge, polys, corner_edges, totloop);
if (luvs) {
BKE_mesh_edge_loop_map_create(
&edge_loop_map, &edge_loop_mem, totedge, polys, totpoly, corner_edges, totloop);
&edge_loop_map, &edge_loop_mem, totedge, polys, corner_edges, totloop);
}
/* TODO: I'm not sure edge seam flag is enough to define UV islands?
@@ -1083,7 +1058,7 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge,
};
poly_edge_loop_islands_calc(totedge,
{polys, totpoly},
polys,
{corner_edges, totloop},
edge_poly_map,
false,
@@ -1112,7 +1087,7 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge,
}
poly_indices = static_cast<int *>(
MEM_mallocN(sizeof(*poly_indices) * size_t(totpoly), __func__));
MEM_mallocN(sizeof(*poly_indices) * size_t(polys.size()), __func__));
loop_indices = static_cast<int *>(
MEM_mallocN(sizeof(*loop_indices) * size_t(totloop), __func__));
@@ -1124,15 +1099,14 @@ static bool mesh_calc_islands_loop_poly_uv(const int totedge,
memset(edge_border_count, 0, sizeof(*edge_border_count) * size_t(totedge));
}
for (p_idx = 0; p_idx < totpoly; p_idx++) {
for (const int64_t p_idx : polys.index_range()) {
if (poly_groups[p_idx] != grp_idx) {
continue;
}
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 int edge_i = corner_edges[l_idx];
loop_indices[num_lidx++] = l_idx;
poly_indices[num_pidx++] = int(p_idx);
for (const int64_t corner : polys[p_idx]) {
const int edge_i = corner_edges[corner];
loop_indices[num_lidx++] = int(corner);
if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, edge_i) &&
(edge_border_count[edge_i] < 2)) {
edge_border_count[edge_i]++;
@@ -1180,23 +1154,15 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
const MEdge *edges,
const int totedge,
const bool *uv_seams,
const MPoly *polys,
const int totpoly,
const blender::OffsetIndices<int> polys,
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,
corner_verts,
corner_edges,
totloop,
nullptr,
r_island_store);
return mesh_calc_islands_loop_poly_uv(
totedge, uv_seams, polys, corner_verts, corner_edges, totloop, nullptr, r_island_store);
}
bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
@@ -1204,8 +1170,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
MEdge *edges,
const int totedge,
const bool *uv_seams,
MPoly *polys,
const int totpoly,
const blender::OffsetIndices<int> polys,
const int *corner_verts,
const int *corner_edges,
const int totloop,
@@ -1214,15 +1179,8 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
{
UNUSED_VARS(vert_positions, totvert, edges);
BLI_assert(luvs != nullptr);
return mesh_calc_islands_loop_poly_uv(totedge,
uv_seams,
polys,
totpoly,
corner_verts,
corner_edges,
totloop,
luvs,
r_island_store);
return mesh_calc_islands_loop_poly_uv(
totedge, uv_seams, polys, corner_verts, corner_edges, totloop, luvs, r_island_store);
}
/** \} */
@@ -114,13 +114,8 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
int *vert_map_mem;
struct MeshElemMap *vert_to_loop;
BKE_mesh_vert_loop_map_create(&vert_to_loop,
&vert_map_mem,
me->polys().data(),
me->corner_verts().data(),
me->totvert,
me->totpoly,
me->totloop);
BKE_mesh_vert_loop_map_create(
&vert_to_loop, &vert_map_mem, me->polys(), me->corner_verts().data(), me->totvert);
Vector<float2 *> mloopuv_layers;
mloopuv_layers.reserve(mloopuv_layers_num);
+11 -10
View File
@@ -187,7 +187,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
const int src_verts_num = mesh->totvert;
const int src_edges_num = mesh->totedge;
const blender::Span<MPoly> src_polys = mesh->polys();
const blender::OffsetIndices src_polys = mesh->polys();
const int src_loops_num = mesh->totloop;
Mesh *result = BKE_mesh_new_nomain_from_template(
@@ -287,7 +287,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
blender::MutableSpan<MEdge> result_edges = result->edges_for_write();
blender::MutableSpan<MPoly> result_polys = result->polys_for_write();
blender::MutableSpan<int> result_poly_offsets = result->poly_offsets_for_write();
blender::MutableSpan<int> result_corner_verts = result->corner_verts_for_write();
blender::MutableSpan<int> result_corner_edges = result->corner_edges_for_write();
@@ -297,16 +297,17 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
result_edges[i].v2 += src_verts_num;
}
for (const int i : result_polys.index_range().drop_front(src_polys.size())) {
result_polys[i].loopstart += src_loops_num;
result_poly_offsets.take_front(src_polys.size()).copy_from(mesh->poly_offsets().drop_back(1));
for (const int i : src_polys.index_range()) {
result_poly_offsets[src_polys.size() + i] = src_polys[i].start() + src_loops_num;
}
const blender::OffsetIndices result_polys = result->polys();
/* reverse loop order (normals) */
for (const int i : src_polys.index_range()) {
const blender::IndexRange src_poly(src_polys[i].loopstart, src_polys[i].totloop);
const blender::IndexRange src_poly = src_polys[i];
const int mirror_i = src_polys.size() + i;
const blender::IndexRange mirror_poly(result_polys[mirror_i].loopstart,
result_polys[mirror_i].totloop);
const blender::IndexRange mirror_poly = result_polys[mirror_i];
/* reverse the loop, but we keep the first vertex in the face the same,
* to ensure that quads are split the same way as on the other side */
@@ -412,13 +413,13 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* mirroring has to account for loops being reversed in polys in second half */
for (const int i : src_polys.index_range()) {
const blender::IndexRange src_poly(src_polys[i].loopstart, src_polys[i].totloop);
const blender::IndexRange src_poly = src_polys[i];
const int mirror_i = src_polys.size() + i;
for (const int j : src_poly) {
int mirrorj = result_polys[mirror_i].loopstart;
int mirrorj = result_polys[mirror_i].start();
if (j > src_poly.start()) {
mirrorj += result_polys[mirror_i].totloop - (j - src_poly.start());
mirrorj += result_polys[mirror_i].size() - (j - src_poly.start());
}
copy_v3_v3(loop_normals[mirrorj], loop_normals[j]);
mul_m4_v3(mtx_nor, loop_normals[mirrorj]);
@@ -196,16 +196,14 @@ void BKE_mesh_calc_poly_normal(const int *poly_verts,
namespace blender::bke::mesh {
void normals_calc_polys(const Span<float3> positions,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
MutableSpan<float3> 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,
corner_verts.slice(poly.loopstart, poly.totloop));
poly_normals[i] = poly_normal_calc(positions, corner_verts.slice(polys[i]));
}
});
}
@@ -220,7 +218,7 @@ void normals_calc_polys(const Span<float3> positions,
* \{ */
void normals_calc_poly_vert(const Span<float3> positions,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
MutableSpan<float3> poly_normals,
MutableSpan<float3> vert_normals)
@@ -235,12 +233,11 @@ void normals_calc_poly_vert(const Span<float3> 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<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
const Span<int> poly_verts = corner_verts.slice(polys[poly_i]);
float3 &pnor = poly_normals[poly_i];
const int i_end = poly.totloop - 1;
const int i_end = poly_verts.size() - 1;
/* Polygon Normal and edge-vector. */
/* Inline version of #poly_normal_calc, also does edge-vectors. */
@@ -332,7 +329,7 @@ blender::Span<blender::float3> Mesh::vert_normals() const
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
const Span<float3> positions = this->vert_positions();
const Span<MPoly> polys = this->polys();
const blender::OffsetIndices polys = this->polys();
const Span<int> corner_verts = this->corner_verts();
this->runtime->vert_normals.reinitialize(positions.size());
@@ -363,7 +360,7 @@ blender::Span<blender::float3> Mesh::poly_normals() const
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
const Span<float3> positions = this->vert_positions();
const Span<MPoly> polys = this->polys();
const blender::OffsetIndices polys = this->polys();
const Span<int> corner_verts = this->corner_verts();
this->runtime->poly_normals.reinitialize(polys.size());
@@ -707,7 +704,7 @@ struct LoopSplitTaskDataCommon {
Span<MEdge> edges;
Span<int> corner_verts;
Span<int> corner_edges;
Span<MPoly> polys;
blender::OffsetIndices<int> polys;
Span<int2> edge_to_loops;
Span<int> loop_to_poly;
Span<float3> poly_normals;
@@ -721,7 +718,7 @@ struct LoopSplitTaskDataCommon {
namespace blender::bke::mesh {
static void mesh_edges_sharp_tag(const Span<MPoly> polys,
static void mesh_edges_sharp_tag(const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<int> corner_edges,
const Span<int> loop_to_poly_map,
@@ -739,8 +736,7 @@ static void mesh_edges_sharp_tag(const Span<MPoly> 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)) {
for (const int loop_index : polys[poly_i]) {
const int vert_i = corner_verts[loop_index];
const int edge_i = corner_edges[loop_index];
@@ -793,7 +789,7 @@ static void mesh_edges_sharp_tag(const Span<MPoly> polys,
}
}
void edges_sharp_from_angle_set(const Span<MPoly> polys,
void edges_sharp_from_angle_set(const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<int> corner_edges,
const Span<float3> poly_normals,
@@ -810,8 +806,7 @@ void edges_sharp_from_angle_set(const Span<MPoly> polys,
Array<int2> edge_to_loops(sharp_edges.size(), int2(0));
/* Simple mapping from a loop to its polygon index. */
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map(polys,
corner_verts.size());
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map(polys);
mesh_edges_sharp_tag(polys,
corner_verts,
@@ -827,7 +822,7 @@ void edges_sharp_from_angle_set(const Span<MPoly> polys,
}
static void loop_manifold_fan_around_vert_next(const Span<int> corner_verts,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<int> loop_to_poly,
const int *e2lfan_curr,
const uint mv_pivot_index,
@@ -852,19 +847,19 @@ static void loop_manifold_fan_around_vert_next(const Span<int> corner_verts,
BLI_assert(*r_mpfan_curr_index >= 0);
const uint vert_fan_next = corner_verts[*r_mlfan_curr_index];
const MPoly &mpfan_next = polys[*r_mpfan_curr_index];
const blender::IndexRange 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)) {
/* We need the previous loop, but current one is our vertex's loop. */
*r_mlfan_vert_index = *r_mlfan_curr_index;
if (--(*r_mlfan_curr_index) < mpfan_next.loopstart) {
*r_mlfan_curr_index = mpfan_next.loopstart + mpfan_next.totloop - 1;
if (--(*r_mlfan_curr_index) < mpfan_next.start()) {
*r_mlfan_curr_index = mpfan_next.start() + mpfan_next.size() - 1;
}
}
else {
/* We need the next loop, which is also our vertex's loop. */
if (++(*r_mlfan_curr_index) >= mpfan_next.loopstart + mpfan_next.totloop) {
*r_mlfan_curr_index = mpfan_next.loopstart;
if (++(*r_mlfan_curr_index) >= mpfan_next.start() + mpfan_next.size()) {
*r_mlfan_curr_index = mpfan_next.start();
}
*r_mlfan_vert_index = *r_mlfan_curr_index;
}
@@ -937,7 +932,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
const Span<float3> positions = common_data->positions;
const Span<MEdge> edges = common_data->edges;
const Span<MPoly> polys = common_data->polys;
const blender::OffsetIndices polys = common_data->polys;
const Span<int> corner_verts = common_data->corner_verts;
const Span<int> corner_edges = common_data->corner_edges;
const Span<int2> edge_to_loops = common_data->edge_to_loops;
@@ -1172,7 +1167,7 @@ static void loop_split_worker(TaskPool *__restrict pool, void *taskdata)
*/
static bool loop_split_generator_check_cyclic_smooth_fan(const Span<int> corner_verts,
const Span<int> corner_edges,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<int2> edge_to_loops,
const Span<int> loop_to_poly,
const int *e2l_prev,
@@ -1242,7 +1237,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
const Span<int> corner_verts = common_data->corner_verts;
const Span<int> corner_edges = common_data->corner_edges;
const Span<MPoly> polys = common_data->polys;
const OffsetIndices polys = common_data->polys;
const Span<int> loop_to_poly = common_data->loop_to_poly;
const Span<int2> edge_to_loops = common_data->edge_to_loops;
@@ -1269,18 +1264,18 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
* and edges that will be hard! Now, time to generate the normals.
*/
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
const IndexRange poly = polys[poly_index];
for (const int ml_curr_index : IndexRange(poly.loopstart, poly.totloop)) {
for (const int ml_curr_index : poly) {
const int ml_prev_index = mesh::poly_corner_prev(poly, ml_curr_index);
#if 0
printf("Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)",
ml_curr_index,
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]);
ml_curr_index,
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
/* A smooth edge, we have to check for cyclic smooth fan case.
@@ -1376,7 +1371,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
void normals_calc_loop(const Span<float3> vert_positions,
const Span<MEdge> edges,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<int> corner_edges,
const Span<int> loop_to_poly_map,
@@ -1402,17 +1397,13 @@ void normals_calc_loop(const Span<float3> vert_positions,
* (see e.g. mesh mapping code). As usual, we could handle that on case-by-case basis,
* but simpler to keep it well confined here. */
for (const int poly_index : polys.index_range()) {
const MPoly *poly = &polys[poly_index];
int ml_index = poly->loopstart;
const int ml_index_end = ml_index + poly->totloop;
const bool is_poly_flat = sharp_faces && sharp_faces[poly_index];
for (; ml_index < ml_index_end; ml_index++) {
for (const int corner : polys[poly_index]) {
if (is_poly_flat) {
copy_v3_v3(r_loop_normals[ml_index], poly_normals[poly_index]);
copy_v3_v3(r_loop_normals[corner], poly_normals[poly_index]);
}
else {
copy_v3_v3(r_loop_normals[ml_index], vert_normals[corner_verts[ml_index]]);
copy_v3_v3(r_loop_normals[corner], vert_normals[corner_verts[corner]]);
}
}
}
@@ -1439,7 +1430,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
Span<int> loop_to_poly;
Array<int> 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, corner_verts.size());
local_loop_to_poly_map = mesh_topology::build_loop_to_poly_map(polys);
loop_to_poly = local_loop_to_poly_map;
}
else {
@@ -1483,8 +1474,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
* This way we don't have to compute those later! */
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
for (const int poly_i : range) {
const MPoly &poly = polys[poly_i];
for (const int loop_i : IndexRange(poly.loopstart, poly.totloop)) {
for (const int loop_i : polys[poly_i]) {
copy_v3_v3(r_loop_normals[loop_i], vert_normals[corner_verts[loop_i]]);
}
}
@@ -1540,7 +1530,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
static void mesh_normals_loop_custom_set(Span<float3> positions,
Span<MEdge> edges,
Span<MPoly> polys,
const OffsetIndices<int> polys,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
@@ -1559,8 +1549,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
MLoopNorSpaceArray lnors_spacearr = {nullptr};
BitVector<> done_loops(corner_verts.size(), false);
Array<float3> loop_normals(corner_verts.size());
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map(polys,
corner_verts.size());
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map(polys);
/* 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;
@@ -1658,8 +1647,8 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
* previous loop's face and current's one as sharp.
* 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 int mlp = (lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1;
const IndexRange poly = polys[loop_to_poly[lidx]];
const int mlp = (lidx == poly.start()) ? poly.start() + poly.size() - 1 : lidx - 1;
const int edge = corner_edges[lidx];
const int edge_p = corner_edges[mlp];
const int prev_edge = corner_edges[prev_corner];
@@ -1683,8 +1672,8 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
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 int mlp = (lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1;
const IndexRange poly = polys[loop_to_poly[lidx]];
const int mlp = (lidx == poly.start()) ? poly.start() + poly.size() - 1 : lidx - 1;
const int edge = corner_edges[lidx];
const int edge_p = corner_edges[mlp];
const int prev_edge = corner_edges[prev_corner];
@@ -1772,7 +1761,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
void normals_loop_custom_set(const Span<float3> vert_positions,
const Span<MEdge> edges,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<int> corner_edges,
const Span<float3> vert_normals,
@@ -1798,7 +1787,7 @@ void normals_loop_custom_set(const Span<float3> vert_positions,
void normals_loop_custom_set_from_verts(const Span<float3> vert_positions,
const Span<MEdge> edges,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<int> corner_edges,
const Span<float3> vert_normals,
+92 -120
View File
@@ -368,7 +368,7 @@ void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index)
mesh_remap_item_define(map, index, FLT_MAX, 0, 0, nullptr, nullptr);
}
static int mesh_remap_interp_poly_data_get(const MPoly &poly,
static int mesh_remap_interp_poly_data_get(const blender::IndexRange poly,
const blender::Span<int> corner_verts,
const float (*vcos_src)[3],
const float point[3],
@@ -383,7 +383,7 @@ static int mesh_remap_interp_poly_data_get(const MPoly &poly,
float(*vco)[3];
float ref_dist_sq = FLT_MAX;
int *index;
const int sources_num = poly.totloop;
const int sources_num = int(poly.size());
int i;
if (size_t(sources_num) > *buff_size) {
@@ -396,8 +396,8 @@ static int mesh_remap_interp_poly_data_get(const MPoly &poly,
}
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;
const int vert = corner_verts[poly[i]];
*index = use_loops ? int(poly[i]) : vert;
copy_v3_v3(*vco, vcos_src[vert]);
if (r_closest_index) {
/* Find closest vert/loop in this case. */
@@ -562,7 +562,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
MREMAP_MODE_VERT_POLY_NEAREST,
MREMAP_MODE_VERT_POLYINTERP_NEAREST,
MREMAP_MODE_VERT_POLYINTERP_VNORPROJ)) {
const blender::Span<MPoly> polys_src = me_src->polys();
const blender::OffsetIndices polys_src = me_src->polys();
const blender::Span<int> corner_verts_src = me_src->corner_verts();
const float(*vcos_src)[3] = BKE_mesh_vert_positions(me_src);
const blender::Span<blender::float3> vert_normals_dst = me_dst->vert_normals();
@@ -865,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<MEdge> edges_src = me_src->edges();
const blender::Span<MPoly> polys_src = me_src->polys();
const blender::OffsetIndices polys_src = me_src->polys();
const blender::Span<int> corner_edges_src = me_src->corner_edges();
const float(*vcos_src)[3] = BKE_mesh_vert_positions(me_src);
@@ -885,9 +885,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&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 int *corner_edge_src = &corner_edges_src[poly_src.loopstart];
int nloops = poly_src.totloop;
const blender::IndexRange poly_src = polys_src[lt->poly];
const int *corner_edge_src = &corner_edges_src[poly_src.start()];
int nloops = int(poly_src.size());
float best_dist_sq = FLT_MAX;
int best_eidx_src = -1;
@@ -1035,7 +1035,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
const int island_index,
BLI_AStarGraph *as_graph,
const blender::Span<blender::float3> positions,
const blender::Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const blender::Span<int> corner_verts,
const int edge_idx,
BLI_bitmap *done_edges,
@@ -1050,11 +1050,11 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
for (i = 0; i < edge_to_poly_map[edge_idx].count; i++) {
const int pidx = edge_to_poly_map[edge_idx].indices[i];
const MPoly &poly = polys[pidx];
const blender::IndexRange poly = polys[pidx];
const int pidx_isld = islands ? poly_island_index_map[pidx] : pidx;
void *custom_data = is_edge_innercut ? POINTER_FROM_INT(edge_idx) : POINTER_FROM_INT(-1);
if (UNLIKELY(islands && (islands->items_to_islands[poly.loopstart] != island_index))) {
if (UNLIKELY(islands && (islands->items_to_islands[poly.start()] != island_index))) {
/* poly not in current island, happens with border edges... */
poly_island_indices[i] = -1;
continue;
@@ -1067,8 +1067,7 @@ 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, corner_verts.slice(poly.loopstart, poly.totloop)));
blender::bke::mesh::poly_center_calc(positions, corner_verts.slice(poly)));
BLI_astar_node_init(as_graph, pidx_isld, poly_centers[pidx_isld]);
poly_status[pidx_isld] = POLY_CENTER_INIT;
}
@@ -1096,10 +1095,9 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
const blender::Span<blender::float3> positions,
MeshElemMap *edge_to_poly_map,
const int numedges,
const blender::Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const blender::Span<int> corner_verts,
const blender::Span<int> corner_edges,
const int numpolys,
BLI_AStarGraph *r_as_graph)
{
MeshElemMap *island_poly_map = islands ? islands->islands[island_index] : nullptr;
@@ -1108,7 +1106,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
int *poly_island_index_map = nullptr;
BLI_bitmap *done_edges = BLI_BITMAP_NEW(numedges, __func__);
const int node_num = islands ? island_poly_map->count : numpolys;
const int node_num = islands ? island_poly_map->count : int(polys.size());
uchar *poly_status = static_cast<uchar *>(
MEM_callocN(sizeof(*poly_status) * size_t(node_num), __func__));
float(*poly_centers)[3];
@@ -1123,8 +1121,8 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
if (islands) {
/* poly_island_index_map is owned by graph memarena. */
poly_island_index_map = static_cast<int *>(
BLI_memarena_calloc(r_as_graph->mem, sizeof(*poly_island_index_map) * size_t(numpolys)));
poly_island_index_map = static_cast<int *>(BLI_memarena_calloc(
r_as_graph->mem, sizeof(*poly_island_index_map) * size_t(polys.size())));
for (i = island_poly_map->count; i--;) {
poly_island_index_map[island_poly_map->indices[i]] = i;
}
@@ -1150,16 +1148,12 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
for (pidx_isld = node_num; pidx_isld--;) {
const int pidx = islands ? island_poly_map->indices[pidx_isld] : pidx_isld;
const MPoly &poly = polys[pidx];
int pl_idx, l_idx;
if (poly_status[pidx_isld] == POLY_COMPLETE) {
continue;
}
for (pl_idx = 0, l_idx = poly.loopstart; pl_idx < poly.totloop; pl_idx++, l_idx++) {
const int edge = corner_edges[l_idx];
for (const int edge : corner_edges.slice(polys[pidx])) {
if (BLI_BITMAP_TEST(done_edges, edge)) {
continue;
}
@@ -1233,8 +1227,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const int *corner_verts_dst,
const int *corner_edges_dst,
const int numloops_dst,
const MPoly *polys_dst,
const int numpolys_dst,
const blender::OffsetIndices<int> polys_dst,
CustomData *ldata_dst,
const bool use_split_nors_dst,
const float split_angle_dst,
@@ -1297,13 +1290,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int *poly_to_looptri_map_src_buff = nullptr;
/* Unlike above, those are one-to-one mappings, simpler! */
int *loop_to_poly_map_src = nullptr;
blender::Array<int> loop_to_poly_map_src;
const blender::Span<blender::float3> positions_src = me_src->vert_positions();
const int num_verts_src = me_src->totvert;
const float(*vcos_src)[3] = nullptr;
const blender::Span<MEdge> edges_src = me_src->edges();
const blender::Span<MPoly> polys_src = me_src->polys();
const blender::OffsetIndices polys_src = me_src->polys();
const blender::Span<int> corner_verts_src = me_src->corner_verts();
const blender::Span<int> corner_edges_src = me_src->corner_edges();
blender::Span<MLoopTri> looptris_src;
@@ -1313,7 +1306,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int *indices_interp = nullptr;
float *weights_interp = nullptr;
const MPoly *mp_dst;
int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src;
IslandResult **islands_res;
@@ -1362,7 +1354,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
blender::bke::mesh::normals_calc_loop(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{edges_dst, numedges_dst},
{polys_dst, numpolys_dst},
polys_dst,
{corner_verts_dst, numloops_dst},
{corner_edges_dst, numloops_dst},
{},
@@ -1393,19 +1385,15 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (use_from_vert) {
BKE_mesh_vert_loop_map_create(&vert_to_loop_map_src,
&vert_to_loop_map_src_buff,
polys_src.data(),
polys_src,
corner_verts_src.data(),
num_verts_src,
int(polys_src.size()),
int(corner_verts_src.size()));
num_verts_src);
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(),
polys_src,
corner_verts_src.data(),
num_verts_src,
int(polys_src.size()),
int(corner_verts_src.size()));
num_verts_src);
}
}
@@ -1413,22 +1401,15 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
BKE_mesh_edge_poly_map_create(&edge_to_poly_map_src,
&edge_to_poly_map_src_buff,
int(edges_src.size()),
polys_src.data(),
int(polys_src.size()),
polys_src,
corner_edges_src.data(),
int(corner_edges_src.size()));
if (use_from_vert) {
loop_to_poly_map_src = static_cast<int *>(
MEM_mallocN(sizeof(*loop_to_poly_map_src) * size_t(corner_verts_src.size()), __func__));
loop_to_poly_map_src = blender::bke::mesh_topology::build_loop_to_poly_map(polys_src);
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];
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, corner_verts_src.slice(poly.loopstart, poly.totloop));
for (const int64_t i : polys_src.index_range()) {
poly_cents_src[i] = blender::bke::mesh::poly_center_calc(
positions_src, corner_verts_src.slice(polys_src[i]));
}
}
@@ -1448,8 +1429,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
edges_src.data(),
int(edges_src.size()),
uv_seams,
polys_src.data(),
int(polys_src.size()),
polys_src,
corner_verts_src.data(),
corner_edges_src.data(),
int(corner_verts_src.size()),
@@ -1491,7 +1471,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
polys_src,
corner_verts_src,
corner_edges_src,
int(polys_src.size()),
&as_graphdata[tindex]);
}
}
@@ -1506,9 +1485,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int num_verts_active = 0;
verts_active.fill(false);
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 int vidx_src = corner_verts_src[lidx_src];
for (const int vidx_src : corner_verts_src.slice(polys_src[isld->indices[i]])) {
if (!verts_active[vidx_src]) {
verts_active[vidx_src].set();
num_verts_active++;
@@ -1539,8 +1516,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int num_looptri_active = 0;
looptri_active.fill(false);
for (const int64_t i : looptris_src.index_range()) {
const MPoly &poly = polys_src[looptris_src[i].poly];
if (island_store.items_to_islands[poly.loopstart] == tindex) {
const blender::IndexRange poly = polys_src[looptris_src[i].poly];
if (island_store.items_to_islands[poly.start()] == tindex) {
looptri_active[i].set();
num_looptri_active++;
}
@@ -1571,7 +1548,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
MEM_mallocN(sizeof(**islands_res) * islands_res_buff_size, __func__));
}
for (pidx_dst = 0, mp_dst = polys_dst; pidx_dst < numpolys_dst; pidx_dst++, mp_dst++) {
for (pidx_dst = 0; pidx_dst < polys_dst.size(); pidx_dst++) {
const blender::IndexRange poly_dst = polys_dst[pidx_dst];
float pnor_dst[3];
/* Only in use_from_vert case, we may need polys' centers as fallback
@@ -1586,8 +1564,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
}
if (size_t(mp_dst->totloop) > islands_res_buff_size) {
islands_res_buff_size = size_t(mp_dst->totloop) + MREMAP_DEFAULT_BUFSIZE;
if (size_t(poly_dst.size()) > islands_res_buff_size) {
islands_res_buff_size = size_t(poly_dst.size()) + MREMAP_DEFAULT_BUFSIZE;
for (tindex = 0; tindex < num_trees; tindex++) {
islands_res[tindex] = static_cast<IslandResult *>(
MEM_reallocN(islands_res[tindex], sizeof(**islands_res) * islands_res_buff_size));
@@ -1597,8 +1575,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
for (tindex = 0; tindex < num_trees; tindex++) {
BVHTreeFromMesh *tdata = &treedata[tindex];
for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
const int vert_dst = corner_verts_dst[mp_dst->loopstart + plidx_dst];
for (plidx_dst = 0; plidx_dst < poly_dst.size(); plidx_dst++) {
const int vert_dst = corner_verts_dst[poly_dst.start() + plidx_dst];
if (use_from_vert) {
MeshElemMap *vert_to_refelem_map_src = nullptr;
@@ -1619,7 +1597,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int best_index_src = -1;
if (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) {
copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + mp_dst->loopstart]);
copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + poly_dst.start()]);
if (space_transform) {
BLI_space_transform_apply_normal(space_transform, tmp_no);
}
@@ -1646,7 +1624,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
* on same island!). */
lidx_src = ((mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) ?
index_src :
polys_src[pidx_src].loopstart);
int(polys_src[pidx_src].start()));
/* A same vert may be at the boundary of several islands! Hence, we have to ensure
* poly/loop we are currently considering *belongs* to current island! */
@@ -1664,7 +1642,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
pcent_dst = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst),
numverts_dst},
{&corner_verts_dst[mp_dst->loopstart], mp_dst->totloop});
corner_verts_src.slice(poly_dst));
pcent_dst_valid = true;
}
pcent_src = poly_cents_src[pidx_src];
@@ -1685,11 +1663,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
else if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) {
/* 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];
for (plidx_src = 0; plidx_src < poly.totloop; plidx_src++) {
const int vert_src = corner_verts_src[poly.loopstart + plidx_src];
const blender::IndexRange poly_src = polys_src[best_index_src];
for (plidx_src = 0; plidx_src < poly_src.size(); plidx_src++) {
const int vert_src = corner_verts_src[poly_src.start() + plidx_src];
if (vert_src == nearest.index) {
best_index_src = plidx_src + poly.loopstart;
best_index_src = plidx_src + int(poly_src.start());
break;
}
}
@@ -1711,7 +1689,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
float w = 1.0f;
copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]);
copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + mp_dst->loopstart]);
copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + poly_dst.start()]);
/* We do our transform here, since we may do several raycast/nearest queries. */
if (space_transform) {
@@ -1813,10 +1791,10 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
for (tindex = 0; tindex < num_trees; tindex++) {
float island_fac = 0.0f;
for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
for (plidx_dst = 0; plidx_dst < poly_dst.size(); plidx_dst++) {
island_fac += islands_res[tindex][plidx_dst].factor;
}
island_fac /= float(mp_dst->totloop);
island_fac /= float(poly_dst.size());
if (island_fac > best_island_fac) {
best_island_fac = island_fac;
@@ -1831,9 +1809,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
BLI_astar_solution_init(as_graph, &as_solution, nullptr);
}
for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
for (plidx_dst = 0; plidx_dst < poly_dst.size(); plidx_dst++) {
IslandResult *isld_res;
lidx_dst = plidx_dst + mp_dst->loopstart;
lidx_dst = plidx_dst + int(poly_dst.start());
if (best_island_index == -1) {
/* No source for any loops of our dest poly in any source islands. */
@@ -1890,7 +1868,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (last_valid_pidx_isld_src != -1) {
/* Find a new valid loop in that new poly (nearest one for now).
* Note we could be much more subtle here, again that's for later... */
int j;
float best_dist_sq = FLT_MAX;
copy_v3_v3(tmp_co, vert_positions_dst[corner_verts_dst[lidx_dst]]);
@@ -1903,13 +1880,13 @@ 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];
for (j = 0; j < poly.totloop; j++) {
const int vert_src = corner_verts_src[poly.loopstart + j];
const blender::IndexRange poly_src = polys_src[pidx_src];
for (const int64_t corner : poly_src) {
const int vert_src = corner_verts_src[corner];
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;
lidx_src = int(corner);
}
}
}
@@ -1939,7 +1916,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
float *hit_co = isld_res->hit_point;
int best_loop_index_src;
const MPoly &poly = polys_src[pidx_src];
const blender::IndexRange poly_src = polys_src[pidx_src];
/* If prev and curr poly are the same, no need to do anything more!!! */
if (!ELEM(pidx_src_prev, -1, pidx_src) && isld_steps_src) {
int pidx_isld_src, pidx_isld_src_prev;
@@ -2001,8 +1978,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (poly_to_looptri_map_src == nullptr) {
BKE_mesh_origindex_map_create_looptri(&poly_to_looptri_map_src,
&poly_to_looptri_map_src_buff,
polys_src.data(),
int(polys_src.size()),
polys_src,
looptris_src.data(),
int(looptris_src.size()));
}
@@ -2029,7 +2005,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,
mesh_remap_interp_poly_data_get(poly_src,
corner_verts_src,
vcos_src,
hit_co,
@@ -2050,7 +2026,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
&full_weight);
}
else {
const int sources_num = mesh_remap_interp_poly_data_get(poly,
const int sources_num = mesh_remap_interp_poly_data_get(poly_src,
corner_verts_src,
vcos_src,
hit_co,
@@ -2126,9 +2102,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (poly_to_looptri_map_src_buff) {
MEM_freeN(poly_to_looptri_map_src_buff);
}
if (loop_to_poly_map_src) {
MEM_freeN(loop_to_poly_map_src);
}
if (vcos_interp) {
MEM_freeN(vcos_interp);
}
@@ -2149,8 +2122,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const float (*vert_positions_dst)[3],
const int numverts_dst,
const int *corner_verts_dst,
const MPoly *polys_dst,
const int numpolys_dst,
const blender::OffsetIndices<int> polys_dst,
const Mesh *me_src,
MeshPairRemap *r_map)
{
@@ -2158,7 +2130,6 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const float max_dist_sq = max_dist * max_dist;
blender::Span<blender::float3> poly_normals_dst;
blender::float3 tmp_co, tmp_no;
int i;
BLI_assert(mode & MREMAP_MODE_POLY);
@@ -2166,12 +2137,13 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
poly_normals_dst = mesh_dst->poly_normals();
}
BKE_mesh_remap_init(r_map, numpolys_dst);
BKE_mesh_remap_init(r_map, int(polys_dst.size()));
if (mode == MREMAP_MODE_TOPOLOGY) {
BLI_assert(numpolys_dst == me_src->totpoly);
for (i = 0; i < numpolys_dst; i++) {
mesh_remap_item_define(r_map, i, FLT_MAX, 0, 1, &i, &full_weight);
BLI_assert(polys_dst.size() == me_src->totpoly);
for (const int64_t i : polys_dst.index_range()) {
const int index = int(i);
mesh_remap_item_define(r_map, int(i), FLT_MAX, 0, 1, &index, &full_weight);
}
}
else {
@@ -2185,11 +2157,11 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
if (mode == MREMAP_MODE_POLY_NEAREST) {
nearest.index = -1;
for (i = 0; i < numpolys_dst; i++) {
const MPoly &poly = polys_dst[i];
for (const int64_t i : polys_dst.index_range()) {
const blender::IndexRange poly = polys_dst[i];
tmp_co = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&corner_verts_dst[poly.loopstart], poly.totloop});
{&corner_verts_dst[poly.start()], poly.size()});
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -2200,21 +2172,21 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[nearest.index];
const int poly_index = int(lt->poly);
mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &poly_index, &full_weight);
mesh_remap_item_define(r_map, int(i), hit_dist, 0, 1, &poly_index, &full_weight);
}
else {
/* No source for this dest poly! */
BKE_mesh_remap_item_define_invalid(r_map, i);
BKE_mesh_remap_item_define_invalid(r_map, int(i));
}
}
}
else if (mode == MREMAP_MODE_POLY_NOR) {
for (i = 0; i < numpolys_dst; i++) {
const MPoly &poly = polys_dst[i];
for (const int64_t i : polys_dst.index_range()) {
const blender::IndexRange poly = polys_dst[i];
tmp_co = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&corner_verts_dst[poly.loopstart], poly.totloop});
{&corner_verts_dst[poly.start()], poly.size()});
copy_v3_v3(tmp_no, poly_normals_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
@@ -2228,11 +2200,11 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const MLoopTri *lt = &treedata.looptri[rayhit.index];
const int poly_index = int(lt->poly);
mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &poly_index, &full_weight);
mesh_remap_item_define(r_map, int(i), hit_dist, 0, 1, &poly_index, &full_weight);
}
else {
/* No source for this dest poly! */
BKE_mesh_remap_item_define_invalid(r_map, i);
BKE_mesh_remap_item_define_invalid(r_map, int(i));
}
}
}
@@ -2257,11 +2229,11 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
int(*tri_vidx_2d)[3] = static_cast<int(*)[3]>(
MEM_mallocN(sizeof(*tri_vidx_2d) * (tmp_poly_size - 2), __func__));
for (i = 0; i < numpolys_dst; i++) {
for (const int64_t i : polys_dst.index_range()) {
/* For each dst poly, we sample some rays from it (2D grid in pnor space)
* and use their hits to interpolate from source polys. */
/* NOTE: dst poly is early-converted into src space! */
const MPoly &poly = polys_dst[i];
const blender::IndexRange poly = polys_dst[i];
int tot_rays, done_rays = 0;
float poly_area_2d_inv, done_area = 0.0f;
@@ -2274,12 +2246,12 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
float totweights = 0.0f;
float hit_dist_accum = 0.0f;
int sources_num = 0;
const int tris_num = poly.totloop - 2;
const int tris_num = int(poly.size()) - 2;
int j;
pcent_dst = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&corner_verts_dst[poly.loopstart], poly.totloop});
{&corner_verts_dst[poly.start()], poly.size()});
copy_v3_v3(tmp_no, poly_normals_dst[i]);
@@ -2291,8 +2263,8 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
copy_vn_fl(weights, int(numpolys_src), 0.0f);
if (UNLIKELY(size_t(poly.totloop) > tmp_poly_size)) {
tmp_poly_size = size_t(poly.totloop);
if (UNLIKELY(size_t(poly.size()) > tmp_poly_size)) {
tmp_poly_size = size_t(poly.size());
poly_vcos_2d = static_cast<float(*)[2]>(
MEM_reallocN(poly_vcos_2d, sizeof(*poly_vcos_2d) * tmp_poly_size));
tri_vidx_2d = static_cast<int(*)[3]>(
@@ -2308,8 +2280,8 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
/* Get (2D) bounding square of our poly. */
INIT_MINMAX2(poly_dst_2d_min, poly_dst_2d_max);
for (j = 0; j < poly.totloop; j++) {
const int vert = corner_verts_dst[poly.loopstart + j];
for (j = 0; j < poly.size(); j++) {
const int vert = corner_verts_dst[poly[j]];
copy_v3_v3(tmp_co, vert_positions_dst[vert]);
if (space_transform) {
BLI_space_transform_apply(space_transform, tmp_co);
@@ -2332,17 +2304,17 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
}
tot_rays *= tot_rays;
poly_area_2d_inv = area_poly_v2(poly_vcos_2d, uint(poly.totloop));
poly_area_2d_inv = area_poly_v2(poly_vcos_2d, uint(poly.size()));
/* In case we have a null-area degenerated poly... */
poly_area_2d_inv = 1.0f / max_ff(poly_area_2d_inv, 1e-9f);
/* Tessellate our poly. */
if (poly.totloop == 3) {
if (poly.size() == 3) {
tri_vidx_2d[0][0] = 0;
tri_vidx_2d[0][1] = 1;
tri_vidx_2d[0][2] = 2;
}
if (poly.totloop == 4) {
if (poly.size() == 4) {
tri_vidx_2d[0][0] = 0;
tri_vidx_2d[0][1] = 1;
tri_vidx_2d[0][2] = 2;
@@ -2351,7 +2323,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
tri_vidx_2d[1][2] = 3;
}
else {
BLI_polyfill_calc(poly_vcos_2d, uint(poly.totloop), -1, (uint(*)[3])tri_vidx_2d);
BLI_polyfill_calc(poly_vcos_2d, uint(poly.size()), -1, (uint(*)[3])tri_vidx_2d);
}
for (j = 0; j < tris_num; j++) {
@@ -2404,11 +2376,11 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
sources_num++;
}
mesh_remap_item_define(
r_map, i, hit_dist_accum / totweights, 0, sources_num, indices, weights);
r_map, int(i), hit_dist_accum / totweights, 0, sources_num, indices, weights);
}
else {
/* No source for this dest poly! */
BKE_mesh_remap_item_define_invalid(r_map, i);
BKE_mesh_remap_item_define_invalid(r_map, int(i));
}
}
@@ -2420,7 +2392,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
}
else {
CLOG_WARN(&LOG, "Unsupported mesh-to-mesh poly mapping mode (%d)!", mode);
memset(r_map->items, 0, sizeof(*r_map->items) * size_t(numpolys_dst));
memset(r_map->items, 0, sizeof(*r_map->items) * size_t(polys_dst.size()));
}
free_bvhtree_from_mesh(&treedata);
@@ -119,17 +119,17 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
/* Construct the new output 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<MPoly> polys = mesh->polys_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
poly_offsets.fill(4);
blender::offset_indices::accumulate_counts_to_offsets(poly_offsets);
mesh->vert_positions_for_write().copy_from(
Span(reinterpret_cast<float3 *>(qrd.out_verts), qrd.out_totverts));
for (const int i : IndexRange(qrd.out_totfaces)) {
MPoly &poly = polys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
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];
@@ -224,18 +224,19 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set
Mesh *mesh = BKE_mesh_new_nomain(
vertices.size(), 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size());
MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
MutableSpan<MPoly> mesh_polys = mesh->polys_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> mesh_corner_verts = mesh->corner_verts_for_write();
poly_offsets.take_front(quads.size()).fill(4);
poly_offsets.drop_front(quads.size()).fill(3);
blender::offset_indices::accumulate_counts_to_offsets(poly_offsets);
for (const int i : vert_positions.index_range()) {
vert_positions[i] = float3(vertices[i].x(), vertices[i].y(), vertices[i].z());
}
for (const int i : IndexRange(quads.size())) {
MPoly &poly = mesh_polys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
mesh_corner_verts[loopstart] = quads[i][0];
mesh_corner_verts[loopstart + 1] = quads[i][3];
mesh_corner_verts[loopstart + 2] = quads[i][2];
@@ -244,10 +245,7 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set
const int triangle_loop_start = quads.size() * 4;
for (const int i : IndexRange(tris.size())) {
MPoly &poly = mesh_polys[quads.size() + i];
const int loopstart = triangle_loop_start + i * 3;
poly.loopstart = loopstart;
poly.totloop = 3;
mesh_corner_verts[loopstart] = tris[i][2];
mesh_corner_verts[loopstart + 1] = tris[i][1];
mesh_corner_verts[loopstart + 2] = tris[i][0];
@@ -316,7 +314,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
const AttributeAccessor src_attributes = source->attributes();
MutableAttributeAccessor dst_attributes = target->attributes_for_write();
const Span<float3> target_positions = target->vert_positions();
const Span<MPoly> target_polys = target->polys();
const OffsetIndices target_polys = target->polys();
const Span<int> target_corner_verts = target->corner_verts();
const VArray<int> src_face_sets = src_attributes.lookup<int>(".sculpt_face_set",
@@ -342,9 +340,8 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
const MPoly &poly = target_polys[i];
const float3 from_co = mesh::poly_center_calc(
target_positions, target_corner_verts.slice(poly.loopstart, poly.totloop));
const float3 from_co = mesh::poly_center_calc(target_positions,
target_corner_verts.slice(target_polys[i]));
BLI_bvhtree_find_nearest(
bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
@@ -416,19 +413,15 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
if (!source_lmap) {
BKE_mesh_vert_loop_map_create(&source_lmap,
&source_lmap_mem,
source->polys().data(),
source->polys(),
source->corner_verts().data(),
source->totvert,
source->totpoly,
source->totloop);
source->totvert);
BKE_mesh_vert_loop_map_create(&target_lmap,
&target_lmap_mem,
target->polys().data(),
target->polys(),
target->corner_verts().data(),
target->totvert,
target->totpoly,
target->totloop);
target->totvert);
}
blender::threading::parallel_for(
@@ -145,7 +145,7 @@ blender::Span<MLoopTri> Mesh::looptris() const
{
this->runtime->looptris_cache.ensure([&](blender::Array<MLoopTri> &r_data) {
const Span<float3> positions = this->vert_positions();
const Span<MPoly> polys = this->polys();
const blender::OffsetIndices polys = this->polys();
const Span<int> corner_verts = this->corner_verts();
r_data.reinitialize(poly_to_tri_count(polys.size(), corner_verts.size()));
@@ -324,7 +324,7 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
MutableSpan<float3> positions = me_eval->vert_positions_for_write();
MutableSpan<MEdge> edges = me_eval->edges_for_write();
MutableSpan<MPoly> polys = me_eval->polys_for_write();
MutableSpan<int> poly_offsets = me_eval->poly_offsets_for_write();
MutableSpan<int> corner_verts = me_eval->corner_verts_for_write();
MutableSpan<int> corner_edges = me_eval->corner_edges_for_write();
@@ -353,8 +353,8 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
corner_verts.data(),
corner_edges.data(),
corner_verts.size(),
polys.data(),
polys.size(),
poly_offsets.data(),
me_eval->totpoly,
me_eval->deform_verts_for_write().data(),
do_verbose,
do_fixes,
@@ -44,39 +44,39 @@ struct BKEMeshToTangent {
uint GetNumVerticesOfFace(const uint face_num)
{
return uint(polys[face_num].totloop);
return uint(polys[face_num].size());
}
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
{
const uint loop_idx = uint(polys[face_num].loopstart) + vert_num;
const uint loop_idx = uint(polys[face_num].start()) + vert_num;
return mikk::float3(positions[corner_verts[loop_idx]]);
}
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
{
const float *uv = luvs[uint(polys[face_num].loopstart) + vert_num];
const float *uv = luvs[uint(polys[face_num].start()) + vert_num];
return mikk::float3(uv[0], uv[1], 1.0f);
}
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
{
return mikk::float3(loop_normals[uint(polys[face_num].loopstart) + vert_num]);
return mikk::float3(loop_normals[uint(polys[face_num].start()) + vert_num]);
}
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
{
float *p_res = tangents[uint(polys[face_num].loopstart) + vert_num];
float *p_res = tangents[uint(polys[face_num].start()) + vert_num];
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
}
const MPoly *polys; /* faces */
const int *corner_verts; /* faces vertices */
const float (*positions)[3]; /* vertices */
const float (*luvs)[2]; /* texture coordinates */
const float (*loop_normals)[3]; /* loops' normals */
float (*tangents)[4]; /* output tangents */
int num_polys; /* number of polygons */
blender::OffsetIndices<int> polys; /* faces */
const int *corner_verts; /* faces vertices */
const float (*positions)[3]; /* vertices */
const float (*luvs)[2]; /* texture coordinates */
const float (*loop_normals)[3]; /* loops' normals */
float (*tangents)[4]; /* output tangents */
int num_polys; /* number of polygons */
};
void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
@@ -86,8 +86,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
const float (*loop_normals)[3],
const float (*loop_uvs)[2],
const int /*numLoops*/,
const MPoly *polys,
const int numPolys,
const blender::OffsetIndices<int> polys,
ReportList *reports)
{
/* Compute Mikktspace's tangent normals. */
@@ -98,13 +97,13 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
mesh_to_tangent.luvs = loop_uvs;
mesh_to_tangent.loop_normals = loop_normals;
mesh_to_tangent.tangents = r_looptangent;
mesh_to_tangent.num_polys = numPolys;
mesh_to_tangent.num_polys = int(polys.size());
mikk::Mikktspace<BKEMeshToTangent> mikk(mesh_to_tangent);
/* First check we do have a tris/quads only mesh. */
for (int i = 0; i < numPolys; i++) {
if (polys[i].totloop > 4) {
for (const int64_t i : polys.index_range()) {
if (polys[i].size() > 4) {
BKE_report(
reports, RPT_ERROR, "Tangent space can only be computed for tris/quads, aborting");
return;
@@ -151,8 +150,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
loop_normals,
reinterpret_cast<const float(*)[2]>(uv_map.data()),
mesh->totloop,
mesh->polys().data(),
mesh->totpoly,
mesh->polys(),
reports);
}
@@ -180,8 +178,7 @@ struct SGLSLMeshToTangent {
#ifdef USE_LOOPTRI_DETECT_QUADS
if (face_as_quad_map) {
const MLoopTri *lt = &looptri[face_as_quad_map[face_num]];
const MPoly &poly = polys[lt->poly];
if (poly.totloop == 4) {
if (polys[lt->poly].size() == 4) {
return 4;
}
}
@@ -197,9 +194,8 @@ struct SGLSLMeshToTangent {
#ifdef USE_LOOPTRI_DETECT_QUADS
if (face_as_quad_map) {
lt = &looptri[face_as_quad_map[face_num]];
const MPoly &poly = polys[lt->poly];
if (poly.totloop == 4) {
return (uint(poly.loopstart) + vert_num);
if (polys[lt->poly].size() == 4) {
return uint(polys[lt->poly][vert_num]);
}
/* fall through to regular triangle */
}
@@ -245,14 +241,14 @@ struct SGLSLMeshToTangent {
return mikk::float3(precomputedFaceNormals[lt->poly]);
}
#ifdef USE_LOOPTRI_DETECT_QUADS
const MPoly &poly = polys[lt->poly];
const blender::IndexRange poly = polys[lt->poly];
float normal[3];
if (poly.totloop == 4) {
if (poly.size() == 4) {
normal_quad_v3(normal,
positions[corner_verts[poly.loopstart + 0]],
positions[corner_verts[poly.loopstart + 1]],
positions[corner_verts[poly.loopstart + 2]],
positions[corner_verts[poly.loopstart + 3]]);
positions[corner_verts[poly[0]]],
positions[corner_verts[poly[1]]],
positions[corner_verts[poly[2]]],
positions[corner_verts[poly[3]]]);
}
else
#endif
@@ -278,8 +274,8 @@ struct SGLSLMeshToTangent {
const float (*precomputedFaceNormals)[3];
const float (*precomputedLoopNormals)[3];
const MLoopTri *looptri;
const float2 *mloopuv; /* texture coordinates */
const MPoly *polys; /* indices */
const float2 *mloopuv; /* texture coordinates */
blender::OffsetIndices<int> polys;
const int *corner_verts; /* indices */
const float (*positions)[3]; /* vertex coordinates */
const float (*vert_normals)[3];
@@ -389,8 +385,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 blender::OffsetIndices<int> polys,
const int *corner_verts,
const MLoopTri *looptri,
const uint looptri_len,
@@ -457,7 +452,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
int *face_as_quad_map = nullptr;
/* map faces to quads */
if (looptri_len != polys_len) {
if (looptri_len != uint(polys.size())) {
/* Over allocate, since we don't know how many ngon or quads we have. */
/* map fake face index to looptri */
@@ -466,7 +461,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
for (k = 0, j = 0; j < int(looptri_len); k++, j++) {
face_as_quad_map[k] = j;
/* step over all quads */
if (polys[looptri[j].poly].totloop == 4) {
if (polys[looptri[j].poly].size() == 4) {
j++; /* skips the nest looptri */
}
}
@@ -580,8 +575,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
short tangent_mask = 0;
BKE_mesh_calc_loop_tangent_ex(
BKE_mesh_vert_positions(me_eval),
me_eval->polys().data(),
uint(me_eval->totpoly),
me_eval->polys(),
me_eval->corner_verts().data(),
looptris.data(),
uint(looptris.size()),
@@ -35,7 +35,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<int> corner_verts,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<float3> positions,
uint poly_index,
MLoopTri *mlt,
@@ -43,8 +43,8 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span<int> corner_vert
const bool face_normal,
const float normal_precalc[3])
{
const uint mp_loopstart = uint(polys[poly_index].loopstart);
const uint mp_totloop = uint(polys[poly_index].totloop);
const uint mp_loopstart = uint(polys[poly_index].start());
const uint mp_totloop = uint(polys[poly_index].size());
auto create_tri = [&](uint i1, uint i2, uint i3) {
mlt->tri[0] = mp_loopstart + i1;
@@ -142,7 +142,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span<int> corner_vert
}
static void mesh_calc_tessellation_for_face(const Span<int> corner_verts,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<float3> positions,
uint poly_index,
MLoopTri *mlt,
@@ -153,7 +153,7 @@ static void mesh_calc_tessellation_for_face(const Span<int> corner_verts,
}
static void mesh_calc_tessellation_for_face_with_normal(const Span<int> corner_verts,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<float3> positions,
uint poly_index,
MLoopTri *mlt,
@@ -165,34 +165,31 @@ static void mesh_calc_tessellation_for_face_with_normal(const Span<int> corner_v
}
static void mesh_recalc_looptri__single_threaded(const Span<int> corner_verts,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<float3> positions,
int totloop,
int totpoly,
MLoopTri *mlooptri,
const float (*poly_normals)[3])
{
MemArena *pf_arena = nullptr;
const MPoly *poly = polys.data();
uint tri_index = 0;
if (poly_normals != nullptr) {
for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, poly++) {
for (const int64_t i : polys.index_range()) {
mesh_calc_tessellation_for_face_with_normal(corner_verts,
polys,
positions,
poly_index,
uint(i),
&mlooptri[tri_index],
&pf_arena,
poly_normals[poly_index]);
tri_index += uint(poly->totloop - 2);
poly_normals[i]);
tri_index += uint(polys[i].size() - 2);
}
}
else {
for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, poly++) {
for (const int64_t i : polys.index_range()) {
mesh_calc_tessellation_for_face(
corner_verts, polys, positions, poly_index, &mlooptri[tri_index], &pf_arena);
tri_index += uint(poly->totloop - 2);
corner_verts, polys, positions, uint(i), &mlooptri[tri_index], &pf_arena);
tri_index += uint(polys[i].size() - 2);
}
}
@@ -200,13 +197,12 @@ static void mesh_recalc_looptri__single_threaded(const Span<int> corner_verts,
BLI_memarena_free(pf_arena);
pf_arena = nullptr;
}
BLI_assert(tri_index == uint(poly_to_tri_count(totpoly, totloop)));
UNUSED_VARS_NDEBUG(totloop);
BLI_assert(tri_index == uint(poly_to_tri_count(int(polys.size()), int(corner_verts.size()))));
}
struct TessellationUserData {
Span<int> corner_verts;
Span<MPoly> polys;
blender::OffsetIndices<int> polys;
Span<float3> positions;
/** Output array. */
@@ -226,7 +222,7 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata,
{
const TessellationUserData *data = static_cast<const TessellationUserData *>(userdata);
TessellationUserTLS *tls_data = static_cast<TessellationUserTLS *>(tls->userdata_chunk);
const int tri_index = poly_to_tri_count(index, data->polys[index].loopstart);
const int tri_index = poly_to_tri_count(index, int(data->polys[index].start()));
mesh_calc_tessellation_for_face_impl(data->corner_verts,
data->polys,
data->positions,
@@ -243,7 +239,7 @@ static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict user
{
const TessellationUserData *data = static_cast<const TessellationUserData *>(userdata);
TessellationUserTLS *tls_data = static_cast<TessellationUserTLS *>(tls->userdata_chunk);
const int tri_index = poly_to_tri_count(index, data->polys[index].loopstart);
const int tri_index = poly_to_tri_count(index, int(data->polys[index].start()));
mesh_calc_tessellation_for_face_impl(data->corner_verts,
data->polys,
data->positions,
@@ -264,7 +260,7 @@ static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict /*use
}
static void looptris_calc_all(const Span<float3> positions,
const Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<float3> poly_normals,
MutableSpan<MLoopTri> looptris)
@@ -273,8 +269,6 @@ static void looptris_calc_all(const Span<float3> positions,
mesh_recalc_looptri__single_threaded(corner_verts,
polys,
positions,
int(corner_verts.size()),
int(polys.size()),
looptris.data(),
reinterpret_cast<const float(*)[3]>(poly_normals.data()));
return;
@@ -306,7 +300,7 @@ static void looptris_calc_all(const Span<float3> positions,
}
void looptris_calc(const Span<float3> vert_positions,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
MutableSpan<MLoopTri> looptris)
{
@@ -314,19 +308,19 @@ void looptris_calc(const Span<float3> vert_positions,
}
void looptris_calc_with_normals(const Span<float3> vert_positions,
const Span<MPoly> polys,
const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<float3> poly_normals,
MutableSpan<MLoopTri> looptris)
{
BLI_assert(!poly_normals.is_empty() || polys.is_empty());
BLI_assert(!poly_normals.is_empty() || polys.size() == 0);
looptris_calc_all(vert_positions, polys, corner_verts, poly_normals, looptris);
}
} // namespace blender::bke::mesh
void BKE_mesh_recalc_looptri(const int *corner_verts,
const MPoly *polys,
const int *poly_offsets,
const float (*vert_positions)[3],
int totvert,
int totloop,
@@ -335,7 +329,7 @@ void BKE_mesh_recalc_looptri(const int *corner_verts,
{
blender::bke::mesh::looptris_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions), totvert},
{polys, totpoly},
blender::Span(poly_offsets, totpoly + 1),
{corner_verts, totloop},
{mlooptri, poly_to_tri_count(totpoly, totloop)});
}
@@ -42,7 +42,7 @@ using blender::Span;
static CLG_LogRef LOG = {"bke.mesh"};
void mesh_strip_polysloops(Mesh *me);
void strip_loose_polysloops(Mesh *me, blender::BitSpan polys_to_remove);
void mesh_strip_edges(Mesh *me);
/* -------------------------------------------------------------------- */
@@ -219,7 +219,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
int *corner_verts,
int *corner_edges,
uint totloop,
MPoly *polys,
int *poly_offsets,
uint totpoly,
MDeformVert *dverts, /* assume totvert length */
const bool do_verbose,
@@ -240,17 +240,19 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
free_flag.polyloops = do_fixes; \
} \
(void)0
#define REMOVE_POLY_TAG(_mp) \
{ \
_mp->totloop *= -1; \
free_flag.polyloops = do_fixes; \
} \
(void)0
blender::BitVector<> polys_to_remove(totpoly);
blender::bke::AttributeWriter<int> material_indices =
mesh->attributes_for_write().lookup_for_write<int>("material_index");
blender::MutableVArraySpan<int> material_indices_span(material_indices.varray);
#if 0
const blender::OffsetIndices<int> polys({poly_offsets, totpoly + 1});
for (const int i : polys.index_range()) {
BLI_assert(polys[i].size() > 2);
}
#endif
MEdge *edge;
uint i, j;
int *v;
@@ -346,7 +348,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
}
if (mfaces && !polys) {
if (mfaces && !poly_offsets) {
#define REMOVE_FACE_TAG(_mf) \
{ \
_mf->v3 = 0; \
@@ -531,8 +533,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
int prev_end;
for (const int64_t i : blender::IndexRange(totpoly)) {
const MPoly &poly = polys[i];
const int poly_start = poly_offsets[i];
const int poly_size = poly_offsets[i + 1] - poly_start;
sp->index = i;
/* Material index, isolated from other tests here. While large indices are clamped,
@@ -545,22 +547,20 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
}
if (poly.loopstart < 0 || poly.totloop < 3) {
if (poly_start < 0 || poly_size < 3) {
/* Invalid loop data. */
PRINT_ERR("\tPoly %u is invalid (loopstart: %d, totloop: %d)",
sp->index,
poly.loopstart,
poly.totloop);
PRINT_ERR(
"\tPoly %u is invalid (loopstart: %d, totloop: %d)", sp->index, poly_start, poly_size);
sp->invalid = true;
}
else if (poly.loopstart + poly.totloop > totloop) {
else if (poly_start + poly_size > totloop) {
/* Invalid loop data. */
PRINT_ERR(
"\tPoly %u uses loops out of range "
"(loopstart: %d, loopend: %d, max number of loops: %u)",
sp->index,
poly.loopstart,
poly.loopstart + poly.totloop - 1,
poly_start,
poly_start + poly_size - 1,
totloop - 1);
sp->invalid = true;
}
@@ -568,14 +568,14 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
/* Poly itself is valid, for now. */
int v1, v2; /* v1 is prev loop vert idx, v2 is current loop one. */
sp->invalid = false;
sp->verts = v = (int *)MEM_mallocN(sizeof(int) * poly.totloop, "Vert idx of SortPoly");
sp->numverts = poly.totloop;
sp->loopstart = poly.loopstart;
sp->verts = v = (int *)MEM_mallocN(sizeof(int) * poly_size, "Vert idx of SortPoly");
sp->numverts = poly_size;
sp->loopstart = poly_start;
/* 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; j < poly.totloop; j++) {
for (j = 0; j < poly_size; j++) {
const int vert = corner_verts[sp->loopstart + j];
if (vert < totvert) {
BLI_BITMAP_DISABLE(vert_tag, vert);
@@ -583,7 +583,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
/* Test all poly's loops' vert idx. */
for (j = 0; j < poly.totloop; j++, v++) {
for (j = 0; j < poly_size; j++, v++) {
const int vert = corner_verts[sp->loopstart + j];
if (vert >= totvert) {
/* Invalid vert idx. */
@@ -606,12 +606,12 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
/* Test all poly's loops. */
for (j = 0; j < poly.totloop; j++) {
for (j = 0; j < poly_size; 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];
v2 = corner_verts[sp->loopstart + (j + 1) % poly_size];
if (!BLI_edgehash_haskey(edge_hash, v1, v2)) {
/* Edge not existing. */
PRINT_ERR("\tPoly %u needs missing edge (%d, %d)", sp->index, v1, v2);
@@ -726,7 +726,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
*/
if (sp->invalid) {
if (do_fixes) {
REMOVE_POLY_TAG((&polys[sp->index]));
polys_to_remove[sp->index].set();
/* DO NOT REMOVE ITS LOOPS!!!
* As already invalid polys are at the end of the SortPoly list, the loops they
* were the only users have already been tagged as "to remove" during previous
@@ -757,7 +757,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
prev_end,
sp->index);
if (do_fixes) {
REMOVE_POLY_TAG((&polys[sp->index]));
polys_to_remove[sp->index].set();
/* DO NOT REMOVE ITS LOOPS!!!
* They might be used by some next, valid poly!
* Just not updating prev_end/prev_sp vars is enough to ensure the loops
@@ -843,7 +843,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
if (free_flag.polyloops) {
mesh_strip_polysloops(mesh);
strip_loose_polysloops(mesh, polys_to_remove);
}
if (free_flag.edges) {
@@ -1091,7 +1091,7 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
&changed);
MutableSpan<float3> positions = me->vert_positions_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<int> poly_offsets = me->poly_offsets_for_write();
MutableSpan<int> corner_verts = me->corner_verts_for_write();
MutableSpan<int> corner_edges = me->corner_edges_for_write();
@@ -1106,8 +1106,8 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
corner_verts.data(),
corner_edges.data(),
corner_verts.size(),
polys.data(),
polys.size(),
poly_offsets.data(),
me->totpoly,
me->deform_verts_for_write().data(),
do_verbose,
true,
@@ -1145,7 +1145,7 @@ bool BKE_mesh_is_valid(Mesh *me)
MutableSpan<float3> positions = me->vert_positions_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<int> poly_offsets = me->poly_offsets_for_write();
MutableSpan<int> corner_verts = me->corner_verts_for_write();
MutableSpan<int> corner_edges = me->corner_edges_for_write();
@@ -1160,8 +1160,8 @@ bool BKE_mesh_is_valid(Mesh *me)
corner_verts.data(),
corner_edges.data(),
corner_verts.size(),
polys.data(),
polys.size(),
poly_offsets.data(),
me->totpoly,
me->deform_verts_for_write().data(),
do_verbose,
do_fixes,
@@ -1225,9 +1225,9 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
}
}
void mesh_strip_polysloops(Mesh *me)
void strip_loose_polysloops(Mesh *me, blender::BitSpan polys_to_remove)
{
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<int> poly_offsets = me->poly_offsets_for_write();
MutableSpan<int> corner_edges = me->corner_edges_for_write();
int a, b;
@@ -1235,26 +1235,26 @@ void mesh_strip_polysloops(Mesh *me)
int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__);
for (a = b = 0; a < me->totpoly; a++) {
const MPoly &poly = polys[a];
bool invalid = false;
int i = poly.loopstart;
int stop = i + poly.totloop;
int start = poly_offsets[a];
int size = poly_offsets[a + 1] - start;
int stop = start + size;
if (stop > me->totloop || stop < i || poly.loopstart < 0) {
if (polys_to_remove[a]) {
invalid = true;
}
else if (stop > me->totloop || stop < start || size < 0) {
invalid = true;
}
else {
/* If one of the poly's loops is invalid, the whole poly is invalid! */
if (corner_edges.slice(poly.loopstart, poly.totloop)
.as_span()
.contains(INVALID_LOOP_EDGE_MARKER)) {
if (corner_edges.slice(start, size).as_span().contains(INVALID_LOOP_EDGE_MARKER)) {
invalid = true;
}
}
if (poly.totloop >= 3 && !invalid) {
if (size >= 3 && !invalid) {
if (a != b) {
memcpy(&polys[b], &poly, sizeof(polys[b]));
CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
}
b++;
@@ -1286,10 +1286,13 @@ void mesh_strip_polysloops(Mesh *me)
me->totloop = b;
}
poly_offsets[me->totpoly] = me->totloop;
/* And now, update polys' start loop index. */
/* NOTE: At this point, there should never be any poly using a striped loop! */
for (const int i : polys.index_range()) {
polys[i].loopstart = new_idx[polys[i].loopstart];
for (const int i : blender::IndexRange(me->totpoly)) {
poly_offsets[i] = new_idx[poly_offsets[i]];
BLI_assert(poly_offsets[i] >= 0);
}
MEM_freeN(new_idx);
@@ -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, corner verts, corner edges, #MEdge, etc).
* #Mesh data (#Mesh::polys(), 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.
+20 -23
View File
@@ -183,7 +183,7 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidde
static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int level)
{
const blender::Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const MDisps *mdisps = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
BLI_bitmap **grid_hidden = ccgdm->gridHidden;
int *gridOffset;
@@ -192,7 +192,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int
gridOffset = ccgdm->dm.getGridOffset(&ccgdm->dm);
for (const int i : polys.index_range()) {
for (j = 0; j < polys[i].totloop; j++) {
for (j = 0; j < polys[i].size(); j++) {
int g = gridOffset[i] + j;
const MDisps *md = &mdisps[g];
BLI_bitmap *gh = md->hidden;
@@ -487,15 +487,14 @@ void multires_force_external_reload(Object *object)
static int get_levels_from_disps(Object *ob)
{
Mesh *me = static_cast<Mesh *>(ob->data);
const blender::Span<MPoly> polys = me->polys();
int j, totlvl = 0;
const blender::OffsetIndices polys = me->polys();
int totlvl = 0;
const MDisps *mdisp = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
for (const int i : polys.index_range()) {
const MDisps *md = mdisp + polys[i].loopstart;
for (j = 0; j < polys[i].totloop; j++, md++) {
for (const int corner : polys[i]) {
const MDisps *md = &mdisp[corner];
if (md->totdisp == 0) {
continue;
}
@@ -657,7 +656,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
{
Mesh *me = (Mesh *)ob->data;
const blender::Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
GridPaintMask *gpm;
@@ -675,12 +674,10 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
if (lvl > 0) {
int nsize = multires_side_tot[lvl];
int hsize = multires_side_tot[mmd->totlvl];
int j;
for (const int i : polys.index_range()) {
for (j = 0; j < polys[i].totloop; j++) {
int g = polys[i].loopstart + j;
MDisps *mdisp = &mdisps[g];
for (const int corner : polys[i]) {
MDisps *mdisp = &mdisps[corner];
float(*disps)[3], (*ndisps)[3], (*hdisps)[3];
int totdisp = multires_grid_tot[lvl];
@@ -706,7 +703,7 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
mdisp->level = lvl;
if (gpm) {
multires_grid_paint_mask_downsample(&gpm[g], lvl);
multires_grid_paint_mask_downsample(&gpm[corner], lvl);
}
}
}
@@ -855,7 +852,7 @@ struct MultiresThreadedData {
CCGElem **gridData, **subGridData;
CCGKey *key;
CCGKey *sub_key;
const MPoly *polys;
blender::OffsetIndices<int> polys;
MDisps *mdisps;
GridPaintMask *grid_paint_mask;
int *gridOffset;
@@ -873,7 +870,7 @@ static void multires_disp_run_cb(void *__restrict userdata,
CCGElem **gridData = tdata->gridData;
CCGElem **subGridData = tdata->subGridData;
CCGKey *key = tdata->key;
const MPoly *polys = tdata->polys;
blender::OffsetIndices<int> polys = tdata->polys;
MDisps *mdisps = tdata->mdisps;
GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
int *gridOffset = tdata->gridOffset;
@@ -881,12 +878,12 @@ static void multires_disp_run_cb(void *__restrict userdata,
int dGridSize = tdata->dGridSize;
int dSkip = tdata->dSkip;
const int numVerts = polys[pidx].totloop;
const int numVerts = polys[pidx].size();
int S, x, y, gIndex = gridOffset[pidx];
for (S = 0; S < numVerts; S++, gIndex++) {
GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : nullptr;
MDisps *mdisp = &mdisps[polys[pidx].loopstart + S];
MDisps *mdisp = &mdisps[polys[pidx][S]];
CCGElem *grid = gridData[gIndex];
CCGElem *subgrid = subGridData[gIndex];
float(*dispgrid)[3] = nullptr;
@@ -967,7 +964,7 @@ static void multiresModifier_disp_run(
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGElem **gridData, **subGridData;
CCGKey key;
const MPoly *polys = me->polys().data();
blender::OffsetIndices polys = me->polys();
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
GridPaintMask *grid_paint_mask = nullptr;
@@ -977,8 +974,8 @@ static void multiresModifier_disp_run(
/* this happens in the dm made by bmesh_mdisps_space_set */
if (dm2 && CustomData_has_layer(&dm2->loopData, CD_MDISPS)) {
polys = static_cast<const MPoly *>(
CustomData_get_layer_for_write(&dm2->polyData, CD_MPOLY, dm2->getNumPolys(dm)));
polys = blender::OffsetIndices(
blender::Span(dm2->getPolyArray(dm2), dm2->getNumPolys(dm2) + 1));
mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&dm2->loopData, CD_MDISPS, dm2->getNumLoops(dm)));
totloop = dm2->numLoopData;
@@ -1555,12 +1552,12 @@ void multiresModifier_ensure_external_read(struct Mesh *mesh, const MultiresModi
/***************** Multires interpolation stuff *****************/
int mdisp_rot_face_to_crn(
const MPoly *poly, const int face_side, const float u, const float v, float *x, float *y)
const int face_size, const int face_side, const float u, const float v, float *x, float *y)
{
const float offset = face_side * 0.5f - 0.5f;
int S = 0;
if (poly->totloop == 4) {
if (face_size == 4) {
if (u <= offset && v <= offset) {
S = 0;
}
@@ -1591,7 +1588,7 @@ int mdisp_rot_face_to_crn(
*y = v - offset;
}
}
else if (poly->totloop == 3) {
else if (face_size == 3) {
int grid_size = offset;
float w = (face_side - 1) - u - v;
float W1, W2;
@@ -7,6 +7,7 @@
#pragma once
#include "BLI_offset_indices.hh"
#include "BLI_span.hh"
#include "BLI_sys_types.h"
@@ -17,7 +18,6 @@ struct GridPaintMask;
struct MDisps;
struct MEdge;
struct Mesh;
struct MPoly;
struct MultiresModifierData;
struct Object;
struct Subdiv;
@@ -35,7 +35,7 @@ struct MultiresReshapeContext {
Mesh *base_mesh;
const float (*base_positions)[3];
blender::Span<MEdge> base_edges;
blender::Span<MPoly> base_polys;
blender::OffsetIndices<int> base_polys;
blender::Span<int> base_corner_verts;
blender::Span<int> base_corner_edges;
@@ -74,11 +74,9 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
int *pmap_mem;
BKE_mesh_vert_poly_map_create(&pmap,
&pmap_mem,
reshape_context->base_polys.data(),
reshape_context->base_polys,
reshape_context->base_corner_verts.data(),
base_mesh->totvert,
base_mesh->totpoly,
base_mesh->totloop);
base_mesh->totvert);
float(*origco)[3] = static_cast<float(*)[3]>(
MEM_calloc_arrayN(base_mesh->totvert, sizeof(float[3]), __func__));
@@ -97,11 +95,11 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find center. */
int tot = 0;
for (int j = 0; j < pmap[i].count; j++) {
const MPoly &poly = reshape_context->base_polys[pmap[i].indices[j]];
const blender::IndexRange poly = reshape_context->base_polys[pmap[i].indices[j]];
/* 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_corner_verts[poly.loopstart + k];
for (const int corner : poly) {
const int vndx = reshape_context->base_corner_verts[corner];
if (vndx != i) {
add_v3_v3(center, origco[vndx]);
tot++;
@@ -112,14 +110,14 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find normal. */
for (int j = 0; j < pmap[i].count; j++) {
const MPoly &poly = reshape_context->base_polys[pmap[i].indices[j]];
const blender::IndexRange 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<int> poly_verts(poly.totloop);
blender::Array<blender::float3> fake_co(poly.totloop);
blender::Array<int> poly_verts(poly.size());
blender::Array<blender::float3> fake_co(poly.size());
for (int k = 0; k < poly.totloop; k++) {
const int vndx = reshape_context->base_corner_verts[poly.loopstart + k];
for (int k = 0; k < poly.size(); k++) {
const int vndx = reshape_context->base_corner_verts[poly[k]];
poly_verts[k] = k;
@@ -648,8 +648,7 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context,
const int face_index = multires_reshape_grid_to_face_index(reshape_context,
grid_coord.grid_index);
const MPoly &base_poly = reshape_context->base_polys[face_index];
const int num_corners = base_poly.totloop;
const int num_corners = reshape_context->base_polys[face_index].size();
const int start_grid_index = reshape_context->face_start_grid_index[face_index];
const int corner = grid_coord.grid_index - start_grid_index;
@@ -849,7 +848,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<MPoly> base_polys = reshape_context->base_polys;
const blender::OffsetIndices base_polys = reshape_context->base_polys;
const blender::Span<int> base_corner_edges = reshape_context->base_corner_edges;
reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge,
@@ -857,8 +856,7 @@ 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 (const int edge : base_corner_edges.slice(base_poly.loopstart, base_poly.totloop)) {
for (const int edge : base_corner_edges.slice(base_polys[poly_index])) {
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);
@@ -31,24 +31,23 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
const Span<float3> positions = mesh->vert_positions();
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
MDisps *mdisps = static_cast<MDisps *>(
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, corner_verts.slice(poly.loopstart, poly.totloop));
for (int l = 0; l < poly.totloop; l++) {
const int loop_index = poly.loopstart + l;
const blender::IndexRange poly = polys[p];
const float3 poly_center = mesh::poly_center_calc(positions, corner_verts.slice(poly));
for (int l = 0; l < poly.size(); l++) {
const int loop_index = poly[l];
float(*disps)[3] = mdisps[loop_index].disps;
mdisps[loop_index].totdisp = 4;
mdisps[loop_index].level = 1;
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;
int prev_loop_index = l - 1 >= 0 ? loop_index - 1 : loop_index + poly.size() - 1;
int next_loop_index = l + 1 < poly.size() ? loop_index + 1 : poly.start();
const int vert = corner_verts[loop_index];
const int vert_next = corner_verts[next_loop_index];
@@ -67,7 +67,7 @@ static void context_zero(MultiresReshapeContext *reshape_context)
static void context_init_lookup(MultiresReshapeContext *reshape_context)
{
const Mesh *base_mesh = reshape_context->base_mesh;
const blender::Span<MPoly> polys = reshape_context->base_polys;
const blender::OffsetIndices polys = reshape_context->base_polys;
const int num_faces = base_mesh->totpoly;
reshape_context->face_start_grid_index = static_cast<int *>(
@@ -75,7 +75,7 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context)
int num_grids = 0;
int num_ptex_faces = 0;
for (int face_index = 0; face_index < num_faces; ++face_index) {
const int num_corners = polys[face_index].totloop;
const int num_corners = polys[face_index].size();
reshape_context->face_start_grid_index[face_index] = num_grids;
num_grids += num_corners;
num_ptex_faces += (num_corners == 4) ? 1 : num_corners;
@@ -86,7 +86,7 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context)
reshape_context->ptex_start_grid_index = static_cast<int *>(
MEM_malloc_arrayN(num_ptex_faces, sizeof(int), "ptex_start_grid_index"));
for (int face_index = 0, grid_index = 0, ptex_index = 0; face_index < num_faces; ++face_index) {
const int num_corners = polys[face_index].totloop;
const int num_corners = polys[face_index].size();
const int num_face_ptex_faces = (num_corners == 4) ? 1 : num_corners;
for (int i = 0; i < num_face_ptex_faces; ++i) {
reshape_context->ptex_start_grid_index[ptex_index + i] = grid_index + i;
@@ -372,8 +372,7 @@ int multires_reshape_grid_to_corner(const MultiresReshapeContext *reshape_contex
bool multires_reshape_is_quad_face(const MultiresReshapeContext *reshape_context, int face_index)
{
const MPoly &base_poly = reshape_context->base_polys[face_index];
return (base_poly.totloop == 4);
return reshape_context->base_polys[face_index].size() == 4;
}
int multires_reshape_grid_to_ptex_index(const MultiresReshapeContext *reshape_context,
@@ -669,11 +668,11 @@ static void foreach_grid_face_coordinate_task(void *__restrict userdata_v,
const MultiresReshapeContext *reshape_context = data->reshape_context;
const blender::Span<MPoly> polys = reshape_context->base_polys;
const blender::OffsetIndices polys = reshape_context->base_polys;
const int grid_size = data->grid_size;
const float grid_size_1_inv = 1.0f / (float(grid_size) - 1.0f);
const int num_corners = polys[face_index].totloop;
const int num_corners = polys[face_index].size();
int grid_index = reshape_context->face_start_grid_index[face_index];
for (int corner = 0; corner < num_corners; ++corner, ++grid_index) {
for (int y = 0; y < grid_size; ++y) {
@@ -54,8 +54,7 @@ static void multires_reshape_vertcos_foreach_vertex(const SubdivForeachContext *
const int face_index = multires_reshape_grid_to_face_index(reshape_context,
grid_coord.grid_index);
const MPoly &base_poly = reshape_context->base_polys[face_index];
const int num_corners = base_poly.totloop;
const int num_corners = reshape_context->base_polys[face_index].size();
const int start_grid_index = reshape_context->face_start_grid_index[face_index];
const int corner = grid_coord.grid_index - start_grid_index;
@@ -642,17 +642,17 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
int grid_y)
{
Mesh *original_mesh = context->original_mesh;
const blender::Span<MPoly> polys = original_mesh->polys();
const blender::OffsetIndices polys = original_mesh->polys();
const blender::Span<int> corner_verts = original_mesh->corner_verts();
const MPoly &poly = polys[BM_elem_index_get(f)];
const blender::IndexRange poly = polys[BM_elem_index_get(f)];
const int corner_vertex_index = BM_elem_index_get(v);
/* Calculates an offset to write the grids correctly oriented in the main
* #MultiresUnsubdivideGrid. */
int loop_offset = 0;
for (int i = 0; i < poly.totloop; i++) {
const int loop_index = poly.loopstart + i;
for (int i = 0; i < poly.size(); i++) {
const int loop_index = poly[i];
if (corner_verts[loop_index] == corner_vertex_index) {
loop_offset = i;
break;
@@ -666,8 +666,8 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
float(*face_grid)[3] = static_cast<float(*)[3]>(
MEM_calloc_arrayN(face_grid_area, sizeof(float[3]), "face_grid"));
for (int i = 0; i < poly.totloop; i++) {
const int loop_index = poly.loopstart + i;
for (int i = 0; i < poly.size(); i++) {
const int loop_index = poly[i];
MDisps *mdisp = &context->original_mdisp[loop_index];
int quad_loop = i - loop_offset;
if (quad_loop < 0) {
@@ -920,7 +920,7 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
MultiresUnsubdivideContext *context)
{
Mesh *original_mesh = context->original_mesh;
const blender::Span<MPoly> original_polys = original_mesh->polys();
const blender::OffsetIndices original_polys = original_mesh->polys();
Mesh *base_mesh = context->base_mesh;
@@ -953,10 +953,8 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
MEM_calloc_arrayN(original_mesh->totloop, sizeof(int), "loop map"));
for (int i = 0; i < original_mesh->totpoly; i++) {
const MPoly &poly = original_polys[i];
for (int l = 0; l < poly.totloop; l++) {
int original_loop_index = l + poly.loopstart;
context->loop_to_face_map[original_loop_index] = i;
for (const int corner : original_polys[i]) {
context->loop_to_face_map[corner] = i;
}
}
}
@@ -965,21 +963,21 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
* Checks the orientation of the loops to flip the x and y axis when extracting the grid if
* necessary.
*/
static bool multires_unsubdivide_flip_grid_x_axis(const blender::Span<MPoly> polys,
static bool multires_unsubdivide_flip_grid_x_axis(const blender::OffsetIndices<int> polys,
const blender::Span<int> corner_verts,
int poly_index,
int loop,
int v_x)
{
const MPoly &poly = polys[poly_index];
const blender::IndexRange poly = polys[poly_index];
const int v_first = corner_verts[poly.loopstart];
if ((loop == (poly.loopstart + (poly.totloop - 1))) && v_first == v_x) {
const int v_first = corner_verts[poly.start()];
if ((loop == (poly.start() + (poly.size() - 1))) && v_first == v_x) {
return true;
}
int next_l_index = loop + 1;
if (next_l_index < poly.loopstart + poly.totloop) {
if (next_l_index < poly.start() + poly.size()) {
const int v_next = corner_verts[next_l_index];
if (v_next == v_x) {
return true;
@@ -1043,7 +1041,7 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte
const int base_l_offset = CustomData_get_n_offset(
&bm_base_mesh->ldata, CD_PROP_INT32, base_l_layer_index);
const blender::Span<MPoly> polys = base_mesh->polys();
const blender::OffsetIndices polys = base_mesh->polys();
const blender::Span<int> corner_verts = base_mesh->corner_verts();
/* Main loop for extracting the grids. Iterates over the base mesh vertices. */
@@ -1056,8 +1056,8 @@ struct FaceDupliData_Mesh {
FaceDupliData_Params params;
int totface;
const MPoly *polys;
const int *corner_verts;
blender::OffsetIndices<int> polys;
Span<int> corner_verts;
Span<float3> vert_positions;
const float (*orco)[3];
const float2 *mloopuv;
@@ -1155,14 +1155,12 @@ static DupliObject *face_dupli_from_mesh(const DupliContext *ctx,
const float scale_fac,
/* Mesh variables. */
const MPoly &poly,
const int *poly_verts,
const Span<int> poly_verts,
const Span<float3> vert_positions)
{
const int coords_len = poly.totloop;
Array<float3, 64> coords(coords_len);
Array<float3, 64> coords(poly_verts.size());
for (int i = 0; i < coords_len; i++) {
for (int i = 0; i < poly_verts.size(); i++) {
coords[i] = vert_positions[poly_verts[i]];
}
@@ -1205,8 +1203,6 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
Object *inst_ob)
{
FaceDupliData_Mesh *fdd = (FaceDupliData_Mesh *)userdata;
const MPoly *polys = fdd->polys;
const int *corner_verts = fdd->corner_verts;
const float(*orco)[3] = fdd->orco;
const float2 *mloopuv = fdd->mloopuv;
const int totface = fdd->totface;
@@ -1220,27 +1216,26 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
const float scale_fac = ctx->object->instance_faces_scale;
for (const int a : blender::IndexRange(totface)) {
const MPoly &poly = polys[a];
const int *poly_verts = &corner_verts[poly.loopstart];
const blender::IndexRange poly = fdd->polys[a];
const Span<int> poly_verts = fdd->corner_verts.slice(poly);
DupliObject *dob = face_dupli_from_mesh(fdd->params.ctx,
inst_ob,
child_imat,
a,
use_scale,
scale_fac,
poly,
poly_verts,
fdd->vert_positions);
const float w = 1.0f / float(poly.totloop);
const float w = 1.0f / float(poly.size());
if (orco) {
for (int j = 0; j < poly.totloop; j++) {
for (int j = 0; j < poly.size(); j++) {
madd_v3_v3fl(dob->orco, orco[poly_verts[j]], w);
}
}
if (mloopuv) {
for (int j = 0; j < poly.totloop; j++) {
madd_v2_v2fl(dob->uv, mloopuv[poly.loopstart + j], w);
for (int j = 0; j < poly.size(); j++) {
madd_v2_v2fl(dob->uv, mloopuv[poly[j]], w);
}
}
}
@@ -1318,8 +1313,8 @@ static void make_duplis_faces(const DupliContext *ctx)
FaceDupliData_Mesh fdd{};
fdd.params = fdd_params;
fdd.totface = me_eval->totpoly;
fdd.polys = me_eval->polys().data();
fdd.corner_verts = me_eval->corner_verts().data();
fdd.polys = me_eval->polys();
fdd.corner_verts = me_eval->corner_verts();
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) :
+9 -14
View File
@@ -1763,13 +1763,8 @@ static void sculpt_update_object(
sculpt_update_persistent_base(ob);
if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
BKE_mesh_vert_poly_map_create(&ss->pmap,
&ss->pmap_mem,
me->polys().data(),
me->corner_verts().data(),
me->totvert,
me->totpoly,
me->totloop);
BKE_mesh_vert_poly_map_create(
&ss->pmap, &ss->pmap_mem, me->polys(), me->corner_verts().data(), me->totvert);
if (ss->pbvh) {
BKE_pbvh_pmap_set(ss->pbvh, ss->pmap);
@@ -1992,7 +1987,7 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph,
MultiresModifierData *mmd)
{
Mesh *me = static_cast<Mesh *>(ob->data);
const Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
int ret = 0;
@@ -2021,17 +2016,17 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph,
/* If vertices already have mask, copy into multires data. */
if (paint_mask) {
for (const int i : polys.index_range()) {
const MPoly &poly = polys[i];
const blender::IndexRange poly = polys[i];
/* Mask center. */
float avg = 0.0f;
for (const int vert : corner_verts.slice(poly.loopstart, poly.totloop)) {
for (const int vert : corner_verts.slice(poly)) {
avg += paint_mask[vert];
}
avg /= float(poly.totloop);
avg /= float(poly.size());
/* Fill in multires mask corner. */
for (const int corner : blender::IndexRange(poly.loopstart, poly.totloop)) {
for (const int corner : poly) {
GridPaintMask *gpm = &gmask[corner];
const int vert = corner_verts[corner];
const int prev = corner_verts[blender::bke::mesh::poly_corner_prev(poly, vert)];
@@ -2187,7 +2182,7 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
MutableSpan<float3> positions = me->vert_positions_for_write();
const Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
MLoopTri *looptri = static_cast<MLoopTri *>(
@@ -2197,7 +2192,7 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_pbvh_build_mesh(pbvh,
me,
polys.data(),
polys,
corner_verts.data(),
reinterpret_cast<float(*)[3]>(positions.data()),
me->totvert,
+18 -16
View File
@@ -825,7 +825,7 @@ static void pbvh_validate_node_prims(PBVH *pbvh)
void BKE_pbvh_build_mesh(PBVH *pbvh,
Mesh *mesh,
const MPoly *polys,
const blender::OffsetIndices<int> polys,
const int *corner_verts,
float (*vert_positions)[3],
int totvert,
@@ -941,9 +941,9 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
/* Find maximum number of grids per face. */
int max_grids = 1;
const blender::Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
for (const int i : polys.index_range()) {
max_grids = max_ii(max_grids, polys[i].totloop);
max_grids = max_ii(max_grids, polys[i].size());
}
/* Ensure leaf limit is at least 4 so there's room
@@ -957,7 +957,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->ldata = &me->ldata;
pbvh->pdata = &me->pdata;
pbvh->polys = me->polys().data();
pbvh->polys = polys;
pbvh->corner_verts = me->corner_verts().data();
/* We also need the base mesh for PBVH draw. */
@@ -1002,7 +1002,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
PBVH *BKE_pbvh_new(PBVHType type)
{
PBVH *pbvh = MEM_cnew<PBVH>(__func__);
PBVH *pbvh = MEM_new<PBVH>(__func__);
pbvh->respect_hide = true;
pbvh->draw_cache_invalid = true;
pbvh->header.type = type;
@@ -1429,10 +1429,10 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
/* Face normal and mask */
if (lt->poly != mpoly_prev) {
const MPoly &poly = pbvh->polys[lt->poly];
const blender::IndexRange poly = pbvh->polys[lt->poly];
fn = blender::bke::mesh::poly_normal_calc(
{reinterpret_cast<const blender::float3 *>(pbvh->vert_positions), pbvh->totvert},
{&pbvh->corner_verts[poly.loopstart], poly.totloop});
{&pbvh->corner_verts[poly.start()], poly.size()});
mpoly_prev = lt->poly;
}
@@ -3730,7 +3730,8 @@ static void pbvh_face_iter_step(PBVHFaceIter *fd, bool do_step)
}
fd->last_face_index_ = face_index;
const MPoly &poly = fd->polys_[face_index];
const int poly_start = fd->poly_offsets_[face_index];
const int poly_size = fd->poly_offsets_[face_index + 1] - poly_start;
fd->face.i = fd->index = face_index;
@@ -3741,15 +3742,15 @@ static void pbvh_face_iter_step(PBVHFaceIter *fd, bool do_step)
fd->hide = fd->hide_poly_ + face_index;
}
pbvh_face_iter_verts_reserve(fd, poly.totloop);
pbvh_face_iter_verts_reserve(fd, poly_size);
const int *poly_verts = &fd->corner_verts_[poly.loopstart];
const int *poly_verts = &fd->corner_verts_[poly_start];
const int grid_area = fd->subdiv_key_.grid_area;
for (int i = 0; i < poly.totloop; i++) {
for (int i = 0; i < poly_size; i++) {
if (fd->pbvh_type_ == PBVH_GRIDS) {
/* Grid corners. */
fd->verts[i].i = (poly.loopstart + i) * grid_area + grid_area - 1;
fd->verts[i].i = (poly_start + i) * grid_area + grid_area - 1;
}
else {
fd->verts[i].i = poly_verts[i];
@@ -3780,7 +3781,7 @@ void BKE_pbvh_face_iter_init(PBVH *pbvh, PBVHNode *node, PBVHFaceIter *fd)
fd->subdiv_key_ = pbvh->gridkey;
ATTR_FALLTHROUGH;
case PBVH_FACES:
fd->polys_ = pbvh->polys;
fd->poly_offsets_ = pbvh->polys.data();
fd->corner_verts_ = pbvh->corner_verts;
fd->looptri_ = pbvh->looptri;
fd->hide_poly_ = pbvh->hide_poly;
@@ -3862,7 +3863,7 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
break;
}
case PBVH_GRIDS: {
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
CCGKey key = pbvh->gridkey;
bool *hide_poly = static_cast<bool *>(CustomData_get_layer_named_for_write(
@@ -3870,10 +3871,11 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
bool delete_hide_poly = true;
for (const int face_index : polys.index_range()) {
const blender::IndexRange poly = polys[face_index];
bool hidden = false;
for (int loop_index = 0; !hidden && loop_index < polys[face_index].totloop; loop_index++) {
int grid_index = polys[face_index].loopstart + loop_index;
for (int loop_index = 0; !hidden && loop_index < poly.size(); loop_index++) {
int grid_index = poly[loop_index];
if (pbvh->grid_hidden[grid_index] &&
BLI_BITMAP_TEST(pbvh->grid_hidden[grid_index], key.grid_area - 1)) {
@@ -94,12 +94,11 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_
int count = 0;
zero_v4(r_color);
for (const int i_poly : Span(melem.indices, melem.count)) {
const MPoly &poly = pbvh.polys[i_poly];
Span<T> colors{static_cast<const T *>(pbvh.color_layer->data) + poly.loopstart,
poly.totloop};
Span<int> poly_verts{pbvh.corner_verts + poly.loopstart, poly.totloop};
const IndexRange poly = pbvh.polys[i_poly];
Span<T> colors{static_cast<const T *>(pbvh.color_layer->data) + poly.start(), poly.size()};
Span<int> poly_verts{pbvh.corner_verts + poly.start(), poly.size()};
for (const int i : poly_verts.index_range()) {
for (const int i : IndexRange(poly.size())) {
if (poly_verts[i] == index) {
float temp[4];
to_float(colors[i], temp);
@@ -128,12 +127,11 @@ static void pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float co
const MeshElemMap &melem = pbvh.pmap[index];
for (const int i_poly : Span(melem.indices, melem.count)) {
const MPoly &poly = pbvh.polys[i_poly];
MutableSpan<T> colors{static_cast<T *>(pbvh.color_layer->data) + poly.loopstart,
poly.totloop};
Span<int> poly_verts{pbvh.corner_verts + poly.loopstart, poly.totloop};
const IndexRange poly = pbvh.polys[i_poly];
MutableSpan<T> colors{static_cast<T *>(pbvh.color_layer->data) + poly.start(), poly.size()};
Span<int> poly_verts{pbvh.corner_verts + poly.start(), poly.size()};
for (const int i : poly_verts.index_range()) {
for (const int i : IndexRange(poly.size())) {
if (poly_verts[i] == index) {
from_float(color, colors[i]);
}
@@ -8,7 +8,6 @@
struct PBVHGPUFormat;
struct MLoopTri;
struct MPoly;
struct MeshElemMap;
/* Axis-aligned bounding box */
@@ -156,7 +155,7 @@ struct PBVH {
float (*vert_normals)[3];
bool *hide_vert;
float (*vert_positions)[3];
const MPoly *polys;
blender::OffsetIndices<int> polys;
bool *hide_poly;
/** Material indices. Only valid for polygon meshes. */
const int *material_indices;
@@ -114,7 +114,7 @@ bool BKE_shrinkwrap_init_tree(
}
data->mesh = mesh;
data->polys = mesh->polys().data();
data->poly_offsets = mesh->poly_offsets().data();
data->corner_edges = mesh->corner_edges().data();
data->vert_normals = reinterpret_cast<const float(*)[3]>(mesh->vert_normals().data()),
data->sharp_faces = static_cast<const bool *>(
+15 -14
View File
@@ -566,11 +566,12 @@ static void ccd_update_deflector_hash(Depsgraph *depsgraph,
static int count_mesh_quads(Mesh *me)
{
int a, result = 0;
const MPoly *polys = BKE_mesh_polys(me);
if (polys) {
for (a = me->totpoly; a > 0; a--) {
if (polys[a].totloop == 4) {
int result = 0;
const int *poly_offsets = BKE_mesh_poly_offsets(me);
if (poly_offsets) {
for (int i = 0; i < me->totpoly; i++) {
const int poly_size = poly_offsets[i + 1] - poly_offsets[i];
if (poly_size == 4) {
result++;
}
}
@@ -589,7 +590,7 @@ static void add_mesh_quad_diag_springs(Object *ob)
nofquads = count_mesh_quads(me);
if (nofquads) {
const int *corner_verts = BKE_mesh_corner_verts(me);
const MPoly *polys = BKE_mesh_polys(me);
const int *poly_offsets = BKE_mesh_poly_offsets(me);
BodySpring *bs;
/* resize spring-array to hold additional quad springs */
@@ -600,14 +601,14 @@ static void add_mesh_quad_diag_springs(Object *ob)
bs = &ob->soft->bspring[ob->soft->totspring];
// bp = ob->soft->bpoint; /* UNUSED */
for (int a = 0; a < me->totpoly; a++) {
const MPoly *poly = &polys[a];
if (poly->totloop == 4) {
bs->v1 = corner_verts[poly->loopstart + 0];
bs->v2 = corner_verts[poly->loopstart + 2];
const int poly_size = poly_offsets[a + 1] - poly_offsets[a];
if (poly_size == 4) {
bs->v1 = corner_verts[poly_offsets[a] + 0];
bs->v2 = corner_verts[poly_offsets[a] + 2];
bs->springtype = SB_STIFFQUAD;
bs++;
bs->v1 = corner_verts[poly->loopstart + 1];
bs->v2 = corner_verts[poly->loopstart + 3];
bs->v1 = corner_verts[poly_offsets[a] + 1];
bs->v2 = corner_verts[poly_offsets[a] + 3];
bs->springtype = SB_STIFFQUAD;
bs++;
}
@@ -2752,7 +2753,7 @@ static void mesh_faces_to_scratch(Object *ob)
BodyFace *bodyface;
int a;
const float(*vert_positions)[3] = BKE_mesh_vert_positions(me);
const MPoly *polys = BKE_mesh_polys(me);
const int *poly_offsets = BKE_mesh_poly_offsets(me);
const int *corner_verts = BKE_mesh_corner_verts(me);
/* Allocate and copy faces. */
@@ -2760,7 +2761,7 @@ static void mesh_faces_to_scratch(Object *ob)
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(
corner_verts, polys, vert_positions, me->totvert, me->totloop, me->totpoly, looptri);
corner_verts, poly_offsets, vert_positions, me->totvert, me->totloop, me->totpoly, looptri);
bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface,
"SB_body_Faces");
+11 -12
View File
@@ -1987,13 +1987,13 @@ 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 blender::Span<int> corner_verts,
const MPoly *polys,
const blender::OffsetIndices<int> polys,
int *r_v1,
int *r_v2)
{
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];
const blender::IndexRange poly = polys[poly_index];
*r_v1 = corner_verts[coord->grid_index];
const int corner = blender::bke::mesh::poly_find_corner_from_vert(poly, corner_verts, *r_v1);
@@ -2007,13 +2007,13 @@ static void adjacet_vertices_index_from_adjacent_edge(const SubdivCCG *subdiv_cc
}
}
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
const int *corner_verts,
const int corners_num,
const MPoly *polys,
int *r_v1,
int *r_v2)
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
const blender::Span<int> corner_verts,
const blender::OffsetIndices<int> polys,
int *r_v1,
int *r_v2)
{
const int grid_size_1 = subdiv_ccg->grid_size - 1;
@@ -2028,8 +2028,7 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
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, {corner_verts, corners_num}, 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;
}
@@ -2037,7 +2036,7 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
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, {corner_verts, corners_num}, polys, r_v1, r_v2);
subdiv_ccg, coord, corner_verts, polys, r_v1, r_v2);
return SUBDIV_CCG_ADJACENT_EDGE;
}
}
@@ -29,7 +29,7 @@ struct PolyCornerIndex {
struct GridPaintMaskData {
// int grid_size;
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
const GridPaintMask *grid_paint_mask;
/* Indexed by ptex face index, contains polygon/corner which corresponds
* to it.
@@ -50,10 +50,10 @@ static int mask_get_grid_and_coord(SubdivCCGMaskEvaluator *mask_evaluator,
{
GridPaintMaskData *data = static_cast<GridPaintMaskData *>(mask_evaluator->user_data);
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int start_grid_index = poly.loopstart + poly_corner->corner;
const blender::IndexRange poly = data->polys[poly_corner->poly_index];
const int start_grid_index = poly.start() + poly_corner->corner;
int corner = 0;
if (poly.totloop == 4) {
if (poly.size() == 4) {
float corner_u, corner_v;
corner = BKE_subdiv_rotate_quad_to_corner(u, v, &corner_u, &corner_v);
*r_mask_grid = &data->grid_paint_mask[start_grid_index + corner];
@@ -103,10 +103,9 @@ static void free_mask_data(SubdivCCGMaskEvaluator *mask_evaluator)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
const blender::Span<MPoly> polys = mesh->polys();
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly &poly = polys[poly_index];
num_ptex_faces += (poly.totloop == 4) ? 1 : poly.totloop;
const blender::OffsetIndices polys = mesh->polys();
for (const int poly_index : polys.index_range()) {
num_ptex_faces += (polys[poly_index].size() == 4) ? 1 : polys[poly_index].size();
}
return num_ptex_faces;
}
@@ -114,7 +113,7 @@ static int count_num_ptex_faces(const Mesh *mesh)
static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh)
{
GridPaintMaskData *data = static_cast<GridPaintMaskData *>(mask_evaluator->user_data);
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = static_cast<PolyCornerIndex *>(
@@ -122,15 +121,15 @@ static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const
/* Fill in offsets. */
int ptex_face_index = 0;
PolyCornerIndex *ptex_poly_corner = data->ptex_poly_corner;
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly &poly = polys[poly_index];
if (poly.totloop == 4) {
for (const int poly_index : polys.index_range()) {
const blender::IndexRange poly = polys[poly_index];
if (poly.size() == 4) {
ptex_poly_corner[ptex_face_index].poly_index = poly_index;
ptex_poly_corner[ptex_face_index].corner = 0;
ptex_face_index++;
}
else {
for (int corner = 0; corner < poly.totloop; corner++) {
for (int corner = 0; corner < poly.size(); corner++) {
ptex_poly_corner[ptex_face_index].poly_index = poly_index;
ptex_poly_corner[ptex_face_index].corner = corner;
ptex_face_index++;
@@ -160,7 +159,7 @@ bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator,
return false;
}
/* Allocate all required memory. */
mask_evaluator->user_data = MEM_callocN(sizeof(GridPaintMaskData), "mask from grid data");
mask_evaluator->user_data = MEM_new<GridPaintMaskData>("mask from grid data");
mask_init_data(mask_evaluator, mesh);
mask_init_functions(mask_evaluator);
return true;
@@ -36,7 +36,7 @@ struct ConverterStorage {
const Mesh *mesh;
const float (*vert_positions)[3];
blender::Span<MEdge> edges;
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
@@ -127,7 +127,7 @@ static int get_num_vertices(const OpenSubdiv_Converter *converter)
static int get_num_face_vertices(const OpenSubdiv_Converter *converter, int manifold_face_index)
{
ConverterStorage *storage = static_cast<ConverterStorage *>(converter->user_data);
return storage->polys[manifold_face_index].totloop;
return storage->polys[manifold_face_index].size();
}
static void get_face_vertices(const OpenSubdiv_Converter *converter,
@@ -135,9 +135,9 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter,
int *manifold_face_vertices)
{
ConverterStorage *storage = static_cast<ConverterStorage *>(converter->user_data);
const MPoly &poly = storage->polys[manifold_face_index];
for (int i = 0; i < poly.totloop; i++) {
const int vert = storage->corner_verts[poly.loopstart + i];
const blender::IndexRange poly = storage->polys[manifold_face_index];
for (int i = 0; i < poly.size(); i++) {
const int vert = storage->corner_verts[poly[i]];
manifold_face_vertices[i] = storage->manifold_vertex_index[vert];
}
}
@@ -204,7 +204,6 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
const Mesh *mesh = storage->mesh;
const float(*mloopuv)[2] = static_cast<const float(*)[2]>(
CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index));
const int num_poly = mesh->totpoly;
const int num_vert = mesh->totvert;
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
/* Initialize memory required for the operations. */
@@ -213,12 +212,11 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
MEM_malloc_arrayN(mesh->totloop, sizeof(int), "loop uv vertex index"));
}
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
storage->polys.data(),
storage->polys,
(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->corner_verts.data(),
mloopuv,
num_poly,
num_vert,
limit,
false,
@@ -231,8 +229,8 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
if (uv_vert->separate) {
storage->num_uv_coordinates++;
}
const MPoly &poly = storage->polys[uv_vert->poly_index];
const int global_loop_index = poly.loopstart + uv_vert->loop_of_poly_index;
const blender::IndexRange poly = storage->polys[uv_vert->poly_index];
const int global_loop_index = poly.start() + uv_vert->loop_of_poly_index;
storage->loop_uv_indices[global_loop_index] = storage->num_uv_coordinates;
uv_vert = uv_vert->next;
}
@@ -257,8 +255,8 @@ static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
const int corner)
{
ConverterStorage *storage = static_cast<ConverterStorage *>(converter->user_data);
const MPoly &poly = storage->polys[face_index];
return storage->loop_uv_indices[poly.loopstart + corner];
const blender::IndexRange poly = storage->polys[face_index];
return storage->loop_uv_indices[poly.start() + corner];
}
static void free_user_data(const OpenSubdiv_Converter *converter)
@@ -353,16 +351,14 @@ static void initialize_manifold_indices(ConverterStorage *storage)
{
const Mesh *mesh = storage->mesh;
const blender::Span<MEdge> edges = storage->edges;
const blender::Span<MPoly> polys = storage->polys;
const blender::OffsetIndices<int> polys = storage->polys;
const blender::Span<int> corner_verts = storage->corner_verts;
const blender::Span<int> 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 i = 0; i < poly.totloop; i++) {
const int corner = poly.loopstart + i;
for (const int corner : polys[poly_index]) {
BLI_BITMAP_ENABLE(vert_used_map, corner_verts[corner]);
BLI_BITMAP_ENABLE(edge_used_map, corner_edges[corner]);
}
@@ -395,8 +391,7 @@ static void init_user_data(OpenSubdiv_Converter *converter,
const SubdivSettings *settings,
const Mesh *mesh)
{
ConverterStorage *user_data = static_cast<ConverterStorage *>(
MEM_mallocN(sizeof(ConverterStorage), __func__));
ConverterStorage *user_data = MEM_new<ConverterStorage>(__func__);
user_data->settings = *settings;
user_data->mesh = mesh;
user_data->vert_positions = BKE_mesh_vert_positions(mesh);
@@ -35,7 +35,7 @@ struct MultiresDisplacementData {
/* Mesh is used to read external displacement. */
Mesh *mesh;
const MultiresModifierData *mmd;
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
const MDisps *mdisps;
/* Indexed by ptex face index, contains polygon/corner which corresponds
* to it.
@@ -71,10 +71,10 @@ static int displacement_get_grid_and_coord(SubdivDisplacement *displacement,
MultiresDisplacementData *data = static_cast<MultiresDisplacementData *>(
displacement->user_data);
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int start_grid_index = poly.loopstart + poly_corner->corner;
const blender::IndexRange poly = data->polys[poly_corner->poly_index];
const int start_grid_index = poly.start() + poly_corner->corner;
int corner = 0;
if (poly.totloop == 4) {
if (poly.size() == 4) {
float corner_u, corner_v;
corner = BKE_subdiv_rotate_quad_to_corner(u, v, &corner_u, &corner_v);
*r_displacement_grid = &data->mdisps[start_grid_index + corner];
@@ -95,10 +95,10 @@ static const MDisps *displacement_get_other_grid(SubdivDisplacement *displacemen
MultiresDisplacementData *data = static_cast<MultiresDisplacementData *>(
displacement->user_data);
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int effective_corner = (poly.totloop == 4) ? corner : poly_corner->corner;
const int next_corner = (effective_corner + corner_delta + poly.totloop) % poly.totloop;
return &data->mdisps[poly.loopstart + next_corner];
const blender::IndexRange poly = data->polys[poly_corner->poly_index];
const int effective_corner = (poly.size() == 4) ? corner : poly_corner->corner;
const int next_corner = (effective_corner + corner_delta + poly.size()) % poly.size();
return &data->mdisps[poly[next_corner]];
}
BLI_INLINE eAverageWith read_displacement_grid(const MDisps *displacement_grid,
@@ -126,14 +126,14 @@ BLI_INLINE eAverageWith read_displacement_grid(const MDisps *displacement_grid,
return AVERAGE_WITH_NONE;
}
static void average_convert_grid_coord_to_ptex(const MPoly &poly,
static void average_convert_grid_coord_to_ptex(const int num_corners,
const int corner,
const float grid_u,
const float grid_v,
float *r_ptex_face_u,
float *r_ptex_face_v)
{
if (poly.totloop == 4) {
if (num_corners == 4) {
BKE_subdiv_rotate_grid_to_quad(corner, grid_u, grid_v, r_ptex_face_u, r_ptex_face_v);
}
else {
@@ -142,14 +142,14 @@ static void average_convert_grid_coord_to_ptex(const MPoly &poly,
}
static void average_construct_tangent_matrix(Subdiv *subdiv,
const MPoly &poly,
const int num_corners,
const int ptex_face_index,
const int corner,
const float u,
const float v,
float r_tangent_matrix[3][3])
{
const bool is_quad = (poly.totloop == 4);
const bool is_quad = num_corners == 4;
const int quad_corner = is_quad ? corner : 0;
float dummy_P[3], dPdu[3], dPdv[3];
BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
@@ -174,16 +174,16 @@ static void average_read_displacement_object(MultiresDisplacementData *data,
float r_D[3])
{
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int num_corners = data->polys[poly_corner->poly_index].size();
/* Get (u, v) coordinate within the other ptex face which corresponds to
* the grid coordinates. */
float u, v;
average_convert_grid_coord_to_ptex(poly, corner_index, grid_u, grid_v, &u, &v);
average_convert_grid_coord_to_ptex(num_corners, corner_index, grid_u, grid_v, &u, &v);
/* Construct tangent matrix which corresponds to partial derivatives
* calculated for the other ptex face. */
float tangent_matrix[3][3];
average_construct_tangent_matrix(
data->subdiv, poly, ptex_face_index, corner_index, u, v, tangent_matrix);
data->subdiv, num_corners, ptex_face_index, corner_index, u, v, tangent_matrix);
/* Read displacement from other grid in a tangent space. */
float tangent_D[3];
average_read_displacement_tangent(data, displacement_grid, grid_u, grid_v, tangent_D);
@@ -199,10 +199,10 @@ static void average_get_other_ptex_and_corner(MultiresDisplacementData *data,
int *r_other_corner_index)
{
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int num_corners = poly.totloop;
const int poly_index = poly_corner->poly_index;
const int num_corners = data->polys[poly_corner->poly_index].size();
const bool is_quad = (num_corners == 4);
const int start_ptex_face_index = data->face_ptex_offset[poly_corner->poly_index];
const int start_ptex_face_index = data->face_ptex_offset[poly_index];
*r_other_corner_index = (corner + corner_delta + num_corners) % num_corners;
*r_other_ptex_face_index = is_quad ? start_ptex_face_index :
start_ptex_face_index + *r_other_corner_index;
@@ -248,8 +248,7 @@ static void average_with_all(SubdivDisplacement *displacement,
MultiresDisplacementData *data = static_cast<MultiresDisplacementData *>(
displacement->user_data);
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int num_corners = poly.totloop;
const int num_corners = data->polys[poly_corner->poly_index].size();
for (int corner_delta = 1; corner_delta < num_corners; corner_delta++) {
average_with_other(displacement, ptex_face_index, corner, 0.0f, 0.0f, corner_delta, r_D);
}
@@ -304,8 +303,7 @@ static int displacement_get_face_corner(MultiresDisplacementData *data,
const float v)
{
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const MPoly &poly = data->polys[poly_corner->poly_index];
const int num_corners = poly.totloop;
const int num_corners = data->polys[poly_corner->poly_index].size();
const bool is_quad = (num_corners == 4);
if (is_quad) {
float dummy_corner_u, dummy_corner_v;
@@ -367,10 +365,9 @@ static void free_displacement(SubdivDisplacement *displacement)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly &poly = polys[poly_index];
num_ptex_faces += (poly.totloop == 4) ? 1 : poly.totloop;
num_ptex_faces += (polys[poly_index].size() == 4) ? 1 : polys[poly_index].size();
}
return num_ptex_faces;
}
@@ -379,7 +376,7 @@ static void displacement_data_init_mapping(SubdivDisplacement *displacement, con
{
MultiresDisplacementData *data = static_cast<MultiresDisplacementData *>(
displacement->user_data);
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = static_cast<PolyCornerIndex *>(
@@ -388,14 +385,14 @@ static void displacement_data_init_mapping(SubdivDisplacement *displacement, con
int ptex_face_index = 0;
PolyCornerIndex *ptex_poly_corner = data->ptex_poly_corner;
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly &poly = polys[poly_index];
if (poly.totloop == 4) {
const blender::IndexRange poly = polys[poly_index];
if (poly.size() == 4) {
ptex_poly_corner[ptex_face_index].poly_index = poly_index;
ptex_poly_corner[ptex_face_index].corner = 0;
ptex_face_index++;
}
else {
for (int corner = 0; corner < poly.totloop; corner++) {
for (int corner = 0; corner < poly.size(); corner++) {
ptex_poly_corner[ptex_face_index].poly_index = poly_index;
ptex_poly_corner[ptex_face_index].corner = corner;
ptex_face_index++;
@@ -82,17 +82,16 @@ static void set_coarse_positions(Subdiv *subdiv,
const float (*coarse_vertex_cos)[3])
{
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const blender::Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
const blender::Span<int> 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
* OpenSubdiv's vertices match mesh ones? */
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 i = 0; i < poly.totloop; i++) {
BLI_BITMAP_ENABLE(vertex_used_map, corner_verts[poly.loopstart + i]);
for (const int i : polys.index_range()) {
for (const int vert : corner_verts.slice(polys[i])) {
BLI_BITMAP_ENABLE(vertex_used_map, vert);
}
}
/* Use a temporary buffer so we do not upload vertices one at a time to the GPU. */
@@ -125,7 +124,7 @@ static void set_coarse_positions(Subdiv *subdiv,
struct FaceVaryingDataFromUVContext {
OpenSubdiv_TopologyRefiner *topology_refiner;
const Mesh *mesh;
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
const float (*mloopuv)[2];
float (*buffer)[2];
int layer_index;
@@ -138,8 +137,7 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata,
FaceVaryingDataFromUVContext *ctx = static_cast<FaceVaryingDataFromUVContext *>(userdata);
OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner;
const int layer_index = ctx->layer_index;
const MPoly &poly = ctx->polys[face_index];
const float(*mluv)[2] = &ctx->mloopuv[poly.loopstart];
const float(*mluv)[2] = &ctx->mloopuv[ctx->polys[face_index].start()];
/* TODO(sergey): OpenSubdiv's C-API converter can change winding of
* loops of a face, need to watch for that, to prevent wrong UVs assigned.
+136 -145
View File
@@ -24,14 +24,16 @@
#include "MEM_guardedalloc.h"
using blender::IndexRange;
/* -------------------------------------------------------------------- */
/** \name General helpers
* \{ */
/* Number of ptex faces for a given polygon. */
BLI_INLINE int num_ptex_faces_per_poly_get(const MPoly &poly)
BLI_INLINE int num_ptex_faces_per_poly_get(const IndexRange poly)
{
return (poly.totloop == 4) ? 1 : poly.totloop;
return (poly.size() == 4) ? 1 : poly.size();
}
BLI_INLINE int num_edges_per_ptex_face_get(const int resolution)
@@ -54,9 +56,9 @@ BLI_INLINE int num_polys_per_ptex_get(const int resolution)
}
/* Subdivision resolution per given polygon's ptex faces. */
BLI_INLINE int ptex_face_resolution_get(const MPoly &poly, int resolution)
BLI_INLINE int ptex_face_resolution_get(const IndexRange poly, int resolution)
{
return (poly.totloop == 4) ? (resolution) : ((resolution >> 1) + 1);
return (poly.size() == 4) ? (resolution) : ((resolution >> 1) + 1);
}
/** \} */
@@ -68,7 +70,7 @@ BLI_INLINE int ptex_face_resolution_get(const MPoly &poly, int resolution)
struct SubdivForeachTaskContext {
const Mesh *coarse_mesh;
blender::Span<MEdge> coarse_edges;
blender::Span<MPoly> coarse_polys;
blender::OffsetIndices<int> coarse_polys;
blender::Span<int> coarse_corner_verts;
blender::Span<int> coarse_corner_edges;
const SubdivToMeshSettings *settings;
@@ -166,7 +168,7 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx)
ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1);
/* Calculate extra vertices and edges created by non-loose geometry. */
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
const IndexRange coarse_poly = ctx->coarse_polys[poly_index];
const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly);
/* Inner vertices of polygon. */
if (num_ptex_faces_per_poly == 1) {
@@ -183,7 +185,7 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx)
(no_quad_patch_resolution - 2) +
num_subdiv_vertices_per_coarse_edge);
if (no_quad_patch_resolution >= 3) {
ctx->num_subdiv_edges += coarse_poly.totloop;
ctx->num_subdiv_edges += coarse_poly.size();
}
ctx->num_subdiv_polygons += num_ptex_faces_per_poly *
num_polys_per_ptex_get(no_quad_patch_resolution);
@@ -220,7 +222,7 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx)
int edge_offset = 0;
int polygon_offset = 0;
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
const IndexRange coarse_poly = ctx->coarse_polys[poly_index];
const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly);
ctx->subdiv_vertex_offset[poly_index] = vertex_offset;
ctx->subdiv_edge_offset[poly_index] = edge_offset;
@@ -237,7 +239,7 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx)
(num_inner_edges_per_ptex_face_get(no_quad_patch_resolution - 1) +
(no_quad_patch_resolution - 2) + num_subdiv_vertices_per_coarse_edge);
if (no_quad_patch_resolution >= 3) {
edge_offset += coarse_poly.totloop;
edge_offset += coarse_poly.size();
}
polygon_offset += num_ptex_faces_per_poly * num_polys_per_ptex_get(no_quad_patch_resolution);
}
@@ -283,15 +285,15 @@ static void subdiv_foreach_ctx_free(SubdivForeachTaskContext *ctx)
static void subdiv_foreach_corner_vertices_regular_do(
SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly,
const int coarse_poly_index,
SubdivForeachVertexFromCornerCb vertex_corner,
bool check_usage)
{
const float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner];
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
if (check_usage &&
BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_vert)) {
continue;
@@ -314,23 +316,23 @@ static void subdiv_foreach_corner_vertices_regular_do(
static void subdiv_foreach_corner_vertices_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_corner_vertices_regular_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_corner, true);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_corner, true);
}
static void subdiv_foreach_corner_vertices_special_do(
SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly,
const int coarse_poly_index,
SubdivForeachVertexFromCornerCb vertex_corner,
bool check_usage)
{
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner];
for (int corner = 0; corner < coarse_poly.size(); corner++, ptex_face_index++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
if (check_usage &&
BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_vert)) {
continue;
@@ -351,38 +353,38 @@ static void subdiv_foreach_corner_vertices_special_do(
static void subdiv_foreach_corner_vertices_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_corner_vertices_special_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_corner, true);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_corner, true);
}
static void subdiv_foreach_corner_vertices(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
if (coarse_poly->totloop == 4) {
subdiv_foreach_corner_vertices_regular(ctx, tls, coarse_poly);
if (ctx->coarse_polys[coarse_poly_index].size() == 4) {
subdiv_foreach_corner_vertices_regular(ctx, tls, coarse_poly_index);
}
else {
subdiv_foreach_corner_vertices_special(ctx, tls, coarse_poly);
subdiv_foreach_corner_vertices_special(ctx, tls, coarse_poly_index);
}
}
static void subdiv_foreach_every_corner_vertices_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_corner_vertices_regular_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_corner, false);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_every_corner, false);
}
static void subdiv_foreach_every_corner_vertices_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_corner_vertices_special_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_corner, false);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_every_corner, false);
}
static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx, void *tls)
@@ -392,12 +394,11 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx,
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
if (coarse_poly.totloop == 4) {
subdiv_foreach_every_corner_vertices_regular(ctx, tls, &coarse_poly);
if (ctx->coarse_polys[poly_index].size() == 4) {
subdiv_foreach_every_corner_vertices_regular(ctx, tls, poly_index);
}
else {
subdiv_foreach_every_corner_vertices_special(ctx, tls, &coarse_poly);
subdiv_foreach_every_corner_vertices_special(ctx, tls, poly_index);
}
}
}
@@ -406,19 +407,19 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly,
const int coarse_poly_index,
SubdivForeachVertexFromEdgeCb vertex_edge,
bool check_usage)
{
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int resolution = ctx->settings->resolution;
const int resolution_1 = resolution - 1;
const float inv_resolution_1 = 1.0f / float(resolution_1);
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
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 int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner];
const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner];
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly[corner]];
if (check_usage &&
BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) {
continue;
@@ -460,28 +461,28 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct
static void subdiv_foreach_edge_vertices_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_edge_vertices_regular_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_edge, true);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_edge, true);
}
static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly,
const int coarse_poly_index,
SubdivForeachVertexFromEdgeCb vertex_edge,
bool check_usage)
{
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int resolution = ctx->settings->resolution;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1);
const float inv_ptex_resolution_1 = 1.0f / float(num_vertices_per_ptex_edge - 1);
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
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 int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner];
const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner];
for (int corner = 0; corner < coarse_poly.size(); corner++, ptex_face_index++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly[corner]];
if (check_usage &&
BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) {
continue;
@@ -508,7 +509,7 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct
corner,
subdiv_vertex_index);
}
const int next_corner = (corner + 1) % coarse_poly->totloop;
const int next_corner = (corner + 1) % coarse_poly.size();
const int next_ptex_face_index = ptex_face_start_index + next_corner;
for (int vertex_index = 1; vertex_index < num_vertices_per_ptex_edge - 1;
vertex_index++, subdiv_vertex_index += vertex_delta) {
@@ -528,38 +529,38 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct
static void subdiv_foreach_edge_vertices_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_edge_vertices_special_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_edge, true);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_edge, true);
}
static void subdiv_foreach_edge_vertices(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
if (coarse_poly->totloop == 4) {
subdiv_foreach_edge_vertices_regular(ctx, tls, coarse_poly);
if (ctx->coarse_polys[coarse_poly_index].size() == 4) {
subdiv_foreach_edge_vertices_regular(ctx, tls, coarse_poly_index);
}
else {
subdiv_foreach_edge_vertices_special(ctx, tls, coarse_poly);
subdiv_foreach_edge_vertices_special(ctx, tls, coarse_poly_index);
}
}
static void subdiv_foreach_every_edge_vertices_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_edge_vertices_regular_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_edge, false);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_every_edge, false);
}
static void subdiv_foreach_every_edge_vertices_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
subdiv_foreach_edge_vertices_special_do(
ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_edge, false);
ctx, tls, coarse_poly_index, ctx->foreach_context->vertex_every_edge, false);
}
static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, void *tls)
@@ -569,12 +570,11 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
if (coarse_poly.totloop == 4) {
subdiv_foreach_every_edge_vertices_regular(ctx, tls, &coarse_poly);
if (ctx->coarse_polys[poly_index].size() == 4) {
subdiv_foreach_every_edge_vertices_regular(ctx, tls, poly_index);
}
else {
subdiv_foreach_every_edge_vertices_special(ctx, tls, &coarse_poly);
subdiv_foreach_every_edge_vertices_special(ctx, tls, poly_index);
}
}
}
@@ -583,11 +583,10 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo
static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
const int resolution = ctx->settings->resolution;
const float inv_resolution_1 = 1.0f / float(resolution - 1);
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index];
int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index;
@@ -609,12 +608,12 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
const int resolution = ctx->settings->resolution;
const int ptex_face_resolution = ptex_face_resolution_get(*coarse_poly, resolution);
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const float inv_ptex_face_resolution_1 = 1.0f / float(ptex_face_resolution - 1);
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index];
int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index;
@@ -627,7 +626,7 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
0,
subdiv_vertex_index);
subdiv_vertex_index++;
for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
for (int corner = 0; corner < coarse_poly.size(); corner++, ptex_face_index++) {
for (int y = 1; y < ptex_face_resolution - 1; y++) {
const float v = y * inv_ptex_face_resolution_1;
for (int x = 1; x < ptex_face_resolution; x++, subdiv_vertex_index++) {
@@ -647,13 +646,13 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
if (coarse_poly->totloop == 4) {
subdiv_foreach_inner_vertices_regular(ctx, tls, coarse_poly);
if (ctx->coarse_polys[coarse_poly_index].size() == 4) {
subdiv_foreach_inner_vertices_regular(ctx, tls, coarse_poly_index);
}
else {
subdiv_foreach_inner_vertices_special(ctx, tls, coarse_poly);
subdiv_foreach_inner_vertices_special(ctx, tls, coarse_poly_index);
}
}
@@ -661,7 +660,7 @@ static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx, void *tls, const int poly_index)
{
if (ctx->foreach_context->vertex_inner != nullptr) {
subdiv_foreach_inner_vertices(ctx, tls, &ctx->coarse_polys[poly_index]);
subdiv_foreach_inner_vertices(ctx, tls, poly_index);
}
}
@@ -739,14 +738,14 @@ static int subdiv_foreach_edges_column(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
const int poly_index = coarse_poly - ctx->coarse_polys.data();
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int resolution = ctx->settings->resolution;
const int start_vertex_index = ctx->vertices_inner_offset +
ctx->subdiv_vertex_offset[poly_index];
ctx->subdiv_vertex_offset[coarse_poly_index];
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
int subdiv_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index];
int subdiv_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[coarse_poly_index];
/* Traverse bottom row of edges (0-1, 1-2). */
subdiv_edge_index = subdiv_foreach_edges_row(
ctx, tls, ORIGINDEX_NONE, subdiv_edge_index, start_vertex_index, resolution - 2);
@@ -778,9 +777,9 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c
resolution - 2);
}
/* Connect inner part of patch to boundary. */
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
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];
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int coarse_vert_index = ctx->coarse_corner_verts[coarse_poly[corner]];
const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly[corner]];
const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index];
const int start_edge_vertex = ctx->vertices_edge_offset +
coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
@@ -817,20 +816,20 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c
static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
const int poly_index = coarse_poly - ctx->coarse_polys.data();
const int resolution = ctx->settings->resolution;
const int ptex_face_resolution = ptex_face_resolution_get(*coarse_poly, resolution);
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_face_inner_resolution = ptex_face_resolution - 2;
const int num_inner_vertices_per_ptex = (ptex_face_resolution - 1) * (ptex_face_resolution - 2);
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const int center_vertex_index = ctx->vertices_inner_offset +
ctx->subdiv_vertex_offset[poly_index];
ctx->subdiv_vertex_offset[coarse_poly_index];
const int start_vertex_index = center_vertex_index + 1;
int subdiv_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index];
int subdiv_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[coarse_poly_index];
/* Traverse inner ptex edges. */
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int start_ptex_face_vertex_index = start_vertex_index +
corner * num_inner_vertices_per_ptex;
/* Similar steps to regular patch case. */
@@ -860,8 +859,8 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
}
}
/* Create connections between ptex faces. */
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const int next_corner = (corner + 1) % coarse_poly->totloop;
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int next_corner = (corner + 1) % coarse_poly.size();
int current_patch_vertex_index = start_vertex_index + corner * num_inner_vertices_per_ptex +
ptex_face_inner_resolution;
int next_path_vertex_index = start_vertex_index + next_corner * num_inner_vertices_per_ptex +
@@ -877,7 +876,7 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
}
/* Create edges from center. */
if (ptex_face_resolution >= 3) {
for (int corner = 0; corner < coarse_poly->totloop; corner++, subdiv_edge_index++) {
for (int corner = 0; corner < coarse_poly.size(); corner++, subdiv_edge_index++) {
const int current_patch_end_vertex_index = start_vertex_index +
corner * num_inner_vertices_per_ptex +
num_inner_vertices_per_ptex - 1;
@@ -888,11 +887,11 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
}
}
/* Connect inner path of patch to boundary. */
int prev_corner = coarse_poly->totloop - 1;
for (int corner = 0; corner < coarse_poly->totloop; 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];
int prev_corner = coarse_poly.size() - 1;
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly[corner]];
const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly[prev_corner]];
{
const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i];
const int start_edge_vertex = ctx->vertices_edge_offset +
@@ -933,19 +932,19 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
if (coarse_poly->totloop == 4) {
subdiv_foreach_edges_all_patches_regular(ctx, tls, coarse_poly);
if (ctx->coarse_polys[coarse_poly_index].size() == 4) {
subdiv_foreach_edges_all_patches_regular(ctx, tls, coarse_poly_index);
}
else {
subdiv_foreach_edges_all_patches_special(ctx, tls, coarse_poly);
subdiv_foreach_edges_all_patches_special(ctx, tls, coarse_poly_index);
}
}
static void subdiv_foreach_edges(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
subdiv_foreach_edges_all_patches(ctx, tls, &ctx->coarse_polys[poly_index]);
subdiv_foreach_edges_all_patches(ctx, tls, poly_index);
}
static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
@@ -1077,12 +1076,12 @@ static int subdiv_foreach_loops_corner_index(const float u,
static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
const int resolution = ctx->settings->resolution;
/* Base/coarse mesh information. */
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
const int ptex_resolution = ptex_face_resolution_get(*coarse_poly, resolution);
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_inner_resolution = ptex_resolution - 2;
const int num_subdiv_edges_per_coarse_edge = resolution - 1;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
@@ -1137,14 +1136,12 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
}
}
/* Loops for faces connecting inner ptex part with boundary. */
int prev_corner_index = coarse_poly->totloop - 1;
for (int corner = 0; corner < coarse_poly->totloop; 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 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];
int prev_corner_index = coarse_poly.size() - 1;
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly[corner]];
const int coase_prev_vert = ctx->coarse_corner_verts[coarse_poly[prev_corner_index]];
const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly[prev_corner_index]];
const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i];
const MEdge *prev_coarse_edge = &ctx->coarse_edges[coarse_prev_edge];
@@ -1233,7 +1230,7 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
int e2;
if (i == 0) {
e2 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) +
((corner - 1 + coarse_poly->totloop) % coarse_poly->totloop) *
((corner - 1 + coarse_poly.size()) % coarse_poly.size()) *
num_subdiv_vertices_per_coarse_edge +
num_subdiv_vertices_per_coarse_edge - 1;
}
@@ -1273,12 +1270,12 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
const int resolution = ctx->settings->resolution;
/* Base/coarse mesh information. */
const int coarse_poly_index = coarse_poly - ctx->coarse_polys.data();
const int ptex_face_resolution = ptex_face_resolution_get(*coarse_poly, resolution);
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_face_inner_resolution = ptex_face_resolution - 2;
const float inv_ptex_resolution_1 = 1.0f / float(ptex_face_resolution - 1);
const int num_inner_vertices_per_ptex = (ptex_face_resolution - 1) * (ptex_face_resolution - 2);
@@ -1298,7 +1295,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
const float dv = inv_ptex_resolution_1;
/* Hi-poly subdivided mesh. */
int subdiv_loop_index = start_loop_index;
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
for (int corner = 0; corner < coarse_poly.size(); corner++) {
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;
for (int y = 1; y < ptex_face_inner_resolution; y++) {
@@ -1342,8 +1339,8 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
}
}
/* Create connections between ptex faces. */
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const int next_corner = (corner + 1) % coarse_poly->totloop;
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int next_corner = (corner + 1) % coarse_poly.size();
const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face;
const int next_corner_edge_index = start_edge_index +
next_corner * num_inner_edges_per_ptex_face;
@@ -1357,7 +1354,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
int v1 = next_path_vertex_index;
current_patch_vertex_index += ptex_face_inner_resolution + 1;
next_path_vertex_index += 1;
int e0 = start_edge_index + coarse_poly->totloop * num_inner_edges_per_ptex_face +
int e0 = start_edge_index + coarse_poly.size() * num_inner_edges_per_ptex_face +
corner * (ptex_face_resolution - 2);
int e1 = next_corner_edge_index + num_inner_edges_per_ptex_face - ptex_face_resolution + 2;
int e3 = corner_edge_index + 2 * ptex_face_resolution - 4;
@@ -1399,11 +1396,11 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
if (ptex_face_resolution >= 3) {
const int start_center_edge_index = start_edge_index + (num_inner_edges_per_ptex_face +
ptex_face_inner_resolution) *
coarse_poly->totloop;
coarse_poly.size();
const int start_boundary_edge = start_edge_index +
coarse_poly->totloop * num_inner_edges_per_ptex_face +
coarse_poly.size() * num_inner_edges_per_ptex_face +
ptex_face_inner_resolution - 1;
for (int corner = 0, prev_corner = coarse_poly->totloop - 1; corner < coarse_poly->totloop;
for (int corner = 0, prev_corner = coarse_poly.size() - 1; corner < coarse_poly.size();
prev_corner = corner, corner++, subdiv_loop_index += 4) {
const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face;
const int current_patch_end_vertex_index = start_vertex_index +
@@ -1444,12 +1441,12 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
}
}
/* Loops for faces connecting inner ptex part with boundary. */
for (int prev_corner = coarse_poly->totloop - 1, corner = 0; corner < coarse_poly->totloop;
for (int prev_corner = coarse_poly.size() - 1, corner = 0; corner < coarse_poly.size();
prev_corner = corner, 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 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 int coarse_vert = ctx->coarse_corner_verts[coarse_poly[corner]];
const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly[corner]];
const int coase_prev_vert = ctx->coarse_corner_verts[coarse_poly[prev_corner]];
const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly[prev_corner]];
const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i];
const MEdge *prev_coarse_edge = &ctx->coarse_edges[coarse_prev_edge];
@@ -1496,14 +1493,14 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
}
int e1 = start_edge_index + corner * (2 * ptex_face_inner_resolution + 1);
if (ptex_face_resolution >= 3) {
e1 += coarse_poly->totloop *
e1 += coarse_poly.size() *
(num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
i;
}
int e2 = 0;
if (i == 0 && ptex_face_resolution >= 3) {
e2 = start_edge_index +
coarse_poly->totloop *
coarse_poly.size() *
(num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
corner * (2 * ptex_face_inner_resolution + 1) + ptex_face_inner_resolution + 1;
}
@@ -1549,7 +1546,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
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) +
coarse_poly.size() * (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
corner * (2 * ptex_face_inner_resolution + 1) + ptex_face_inner_resolution + 1;
for (int i = 0; i <= ptex_face_inner_resolution - 1; i++, subdiv_loop_index += 4) {
int v1;
@@ -1558,10 +1555,10 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
v1 = start_vertex_index + prev_corner * num_inner_vertices_per_ptex +
ptex_face_inner_resolution;
e1 = start_edge_index +
coarse_poly->totloop *
coarse_poly.size() *
(num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
prev_corner * (2 * ptex_face_inner_resolution + 1) + ptex_face_inner_resolution;
e0 = start_edge_index + coarse_poly->totloop * num_inner_edges_per_ptex_face +
e0 = start_edge_index + coarse_poly.size() * num_inner_edges_per_ptex_face +
prev_corner * ptex_face_inner_resolution;
}
else {
@@ -1610,12 +1607,11 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_loops(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
if (coarse_poly.totloop == 4) {
subdiv_foreach_loops_regular(ctx, tls, &coarse_poly);
if (ctx->coarse_polys[poly_index].size() == 4) {
subdiv_foreach_loops_regular(ctx, tls, poly_index);
}
else {
subdiv_foreach_loops_special(ctx, tls, &coarse_poly);
subdiv_foreach_loops_special(ctx, tls, poly_index);
}
}
@@ -1630,7 +1626,7 @@ static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int p
const int resolution = ctx->settings->resolution;
const int start_poly_index = ctx->subdiv_polygon_offset[poly_index];
/* Base/coarse mesh information. */
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
const IndexRange coarse_poly = ctx->coarse_polys[poly_index];
const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly);
const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int num_polys_per_ptex = num_polys_per_ptex_get(ptex_resolution);
@@ -1721,22 +1717,17 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly &coarse_poly = ctx->coarse_polys[poly_index];
subdiv_foreach_corner_vertices(ctx, tls, &coarse_poly);
subdiv_foreach_edge_vertices(ctx, tls, &coarse_poly);
subdiv_foreach_corner_vertices(ctx, tls, poly_index);
subdiv_foreach_edge_vertices(ctx, tls, poly_index);
}
}
static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
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++) {
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]);
for (const int poly_index : ctx->coarse_polys.index_range()) {
for (const int corner : ctx->coarse_polys[poly_index]) {
BLI_BITMAP_ENABLE(ctx->coarse_vertices_used_map, ctx->coarse_corner_verts[corner]);
BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, ctx->coarse_corner_verts[corner]);
}
}
}
+69 -74
View File
@@ -32,6 +32,7 @@
using blender::float2;
using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
@@ -44,14 +45,14 @@ struct SubdivMeshContext {
const Mesh *coarse_mesh;
const float (*coarse_positions)[3];
blender::Span<MEdge> coarse_edges;
blender::Span<MPoly> coarse_polys;
blender::OffsetIndices<int> coarse_polys;
blender::Span<int> coarse_corner_verts;
Subdiv *subdiv;
Mesh *subdiv_mesh;
blender::MutableSpan<float3> subdiv_positions;
blender::MutableSpan<MEdge> subdiv_edges;
blender::MutableSpan<MPoly> subdiv_polys;
blender::MutableSpan<int> subdiv_poly_offsets;
blender::MutableSpan<int> subdiv_corner_verts;
blender::MutableSpan<int> subdiv_corner_edges;
@@ -96,7 +97,7 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
Mesh *subdiv_mesh = ctx->subdiv_mesh;
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_poly_offsets = subdiv_mesh->poly_offsets_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. */
@@ -150,20 +151,20 @@ struct LoopsOfPtex {
};
static void loops_of_ptex_get(LoopsOfPtex *loops_of_ptex,
const MPoly *coarse_poly,
const IndexRange coarse_poly,
const int ptex_of_poly_index)
{
const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index;
const int first_ptex_loop_index = coarse_poly.start() + ptex_of_poly_index;
/* Loop which look in the (opposite) V direction of the current
* ptex face.
*
* TODO(sergey): Get rid of using module on every iteration. */
const int last_ptex_loop_index = coarse_poly->loopstart +
(ptex_of_poly_index + coarse_poly->totloop - 1) %
coarse_poly->totloop;
const int last_ptex_loop_index = coarse_poly.start() +
(ptex_of_poly_index + coarse_poly.size() - 1) %
coarse_poly.size();
loops_of_ptex->first_loop = first_ptex_loop_index;
loops_of_ptex->last_loop = last_ptex_loop_index;
if (coarse_poly->totloop == 4) {
if (coarse_poly.size() == 4) {
loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1;
loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2;
}
@@ -205,15 +206,15 @@ struct VerticesForInterpolation {
static void vertex_interpolation_init(const SubdivMeshContext *ctx,
VerticesForInterpolation *vertex_interpolation,
const MPoly &coarse_poly)
const IndexRange coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
if (coarse_poly.totloop == 4) {
if (coarse_poly.size() == 4) {
vertex_interpolation->vertex_data = &coarse_mesh->vdata;
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_indices[0] = ctx->coarse_corner_verts[coarse_poly.start() + 0];
vertex_interpolation->vertex_indices[1] = ctx->coarse_corner_verts[coarse_poly.start() + 1];
vertex_interpolation->vertex_indices[2] = ctx->coarse_corner_verts[coarse_poly.start() + 2];
vertex_interpolation->vertex_indices[3] = ctx->coarse_corner_verts[coarse_poly.start() + 3];
vertex_interpolation->vertex_data_storage_allocated = false;
}
else {
@@ -232,29 +233,29 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
vertex_interpolation->vertex_data_storage_allocated = true;
/* Interpolate center of poly right away, it stays unchanged for all
* ptex faces. */
const float weight = 1.0f / float(coarse_poly.totloop);
blender::Array<float, 32> weights(coarse_poly.totloop);
blender::Array<int, 32> indices(coarse_poly.totloop);
for (int i = 0; i < coarse_poly.totloop; i++) {
const float weight = 1.0f / float(coarse_poly.size());
blender::Array<float, 32> weights(coarse_poly.size());
blender::Array<int, 32> indices(coarse_poly.size());
for (int i = 0; i < coarse_poly.size(); i++) {
weights[i] = weight;
indices[i] = ctx->coarse_corner_verts[coarse_poly.loopstart + i];
indices[i] = ctx->coarse_corner_verts[coarse_poly.start() + i];
}
CustomData_interp(&coarse_mesh->vdata,
&vertex_interpolation->vertex_data_storage,
indices.data(),
weights.data(),
nullptr,
coarse_poly.totloop,
coarse_poly.size(),
2);
}
}
static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
VerticesForInterpolation *vertex_interpolation,
const MPoly *coarse_poly,
const IndexRange coarse_poly,
const int corner)
{
if (coarse_poly->totloop == 4) {
if (coarse_poly.size() == 4) {
/* Nothing to do, all indices and data is already assigned. */
}
else {
@@ -264,7 +265,7 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
/* Ptex face corner corresponds to a poly loop with same index. */
CustomData_copy_data(vertex_data,
&vertex_interpolation->vertex_data_storage,
ctx->coarse_corner_verts[coarse_poly->loopstart + corner],
ctx->coarse_corner_verts[coarse_poly.start() + corner],
0,
1);
/* Interpolate remaining ptex face corners, which hits loops
@@ -277,9 +278,9 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
const int last_loop_index = loops_of_ptex.last_loop;
const int first_indices[2] = {
ctx->coarse_corner_verts[first_loop_index],
ctx->coarse_corner_verts[coarse_poly->loopstart +
(first_loop_index - coarse_poly->loopstart + 1) %
coarse_poly->totloop]};
ctx->coarse_corner_verts[coarse_poly.start() +
(first_loop_index - coarse_poly.start() + 1) %
coarse_poly.size()]};
const int last_indices[2] = {ctx->coarse_corner_verts[first_loop_index],
ctx->coarse_corner_verts[last_loop_index]};
CustomData_interp(vertex_data,
@@ -335,15 +336,15 @@ struct LoopsForInterpolation {
static void loop_interpolation_init(const SubdivMeshContext *ctx,
LoopsForInterpolation *loop_interpolation,
const MPoly *coarse_poly)
const IndexRange coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
if (coarse_poly->totloop == 4) {
if (coarse_poly.size() == 4) {
loop_interpolation->loop_data = &coarse_mesh->ldata;
loop_interpolation->loop_indices[0] = coarse_poly->loopstart + 0;
loop_interpolation->loop_indices[1] = coarse_poly->loopstart + 1;
loop_interpolation->loop_indices[2] = coarse_poly->loopstart + 2;
loop_interpolation->loop_indices[3] = coarse_poly->loopstart + 3;
loop_interpolation->loop_indices[0] = coarse_poly.start() + 0;
loop_interpolation->loop_indices[1] = coarse_poly.start() + 1;
loop_interpolation->loop_indices[2] = coarse_poly.start() + 2;
loop_interpolation->loop_indices[3] = coarse_poly.start() + 3;
loop_interpolation->loop_data_storage_allocated = false;
}
else {
@@ -362,29 +363,29 @@ static void loop_interpolation_init(const SubdivMeshContext *ctx,
loop_interpolation->loop_data_storage_allocated = true;
/* Interpolate center of poly right away, it stays unchanged for all
* ptex faces. */
const float weight = 1.0f / float(coarse_poly->totloop);
blender::Array<float, 32> weights(coarse_poly->totloop);
blender::Array<int, 32> indices(coarse_poly->totloop);
for (int i = 0; i < coarse_poly->totloop; i++) {
const float weight = 1.0f / float(coarse_poly.size());
blender::Array<float, 32> weights(coarse_poly.size());
blender::Array<int, 32> indices(coarse_poly.size());
for (int i = 0; i < coarse_poly.size(); i++) {
weights[i] = weight;
indices[i] = coarse_poly->loopstart + i;
indices[i] = coarse_poly.start() + i;
}
CustomData_interp(&coarse_mesh->ldata,
&loop_interpolation->loop_data_storage,
indices.data(),
weights.data(),
nullptr,
coarse_poly->totloop,
coarse_poly.size(),
2);
}
}
static void loop_interpolation_from_corner(const SubdivMeshContext *ctx,
LoopsForInterpolation *loop_interpolation,
const MPoly *coarse_poly,
const IndexRange coarse_poly,
const int corner)
{
if (coarse_poly->totloop == 4) {
if (coarse_poly.size() == 4) {
/* Nothing to do, all indices and data is already assigned. */
}
else {
@@ -394,17 +395,17 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx,
/* Ptex face corner corresponds to a poly loop with same index. */
CustomData_free_elem(&loop_interpolation->loop_data_storage, 0, 1);
CustomData_copy_data(
loop_data, &loop_interpolation->loop_data_storage, coarse_poly->loopstart + corner, 0, 1);
loop_data, &loop_interpolation->loop_data_storage, coarse_poly.start() + corner, 0, 1);
/* Interpolate remaining ptex face corners, which hits loops
* middle points.
*
* TODO(sergey): Re-use one of interpolation results from previous
* iteration. */
const float weights[2] = {0.5f, 0.5f};
const int base_loop_index = coarse_poly->loopstart;
const int base_loop_index = coarse_poly.start();
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;
(first_loop_index - base_loop_index + 1) % coarse_poly.size();
const int first_indices[2] = {first_loop_index, second_loop_index};
const int last_indices[2] = {loops_of_ptex.last_loop, loops_of_ptex.first_loop};
CustomData_interp(
@@ -430,12 +431,12 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
struct SubdivMeshTLS {
bool vertex_interpolation_initialized;
VerticesForInterpolation vertex_interpolation;
const MPoly *vertex_interpolation_coarse_poly;
int vertex_interpolation_coarse_poly_index;
int vertex_interpolation_coarse_corner;
bool loop_interpolation_initialized;
LoopsForInterpolation loop_interpolation;
const MPoly *loop_interpolation_coarse_poly;
int loop_interpolation_coarse_poly_index;
int loop_interpolation_coarse_corner;
};
@@ -686,12 +687,13 @@ static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_contex
static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx,
SubdivMeshTLS *tls,
const MPoly *coarse_poly,
const int coarse_poly_index,
const int coarse_corner)
{
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
/* Check whether we've moved to another corner or polygon. */
if (tls->vertex_interpolation_initialized) {
if (tls->vertex_interpolation_coarse_poly != coarse_poly ||
if (tls->vertex_interpolation_coarse_poly_index != coarse_poly_index ||
tls->vertex_interpolation_coarse_corner != coarse_corner) {
vertex_interpolation_end(&tls->vertex_interpolation);
tls->vertex_interpolation_initialized = false;
@@ -699,7 +701,7 @@ static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx,
}
/* Initialize the interpolation. */
if (!tls->vertex_interpolation_initialized) {
vertex_interpolation_init(ctx, &tls->vertex_interpolation, *coarse_poly);
vertex_interpolation_init(ctx, &tls->vertex_interpolation, coarse_poly);
}
/* Update it for a new corner if needed. */
if (!tls->vertex_interpolation_initialized ||
@@ -708,7 +710,7 @@ static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx,
}
/* Store settings used for the current state of interpolator. */
tls->vertex_interpolation_initialized = true;
tls->vertex_interpolation_coarse_poly = coarse_poly;
tls->vertex_interpolation_coarse_poly_index = coarse_poly_index;
tls->vertex_interpolation_coarse_corner = coarse_corner;
}
@@ -724,15 +726,16 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const MPoly &coarse_poly = ctx->coarse_polys[coarse_poly_index];
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, &coarse_poly, coarse_corner);
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly_index, coarse_corner);
evaluate_vertex_and_apply_displacement_interpolate(
ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vertex_index);
}
static bool subdiv_mesh_is_center_vertex(const MPoly &coarse_poly, const float u, const float v)
static bool subdiv_mesh_is_center_vertex(const IndexRange coarse_poly,
const float u,
const float v)
{
if (coarse_poly.totloop == 4) {
if (coarse_poly.size() == 4) {
if (u == 0.5f && v == 0.5f) {
return true;
}
@@ -745,7 +748,7 @@ static bool subdiv_mesh_is_center_vertex(const MPoly &coarse_poly, const float u
return false;
}
static void subdiv_mesh_tag_center_vertex(const MPoly &coarse_poly,
static void subdiv_mesh_tag_center_vertex(const IndexRange coarse_poly,
const int subdiv_vertex_index,
const float u,
const float v,
@@ -768,10 +771,10 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
Subdiv *subdiv = ctx->subdiv;
const MPoly &coarse_poly = ctx->coarse_polys[coarse_poly_index];
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
float3 &subdiv_position = ctx->subdiv_positions[subdiv_vertex_index];
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, &coarse_poly, coarse_corner);
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly_index, coarse_corner);
subdiv_vertex_data_interpolate(ctx, subdiv_vertex_index, &tls->vertex_interpolation, u, v);
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_position);
subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vertex_index, u, v, subdiv_mesh);
@@ -856,12 +859,13 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
static void subdiv_mesh_ensure_loop_interpolation(SubdivMeshContext *ctx,
SubdivMeshTLS *tls,
const MPoly *coarse_poly,
const int coarse_poly_index,
const int coarse_corner)
{
const IndexRange coarse_poly = ctx->coarse_polys[coarse_poly_index];
/* Check whether we've moved to another corner or polygon. */
if (tls->loop_interpolation_initialized) {
if (tls->loop_interpolation_coarse_poly != coarse_poly ||
if (tls->loop_interpolation_coarse_poly_index != coarse_poly_index ||
tls->loop_interpolation_coarse_corner != coarse_corner) {
loop_interpolation_end(&tls->loop_interpolation);
tls->loop_interpolation_initialized = false;
@@ -878,7 +882,7 @@ static void subdiv_mesh_ensure_loop_interpolation(SubdivMeshContext *ctx,
}
/* Store settings used for the current state of interpolator. */
tls->loop_interpolation_initialized = true;
tls->loop_interpolation_coarse_poly = coarse_poly;
tls->loop_interpolation_coarse_poly_index = coarse_poly_index;
tls->loop_interpolation_coarse_corner = coarse_corner;
}
@@ -896,8 +900,7 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const MPoly &coarse_poly = ctx->coarse_polys[coarse_poly_index];
subdiv_mesh_ensure_loop_interpolation(ctx, tls, &coarse_poly, coarse_corner);
subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly_index, coarse_corner);
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;
@@ -910,26 +913,18 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
/** \name Polygons subdivision process
* \{ */
static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
const int subdiv_poly,
const int coarse_poly)
{
CustomData_copy_data(
&ctx->coarse_mesh->pdata, &ctx->subdiv_mesh->pdata, coarse_poly, subdiv_poly, 1);
}
static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
void * /*tls*/,
const int coarse_poly_index,
const int subdiv_poly_index,
const int start_loop_index,
const int num_loops)
const int /*num_loops*/)
{
BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
subdiv_copy_poly_data(ctx, subdiv_poly_index, coarse_poly_index);
ctx->subdiv_polys[subdiv_poly_index].loopstart = start_loop_index;
ctx->subdiv_polys[subdiv_poly_index].totloop = num_loops;
CustomData_copy_data(
&ctx->coarse_mesh->pdata, &ctx->subdiv_mesh->pdata, coarse_poly_index, subdiv_poly_index, 1);
ctx->subdiv_poly_offsets[subdiv_poly_index] = start_loop_index;
}
/** \} */
+25 -25
View File
@@ -228,13 +228,13 @@ static int getFaceIndex(
}
static void get_face_uv_map_vert(UvVertMap *vmap,
const blender::Span<MPoly> polys,
const blender::OffsetIndices<int> polys,
const int *poly_verts,
int fi,
CCGVertHDL *fverts)
{
UvMapVert *v, *nv;
int j, nverts = polys[fi].totloop;
int j, nverts = polys[fi].size();
for (j = 0; j < nverts; j++) {
for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, poly_verts[j]); v; v = v->next) {
@@ -246,7 +246,7 @@ static void get_face_uv_map_vert(UvVertMap *vmap,
}
}
fverts[j] = POINTER_FROM_UINT(polys[nv->poly_index].loopstart + nv->loop_of_poly_index);
fverts[j] = POINTER_FROM_UINT(polys[nv->poly_index].start() + nv->loop_of_poly_index);
}
}
@@ -255,7 +255,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
DerivedMesh *dm,
const float (*mloopuv)[2])
{
const blender::Span<MPoly> polys(dm->getPolyArray(dm), dm->getNumPolys(dm));
const blender::OffsetIndices polys(blender::Span(dm->getPolyArray(dm), dm->getNumPolys(dm) + 1));
int *corner_verts = dm->getCornerVertArray(dm);
int totvert = dm->getNumVerts(dm);
int totface = dm->getNumPolys(dm);
@@ -273,7 +273,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.data(), nullptr, nullptr, corner_verts, mloopuv, totface, totvert, limit, false, true);
polys, nullptr, nullptr, corner_verts, mloopuv, totvert, limit, false, true);
if (!vmap) {
return 0;
}
@@ -297,7 +297,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
if (v->separate) {
CCGVert *ssv;
int loopid = polys[v->poly_index].loopstart + v->loop_of_poly_index;
int loopid = polys[v->poly_index].start() + v->loop_of_poly_index;
CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
copy_v2_v2(uv, mloopuv[loopid]);
@@ -311,15 +311,15 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
for (i = 0; i < totface; i++) {
const MPoly &poly = polys[i];
int nverts = poly.totloop;
const blender::IndexRange poly = polys[i];
int nverts = poly.size();
int j, j_next;
CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
// uint *fv = &poly.v1;
fverts.reinitialize(nverts);
get_face_uv_map_vert(vmap, polys, &corner_verts[poly.loopstart], i, fverts.data());
get_face_uv_map_vert(vmap, polys, &corner_verts[poly.start()], i, fverts.data());
for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
uint v0 = POINTER_AS_UINT(fverts[j_next]);
@@ -327,7 +327,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
if (BLI_edgeset_add(eset, v0, v1)) {
CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
CCGEdgeHDL ehdl = POINTER_FROM_INT(poly.loopstart + j_next);
CCGEdgeHDL ehdl = POINTER_FROM_INT(poly[j_next]);
float crease = ccgSubSurf_getEdgeCrease(orige);
ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
@@ -339,13 +339,13 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
/* create faces */
for (i = 0; i < totface; i++) {
const MPoly &poly = polys[i];
int nverts = poly.totloop;
const blender::IndexRange poly = polys[i];
int nverts = poly.size();
CCGFace *f;
fverts.reinitialize(nverts);
get_face_uv_map_vert(vmap, polys, &corner_verts[poly.loopstart], i, fverts.data());
get_face_uv_map_vert(vmap, polys, &corner_verts[poly.start()], i, fverts.data());
ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts.data(), &f);
}
@@ -541,7 +541,7 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
MEdge *edges = dm->getEdgeArray(dm);
MEdge *edge;
int *corner_verts = dm->getCornerVertArray(dm);
MPoly *polys = dm->getPolyArray(dm);
const blender::OffsetIndices polys(blender::Span(dm->getPolyArray(dm), dm->getNumPolys(dm) + 1));
int totvert = dm->getNumVerts(dm);
int totedge = dm->getNumEdges(dm);
int i, j;
@@ -584,21 +584,21 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
for (i = 0; i < dm->numPolyData; i++) {
const MPoly &poly = polys[i];
const blender::IndexRange poly = polys[i];
CCGFace *f;
fverts.reinitialize(poly.totloop);
fverts.reinitialize(poly.size());
int corner = poly.loopstart;
for (j = 0; j < poly.totloop; j++, corner++) {
fverts[j] = POINTER_FROM_UINT(corner_verts[corner]);
for (j = 0; j < poly.size(); j++) {
fverts[j] = POINTER_FROM_UINT(corner_verts[poly[j]]);
}
/* This is very bad, means mesh is internally inconsistent.
* it is not really possible to continue without modifying
* other parts of code significantly to handle missing faces.
* since this really shouldn't even be possible we just bail. */
if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), poly.totloop, fverts.data(), &f) ==
if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), poly.size(), fverts.data(), &f) ==
eCCGError_InvalidValue) {
static int hasGivenError = 0;
@@ -1108,7 +1108,7 @@ static void ccgDM_copyFinalCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges)
0, ccgSubSurf_getNumFaces(ss), &data, copyFinalLoopArray_task_cb, &settings);
}
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *polys)
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, int *r_poly_offsets)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGSubSurf *ss = ccgdm->ss;
@@ -1126,15 +1126,14 @@ static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *polys)
for (S = 0; S < numVerts; S++) {
for (y = 0; y < gridSize - 1; y++) {
for (x = 0; x < gridSize - 1; x++) {
polys[i].loopstart = k;
polys[i].totloop = 4;
r_poly_offsets[i] = k;
k += 4;
i++;
}
}
}
}
r_poly_offsets[i] = k;
}
static void ccgDM_release(DerivedMesh *dm)
@@ -1553,7 +1552,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(&dm->polyData, CD_MPOLY, "material_index"));
CustomData_get_layer_named(&dm->polyData, CD_PROP_INT32, "material_index"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face"));
@@ -1827,6 +1826,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
&ccgdm->dm.loopData, ".corner_vert", ccgSubSurf_getNumFinalFaces(ss) * 4);
CustomData_free_layer_named(
&ccgdm->dm.loopData, ".corner_edge", ccgSubSurf_getNumFinalFaces(ss) * 4);
MEM_SAFE_FREE(ccgdm->dm.poly_offsets);
ccgdm->reverseFaceMap = static_cast<int *>(
MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap"));
@@ -114,7 +114,7 @@ void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
const int poly_offset,
const int loop_offset,
MutableSpan<float3> vert_positions,
MutableSpan<MPoly> polys,
MutableSpan<int> poly_offsets,
MutableSpan<int> corner_verts)
{
/* Write vertices. */
@@ -122,8 +122,7 @@ void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
/* Write triangles. */
for (const int i : vdb_tris.index_range()) {
polys[poly_offset + i].loopstart = loop_offset + 3 * i;
polys[poly_offset + i].totloop = 3;
poly_offsets[poly_offset + i] = loop_offset + 3 * i;
for (int j = 0; j < 3; j++) {
/* Reverse vertex order to get correct normals. */
corner_verts[loop_offset + 3 * i + j] = vert_offset + vdb_tris[i][2 - j];
@@ -134,8 +133,7 @@ void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
const int quad_offset = poly_offset + vdb_tris.size();
const int quad_loop_offset = loop_offset + vdb_tris.size() * 3;
for (const int i : vdb_quads.index_range()) {
polys[quad_offset + i].loopstart = quad_loop_offset + 4 * i;
polys[quad_offset + i].totloop = 4;
poly_offsets[quad_offset + i] = quad_loop_offset + 4 * i;
for (int j = 0; j < 4; j++) {
/* Reverse vertex order to get correct normals. */
corner_verts[quad_loop_offset + 4 * i + j] = vert_offset + vdb_quads[i][3 - j];
@@ -176,7 +174,7 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid,
0,
0,
mesh->vert_positions_for_write(),
mesh->polys_for_write(),
mesh->poly_offsets_for_write(),
mesh->corner_verts_for_write());
BKE_mesh_calc_edges(mesh, false, false);
+9 -2
View File
@@ -2,6 +2,8 @@
#pragma once
#include <algorithm>
#include "BLI_index_range.hh"
#include "BLI_span.hh"
@@ -33,7 +35,7 @@ template<typename T> class OffsetIndices {
/** Return the total number of elements in the referenced arrays. */
T total_size() const
{
return offsets_.last();
return offsets_.size() == 1 ? 0 : offsets_.last();
}
/**
@@ -42,7 +44,7 @@ template<typename T> class OffsetIndices {
*/
int64_t size() const
{
return offsets_.size() - 1;
return std::max<int64_t>(offsets_.size() - 1, 0);
}
bool is_empty() const
@@ -83,6 +85,11 @@ template<typename T> class OffsetIndices {
BLI_assert(offsets_.index_range().drop_back(1).contains(range.last()));
return OffsetIndices(offsets_.slice(range.start(), range.one_after_last()));
}
const T *data() const
{
return offsets_.data();
}
};
/**
@@ -817,11 +817,12 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain)
if (MAIN_VERSION_ATLEAST(bmain, 290, 2) && MAIN_VERSION_OLDER(bmain, 291, 1)) {
/* In this range, the extrude manifold could generate meshes with degenerated face. */
LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
blender::MutableSpan<MPoly> polys = me->polys_for_write();
for (const int i : polys.index_range()) {
const MPoly *polys = static_cast<const MPoly *>(CustomData_get_layer(&me->pdata, CD_MPOLY));
for (const int i : blender::IndexRange(me->totpoly)) {
if (polys[i].totloop == 2) {
bool changed;
BKE_mesh_legacy_convert_loops_to_corners(me);
BKE_mesh_legacy_convert_polys_to_offsets(me);
BKE_mesh_validate_arrays(
me,
BKE_mesh_vert_positions_for_write(me),
@@ -832,8 +833,8 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain)
me->totface,
me->corner_verts_for_write().data(),
me->corner_edges_for_write().data(),
polys.size(),
polys.data(),
me->totloop,
BKE_mesh_poly_offsets_for_write(me),
me->totpoly,
BKE_mesh_deform_verts_for_write(me),
false,
@@ -40,6 +40,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &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);
BKE_mesh_legacy_convert_polys_to_offsets(&mesh);
}
static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip)
@@ -487,7 +487,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */
}
const Span<MPoly> polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const Span<int> corner_verts = me->corner_verts();
const Span<int> corner_edges = me->corner_edges();
@@ -500,11 +500,9 @@ 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,
corner_verts.slice(polys[i].loopstart, polys[i].totloop),
corner_edges.slice(polys[i].loopstart, polys[i].totloop),
vtable,
etable);
const IndexRange poly = polys[i];
BMFace *f = bm_face_create_from_mpoly(
*bm, corner_verts.slice(poly), corner_edges.slice(poly), vtable, etable);
if (!ftable.is_empty()) {
ftable[i] = f;
}
@@ -538,7 +536,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm->act_face = f;
}
int j = polys[i].loopstart;
int j = poly.start();
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
do {
@@ -1328,15 +1326,13 @@ static void bm_to_mesh_faces(const BMesh &bm,
MutableSpan<bool> sharp_faces,
MutableSpan<int> material_indices)
{
CustomData_add_layer(&mesh.pdata, CD_MPOLY, CD_CONSTRUCT, mesh.totpoly);
BKE_mesh_poly_offsets_ensure_alloc(&mesh);
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata);
MutableSpan<MPoly> dst_polys = mesh.polys_for_write();
threading::parallel_for(dst_polys.index_range(), 1024, [&](const IndexRange range) {
MutableSpan<int> dst_poly_offsets = mesh.poly_offsets_for_write();
threading::parallel_for(bm_faces.index_range(), 1024, [&](const IndexRange range) {
for (const int face_i : range) {
const BMFace &src_face = *bm_faces[face_i];
MPoly &dst_poly = dst_polys[face_i];
dst_poly.totloop = src_face.len;
dst_poly.loopstart = BM_elem_index_get(BM_FACE_FIRST_LOOP(&src_face));
dst_poly_offsets[face_i] = BM_elem_index_get(BM_FACE_FIRST_LOOP(&src_face));
bmesh_block_copy_to_mesh_attributes(info, face_i, src_face.head.data);
}
if (!select_poly.is_empty()) {
@@ -1391,6 +1387,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
CustomData_free(&me->fdata, me->totface);
CustomData_free(&me->ldata, me->totloop);
CustomData_free(&me->pdata, me->totpoly);
MEM_SAFE_FREE(me->poly_offset_indices);
BKE_mesh_runtime_clear_geometry(me);
me->totvert = bm->totvert;
+2 -2
View File
@@ -10,6 +10,7 @@
/* Needed for BKE_ccg.h. */
#include "BLI_assert.h"
#include "BLI_bitmap.h"
#include "BLI_offset_indices.hh"
#include "BLI_span.hh"
#include "BKE_ccg.h"
@@ -24,7 +25,6 @@ struct DMFlagMat;
struct Mesh;
struct MLoopTri;
struct CustomData;
struct MPoly;
struct SubdivCCG;
struct BMesh;
@@ -34,9 +34,9 @@ struct PBVH_GPU_Args {
BMesh *bm;
const Mesh *me;
const float (*vert_positions)[3];
blender::OffsetIndices<int> polys;
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
const MPoly *polys;
int mesh_verts_num, mesh_faces_num, mesh_grids_num;
CustomData *vdata, *ldata, *pdata;
const float (*vert_normals)[3];
@@ -303,10 +303,9 @@ static void extract_range_iter_poly_mesh(void *__restrict userdata,
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData *mr = data->mr;
const MPoly *poly = &((const MPoly *)data->elems)[iter];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_poly_mesh(
mr, poly, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
mr, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
@@ -886,8 +885,7 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
/* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_poly_index is
* based on the subdivision loops. */
const int poly_origindex = subdiv_loop_poly_index[i * 4];
const MPoly &poly = mr->polys[poly_origindex];
extractor->iter_subdiv_mesh(subdiv_cache, mr, data, i, &poly);
extractor->iter_subdiv_mesh(subdiv_cache, mr, data, i, poly_origindex);
}
}
}
@@ -191,12 +191,11 @@ static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata
MeshRenderData *mr = static_cast<MeshRenderData *>(userdata);
int *mat_tri_len = static_cast<int *>(tls->userdata_chunk);
const MPoly &poly = mr->polys[iter];
if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[iter])) {
const int mat = mr->material_indices ?
clamp_i(mr->material_indices[iter], 0, mr->mat_len - 1) :
0;
mat_tri_len[mat] += poly.totloop - 2;
mat_tri_len[mat] += mr->polys[iter].size() - 2;
}
}
@@ -282,10 +281,9 @@ static void mesh_render_data_polys_sorted_build(MeshRenderData *mr, MeshBufferCa
else {
for (int i = 0; i < mr->poly_len; i++) {
if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[i])) {
const MPoly &poly = mr->polys[i];
const int mat = mr->material_indices ? clamp_i(mr->material_indices[i], 0, mat_last) : 0;
tri_first_index[i] = mat_tri_offs[mat];
mat_tri_offs[mat] += poly.totloop - 2;
mat_tri_offs[mat] += mr->polys[i].size() - 2;
}
else {
tri_first_index[i] = -1;
@@ -754,7 +754,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *
Mesh *mesh,
uint32_t *flags_data)
{
const Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
for (const int i : polys.index_range()) {
uint32_t flag = 0;
if (!(mr->sharp_faces && mr->sharp_faces[i])) {
@@ -766,7 +766,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *
if (mr->hide_poly && mr->hide_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN;
}
flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
flags_data[i] = uint(polys[i].start()) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -780,7 +780,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
return;
}
const Span<MPoly> polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
for (const int i : polys.index_range()) {
BMFace *f = bm_original_face_get(mr, i);
/* Selection and hiding from bmesh. */
@@ -789,7 +789,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
if (!(mr->sharp_faces && mr->sharp_faces[i])) {
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
flags_data[i] = uint(polys[i].start()) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -1209,7 +1209,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
}
/* Only build polygon related data if we have polygons. */
const Span<MPoly> polys = mesh_eval->polys();
const blender::OffsetIndices polys = mesh_eval->polys();
if (cache->num_subdiv_loops != 0) {
/* Build buffers for the PatchMap. */
draw_patch_map_build(&cache->gpu_patch_map, subdiv);
@@ -1223,7 +1223,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
GPU_vertbuf_get_data(cache->fdots_patch_coords);
for (int i = 0; i < mesh_eval->totpoly; i++) {
const int ptex_face_index = cache->face_ptex_offset[i];
if (polys[i].totloop == 4) {
if (polys[i].size() == 4) {
/* For quads, the center coordinate of the coarse face has `u = v = 0.5`. */
blender_fdots_patch_coords[i] = make_patch_coord(ptex_face_index, 0.5f, 0.5f);
}
+1 -2
View File
@@ -342,10 +342,9 @@ struct PBVHBatches {
last_poly = tri->poly;
flat = sharp_faces && sharp_faces[tri->poly];
if (flat) {
const MPoly &poly = args->polys[tri->poly];
const float3 fno = blender::bke::mesh::poly_normal_calc(
{reinterpret_cast<const float3 *>(args->vert_positions), args->mesh_verts_num},
{&args->corner_verts[poly.loopstart], poly.totloop});
args->corner_verts.slice(args->polys[tri->poly]));
normal_float_to_short_v3(no, fno);
}
}
@@ -77,7 +77,7 @@ struct MeshRenderData {
Mesh *me;
blender::Span<blender::float3> vert_positions;
blender::Span<MEdge> edges;
blender::Span<MPoly> polys;
blender::OffsetIndices<int> polys;
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
BMVert *eve_act;
@@ -253,10 +253,7 @@ using ExtractPolyBMeshFn = void(const MeshRenderData *mr,
const BMFace *f,
int f_index,
void *data);
using ExtractPolyMeshFn = void(const MeshRenderData *mr,
const MPoly *poly,
int poly_index,
void *data);
using ExtractPolyMeshFn = void(const MeshRenderData *mr, int poly_index, void *data);
using ExtractLEdgeBMeshFn = void(const MeshRenderData *mr,
const BMEdge *eed,
int ledge_index,
@@ -298,7 +295,7 @@ using ExtractIterSubdivMeshFn = void(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *data,
uint subdiv_quad_index,
const MPoly *coarse_quad);
int coarse_quad_index);
using ExtractFinishSubdivFn = void(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
MeshBatchCache *cache,
@@ -118,12 +118,12 @@ static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache * /*subdiv
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
const int coarse_quad_index)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const uint loop_idx = subdiv_quad_index * 4;
const BMFace *efa = bm_original_face_get(mr, coarse_quad - mr->polys.data());
const BMFace *efa = bm_original_face_get(mr, coarse_quad_index);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
@@ -204,12 +204,11 @@ static void extract_edituv_lines_iter_poly_bm(const MeshRenderData * /*mr*/,
}
static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const int ml_index_end = poly->loopstart + poly->totloop;
const IndexRange poly = mr->polys[poly_index];
bool mp_hidden, mp_select;
if (mr->bm) {
@@ -222,11 +221,11 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
mp_select = mr->select_poly && mr->select_poly[poly_index];
}
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : poly) {
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 int ml_index_last = poly.last();
const int ml_index_next = (ml_index == ml_index_last) ? poly.start() : (ml_index + 1);
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);
}
@@ -285,11 +284,10 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_poly)
const int coarse_poly_index)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
const int coarse_poly_index = coarse_poly - mr->polys.data();
bool mp_hidden, mp_select;
if (mr->bm) {
const BMFace *efa = bm_original_face_get(mr, coarse_poly_index);
@@ -388,7 +386,6 @@ static void extract_edituv_points_iter_poly_bm(const MeshRenderData * /*mr*/,
}
static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
@@ -398,8 +395,7 @@ static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : mr->polys[poly_index]) {
const int vert = mr->corner_verts[ml_index];
const bool real_vert = !mr->v_origindex || mr->v_origindex[vert] != ORIGINDEX_NONE;
@@ -453,12 +449,12 @@ static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
const int coarse_quad_index)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
const BMFace *efa = bm_original_face_get(mr, coarse_quad - mr->polys.data());
const BMFace *efa = bm_original_face_get(mr, coarse_quad_index);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
@@ -543,7 +539,6 @@ static void extract_edituv_fdots_iter_poly_bm(const MeshRenderData * /*mr*/,
}
static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
@@ -556,8 +551,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
if (mr->use_subsurf_fdots) {
const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : mr->polys[poly_index]) {
const int vert = mr->corner_verts[ml_index];
const bool real_fdot = !mr->p_origindex || (mr->p_origindex[poly_index] != ORIGINDEX_NONE);
@@ -38,7 +38,6 @@ static void extract_fdots_iter_poly_bm(const MeshRenderData * /*mr*/,
}
static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_userdata)
{
@@ -48,8 +47,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
if (mr->use_subsurf_fdots) {
const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : mr->polys[poly_index]) {
const int vert = mr->corner_verts[ml_index];
if (facedot_tags[vert] && !hidden) {
GPU_indexbuf_set_point_vert(elb, poly_index, poly_index);
@@ -85,16 +85,18 @@ static void extract_lines_iter_poly_bm(const MeshRenderData * /*mr*/,
}
static void extract_lines_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int /*poly_index*/,
const int poly_index,
void *tls_data)
{
MeshExtract_LinesData *data = static_cast<MeshExtract_LinesData *>(tls_data);
GPUIndexBufBuilder *elb = &data->elb;
const IndexRange poly = mr->polys[poly_index];
/* Using poly & loop iterator would complicate accessing the adjacent loop. */
if (data->test_visibility) {
const int ml_index_last = poly->loopstart + (poly->totloop - 1);
int ml_index = ml_index_last, ml_index_next = poly->loopstart;
const int ml_index_last = poly.last();
int ml_index = ml_index_last, ml_index_next = poly.start();
do {
const int edge = mr->corner_edges[ml_index];
if (is_edge_visible(data, edge)) {
@@ -106,8 +108,8 @@ static void extract_lines_iter_poly_mesh(const MeshRenderData *mr,
} while ((ml_index = ml_index_next++) != ml_index_last);
}
else {
const int ml_index_last = poly->loopstart + (poly->totloop - 1);
int ml_index = ml_index_last, ml_index_next = poly->loopstart;
const int ml_index_last = poly.last();
int ml_index = ml_index_last, ml_index_next = poly.start();
do {
const int edge = mr->corner_edges[ml_index];
GPU_indexbuf_set_line_verts(elb, edge, ml_index, ml_index_next);
@@ -216,7 +216,7 @@ static void extract_lines_adjacency_iter_subdiv_mesh(const DRWSubdivCache *subdi
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly * /*coarse_quad*/)
const int /*coarse_quad_index*/)
{
extract_lines_adjacency_iter_subdiv(subdiv_cache, mr, _data, subdiv_quad_index);
}
@@ -36,20 +36,21 @@ static void extract_lines_paint_mask_init(const MeshRenderData *mr,
}
static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_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 IndexRange poly = mr->polys[poly_index];
const int ml_index_end = poly.start() + poly.size();
for (int ml_index = poly.start(); ml_index < ml_index_end; ml_index += 1) {
const int e_index = mr->corner_edges[ml_index];
if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[e_index]) ||
((mr->e_origindex) && (mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
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 int ml_index_last = poly.size() + poly.start() - 1;
const int ml_index_other = (ml_index == ml_index_last) ? poly.start() : (ml_index + 1);
if (mr->select_poly && mr->select_poly[poly_index]) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, e_index)) {
/* Hide edge as it has more than 2 selected loop. */
@@ -102,14 +103,12 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
const int coarse_quad_index)
{
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_data);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
int *subdiv_loop_subdiv_edge_index = subdiv_cache->subdiv_loop_subdiv_edge_index;
const int coarse_quad_index = coarse_quad - mr->polys.data();
uint start_loop_idx = subdiv_quad_index * 4;
uint end_loop_idx = (subdiv_quad_index + 1) * 4;
for (uint loop_idx = start_loop_idx; loop_idx < end_loop_idx; loop_idx++) {
@@ -69,13 +69,11 @@ static void extract_points_iter_poly_bm(const MeshRenderData * /*mr*/,
}
static void extract_points_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int /*poly_index*/,
const int poly_index,
void *_userdata)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : mr->polys[poly_index]) {
vert_set_mesh(elb, mr, mr->corner_verts[ml_index], ml_index);
}
}
@@ -201,7 +199,7 @@ static void extract_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly * /*coarse_quad*/)
const int /*coarse_quad_index*/)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index, false);
@@ -60,7 +60,6 @@ static void extract_tris_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_tris_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
@@ -69,10 +68,12 @@ static void extract_tris_iter_poly_mesh(const MeshRenderData *mr,
return;
}
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
int tri_first_index_real = poly_to_tri_count(poly_index, poly->loopstart);
const IndexRange poly = mr->polys[poly_index];
int tri_len = poly->totloop - 2;
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
int tri_first_index_real = poly_to_tri_count(poly_index, poly.start());
int tri_len = poly.size() - 2;
for (int offs = 0; offs < tri_len; offs++) {
const MLoopTri *mlt = &mr->looptris[tri_first_index_real + offs];
int tri_index = tri_first_index + offs;
@@ -211,9 +211,9 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr,
break;
case ATTR_DOMAIN_FACE:
for (int poly_index = 0; poly_index < mr->poly_len; poly_index++) {
const MPoly &poly = mr->polys[poly_index];
const IndexRange poly = mr->polys[poly_index];
const VBOType value = Converter::convert_value(attr_data[poly_index]);
for (int l = 0; l < poly.totloop; l++) {
for (int l = 0; l < poly.size(); l++) {
*vbo_data++ = value;
}
}
@@ -109,15 +109,14 @@ static void extract_edge_fac_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
MeshExtract_EdgeFac_Data *data = static_cast<MeshExtract_EdgeFac_Data *>(_data);
const IndexRange poly = mr->polys[poly_index];
const BitSpan optimal_display_edges = mr->me->runtime->subsurf_optimal_display_edges;
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : poly) {
const int edge = mr->corner_edges[ml_index];
if (data->use_edge_render && !optimal_display_edges[edge]) {
@@ -145,14 +145,12 @@ static void extract_edit_data_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
EditLoopData *vbo_data = *(EditLoopData **)_data;
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : mr->polys[poly_index]) {
EditLoopData *data = vbo_data + ml_index;
memset(data, 0x0, sizeof(*data));
BMFace *efa = bm_original_face_get(mr, poly_index);
@@ -295,9 +293,8 @@ static void extract_edit_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cach
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
const int coarse_quad_index)
{
const int coarse_quad_index = int(coarse_quad - mr->polys.data());
BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
extract_edit_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
}
@@ -70,13 +70,13 @@ static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *_data)
{
MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_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 IndexRange poly = mr->polys[poly_index];
const int ml_index_end = poly.start() + poly.size();
for (int ml_index = poly.start(); ml_index < ml_index_end; ml_index += 1) {
EditLoopData *eldata = &data->vbo_data[ml_index];
memset(eldata, 0x0, sizeof(*eldata));
BMFace *efa = bm_original_face_get(mr, poly_index);
@@ -93,8 +93,8 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
if (eed == nullptr) {
/* Find if the loop's vert is not part of an edit edge.
* 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 int ml_index_last = poly.start() + poly.size() - 1;
const int l_prev = (ml_index == poly.start()) ? ml_index_last : (ml_index - 1);
eed = bm_original_edge_get(mr, mr->corner_edges[l_prev]);
}
if (eed) {
@@ -167,9 +167,8 @@ static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_ca
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
const int coarse_quad_index)
{
const int coarse_quad_index = int(coarse_quad - mr->polys.data());
BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
extract_edituv_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
}
@@ -154,21 +154,21 @@ static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int /*poly_index*/,
const int poly_index,
void *_data)
{
MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data);
const IndexRange poly = mr->polys[poly_index];
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
const int ml_index_end = poly.start() + poly.size();
for (int ml_index = poly.start(); ml_index < ml_index_end; ml_index += 1) {
float(*auv)[2] = data->auv, *last_auv = data->last_auv;
float(*av)[3] = data->av, *last_av = data->last_av;
int l_next = ml_index + 1;
if (ml_index == poly->loopstart) {
if (ml_index == poly.start()) {
/* First loop in face. */
const int ml_index_last = ml_index_end - 1;
const int l_next_tmp = poly->loopstart;
const int l_next_tmp = poly.start();
compute_normalize_edge_vectors(auv,
av,
data->uv[ml_index_last],
@@ -180,7 +180,7 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr
copy_v3_v3(last_av, av[1]);
}
if (l_next == ml_index_end) {
l_next = poly->loopstart;
l_next = poly.start();
/* Move previous edge. */
copy_v2_v2(auv[0], auv[1]);
copy_v3_v3(av[0], av[1]);
@@ -76,11 +76,11 @@ static void compute_area_ratio(const MeshRenderData *mr,
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
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->corner_verts.slice(poly.loopstart, poly.totloop));
float uvarea = area_poly_v2(reinterpret_cast<const float(*)[2]>(&uv_data[poly.loopstart]),
poly.totloop);
const IndexRange poly = mr->polys[poly_index];
const float area = bke::mesh::poly_area_calc(mr->vert_positions,
mr->corner_verts.slice(poly));
float uvarea = area_poly_v2(reinterpret_cast<const float(*)[2]>(&uv_data[poly.start()]),
poly.size());
tot_area += area;
tot_uv_area += uvarea;
r_area_ratio[poly_index] = area_ratio_get(area, uvarea);
@@ -115,10 +115,9 @@ static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
}
else {
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
for (const int poly_i : mr->polys.index_range()) {
const MPoly &poly = mr->polys[poly_i];
for (const int loop_i : IndexRange(poly.loopstart, poly.totloop)) {
loop_stretch[loop_i] = area_ratio[poly_i];
for (int poly_index = 0; poly_index < mr->poly_len; poly_index++) {
for (const int l_index : mr->polys[poly_index]) {
loop_stretch[l_index] = area_ratio[poly_index];
}
}
}
@@ -51,7 +51,6 @@ static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
const MPoly * /*poly*/,
const int poly_index,
void *_data)
{
@@ -67,7 +67,6 @@ static void extract_fdots_pos_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *poly,
const int poly_index,
void *data)
{
@@ -77,8 +76,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const int ml_index_end = poly->loopstart + poly->totloop;
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
for (const int ml_index : mr->polys[poly_index]) {
const int vert = mr->corner_verts[ml_index];
if (mr->use_subsurf_fdots) {
if (facedot_tags[vert]) {
@@ -92,7 +90,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
}
if (!mr->use_subsurf_fdots) {
mul_v3_fl(co, 1.0f / float(poly->totloop));
mul_v3_fl(co, 1.0f / float(mr->polys[poly_index].size()));
}
}

Some files were not shown because too many files have changed in this diff Show More