83 remaining uses of MPoly

This commit is contained in:
Hans Goudey 2023-02-04 22:58:45 -05:00
parent e49eaf4ffb
commit 1f4aa3c40f
34 changed files with 619 additions and 661 deletions

View File

@ -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;
/* Owned data. */
int *poly_offsets;
/**
* \warning Typical access is done via #getLoopTriArray, #getNumLoopTri.

View File

@ -920,7 +920,7 @@ bool BKE_mesh_validate_arrays(struct Mesh *me,
int *corner_verts,
int *corner_edges,
unsigned int totloop,
const int *poly_offsets,
int *poly_offsets,
unsigned int totpoly,
struct MDeformVert *dverts, /* assume totvert length */
bool do_verbose,

View File

@ -153,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(
struct MPoly *mpoly, 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 */

View File

@ -303,15 +303,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,
const int *poly_offsets,
int *r_v1,
int *r_v2);
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
const int *corner_verts,
const 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.
*

View File

@ -160,17 +160,10 @@ static int *dm_getCornerEdgeArray(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, nullptr, 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__);
}
return mpoly;
return dm->poly_offsets;
}
static int dm_getNumLoopTri(DerivedMesh *dm)

View File

@ -237,8 +237,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));
cddm->poly_offsets = static_cast<MPoly *>(nullptr) /* TODO. */;
#if 0
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
#else

View File

@ -268,7 +268,7 @@ 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);
mesh->mpoly = BKE_mesh_legacy_convert_offsets_to_polys(
mesh->mpoly = BKE_mesh_legacy_convert_offsets_to_mpolys(
mesh, temp_arrays_for_legacy_format, mesh.polys());
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh);
@ -955,6 +955,7 @@ static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
mesh->poly_offsets_data = static_cast<int *>(
MEM_malloc_arrayN(mesh->totpoly + 1, sizeof(int), __func__));
}
mesh->poly_offsets_for_write().last() = mesh->totloop;
}
if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_MFACE)) {
CustomData_add_layer(&mesh->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, mesh->totface);
@ -1518,8 +1519,8 @@ int poly_get_adj_loops_from_vert(const blender::Span<int> poly_verts, int vert,
if (corner != -1) {
/* vertex was found */
r_adj[0] = corner_verts[ME_POLY_LOOP_PREV(poly, corner)];
r_adj[1] = corner_verts[ME_POLY_LOOP_NEXT(poly, corner)];
r_adj[0] = poly_verts[mod_i(corner - 1, poly_verts.size())];
r_adj[1] = poly_verts[mod_i(corner + 1, poly_verts.size())];
}
return corner;
@ -1840,7 +1841,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
const Span<float3> positions = mesh->vert_positions();
const Span<MEdge> edges = mesh->edges();
const OffsetIndices polys = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(positions.data()),
BKE_mesh_vertex_normals_ensure(mesh),
@ -1853,7 +1854,6 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
mesh->totloop,
polys,
BKE_mesh_poly_normals_ensure(mesh),
polys.size(),
use_split_normals,
split_angle,
sharp_edges,

View File

@ -98,10 +98,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;
@ -137,7 +137,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());
@ -152,12 +152,12 @@ 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());
@ -165,7 +165,6 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
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 *mp = &polys[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@ -175,7 +174,7 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
if (r_index_in_orig_mesh) {
*r_index_in_orig_mesh = index_in_mesh;
}
return mp;
return polys[index_in_mesh];
}
/* Given an index of an original vertex in the `IMesh`, find out the input
@ -226,7 +225,7 @@ const MEdge *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.
@ -284,10 +283,10 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
const float4x4 inv_target_mat = clean_transform(target_transform).inverted();
/* 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;
@ -340,12 +339,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) {
@ -457,16 +457,16 @@ static void copy_edge_attributes(Mesh *dest_mesh,
/**
* For #IMesh face `f`, with corresponding output Mesh poly `mp`,
* where the original Mesh poly is `orig_mp`, coming from the Mesh
* where the original Mesh poly is `orig_poly`, coming from the Mesh
* `orig_me`, which has index `orig_me_index` in `mim`:
* fill in the `orig_loops` Array with corresponding indices of MLoops from `orig_me`
* where they have the same start and end vertices; for cases where that is
* not true, put -1 in the `orig_loops` slot.
* For now, we only try to do this if `mp` and `orig_mp` have the same size.
* For now, we only try to do this if `mp` and `orig_poly` have the same size.
* Return the number of non-null MLoops filled in.
*/
static int fill_orig_loops(const Face *f,
const MPoly *orig_mp,
const IndexRange orig_poly,
const Mesh *orig_me,
int orig_me_index,
MeshesToIMeshInfo &mim,
@ -475,7 +475,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_mp->totloop;
int orig_mplen = orig_poly.size();
if (f->size() != orig_mplen) {
return 0;
}
@ -500,7 +500,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_mp->loopstart;
int loop_i = i + orig_poly.start();
if (orig_corner_verts[loop_i] == first_orig_v_in_orig_me) {
offset = i;
break;
@ -512,7 +512,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_mp->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;
@ -522,7 +522,7 @@ static int fill_orig_loops(const Face *f,
}
if (vert_i == fv_orig) {
const int vert_next =
orig_corner_verts[orig_mp->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;
@ -531,7 +531,7 @@ static int fill_orig_loops(const Face *f,
}
}
if (vert_next == fvnext_orig) {
r_orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index;
r_orig_loops[mp_loop_index] = orig_poly.start() + orig_mp_loop_index;
++num_orig_loops_found;
}
}
@ -539,26 +539,24 @@ static int fill_orig_loops(const Face *f,
return num_orig_loops_found;
}
/* Fill `cos_2d` with the 2d coordinates found by projection MPoly `mp` 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 `mp->totloop` entries. */
* `cos_2d` should have room for `poly.size()` entries. */
static void get_poly2d_cos(const Mesh *me,
const MPoly *mp,
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(mp->loopstart, mp->totloop);
const Span<int> poly_verts = corner_verts.slice(poly);
/* Project coordinates to 2d in cos_2d, using normal as projection axis. */
float axis_dominant[3];
BKE_mesh_calc_poly_normal(mp,
&corner_verts[mp->loopstart],
reinterpret_cast<const float(*)[3]>(positions.data()),
axis_dominant);
BKE_mesh_calc_poly_normal(
poly_verts, reinterpret_cast<const float(*)[3]>(positions.data()), axis_dominant);
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
for (const int i : poly_verts.index_range()) {
float3 co = positions[poly_verts[i]];
@ -567,41 +565,41 @@ static void get_poly2d_cos(const Mesh *me,
}
}
/* For the loops of `mp`, see if the face is unchanged from `orig_mp`, and if so,
/* For the loops of `mp`, see if the face is unchanged from `orig_poly`, and if so,
* copy the Loop attributes from corresponding loops to corresponding loops.
* Otherwise, interpolate the Loop attributes in the face `orig_mp`. */
* Otherwise, interpolate the Loop attributes in the face `orig_poly`. */
static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
const Face *f,
MPoly *mp,
const MPoly *orig_mp,
const IndexRange poly,
const IndexRange orig_poly,
const Mesh *orig_me,
int orig_me_index,
MeshesToIMeshInfo &mim)
{
Array<int> orig_loops(mp->totloop);
int norig = fill_orig_loops(f, orig_mp, orig_me, orig_me_index, mim, orig_loops);
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. */
float(*cos_2d)[2];
Array<float> weights;
Array<const void *> src_blocks_ofs;
float axis_mat[3][3];
if (norig != mp->totloop) {
/* We will need to interpolate. Make `cos_2d` hold 2d-projected coordinates of `orig_mp`,
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_mp->totloop);
weights = Array<float>(orig_mp->totloop);
src_blocks_ofs = Array<const void *>(orig_mp->totloop);
get_poly2d_cos(orig_me, orig_mp, cos_2d, mim.to_target_transform[orig_me_index], axis_mat);
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 < mp->totloop; ++i) {
int loop_index = mp->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) {
@ -610,7 +608,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_mp->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) {
int ty = source_cd->layers[source_layer_i].type;
@ -640,9 +638,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_mp->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_mp->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);
@ -651,7 +649,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
src_blocks_ofs.data(),
weights.data(),
nullptr,
orig_mp->totloop,
orig_poly.size(),
dst_block_ofs,
target_layer_i);
}
@ -735,17 +733,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->poly_offsets_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_mp = 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 *mp = &dst_polys[fi];
mp->totloop = f->size();
mp->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);
@ -761,7 +757,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, mp, orig_mp, orig_me, orig_me_index, mim);
copy_or_interp_loop_attributes(result,
f,
IndexRange(dst_poly_offsets[fi], orig_poly.size()),
orig_poly,
orig_me,
orig_me_index,
mim);
}
dst_material_indices.finish();
@ -770,20 +772,22 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
BKE_mesh_calc_edges(result, false, false);
merge_edge_customdata_layers(result, mim);
const OffsetIndices dst_polys = result->polys();
/* Now that the MEdges are populated, we can copy over the required attributes and custom layers.
*/
MutableSpan<MEdge> edges = result->edges_for_write();
const Span<int> dst_corner_edges = result->corner_edges();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
const MPoly *mp = &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;
const MEdge *orig_medge = mim.input_medge_for_orig_index(
f->edge_orig[j], &orig_me, &index_in_orig_me);
int e_index = dst_corner_edges[mp->loopstart + j];
int e_index = dst_corner_edges[poly[j]];
MEdge *medge = &edges[e_index];
copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me);
}
@ -850,10 +854,10 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
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);
}
}

View File

@ -345,7 +345,6 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
{
int i = me->totpoly;
const MPoly *mpoly;
float poly_volume;
float total_volume = 0.0f;
float poly_cent[3];

View File

@ -201,7 +201,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, maxPolys);
/* Subdivision-surface for eg won't have mesh data in the custom-data arrays.
* Now add position/#MEdge/#MPoly layers. */
* Now add position/#MEdge layers. */
if (BKE_mesh_vert_positions(mesh) != NULL) {
memcpy(BKE_mesh_vert_positions_for_write(result),
BKE_mesh_vert_positions(mesh),
@ -210,9 +210,10 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge);
}
if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
result->corner_verts_for_write().copy_from(mesh->corner_verts());
result->corner_edges_for_write().copy_from(mesh->corner_edges());
blender::MutableSpan<int> poly_offsets = result->poly_offsets_for_write();
poly_offsets.take_front(maxPolys).copy_from(mesh->poly_offsets().drop_back(1));
for (const int i : blender::IndexRange(maxPolys)) {
poly_offsets[maxPolys + i] = poly_offsets[i] + maxLoops;
}
/* Copy custom-data to new geometry,
@ -309,34 +310,31 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
me->v2 += maxVerts;
}
blender::MutableSpan<int> result_polys = result->poly_offsets_for_write();
/* adjust mirrored poly loopstart indices, and reverse loop order (normals) */
blender::MutableSpan<int> corner_edges = result->corner_edges_for_write();
for (i = 0; i < maxPolys; i++, mp++) {
for (i = 0; i < maxPolys; i++) {
int j, e;
const int poly_start = poly_offsets[maxPolys + i];
const int poly_size = poly_offsets[maxPolys + i + 1] - poly_start;
/* 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 */
CustomData_copy_data(
&result->ldata, &result->ldata, mp->loopstart, mp->loopstart + maxLoops, 1);
CustomData_copy_data(&result->ldata, &result->ldata, poly_start, poly_start + maxLoops, 1);
for (j = 1; j < mp->totloop; j++) {
CustomData_copy_data(&result->ldata,
&result->ldata,
mp->loopstart + j,
mp->loopstart + maxLoops + mp->totloop - j,
poly_start + j,
poly_start + maxLoops + mp->totloop - j,
1);
}
int *corner_edge_2 = &corner_edges[mp->loopstart + maxLoops];
int *corner_edge_2 = &corner_edges[poly_start + maxLoops];
e = corner_edge_2[0];
for (j = 0; j < mp->totloop - 1; j++) {
corner_edge_2[j] = corner_edge_2[j + 1];
}
corner_edge_2[mp->totloop - 1] = e;
mp->loopstart += maxLoops;
}
/* adjust mirrored loop vertex and edge indices */

View File

@ -1114,7 +1114,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 : polys.ranges_num();
uchar *poly_status = static_cast<uchar *>(
MEM_callocN(sizeof(*poly_status) * size_t(node_num), __func__));
float(*poly_centers)[3];
@ -1129,8 +1129,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.ranges_num())));
for (i = island_poly_map->count; i--;) {
poly_island_index_map[island_poly_map->indices[i]] = i;
}
@ -1156,15 +1156,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 *mp = &polys[pidx];
int pl_idx, l_idx;
if (poly_status[pidx_isld] == POLY_COMPLETE) {
continue;
}
for (pl_idx = 0, l_idx = mp->loopstart; pl_idx < mp->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;
@ -1303,7 +1300,7 @@ 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 float(*positions_src)[3] = BKE_mesh_vert_positions(me_src);
const int num_verts_src = me_src->totvert;
@ -1323,8 +1320,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int *indices_interp = nullptr;
float *weights_interp = nullptr;
const MPoly *mp_src;
const MPoly *mp_dst;
int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src;
IslandResult **islands_res;
@ -1427,17 +1422,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
corner_edges_src.data(),
num_loops_src);
if (use_from_vert) {
loop_to_poly_map_src = static_cast<int *>(
MEM_mallocN(sizeof(*loop_to_poly_map_src) * size_t(num_loops_src), __func__));
loop_to_poly_map_src = blender::bke::mesh_topology::build_loop_to_poly_map(polys_src);
poly_cents_src = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*poly_cents_src) * size_t(num_polys_src), __func__));
for (pidx_src = 0, mp_src = polys_src; pidx_src < num_polys_src; pidx_src++, mp_src++) {
for (plidx_src = 0, lidx_src = mp_src->loopstart; plidx_src < mp_src->totloop;
plidx_src++, lidx_src++) {
loop_to_poly_map_src[lidx_src] = pidx_src;
}
for (const int i : polys_src.index_range()) {
BKE_mesh_calc_poly_center(
mp_src, &corner_verts_src[mp_src->loopstart], positions_src, poly_cents_src[pidx_src]);
corner_verts_src.slice(polys_src[i]), positions_src, poly_cents_src[pidx_src]);
}
}
@ -1511,10 +1502,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int num_verts_active = 0;
verts_active.fill(false);
for (i = 0; i < isld->count; i++) {
mp_src = &polys_src[isld->indices[i]];
for (lidx_src = mp_src->loopstart; lidx_src < mp_src->loopstart + mp_src->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++;
@ -1547,8 +1535,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int num_looptri_active = 0;
looptri_active.fill(false);
for (i = 0; i < num_looptri_src; i++) {
mp_src = &polys_src[looptri_src[i].poly];
if (island_store.items_to_islands[mp_src->loopstart] == tindex) {
const blender::IndexRange poly_src = polys_src[looptri_src[i].poly];
if (island_store.items_to_islands[poly_src.start()] == tindex) {
looptri_active[i].set();
num_looptri_active++;
}
@ -1579,7 +1567,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.ranges_num(); 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
@ -1594,8 +1583,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));
@ -1605,8 +1594,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;
@ -1627,7 +1616,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_nors_dst[plidx_dst + mp_dst->loopstart]);
copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + poly_dst.start()]);
if (space_transform) {
BLI_space_transform_apply_normal(space_transform, tmp_no);
}
@ -1654,7 +1643,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);
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! */
@ -1668,13 +1657,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
float *pcent_src;
float sqdist;
mp_src = &polys_src[pidx_src];
if (!pcent_dst_valid) {
BKE_mesh_calc_poly_center(mp_dst,
&corner_verts_src[mp_dst->loopstart],
vert_positions_dst,
pcent_dst);
BKE_mesh_calc_poly_center(
corner_verts_src.slice(poly_dst), vert_positions_dst, pcent_dst);
pcent_dst_valid = true;
}
pcent_src = poly_cents_src[pidx_src];
@ -1695,11 +1680,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. */
mp_src = &polys_src[best_index_src];
for (plidx_src = 0; plidx_src < mp_src->totloop; plidx_src++) {
const int vert_src = corner_verts_src[mp_src->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 + mp_src->loopstart;
best_index_src = plidx_src + poly_src.start();
break;
}
}
@ -1721,7 +1706,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_nors_dst[plidx_dst + mp_dst->loopstart]);
copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + poly_dst.start()]);
/* We do our transform here, since we may do several raycast/nearest queries. */
if (space_transform) {
@ -1823,10 +1808,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;
@ -1841,9 +1826,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 + poly_dst.start();
if (best_island_index == -1) {
/* No source for any loops of our dest poly in any source islands. */
@ -1913,13 +1898,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);
mp_src = &polys_src[pidx_src];
for (j = 0; j < mp_src->totloop; j++) {
const int vert_src = corner_verts_src[mp_src->loopstart + j];
const blender::IndexRange poly_src = polys_src[pidx_src];
for (const int 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 = mp_src->loopstart + j;
lidx_src = corner;
}
}
}
@ -1949,7 +1934,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
float *hit_co = isld_res->hit_point;
int best_loop_index_src;
mp_src = &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;
@ -2006,14 +1991,12 @@ 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);
mp_src = &polys_src[pidx_src];
/* Create that one on demand. */
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,
num_polys_src,
looptri_src,
num_looptri_src);
}
@ -2040,7 +2023,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(mp_src,
mesh_remap_interp_poly_data_get(poly_src,
corner_verts_src.data(),
(const float(*)[3])vcos_src,
hit_co,
@ -2062,7 +2045,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
else {
const int sources_num = mesh_remap_interp_poly_data_get(
mp_src,
poly_src,
corner_verts_src.data(),
(const float(*)[3])vcos_src,
hit_co,
@ -2141,9 +2124,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 (poly_cents_src) {
MEM_freeN(poly_cents_src);
}
@ -2201,9 +2181,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
nearest.index = -1;
for (const int i : polys_dst.index_range()) {
const MPoly *mp = &polys_dst[i];
const blender::IndexRange poly = polys_dst[i];
BKE_mesh_calc_poly_center(mp, &corner_verts[mp->loopstart], vert_positions_dst, tmp_co);
BKE_mesh_calc_poly_center(
{&corner_verts[poly.start()], poly.size()}, vert_positions_dst, tmp_co);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@ -2226,9 +2207,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
BLI_assert(poly_nors_dst);
for (const int i : polys_dst.index_range()) {
const MPoly *mp = &polys_dst[i];
const blender::IndexRange poly = polys_dst[i];
BKE_mesh_calc_poly_center(mp, &corner_verts[mp->loopstart], vert_positions_dst, tmp_co);
BKE_mesh_calc_poly_center(
{&corner_verts[poly.start()], poly.size()}, vert_positions_dst, tmp_co);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
@ -2275,7 +2257,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
/* 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 *mp = &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;
@ -2288,10 +2270,11 @@ 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 = mp->totloop - 2;
const int tris_num = poly.size() - 2;
int j;
BKE_mesh_calc_poly_center(mp, &corner_verts[mp->loopstart], vert_positions_dst, pcent_dst);
BKE_mesh_calc_poly_center(
{&corner_verts[poly.start()], poly.size()}, vert_positions_dst, pcent_dst);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
/* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */
@ -2302,8 +2285,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(mp->totloop) > tmp_poly_size)) {
tmp_poly_size = size_t(mp->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]>(
@ -2319,7 +2302,7 @@ 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 < mp->totloop; j++) {
for (j = 0; j < poly.size(); j++) {
const int vert = corner_verts[mp->loopstart + j];
copy_v3_v3(tmp_co, vert_positions_dst[vert]);
if (space_transform) {
@ -2343,17 +2326,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(mp->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 (mp->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 (mp->totloop == 4) {
if (poly.size() == 4) {
tri_vidx_2d[0][0] = 0;
tri_vidx_2d[0][1] = 1;
tri_vidx_2d[0][2] = 2;
@ -2362,7 +2345,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(mp->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++) {

View File

@ -216,7 +216,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
int *corner_verts,
int *corner_edges,
uint totloop,
MPoly *mpolys,
int *poly_offsets,
uint totpoly,
MDeformVert *dverts, /* assume totvert length */
const bool do_verbose,
@ -239,7 +239,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
(void)0
#define REMOVE_POLY_TAG(_mp) \
{ \
_mp->totloop *= -1; \
*_mp = (*_mp * -1); \
free_flag.polyloops = do_fixes; \
} \
(void)0
@ -249,7 +249,6 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
blender::MutableVArraySpan<int> material_indices_span(material_indices.varray);
MEdge *me;
MPoly *mp;
uint i, j;
int *v;
@ -376,7 +375,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
}
if (mfaces && !mpolys) {
if (mfaces && !poly_offsets) {
#define REMOVE_FACE_TAG(_mf) \
{ \
_mf->v3 = 0; \
@ -560,7 +559,9 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
SortPoly *prev_sp, *sp = sort_polys;
int prev_end;
for (i = 0, mp = mpolys; i < totpoly; i++, mp++, sp++) {
for (i = 0; i < totpoly; i++, sp++) {
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,
@ -573,22 +574,20 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
}
if (mp->loopstart < 0 || mp->totloop < 3) {
if (poly_start < 0 || poly_size < 3) {
/* Invalid loop data. */
PRINT_ERR("\tPoly %u is invalid (loopstart: %d, totloop: %d)",
sp->index,
mp->loopstart,
mp->totloop);
PRINT_ERR(
"\tPoly %u is invalid (loopstart: %d, totloop: %d)", sp->index, poly_start, poly_size);
sp->invalid = true;
}
else if (mp->loopstart + mp->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,
mp->loopstart,
mp->loopstart + mp->totloop - 1,
poly_start,
poly_start + poly_size - 1,
totloop - 1);
sp->invalid = true;
}
@ -596,14 +595,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) * mp->totloop, "Vert idx of SortPoly");
sp->numverts = mp->totloop;
sp->loopstart = mp->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 < mp->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);
@ -611,7 +610,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
/* Test all poly's loops' vert idx. */
for (j = 0; j < mp->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. */
@ -633,12 +632,12 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
/* Test all poly's loops. */
for (j = 0; j < mp->totloop; j++) {
for (j = 0; j < poly_size; j++) {
const int corner = sp->loopstart + j;
const int vert = corner_verts[corner];
const int edge = corner_edges[corner];
v1 = vert;
v2 = corner_verts[sp->loopstart + (j + 1) % mp->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);
@ -752,7 +751,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
*/
if (sp->invalid) {
if (do_fixes) {
REMOVE_POLY_TAG((&mpolys[sp->index]));
REMOVE_POLY_TAG(&poly_offsets[sp->index]);
/* 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
@ -783,7 +782,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
prev_end,
sp->index);
if (do_fixes) {
REMOVE_POLY_TAG((&mpolys[sp->index]));
REMOVE_POLY_TAG(&poly_offsets[sp->index]);
/* 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
@ -1088,8 +1087,8 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
me->corner_verts_for_write().data(),
me->corner_edges_for_write().data(),
me->totloop,
polys.data(),
polys.size(),
poly_offsets.data(),
me->totpoly,
me->deform_verts_for_write().data(),
do_verbose,
true,
@ -1140,8 +1139,8 @@ bool BKE_mesh_is_valid(Mesh *me)
me->corner_verts_for_write().data(),
me->corner_edges_for_write().data(),
me->totloop,
polys.data(),
polys.size(),
poly_offsets.data(),
me->totpoly,
me->deform_verts_for_write().data(),
do_verbose,
do_fixes,
@ -1217,31 +1216,28 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
MutableSpan<int> poly_offsets = me->poly_offsets_for_write();
MutableSpan<int> corner_edges = me->corner_edges_for_write();
MPoly *p;
int a, b;
/* New loops idx! */
int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__);
for (a = b = 0, p = polys.data(); a < me->totpoly; a++, p++) {
for (a = b = 0; a < me->totpoly; a++) {
bool invalid = false;
int i = p->loopstart;
int stop = i + p->totloop;
int i = poly_offsets[a];
int size = poly_offsets[a + 1] - i;
int stop = i + size;
if (stop > me->totloop || stop < i || p->loopstart < 0) {
if (stop > me->totloop || stop < i || size < 0) {
invalid = true;
}
else {
/* If one of the poly's loops is invalid, the whole poly is invalid! */
if (corner_edges.slice(p->loopstart, p->totloop)
.as_span()
.contains(INVALID_LOOP_EDGE_MARKER)) {
if (corner_edges.slice(i, size).as_span().contains(INVALID_LOOP_EDGE_MARKER)) {
invalid = true;
}
}
if (p->totloop >= 3 && !invalid) {
if (size >= 3 && !invalid) {
if (a != b) {
memcpy(&polys[b], p, sizeof(polys[b]));
CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
}
b++;
@ -1275,8 +1271,8 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
/* 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 : poly_offsets.index_range()) {
poly_offsets[i] = new_idx[poly_offsets[i]];
}
MEM_freeN(new_idx);

View File

@ -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.

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 OffsetIndices 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 (i = 0; i < me->totpoly; i++) {
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,15 @@ void multires_force_external_reload(Object *object)
static int get_levels_from_disps(Object *ob)
{
Mesh *me = static_cast<Mesh *>(ob->data);
const OffsetIndices polys = me->polys();
const blender::OffsetIndices polys = me->polys();
int i, j, totlvl = 0;
const MDisps *mdisp = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
for (i = 0; i < me->totpoly; i++) {
const MDisps *md = mdisp + polys[i].loopstart;
const MDisps *md = mdisp + polys[i].start();
for (j = 0; j < polys[i].totloop; j++, md++) {
for (j = 0; j < polys[i].size(); j++, md++) {
if (md->totdisp == 0) {
continue;
}
@ -657,7 +657,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 OffsetIndices polys = me->polys();
const blender::OffsetIndices polys = me->polys();
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
GridPaintMask *gpm;
@ -678,8 +678,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
int i, j;
for (i = 0; i < me->totpoly; i++) {
for (j = 0; j < polys[i].totloop; j++) {
int g = polys[i].loopstart + j;
for (j = 0; j < polys[i].size(); j++) {
int g = polys[i].start() + j;
MDisps *mdisp = &mdisps[g];
float(*disps)[3], (*ndisps)[3], (*hdisps)[3];
int totdisp = multires_grid_tot[lvl];
@ -855,7 +855,7 @@ struct MultiresThreadedData {
CCGElem **gridData, **subGridData;
CCGKey *key;
CCGKey *sub_key;
const MPoly *mpoly;
blender::OffsetIndices<int> polys;
MDisps *mdisps;
GridPaintMask *grid_paint_mask;
int *gridOffset;
@ -873,7 +873,7 @@ static void multires_disp_run_cb(void *__restrict userdata,
CCGElem **gridData = tdata->gridData;
CCGElem **subGridData = tdata->subGridData;
CCGKey *key = tdata->key;
const MPoly *mpoly = tdata->mpoly;
blender::OffsetIndices<int> polys = tdata->polys;
MDisps *mdisps = tdata->mdisps;
GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
int *gridOffset = tdata->gridOffset;
@ -881,12 +881,12 @@ static void multires_disp_run_cb(void *__restrict userdata,
int dGridSize = tdata->dGridSize;
int dSkip = tdata->dSkip;
const int numVerts = mpoly[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[mpoly[pidx].loopstart + S];
MDisps *mdisp = &mdisps[polys[pidx][S]];
CCGElem *grid = gridData[gIndex];
CCGElem *subgrid = subGridData[gIndex];
float(*dispgrid)[3] = nullptr;
@ -967,7 +967,7 @@ static void multiresModifier_disp_run(
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGElem **gridData, **subGridData;
CCGKey key;
const OffsetIndices mpoly = me->polys();
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 +977,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)) {
mpoly = 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;
@ -1032,7 +1032,7 @@ static void multiresModifier_disp_run(
data.gridData = gridData;
data.subGridData = subGridData;
data.key = &key;
data.mpoly = mpoly;
data.polys = polys;
data.mdisps = mdisps;
data.grid_paint_mask = grid_paint_mask;
data.gridOffset = gridOffset;
@ -1554,13 +1554,13 @@ void multiresModifier_ensure_external_read(struct Mesh *mesh, const MultiresModi
/***************** Multires interpolation stuff *****************/
int mdisp_rot_face_to_crn(
MPoly *mpoly, const int face_side, const float u, const float v, float *x, float *y)
int mdisp_rot_face_to_crn(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 (mpoly->totloop == 4) {
if (face_size == 4) {
if (u <= offset && v <= offset) {
S = 0;
}
@ -1591,7 +1591,7 @@ int mdisp_rot_face_to_crn(
*y = v - offset;
}
}
else if (mpoly->totloop == 3) {
else if (face_size == 3) {
int grid_size = offset;
float w = (face_side - 1) - u - v;
float W1, W2;

View File

@ -8,6 +8,7 @@
#pragma once
#include "BLI_sys_types.h"
#include "BLI_offset_indices.hh"
#include "BKE_multires.h"
@ -16,7 +17,6 @@ struct GridPaintMask;
struct MDisps;
struct MEdge;
struct Mesh;
struct MPoly;
struct MultiresModifierData;
struct Object;
struct Subdiv;
@ -34,7 +34,7 @@ struct MultiresReshapeContext {
Mesh *base_mesh;
const float (*base_positions)[3];
const MEdge *base_edges;
const MPoly *base_polys;
blender::OffsetIndices<int> base_polys;
const int *base_corner_verts;
const int *base_corner_edges;

View File

@ -76,7 +76,6 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
reshape_context->base_polys,
reshape_context->base_corner_verts,
base_mesh->totvert,
base_mesh->totpoly,
base_mesh->totloop);
float(*origco)[3] = static_cast<float(*)[3]>(
@ -96,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 *p = &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 < p->totloop; k++) {
const int vndx = reshape_context->base_corner_verts[p->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++;
@ -111,19 +110,17 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find normal. */
for (int j = 0; j < pmap[i].count; j++) {
const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]];
MPoly fake_poly;
const blender::IndexRange poly = reshape_context->base_polys[pmap[i].indices[j]];
float no[3];
/* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */
fake_poly.totloop = p->totloop;
fake_poly.loopstart = 0;
int *poly_verts = static_cast<int *>(MEM_malloc_arrayN(p->totloop, sizeof(int), __func__));
blender::Array<int> poly_verts(poly.size());
int *poly_verts = static_cast<int *>(MEM_malloc_arrayN(poly.size(), sizeof(int), __func__));
float(*fake_co)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(p->totloop, sizeof(float[3]), __func__));
MEM_malloc_arrayN(poly.size(), sizeof(float[3]), __func__));
for (int k = 0; k < p->totloop; k++) {
const int vndx = reshape_context->base_corner_verts[p->loopstart + k];
for (int k = 0; k < poly.size(); k++) {
const int vndx = reshape_context->base_corner_verts[poly[k]];
poly_verts[k] = k;
@ -135,8 +132,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
}
}
BKE_mesh_calc_poly_normal(&fake_poly, poly_verts, (const float(*)[3])fake_co, no);
MEM_freeN(poly_verts);
BKE_mesh_calc_poly_normal(poly_verts, (const float(*)[3])fake_co, no);
MEM_freeN(fake_co);
add_v3_v3(avg_no, no);

View File

@ -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.size(face_index);
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 MPoly *base_mpoly = reshape_context->base_polys;
const blender::OffsetIndices base_polys = reshape_context->base_polys;
const int *base_corner_edges = reshape_context->base_corner_edges;
reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge,
@ -857,9 +856,8 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap
int num_used_edges = 0;
for (int poly_index = 0; poly_index < base_mesh->totpoly; ++poly_index) {
const MPoly *base_poly = &base_mpoly[poly_index];
for (int corner = 0; corner < base_poly->totloop; corner++) {
const int edge_i = base_corner_edges[base_poly->loopstart + corner];
for (const int corner : base_polys[poly_index]) {
const int edge_i = base_corner_edges[corner];
if (!BLI_BITMAP_TEST_BOOL(reshape_smooth_context->non_loose_base_edge_map, edge_i)) {
BLI_BITMAP_ENABLE(reshape_smooth_context->non_loose_base_edge_map, edge_i);

View File

@ -29,25 +29,25 @@
static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
{
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const OffsetIndices 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));
const int totpoly = mesh->totpoly;
for (int p = 0; p < totpoly; p++) {
const MPoly *poly = &polys[p];
const blender::IndexRange poly = polys[p];
float poly_center[3];
BKE_mesh_calc_poly_center(poly, &corner_verts[poly->loopstart], positions, poly_center);
for (int l = 0; l < poly->totloop; l++) {
const int loop_index = poly->loopstart + l;
BKE_mesh_calc_poly_center(corner_verts.slice(poly), positions, poly_center);
for (int l = 0; l < poly.size(); l++) {
const int loop_index = poly.start() + 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];

View File

@ -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 MPoly *mpoly = 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 = mpoly[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 = mpoly[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;
@ -157,7 +157,7 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh
reshape_context->base_mesh = base_mesh;
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_poly_offsets(base_mesh);
reshape_context->base_polys = base_mesh->polys();
reshape_context->base_corner_verts = base_mesh->corner_verts().data();
reshape_context->base_corner_edges = base_mesh->corner_edges().data();
@ -195,7 +195,7 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape
reshape_context->base_mesh = base_mesh;
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_poly_offsets(base_mesh);
reshape_context->base_polys = base_mesh->polys();
reshape_context->base_corner_verts = base_mesh->corner_verts().data();
reshape_context->base_corner_edges = base_mesh->corner_edges().data();
@ -230,7 +230,7 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co
reshape_context->base_mesh = base_mesh;
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_poly_offsets(base_mesh);
reshape_context->base_polys = base_mesh->polys();
reshape_context->base_corner_verts = base_mesh->corner_verts().data();
reshape_context->base_corner_edges = base_mesh->corner_edges().data();
@ -278,7 +278,7 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape
reshape_context->base_mesh = base_mesh;
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_poly_offsets(base_mesh);
reshape_context->base_polys = base_mesh->polys();
reshape_context->base_corner_verts = base_mesh->corner_verts().data();
reshape_context->base_corner_edges = base_mesh->corner_edges().data();
reshape_context->cd_vertex_crease = (const float *)CustomData_get_layer(&base_mesh->edata,
@ -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 MPoly *mpoly = 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 = mpoly[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) {

View File

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

View File

@ -642,17 +642,17 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
int grid_y)
{
Mesh *original_mesh = context->original_mesh;
const OffsetIndices 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 OffsetIndices 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,18 +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 MPoly *polys, const int *corner_verts, int poly, int loop, int v_x)
static bool multires_unsubdivide_flip_grid_x_axis(const blender::OffsetIndices<int> polys,
const int *corner_verts,
int poly_index,
int loop,
int v_x)
{
const MPoly *p = &polys[poly];
const blender::IndexRange poly = polys[poly_index];
const int v_first = corner_verts[p->loopstart];
if ((loop == (p->loopstart + (p->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 < p->loopstart + p->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;
@ -1040,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 OffsetIndices 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. */

View File

@ -1987,32 +1987,33 @@ 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 int *corner_verts,
const MPoly *mpoly,
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 *p = &mpoly[poly_index];
const blender::IndexRange poly = polys[poly_index];
*r_v1 = corner_verts[coord->grid_index];
const int corner = poly_find_loop_from_vert(p, &corner_verts[p->loopstart], *r_v1);
const int corner = poly_find_loop_from_vert({&corner_verts[poly.start()], poly.size()}, *r_v1);
if (coord->x == grid_size_1) {
const int next = ME_POLY_LOOP_NEXT(p, corner);
const int next = ME_POLY_LOOP_NEXT(poly, corner);
*r_v2 = corner_verts[next];
}
if (coord->y == grid_size_1) {
const int prev = ME_POLY_LOOP_PREV(p, corner);
const int prev = ME_POLY_LOOP_PREV(poly, corner);
*r_v2 = corner_verts[prev];
}
}
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
const int *corner_verts,
const MPoly *mpoly,
int *r_v1,
int *r_v2)
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
const int *corner_verts,
const blender::OffsetIndices<int> polys,
int *r_v1,
int *r_v2)
{
const int grid_size_1 = subdiv_ccg->grid_size - 1;
@ -2027,7 +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, mpoly, 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;
}
@ -2035,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, mpoly, r_v1, r_v2);
subdiv_ccg, coord, corner_verts, polys, r_v1, r_v2);
return SUBDIV_CCG_ADJACENT_EDGE;
}
}

View File

@ -35,7 +35,7 @@ struct MultiresDisplacementData {
/* Mesh is used to read external displacement. */
Mesh *mesh;
const MultiresModifierData *mmd;
const MPoly *mpoly;
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->mpoly[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->mpoly[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->mpoly[poly_corner->poly_index];
const int num_corners = data->polys.size(poly_corner->poly_index);
/* 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,9 @@ 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->mpoly[poly_corner->poly_index];
const int num_corners = poly->totloop;
const int poly_index = poly_corner->poly_index;
const int num_corners = data->polys.size(poly_corner->poly_index);
const bool is_quad = (num_corners == 4);
const int poly_index = poly - data->mpoly;
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 :
@ -249,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->mpoly[poly_corner->poly_index];
const int num_corners = poly->totloop;
const int num_corners = data->polys.size(poly_corner->poly_index);
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);
}
@ -305,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->mpoly[poly_corner->poly_index];
const int num_corners = poly->totloop;
const int num_corners = data->polys.size(poly_corner->poly_index);
const bool is_quad = (num_corners == 4);
if (is_quad) {
float dummy_corner_u, dummy_corner_v;
@ -368,10 +365,9 @@ static void free_displacement(SubdivDisplacement *displacement)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
const OffsetIndices mpoly = mesh->polys();
const blender::OffsetIndices polys = mesh->polys();
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[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;
}
@ -380,7 +376,7 @@ static void displacement_data_init_mapping(SubdivDisplacement *displacement, con
{
MultiresDisplacementData *data = static_cast<MultiresDisplacementData *>(
displacement->user_data);
const OffsetIndices mpoly = 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 *>(
@ -389,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 = &mpoly[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++;
@ -416,7 +412,7 @@ static void displacement_init_data(SubdivDisplacement *displacement,
data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl);
data->mesh = mesh;
data->mmd = mmd;
data->mpoly = BKE_mesh_poly_offsets(mesh);
data->polys = mesh->polys();
data->mdisps = static_cast<const MDisps *>(CustomData_get_layer(&mesh->ldata, CD_MDISPS));
data->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
data->is_initialized = false;

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;
const MEdge *coarse_edges;
const MPoly *coarse_polys;
blender::OffsetIndices<int> coarse_polys;
const int *coarse_corner_verts;
const int *coarse_corner_edges;
const SubdivToMeshSettings *settings;
@ -166,10 +168,10 @@ 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);
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const int coarse_edge = ctx->coarse_corner_edges[coarse_poly->loopstart + corner];
for (int corner = 0; corner < coarse_poly.size(); corner++) {
const int coarse_edge = ctx->coarse_corner_edges[coarse_poly[corner]];
const bool is_edge_used = BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge);
/* Edges which aren't counted yet. */
if (!is_edge_used) {
@ -192,7 +194,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);
@ -231,7 +233,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;
@ -248,7 +250,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);
}
@ -296,15 +298,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;
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;
@ -327,23 +329,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;
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;
@ -364,38 +366,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.size(coarse_poly_index) == 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)
@ -405,12 +407,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.size(poly_index) == 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);
}
}
}
@ -419,19 +420,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;
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;
@ -473,28 +474,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;
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;
@ -521,7 +522,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) {
@ -541,38 +542,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.size(coarse_poly_index) == 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)
@ -582,12 +583,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.size(poly_index) == 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);
}
}
}
@ -596,11 +596,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;
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;
@ -622,12 +621,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 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;
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;
@ -640,7 +639,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++) {
@ -660,13 +659,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.size(coarse_poly_index) == 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);
}
}
@ -674,7 +673,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);
}
}
@ -752,14 +751,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;
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);
@ -791,9 +790,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;
@ -830,20 +829,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;
const int resolution = ctx->settings->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. */
@ -873,8 +872,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 +
@ -890,7 +889,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;
@ -901,11 +900,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 +
@ -946,19 +945,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.size(coarse_poly_index) == 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,
@ -1090,11 +1089,11 @@ 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;
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;
@ -1150,14 +1149,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];
@ -1246,7 +1243,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;
}
@ -1286,11 +1283,11 @@ 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;
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);
@ -1311,7 +1308,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++) {
@ -1355,8 +1352,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;
@ -1370,7 +1367,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;
@ -1412,11 +1409,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 +
@ -1457,12 +1454,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];
@ -1509,14 +1506,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;
}
@ -1562,7 +1559,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;
@ -1571,10 +1568,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 {
@ -1623,12 +1620,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.size(poly_index) == 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);
}
}
@ -1643,7 +1639,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);
@ -1734,22 +1730,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]);
}
}
}
@ -1819,7 +1810,7 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv,
SubdivForeachTaskContext ctx = {0};
ctx.coarse_mesh = coarse_mesh;
ctx.coarse_edges = BKE_mesh_edges(coarse_mesh);
ctx.coarse_polys = BKE_mesh_poly_offsets(coarse_mesh);
ctx.coarse_polys = coarse_mesh->polys();
ctx.coarse_corner_verts = coarse_mesh->corner_verts().data();
ctx.coarse_corner_edges = coarse_mesh->corner_edges().data();
ctx.settings = mesh_settings;

View File

@ -419,7 +419,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 OffsetIndices 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();
@ -1472,13 +1472,11 @@ static void bm_to_mesh_faces(const BMesh &bm,
MutableSpan<bool> sharp_faces,
MutableSpan<int> material_indices)
{
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(dst_poly_offsets.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));
CustomData_from_bmesh_block(&bm.pdata, &mesh.pdata, src_face.head.data, face_i);
}
if (!select_poly.is_empty()) {
@ -1502,6 +1500,7 @@ static void bm_to_mesh_faces(const BMesh &bm,
}
}
});
dst_poly_offsets.last() = bm.totloop;
}
static void bm_to_mesh_loops(const BMesh &bm, const Span<const BMLoop *> bm_loops, Mesh &mesh)

View File

@ -926,7 +926,7 @@ typedef struct MeshDeformBind {
/* avoid DM function calls during intersections */
struct {
const MPoly *mpoly;
blender::OffsetIndices<int> polys;
const int *corner_verts;
const MLoopTri *looptri;
const float (*poly_nors)[3];
@ -1035,16 +1035,16 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb,
BVH_RAYCAST_WATERTIGHT) != -1) {
const int *corner_verts = mdb->cagemesh_cache.corner_verts;
const MLoopTri *lt = &mdb->cagemesh_cache.looptri[hit.index];
const MPoly *mp = &mdb->cagemesh_cache.mpoly[lt->poly];
const blender::IndexRange poly = mdb->cagemesh_cache.polys[lt->poly];
const float(*cagecos)[3] = mdb->cagecos;
const float len = isect_mdef.lambda;
MDefBoundIsect *isect;
blender::Array<blender::float3, 64> mp_cagecos(mp->totloop);
blender::Array<blender::float3, 64> mp_cagecos(poly.size());
/* create MDefBoundIsect, and extra for 'poly_weights[]' */
isect = static_cast<MDefBoundIsect *>(
BLI_memarena_alloc(mdb->memarena, sizeof(*isect) + (sizeof(float) * mp->totloop)));
BLI_memarena_alloc(mdb->memarena, sizeof(*isect) + (sizeof(float) * poly.size())));
/* compute intersection coordinate */
madd_v3_v3v3fl(isect->co, co1, isect_mdef.vec, len);
@ -1056,13 +1056,13 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb,
isect->len = max_ff(len_v3v3(co1, isect->co), MESHDEFORM_LEN_THRESHOLD);
/* compute mean value coordinates for interpolation */
for (int i = 0; i < mp->totloop; i++) {
copy_v3_v3(mp_cagecos[i], cagecos[corner_verts[mp->loopstart + i]]);
for (int i = 0; i < poly.size(); i++) {
copy_v3_v3(mp_cagecos[i], cagecos[corner_verts[poly[i]]]);
}
interp_weights_poly_v3(isect->poly_weights,
reinterpret_cast<float(*)[3]>(mp_cagecos.data()),
mp->totloop,
poly.size(),
isect->co);
return isect;
@ -1227,10 +1227,10 @@ static float meshdeform_boundary_phi(const MeshDeformBind *mdb,
int cagevert)
{
const int *corner_verts = mdb->cagemesh_cache.corner_verts;
const MPoly *mp = &mdb->cagemesh_cache.mpoly[isect->poly_index];
const blender::IndexRange poly = mdb->cagemesh_cache.polys[isect->poly_index];
for (int i = 0; i < mp->totloop; i++) {
if (corner_verts[mp->loopstart + i] == cagevert) {
for (int i = 0; i < poly.size(); i++) {
if (corner_verts[poly[i]] == cagevert) {
return isect->poly_weights[i];
}
}
@ -1630,7 +1630,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
/* initialize data from 'cagedm' for reuse */
{
Mesh *me = mdb->cagemesh;
mdb->cagemesh_cache.mpoly = BKE_mesh_poly_offsets(me);
mdb->cagemesh_cache.polys = me->polys();
mdb->cagemesh_cache.corner_verts = me->corner_verts().data();
mdb->cagemesh_cache.looptri = BKE_mesh_runtime_looptri_ensure(me);
mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me);

View File

@ -76,7 +76,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
MEdge **medge_pp,
int **corner_verts_pp,
int **corner_edges_pp,
MPoly **mpoly_pp,
int **poly_offsets_pp,
CustomData *vdata,
CustomData *edata,
CustomData *ldata,
@ -102,7 +102,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
MEdge *medge = *medge_pp;
int *corner_verts = *corner_verts_pp;
int *corner_edges = *corner_edges_pp;
MPoly *mpoly = *mpoly_pp;
int *poly_offsets = *poly_offsets_pp;
if (me->totvert) {
/* standard data */
@ -268,8 +268,8 @@ static void join_mesh_single(Depsgraph *depsgraph,
}
}
for (a = 0; a < me->totpoly; a++, mpoly++) {
mpoly->loopstart += *loopofs;
for (a = 0; a < me->totpoly; a++) {
*poly_offsets_pp += *loopofs;
}
/* Face maps. */
@ -299,7 +299,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
*corner_verts_pp += me->totloop;
*corner_edges_pp += me->totloop;
*polyofs += me->totpoly;
*mpoly_pp += me->totpoly;
*poly_offsets_pp += me->totpoly;
}
/* Face Sets IDs are a sparse sequence, so this function offsets all the IDs by face_set_offset and
@ -337,7 +337,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
Material **matar = nullptr, *ma;
Mesh *me;
MEdge *medge = nullptr;
MPoly *mpoly = nullptr;
Key *key, *nkey = nullptr;
float imat[4][4];
int a, b, totcol, totmat = 0, totedge = 0, totvert = 0;
@ -592,7 +591,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
&ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, totloop, ".corner_vert");
int *corner_edges = (int *)CustomData_add_layer_named(
&ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, totloop, ".corner_edge");
mpoly = (MPoly *)CustomData_add_layer(&pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly);
int *poly_offsets = (MPoly *)CustomData_add_layer(
&pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly);
vertofs = 0;
edgeofs = 0;
@ -618,7 +618,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
&medge,
&corner_verts,
&corner_edges,
&mpoly,
&poly_offsets,
&vdata,
&edata,
&ldata,
@ -653,7 +653,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
&medge,
&corner_verts,
&corner_edges,
&mpoly,
&poly_offsets,
&vdata,
&edata,
&ldata,
@ -1231,16 +1231,16 @@ static void ed_mesh_pick_face_vert__mpoly_find(
ARegion *region,
const float mval[2],
/* mesh data (evaluated) */
const MPoly *mp,
const blender::IndexRange poly,
const Span<float3> vert_positions,
const int *corner_verts,
/* return values */
float *r_len_best,
int *r_v_idx_best)
{
for (int j = mp->totloop; j--;) {
for (int j = poly.size(); j--;) {
float sco[2];
const int v_idx = corner_verts[mp->loopstart + j];
const int v_idx = corner_verts[poly[j]];
if (ED_view3d_project_float_object(region, vert_positions[v_idx], sco, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
const float len_test = len_manhattan_v2v2(mval, sco);
@ -1276,7 +1276,7 @@ bool ED_mesh_pick_face_vert(
float len_best = FLT_MAX;
const Span<float3> vert_positions = me_eval->vert_positions();
const OffsetIndices polys = me_eval->polys();
const blender::OffsetIndices polys = me_eval->polys();
const Span<int> corner_verts = me_eval->corner_verts();
const int *index_mp_to_orig = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
@ -1287,7 +1287,7 @@ bool ED_mesh_pick_face_vert(
if (index_mp_to_orig[i] == poly_index) {
ed_mesh_pick_face_vert__mpoly_find(region,
mval_f,
&polys[i],
polys[i],
vert_positions,
corner_verts.data(),
&len_best,
@ -1296,10 +1296,10 @@ bool ED_mesh_pick_face_vert(
}
}
else {
if (poly_index < polys.size()) {
if (poly_index < polys.ranges_num()) {
ed_mesh_pick_face_vert__mpoly_find(region,
mval_f,
&polys[poly_index],
polys[poly_index],
vert_positions,
corner_verts.data(),
&len_best,

View File

@ -978,7 +978,7 @@ static bool bake_targets_init_vertex_colors(Main *bmain,
return true;
}
static int find_original_loop(const MPoly *orig_polys,
static int find_original_loop(const blender::OffsetIndices<int> orig_polys,
const int *orig_corner_verts,
const int *vert_origindex,
const int *poly_origindex,
@ -988,18 +988,18 @@ static int find_original_loop(const MPoly *orig_polys,
/* Get original vertex and polygon index. There is currently no loop mapping
* in modifier stack evaluation. */
const int vert_orig = vert_origindex[vert_eval];
const int poly_orig = poly_origindex[poly_eval];
const int poly_orig_index = poly_origindex[poly_eval];
if (vert_orig == ORIGINDEX_NONE || poly_orig == ORIGINDEX_NONE) {
if (vert_orig == ORIGINDEX_NONE || poly_orig_index == ORIGINDEX_NONE) {
return ORIGINDEX_NONE;
}
/* Find matching loop with original vertex in original polygon. */
const MPoly *mpoly_orig = orig_polys + poly_orig;
const int *poly_verts_orig = orig_corner_verts + mpoly_orig->loopstart;
for (int j = 0; j < mpoly_orig->totloop; ++j) {
const blender::IndexRange orig_poly = orig_polys[poly_orig_index];
const int *poly_verts_orig = orig_corner_verts + orig_poly.start();
for (int j = 0; j < orig_poly.size(); ++j) {
if (poly_verts_orig[j] == vert_orig) {
return mpoly_orig->loopstart + j;
return orig_poly.start() + j;
}
}
@ -1046,7 +1046,7 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets,
CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX));
const int *poly_origindex = static_cast<const int *>(
CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX));
const OffsetIndices orig_polys = me->polys();
const blender::OffsetIndices orig_polys = me->polys();
const blender::Span<int> orig_corner_verts = me->corner_verts();
for (int i = 0; i < tottri; i++) {

View File

@ -317,7 +317,7 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
const OffsetIndices polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const blender::Span<int> corner_verts = me->corner_verts();
const MDeformVert *dverts = BKE_mesh_deform_verts(me);
@ -344,11 +344,11 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
}
else {
if (ED_mesh_pick_face(C, vc.obact, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
const MPoly *mp = &polys[index];
uint fidx = mp->totloop - 1;
const blender::IndexRange poly = polys[index];
int fidx = poly.size() - 1;
do {
const MDeformVert *dvert = &dverts[corner_verts[mp->loopstart + fidx]];
const MDeformVert *dvert = &dverts[corner_verts[poly[fidx]]];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
} while (fidx--);
}
@ -438,7 +438,6 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot)
static bool weight_paint_set(Object *ob, float paintweight)
{
Mesh *me = static_cast<Mesh *>(ob->data);
const MPoly *mp;
MDeformWeight *dw, *dw_prev;
int vgroup_active, vgroup_mirror = -1;
uint index;
@ -447,7 +446,7 @@ static bool weight_paint_set(Object *ob, float paintweight)
/* mutually exclusive, could be made into a */
const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me);
const OffsetIndices polys = me->polys();
const blender::OffsetIndices polys = me->polys();
const blender::Span<int> corner_verts = me->corner_verts();
MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me);
@ -470,15 +469,16 @@ static bool weight_paint_set(Object *ob, float paintweight)
const bool *select_poly = (const bool *)CustomData_get_layer_named(
&me->pdata, CD_PROP_BOOL, ".select_poly");
for (index = 0, mp = polys; index < me->totpoly; index++, mp++) {
uint fidx = mp->totloop - 1;
for (index = 0; index < me->totpoly; index++) {
const blender::IndexRange poly = polys[index];
uint fidx = poly.size() - 1;
if ((paint_selmode == SCE_SELECT_FACE) && !(select_poly && select_poly[index])) {
continue;
}
do {
const int vidx = corner_verts[mp->loopstart + fidx];
const int vidx = corner_verts[poly[fidx]];
if (!dvert[vidx].flag) {
if ((paint_selmode == SCE_SELECT_VERTEX) && !(select_vert && select_vert[vidx])) {

View File

@ -6114,11 +6114,9 @@ void SCULPT_boundary_info_ensure(Object *object)
int *adjacent_faces_edge_count = static_cast<int *>(
MEM_calloc_arrayN(base_mesh->totedge, sizeof(int), "Adjacent face edge count"));
for (int p = 0; p < base_mesh->totpoly; p++) {
const MPoly *poly = &polys[p];
for (int l = 0; l < poly->totloop; l++) {
const int edge_i = corner_edges[poly->loopstart + l];
adjacent_faces_edge_count[edge_i]++;
for (const int i : polys.index_range()) {
for (const int edge : corner_edges.slice(polys[i])) {
adjacent_faces_edge_count[edge]++;
}
}

View File

@ -314,12 +314,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly);
const OffsetIndices orig_mpoly = mesh->polys();
const blender::OffsetIndices orig_polys = mesh->polys();
const blender::Span<int> orig_corner_verts = mesh->corner_verts();
const blender::Span<int> orig_corner_edges = mesh->corner_edges();
float(*positions)[3] = BKE_mesh_vert_positions_for_write(result);
MEdge *edges = BKE_mesh_edges_for_write(result);
MutableSpan<int> mpoly = result->poly_offsets_for_write();
blender::MutableSpan<int> poly_offsets = result->poly_offsets_for_write();
blender::MutableSpan<int> corner_verts = result->corner_verts_for_write();
blender::MutableSpan<int> corner_edges = result->corner_edges_for_write();
@ -478,20 +478,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* create polys and loops */
for (k = 0; k < totpoly; k++) {
const MPoly *inMP = orig_mpoly + k;
MPoly *mp = mpoly + p_skip * totpoly + k;
const blender::IndexRange in_poly = orig_polys[k];
CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1);
*mp = *inMP;
mp->loopstart += p_skip * totloop;
poly_offsets[p_skip * totpoly + k] += p_skip * totloop;
const int dst_poly_offset = poly_offsets[p_skip * totpoly + k];
{
int orig_corner_i = inMP->loopstart;
int dst_corner_i = mp->loopstart;
int j = mp->totloop;
int orig_corner_i = in_poly.start();
int dst_corner_i = dst_poly_offset;
int j = in_poly.size();
CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j);
CustomData_copy_data(&mesh->ldata, &result->ldata, in_poly.start(), dst_poly_offset, j);
for (; j; j--, orig_corner_i++, dst_corner_i++) {
corner_verts[dst_corner_i] = orig_corner_verts[orig_corner_i] + (p_skip * totvert);
corner_edges[dst_corner_i] = orig_corner_edges[orig_corner_i] + (p_skip * totedge);

View File

@ -413,31 +413,35 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (do_shell) {
uint i;
for (i = 0; i < mesh->totpoly; i++) {
const int loop_end = mp->totloop - 1;
/* TODO: FACE-GENERIC: This isn't quite right and probably needs more attention. */
int poly_index = polys_num;
for (i = 0; i < mesh->totpoly; i++, poly_index++) {
const int loop_start = poly_offsets[poly_index];
const int poly_size = poly_offsets[poly_index + 1] - loop_start;
const int loop_end = loop_start - 1;
int e;
int j;
/* reverses the loop direction (corner verts as well as custom-data)
* Corner edges also need to be corrected too, done in a separate loop below. */
const int corner_2 = mp->loopstart + mesh->totloop;
const int corner_2 = loop_start + mesh->totloop;
#if 0
for (j = 0; j < mp->totloop; j++) {
for (j = 0; j < poly_size; j++) {
CustomData_copy_data(&mesh->ldata,
&result->ldata,
mp->loopstart + j,
mp->loopstart + (loop_end - j) + mesh->totloop,
loop_start + j,
loop_start + (loop_end - j) + mesh->totloop,
1);
}
#else
/* slightly more involved, keep the first vertex the same for the copy,
* ensures the diagonals in the new face match the original. */
j = 0;
for (int j_prev = loop_end; j < mp->totloop; j_prev = j++) {
for (int j_prev = loop_end; j < poly_size; j_prev = j++) {
CustomData_copy_data(&mesh->ldata,
&result->ldata,
mp->loopstart + j,
mp->loopstart + (loop_end - j_prev) + mesh->totloop,
loop_start + j,
loop_start + (loop_end - j_prev) + mesh->totloop,
1);
}
#endif
@ -453,9 +457,9 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
corner_edges[corner_2 + loop_end] = e;
mp->loopstart += mesh->totloop;
poly_offsets[i] += mesh->totloop;
for (j = 0; j < mp->totloop; j++) {
for (j = 0; j < poly_size; j++) {
corner_verts[corner_2 + j] += verts_num;
corner_edges[corner_2 + j] += edges_num;
}
@ -711,23 +715,23 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
}
const MPoly *mp;
for (i = 0; i < polys_num; i++) {
const blender::IndexRange poly = orig_polys[i];
/* #BKE_mesh_calc_poly_angles logic is inlined here */
float nor_prev[3];
float nor_next[3];
int i_curr = mp->totloop - 1;
int i_curr = poly.size() - 1;
int i_next = 0;
const int *poly_verts = &corner_verts[mp->loopstart];
const int *poly_edges = &corner_edges[mp->loopstart];
const int *poly_verts = &corner_verts[poly.start()];
const int *poly_edges = &corner_edges[poly.start()];
sub_v3_v3v3(
nor_prev, vert_positions[poly_verts[i_curr - 1]], vert_positions[poly_verts[i_curr]]);
normalize_v3(nor_prev);
while (i_next < mp->totloop) {
while (i_next < poly.size()) {
float angle;
sub_v3_v3v3(
nor_next, vert_positions[poly_verts[i_curr]], vert_positions[poly_verts[i_next]]);
@ -812,10 +816,11 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
edge_user_pairs[eidx][0] = INVALID_UNUSED;
edge_user_pairs[eidx][1] = INVALID_UNUSED;
}
for (i = 0, mp = orig_polys; i < polys_num; i++, mp++) {
int prev_corner_i = mp->loopstart + mp->totloop - 1;
for (int j = 0; j < mp->totloop; j++) {
const int corner_i = mp->loopstart + j;
for (i = 0; i < polys_num; i++) {
const blender::IndexRange poly = orig_polys[i];
int prev_corner_i = poly.start() + poly.size() - 1;
for (int j = 0; j < poly.size(); j++) {
const int corner_i = poly.start() + j;
const int vert_i = orig_corner_verts[corner_i];
const int prev_vert_i = orig_corner_verts[prev_corner_i];
@ -1063,11 +1068,11 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
/* faces */
MPoly *mp = polys + (polys_num * stride);
int new_poly_index = polys_num * stride;
int *new_corner_verts = &corner_verts[loops_num * stride];
int *new_corner_edges = &corner_edges[loops_num * stride];
j = 0;
for (i = 0; i < newPolys; i++, mp++) {
for (i = 0; i < newPolys; i++, new_poly_index++) {
uint eidx = new_edge_arr[i];
uint pidx = edge_users[eidx];
int k1, k2;
@ -1086,18 +1091,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
/* copy most of the face settings */
CustomData_copy_data(
&mesh->pdata, &result->pdata, int(pidx), int((polys_num * stride) + i), 1);
mp->loopstart = int(j + (loops_num * stride));
/* notice we use 'mp->totloop' which is later overwritten,
/* notice we use 'old_poly_size' which is later overwritten,
* we could lookup the original face but there's no point since this is a copy
* and will have the same value, just take care when changing order of assignment */
const int old_poly_size = poly_offsets[new_poly_index + 1] - poly_offsets[new_poly_index];
poly_offsets[new_poly_index] = int(j + (loops_num * stride));
/* prev loop */
k1 = polys[pidx].loopstart + (((edge_order[eidx] - 1) + mp->totloop) % mp->totloop);
k1 = poly_offsets[pidx] + (((edge_order[eidx] - 1) + old_poly_size) % old_poly_size);
k2 = polys[pidx].loopstart + (edge_order[eidx]);
mp->totloop = 4;
k2 = poly_offsets[pidx] + (edge_order[eidx]);
CustomData_copy_data(&mesh->ldata, &result->ldata, k2, int((loops_num * stride) + j + 0), 1);
CustomData_copy_data(&mesh->ldata, &result->ldata, k1, int((loops_num * stride) + j + 1), 1);
@ -1138,8 +1142,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
/* use the next material index if option enabled */
if (mat_ofs_rim) {
dst_material_index[mp - polys] += mat_ofs_rim;
CLAMP(dst_material_index[mp - polys], 0, mat_nr_max);
dst_material_index[new_poly_index] += mat_ofs_rim;
CLAMP(dst_material_index[new_poly_index], 0, mat_nr_max);
}
if (crease_outer) {
/* crease += crease_outer; without wrapping */

View File

@ -74,7 +74,7 @@ static float clamp_nonzero(const float value, const float epsilon)
struct NewEdgeRef;
struct NewFaceRef {
const MPoly *face;
blender::IndexRange face;
uint index;
bool reversed;
NewEdgeRef **link_edges;
@ -184,7 +184,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const float(*orig_vert_positions)[3] = BKE_mesh_vert_positions(mesh);
const MEdge *orig_medge = BKE_mesh_edges(mesh);
const OffsetIndices orig_mpoly = mesh->polys();
const blender::OffsetIndices orig_polys = mesh->polys();
const blender::Span<int> orig_corner_verts = mesh->corner_verts();
const blender::Span<int> orig_corner_edges = mesh->corner_edges();
@ -217,11 +217,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
uint largest_ngon = 3;
/* Calculate face to #NewFaceRef map. */
{
const MPoly *mp = orig_mpoly;
for (uint i = 0; i < polys_num; i++, mp++) {
for (uint i = 0; i < polys_num; i++) {
const blender::IndexRange poly = orig_polys[i];
/* Make normals for faces without area (should really be avoided though). */
if (len_squared_v3(poly_nors[i]) < 0.5f) {
const MEdge *e = orig_medge + orig_corner_edges[mp->loopstart];
const MEdge *e = orig_medge + orig_corner_edges[poly.start()];
float edgedir[3];
sub_v3_v3v3(edgedir, orig_vert_positions[e->v2], orig_vert_positions[e->v1]);
if (fabsf(edgedir[2]) < fabsf(edgedir[1])) {
@ -236,32 +236,32 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
NewEdgeRef **link_edges = static_cast<NewEdgeRef **>(
MEM_calloc_arrayN(uint(mp->totloop), sizeof(*link_edges), __func__));
MEM_calloc_arrayN(uint(poly.size()), sizeof(*link_edges), __func__));
NewFaceRef new_face_ref_a{};
new_face_ref_a.face = mp;
new_face_ref_a.face = poly;
new_face_ref_a.index = i;
new_face_ref_a.reversed = false;
new_face_ref_a.link_edges = link_edges;
face_sides_arr[i * 2] = new_face_ref_a;
link_edges = static_cast<NewEdgeRef **>(
MEM_calloc_arrayN(uint(mp->totloop), sizeof(*link_edges), __func__));
MEM_calloc_arrayN(uint(poly.size()), sizeof(*link_edges), __func__));
NewFaceRef new_face_ref_b{};
new_face_ref_b.face = mp;
new_face_ref_b.face = poly;
new_face_ref_b.index = i;
new_face_ref_b.reversed = true;
new_face_ref_b.link_edges = link_edges;
face_sides_arr[i * 2 + 1] = new_face_ref_b;
if (mp->totloop > largest_ngon) {
largest_ngon = uint(mp->totloop);
if (poly.size() > largest_ngon) {
largest_ngon = uint(poly.size());
}
/* add to final mesh face count */
if (do_shell) {
new_polys_num += 2;
new_loops_num += uint(mp->totloop * 2);
new_loops_num += uint(poly.size() * 2);
}
}
}
@ -270,10 +270,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_calloc_arrayN(edges_num, sizeof(*edge_adj_faces_len), __func__));
/* Count for each edge how many faces it has adjacent. */
{
const MPoly *mp = orig_mpoly;
for (uint i = 0; i < polys_num; i++, mp++) {
for (uint j = 0; j < mp->totloop; j++) {
edge_adj_faces_len[orig_corner_edges[mp->loopstart + j]]++;
for (uint i = 0; i < polys_num; i++) {
for (const int64_t edge : orig_corner_edges.slice(orig_polys[i])) {
edge_adj_faces_len[edge]++;
}
}
}
@ -319,11 +318,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Create link_faces for edges. */
{
const MPoly *mp = orig_mpoly;
for (uint i = 0; i < polys_num; i++, mp++) {
for (uint j = 0; j < mp->totloop; j++) {
const int vert = orig_corner_verts[mp->loopstart + j];
const int edge = orig_corner_edges[mp->loopstart + j];
for (uint i = 0; i < polys_num; i++) {
for (const int64_t corner : orig_polys[i]) {
const int vert = orig_corner_verts[corner];
const int edge = orig_corner_edges[corner];
const bool reversed = orig_medge[edge].v2 != vert;
OldEdgeFaceRef *old_face_edge_ref = edge_adj_faces[edge];
if (old_face_edge_ref == nullptr) {
@ -393,12 +391,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
if (k != i && edge_adj_faces_len[k] > 0 &&
(ELEM(vm[orig_medge[k].v1], v1, v2) != ELEM(vm[orig_medge[k].v2], v1, v2))) {
for (uint j = 0; j < edge_adj_faces[k]->faces_len && can_merge; j++) {
const MPoly *mp = orig_mpoly + edge_adj_faces[k]->faces[j];
const blender::IndexRange poly = orig_polys[edge_adj_faces[k]->faces[j]];
uint changes = 0;
int cur = mp->totloop - 1;
for (int next = 0; next < mp->totloop && changes <= 2; next++) {
uint cur_v = vm[orig_corner_verts[mp->loopstart + cur]];
uint next_v = vm[orig_corner_verts[mp->loopstart + next]];
int cur = poly.size() - 1;
for (int next = 0; next < poly.size() && changes <= 2; next++) {
uint cur_v = vm[orig_corner_verts[poly[cur]]];
uint next_v = vm[orig_corner_verts[poly[next]]];
changes += (ELEM(cur_v, v1, v2) != ELEM(next_v, v1, v2));
cur = next;
}
@ -455,8 +453,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const uint face = edge_adj_faces[i]->faces[j];
if (!face_singularity[face]) {
bool is_singularity = true;
for (uint k = 0; k < orig_mpoly[face].totloop; k++) {
if (vm[orig_corner_verts[(uint(orig_mpoly[face].loopstart)) + k]] != v1) {
for (const int64_t corner : orig_polys[face]) {
if (vm[orig_corner_verts[corner]] != v1) {
is_singularity = false;
break;
}
@ -622,15 +620,15 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* For each face pair check if they have equal verts. */
for (uint j = 0; j < adj_len; j++) {
const uint face = adj_faces->faces[j];
const int j_loopstart = orig_mpoly[face].loopstart;
const int totloop = orig_mpoly[face].totloop;
const int j_loopstart = orig_polys[face].start();
const int totloop = orig_polys[face].size();
const uint j_first_v = vm[orig_corner_verts[j_loopstart]];
for (uint k = j + 1; k < adj_len; k++) {
if (orig_mpoly[adj_faces->faces[k]].totloop != totloop) {
if (orig_polys[adj_faces->faces[k]].size() != totloop) {
continue;
}
/* Find first face first loop vert in second face loops. */
const int k_loopstart = orig_mpoly[adj_faces->faces[k]].loopstart;
const int k_loopstart = orig_polys[adj_faces->faces[k]].start();
int l;
{
const int *corner_vert = &orig_corner_verts[k_loopstart];
@ -792,7 +790,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
copy_v3_v3(nor, poly_nors[face_i]);
}
float d = 1;
if (orig_mpoly[face_i].totloop > 3) {
if (orig_polys[face_i].size() > 3) {
d = project_v3_v3(nor, edgedir);
if (LIKELY(d != 0)) {
d = normalize_v3(nor);
@ -873,8 +871,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
new_edges[j] = edge_data;
for (uint k = 0; k < 2; k++) {
if (faces[k] != nullptr) {
for (int l = 0; l < faces[k]->face->totloop; l++) {
const int edge = orig_corner_edges[faces[k]->face->loopstart + l];
for (int l = 0; l < faces[k]->face.size(); l++) {
const int edge = orig_corner_edges[faces[k]->face.start() + l];
if (edge_adj_faces[edge] == edge_adj_faces[i]) {
if (edge != i && orig_edge_data_arr[edge] == nullptr) {
orig_edge_data_arr[edge] = new_edges;
@ -1409,12 +1407,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
face_weight = static_cast<float *>(
MEM_malloc_arrayN(polys_num, sizeof(*face_weight), __func__));
const MPoly *mp = orig_mpoly;
for (uint i = 0; i < polys_num; i++, mp++) {
for (uint i = 0; i < polys_num; i++) {
float scalar_vgroup = 1.0f;
int loopend = mp->loopstart + mp->totloop;
for (int j = mp->loopstart; j < loopend; j++) {
const int vert = orig_corner_verts[mp->loopstart + j];
for (const int vert : orig_corner_verts.slice(orig_polys[i])) {
const MDeformVert *dv = &dvert[vert];
if (defgrp_invert) {
scalar_vgroup = min_ff(1.0f - BKE_defvert_find_weight(dv, defgrp_index),
@ -1685,12 +1680,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
if (smd->nonmanifold_offset_mode ==
MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) {
int corner_next = face->face->loopstart;
int corner = corner_next + (face->face->totloop - 1);
int corner_next = face->face.start();
int corner = corner_next + (face->face.size() - 1);
int corner_prev = corner - 1;
for (int m = 0;
m < face->face->totloop && vm[orig_corner_verts[corner]] != i;
m < face->face.size() && vm[orig_corner_verts[corner]] != i;
m++, corner_next++) {
corner_prev = corner;
corner = corner_next;
@ -1991,7 +1986,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result);
MEdge *medge = BKE_mesh_edges_for_write(result);
MutableSpan<int> mpoly = result->poly_offsets_for_write();
blender::MutableSpan<int> poly_offsets = result->poly_offsets_for_write();
blender::MutableSpan<int> corner_verts = result->corner_verts_for_write();
blender::MutableSpan<int> corner_edges = result->corner_edges_for_write();
@ -2324,8 +2319,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
if (origindex_poly) {
origindex_poly[poly_index] = ORIGINDEX_NONE;
}
mpoly[poly_index].loopstart = int(loop_index);
mpoly[poly_index].totloop = int(j);
poly_offsets[poly_index] = int(loop_index);
dst_material_index[poly_index] = most_mat_nr +
(g->is_orig_closed || !do_rim ? 0 : mat_ofs_rim);
CLAMP(dst_material_index[poly_index], 0, mat_nr_max);
@ -2333,11 +2327,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
for (uint k = 0; g2->valid && k < j; g2++) {
if ((do_rim && !g2->is_orig_closed) || (do_shell && g2->split)) {
const MPoly *face = g2->edges[0]->faces[0]->face;
for (int l = 0; l < face->totloop; l++) {
const int vert = orig_corner_verts[face->loopstart + l];
const blender::IndexRange face = g2->edges[0]->faces[0]->face;
for (int l = 0; l < face.size(); l++) {
const int vert = orig_corner_verts[face[l]];
if (vm[vert] == i) {
loops[k] = face->loopstart + l;
loops[k] = face[l];
break;
}
}
@ -2396,11 +2390,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
const uint orig_face_index = (*new_edges)->faces[0]->index;
const MPoly *face = (*new_edges)->faces[0]->face;
const blender::IndexRange face = (*new_edges)->faces[0]->face;
CustomData_copy_data(
&mesh->pdata, &result->pdata, int((*new_edges)->faces[0]->index), int(poly_index), 1);
mpoly[poly_index].loopstart = int(loop_index);
mpoly[poly_index].totloop = 4 - int(v1_singularity || v2_singularity);
poly_offsets[poly_index] = int(loop_index);
dst_material_index[poly_index] =
(src_material_index ? src_material_index[orig_face_index] : 0) + mat_ofs_rim;
CLAMP(dst_material_index[poly_index], 0, mat_nr_max);
@ -2410,13 +2403,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
int loop2 = -1;
const uint old_v1 = vm[orig_medge[edge1->old_edge].v1];
const uint old_v2 = vm[orig_medge[edge1->old_edge].v2];
for (uint j = 0; j < face->totloop; j++) {
const int vert = orig_corner_verts[face->loopstart + j];
for (uint j = 0; j < face.size(); j++) {
const int vert = orig_corner_verts[face.start() + j];
if (vm[vert] == old_v1) {
loop1 = face->loopstart + int(j);
loop1 = face.start() + int(j);
}
else if (vm[vert] == old_v2) {
loop2 = face->loopstart + int(j);
loop2 = face.start() + int(j);
}
}
BLI_assert(loop1 != -1 && loop2 != -1);
@ -2538,8 +2531,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
uint *face_edges = static_cast<uint *>(
MEM_malloc_arrayN(largest_ngon * 2, sizeof(*face_edges), __func__));
for (uint i = 0; i < polys_num * 2; i++, fr++) {
const uint loopstart = uint(fr->face->loopstart);
uint totloop = uint(fr->face->totloop);
const uint loopstart = uint(fr->face.start());
uint totloop = uint(fr->face.size());
uint valid_edges = 0;
uint k = 0;
while (totloop > 0 && (!fr->link_edges[totloop - 1] ||
@ -2590,8 +2583,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
if (k > 2 && valid_edges > 2) {
CustomData_copy_data(&mesh->pdata, &result->pdata, int(i / 2), int(poly_index), 1);
mpoly[poly_index].loopstart = int(loop_index);
mpoly[poly_index].totloop = int(k);
poly_offsets[poly_index] = int(loop_index);
dst_material_index[poly_index] = (src_material_index ? src_material_index[fr->index] :
0) +
(fr->reversed != do_flip ? mat_ofs : 0);

View File

@ -65,7 +65,7 @@ struct MResolvePixelData {
blender::OffsetIndices<int> polys;
const int *material_indices;
const bool *sharp_faces;
blender::Span<int> corner_verts;
const int *corner_verts;
float (*mloopuv)[2];
float uv_offset[2];
const MLoopTri *mlooptri;
@ -675,13 +675,17 @@ static void get_ccgdm_data(DerivedMesh *lodm,
hidm->getGridKey(hidm, &key);
if (lvl == 0) {
MPoly *mpoly;
face_side = (grid_size << 1) - 1;
const blender::OffsetIndices<int> polys(
blender::Span(lodm->getPolyArray(lodm), lodm->getNumPolys(lodm) + 1));
mpoly = lodm->getPolyArray(lodm) + poly_index;
g_index = grid_offset[poly_index];
S = mdisp_rot_face_to_crn(
mpoly, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y);
S = mdisp_rot_face_to_crn(polys[poly_index].size(),
face_side,
u * (face_side - 1),
v * (face_side - 1),
&crn_x,
&crn_y);
}
else {
/* number of faces per grid side */
@ -843,7 +847,9 @@ static void apply_heights_callback(DerivedMesh *lores_dm,
{
const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index;
const int *corner_verts = lores_dm->getCornerVertArray(lores_dm);
MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly;
const blender::OffsetIndices<int> polys(
blender::Span(lores_dm->getPolyArray(lores_dm), lores_dm->getNumPolys(lores_dm) + 1));
const blender::IndexRange poly = polys[lt->poly];
float(*mloopuv)[2] = static_cast<float(*)[2]>(
lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2));
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
@ -854,11 +860,11 @@ static void apply_heights_callback(DerivedMesh *lores_dm,
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
if (mpoly->totloop == 4) {
st0 = mloopuv[mpoly->loopstart];
st1 = mloopuv[mpoly->loopstart + 1];
st2 = mloopuv[mpoly->loopstart + 2];
st3 = mloopuv[mpoly->loopstart + 3];
if (poly.size() == 4) {
st0 = mloopuv[poly[0]];
st1 = mloopuv[poly[1]];
st2 = mloopuv[poly[2]];
st3 = mloopuv[poly[3]];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
@ -885,9 +891,9 @@ static void apply_heights_callback(DerivedMesh *lores_dm,
n);
}
else {
if (mpoly->totloop == 4) {
interp_bilinear_mpoly(lores_dm, corner_verts, mpoly, uv[0], uv[1], 1, p0);
interp_bilinear_mpoly(lores_dm, corner_verts, mpoly, uv[0], uv[1], 0, n);
if (poly.size() == 4) {
interp_bilinear_mpoly(lores_dm, corner_verts, poly, uv[0], uv[1], 1, p0);
interp_bilinear_mpoly(lores_dm, corner_verts, poly, uv[0], uv[1], 0, n);
}
else {
interp_barycentric_mlooptri(lores_dm, corner_verts, lt, uv[0], uv[1], 1, p0);
@ -958,7 +964,9 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm,
const int y)
{
const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index;
MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly;
const blender::OffsetIndices<int> polys(
blender::Span(lores_dm->getPolyArray(lores_dm), lores_dm->getNumPolys(lores_dm) + 1));
const blender::IndexRange poly = polys[lt->poly];
float(*mloopuv)[2] = static_cast<float(*)[2]>(
lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2));
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
@ -968,11 +976,11 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm,
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
if (mpoly->totloop == 4) {
st0 = mloopuv[mpoly->loopstart];
st1 = mloopuv[mpoly->loopstart + 1];
st2 = mloopuv[mpoly->loopstart + 2];
st3 = mloopuv[mpoly->loopstart + 3];
if (poly.size() == 4) {
st0 = mloopuv[poly[0]];
st1 = mloopuv[poly[1]];
st2 = mloopuv[poly[2]];
st3 = mloopuv[poly[3]];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
@ -1235,7 +1243,7 @@ static void apply_ao_callback(DerivedMesh *lores_dm,
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
if (mpoly->totloop == 4) {
if (poly.size() == 4) {
st0 = mloopuv[mpoly->loopstart];
st1 = mloopuv[mpoly->loopstart + 1];
st2 = mloopuv[mpoly->loopstart + 2];