Mesh: Remove redundant custom data pointers

For copy-on-write, we want to share attribute arrays between meshes
where possible. Mutable pointers like `Mesh.mvert` make that difficult
by making ownership vague. They also make code more complex by adding
redundancy.

The simplest solution is just removing them and retrieving layers from
`CustomData` as needed. Similar changes have already been applied to
curves and point clouds (e9f82d3dc7, 410a6efb74). Removing use of
the pointers generally makes code more obvious and more reusable.

Mesh data is now accessed with a C++ API (`Mesh::edges()` or
`Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`).

The CoW changes this commit makes possible are described in T95845
and T95842, and started in D14139 and D14140. The change also simplifies
the ongoing mesh struct-of-array refactors from T95965.

**RNA/Python Access Performance**
Theoretically, accessing mesh elements with the RNA API may become
slower, since the layer needs to be found on every random access.
However, overhead is already high enough that this doesn't make a
noticible differenc, and performance is actually improved in some
cases. Random access can be up to 10% faster, but other situations
might be a bit slower. Generally using `foreach_get/set` are the best
way to improve performance. See the differential revision for more
discussion about Python performance.

Cycles has been updated to use raw pointers and the internal Blender
mesh types, mostly because there is no sense in having this overhead
when it's already compiled with Blender. In my tests this roughly
halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million
face grid).

Differential Revision: https://developer.blender.org/D15488
This commit is contained in:
2022-09-05 11:56:34 -05:00
parent 63cfc8f9f6
commit 05952aa94d
233 changed files with 4072 additions and 3356 deletions
+150 -76
View File
@@ -26,6 +26,8 @@
#include "mikktspace.h"
#include "DNA_meshdata_types.h"
CCL_NAMESPACE_BEGIN
/* Tangent Space */
@@ -279,10 +281,15 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
switch (b_domain) {
case BL::Attribute::domain_CORNER: {
if (subdivision) {
for (BL::MeshPolygon &p : b_mesh.polygons) {
int n = p.loop_total();
for (int i = 0; i < n; i++) {
*data = get_value_at_index(p.loop_start() + i);
const int polys_num = b_mesh.polygons.length();
if (polys_num == 0) {
return;
}
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
for (int j = 0; j < b_poly.totloop; j++) {
*data = get_value_at_index(b_poly.loopstart + j);
data++;
}
}
@@ -299,27 +306,32 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
break;
}
case BL::Attribute::domain_EDGE: {
const size_t edges_num = b_mesh.edges.length();
if (edges_num == 0) {
return;
}
if constexpr (std::is_same_v<TypeInCycles, uchar4>) {
/* uchar4 edge attributes do not exist, and averaging in place
* would not work. */
assert(0);
}
else {
const MEdge *edges = static_cast<const MEdge *>(b_mesh.edges[0].ptr.data);
const size_t verts_num = b_mesh.vertices.length();
vector<int> count(verts_num, 0);
/* Average edge attributes at vertices. */
const size_t num_verts = b_mesh.vertices.length();
vector<int> count(num_verts, 0);
for (int i = 0; i < edges_num; i++) {
TypeInCycles value = get_value_at_index(i);
for (BL::MeshEdge &e : b_mesh.edges) {
BL::Array<int, 2> vertices = e.vertices();
TypeInCycles value = get_value_at_index(e.index());
data[vertices[0]] += value;
data[vertices[1]] += value;
count[vertices[0]]++;
count[vertices[1]]++;
const MEdge &b_edge = edges[i];
data[b_edge.v1] += value;
data[b_edge.v2] += value;
count[b_edge.v1]++;
count[b_edge.v2]++;
}
for (size_t i = 0; i < num_verts; i++) {
for (size_t i = 0; i < verts_num; i++) {
if (count[i] > 1) {
data[i] /= (float)count[i];
}
@@ -603,6 +615,12 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
{
const int polys_num = b_mesh.polygons.length();
if (polys_num == 0) {
return;
}
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
if (!b_mesh.uv_layers.empty()) {
BL::Mesh::uv_layers_iterator l;
int i = 0;
@@ -636,10 +654,10 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
float2 *fdata = uv_attr->data_float2();
for (BL::MeshPolygon &p : b_mesh.polygons) {
int n = p.loop_total();
for (int j = 0; j < n; j++) {
*(fdata++) = get_float2(l->data[p.loop_start() + j].uv());
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
for (int j = 0; j < b_poly.totloop; j++) {
*(fdata++) = get_float2(l->data[b_poly.loopstart + j].uv());
}
}
}
@@ -702,6 +720,8 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
if (num_verts == 0) {
return;
}
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
/* STEP 1: Find out duplicated vertices and point duplicates to a single
* original vertex.
*/
@@ -754,10 +774,12 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
*/
vector<float3> vert_normal(num_verts, zero_float3());
/* First we accumulate all vertex normals in the original index. */
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
b_mesh.vertex_normals[0].ptr.data);
for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
const float *b_vert_normal = b_vert_normals[vert_index];
const int orig_index = vert_orig_index[vert_index];
vert_normal[orig_index] += normal;
vert_normal[orig_index] += make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
}
/* Then we normalize the accumulated result and flush it to all duplicates
* as well.
@@ -770,18 +792,24 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
vector<int> counter(num_verts, 0);
vector<float> raw_data(num_verts, 0.0f);
vector<float3> edge_accum(num_verts, zero_float3());
BL::Mesh::edges_iterator e;
EdgeMap visited_edges;
int edge_index = 0;
memset(&counter[0], 0, sizeof(int) * counter.size());
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
const int edges_num = b_mesh.edges.length();
for (int i = 0; i < edges_num; i++) {
const MEdge &b_edge = edges[i];
const int v0 = vert_orig_index[b_edge.v1];
const int v1 = vert_orig_index[b_edge.v2];
if (visited_edges.exists(v0, v1)) {
continue;
}
visited_edges.insert(v0, v1);
float3 co0 = get_float3(b_mesh.vertices[v0].co()), co1 = get_float3(b_mesh.vertices[v1].co());
const MVert &b_vert_0 = verts[v0];
const MVert &b_vert_1 = verts[v1];
float3 co0 = make_float3(b_vert_0.co[0], b_vert_0.co[1], b_vert_0.co[2]);
float3 co1 = make_float3(b_vert_1.co[0], b_vert_1.co[1], b_vert_1.co[2]);
float3 edge = normalize(co1 - co0);
edge_accum[v0] += edge;
edge_accum[v1] += -edge;
@@ -809,11 +837,11 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
float *data = attr->data_float();
memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
memset(&counter[0], 0, sizeof(int) * counter.size());
edge_index = 0;
visited_edges.clear();
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
for (int i = 0; i < edges_num; i++) {
const MEdge &b_edge = edges[i];
const int v0 = vert_orig_index[b_edge.v1];
const int v1 = vert_orig_index[b_edge.v2];
if (visited_edges.exists(v0, v1)) {
continue;
}
@@ -852,6 +880,7 @@ static void attr_create_random_per_island(Scene *scene,
return;
}
const int polys_num = b_mesh.polygons.length();
int number_of_vertices = b_mesh.vertices.length();
if (number_of_vertices == 0) {
return;
@@ -859,8 +888,11 @@ static void attr_create_random_per_island(Scene *scene,
DisjointSet vertices_sets(number_of_vertices);
for (BL::MeshEdge &e : b_mesh.edges) {
vertices_sets.join(e.vertices()[0], e.vertices()[1]);
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
const int edges_num = b_mesh.edges.length();
for (int i = 0; i < edges_num; i++) {
vertices_sets.join(edges[i].v1, edges[i].v2);
}
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
@@ -873,8 +905,14 @@ static void attr_create_random_per_island(Scene *scene,
}
}
else {
for (BL::MeshPolygon &p : b_mesh.polygons) {
data[p.index()] = hash_uint_to_float(vertices_sets.find(p.vertices()[0]));
if (polys_num != 0) {
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
const MLoop *loops = static_cast<const MLoop *>(b_mesh.loops[0].ptr.data);
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
const MLoop &b_loop = loops[b_poly.loopstart];
data[i] = hash_uint_to_float(vertices_sets.find(b_loop.v));
}
}
}
}
@@ -909,6 +947,7 @@ static void create_mesh(Scene *scene,
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
const int polys_num = b_mesh.polygons.length();
int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
int numtris = 0;
int numcorners = 0;
@@ -921,13 +960,17 @@ static void create_mesh(Scene *scene,
return;
}
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
if (!subdivision) {
numtris = numfaces;
}
else {
for (BL::MeshPolygon &p : b_mesh.polygons) {
numngons += (p.loop_total() == 4) ? 0 : 1;
numcorners += p.loop_total();
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
for (int i = 0; i < polys_num; i++) {
const MPoly &b_poly = polys[i];
numngons += (b_poly.totloop == 4) ? 0 : 1;
numcorners += b_poly.totloop;
}
}
@@ -939,17 +982,23 @@ static void create_mesh(Scene *scene,
mesh->reserve_mesh(numverts, numtris);
/* create vertex coordinates and normals */
BL::Mesh::vertices_iterator v;
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
mesh->add_vertex(get_float3(v->co()));
for (int i = 0; i < numverts; i++) {
const MVert &b_vert = verts[i];
mesh->add_vertex(make_float3(b_vert.co[0], b_vert.co[1], b_vert.co[2]));
}
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
float3 *N = attr_N->data_float3();
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
*N = get_float3(v->normal());
N = attr_N->data_float3();
if (subdivision || !use_loop_normals) {
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
b_mesh.vertex_normals[0].ptr.data);
for (int i = 0; i < numverts; i++) {
const float *b_vert_normal = b_vert_normals[i];
N[i] = make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
}
}
/* create generated coordinates from undeformed coordinates */
const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.empty()) &&
@@ -964,6 +1013,7 @@ static void create_mesh(Scene *scene,
float3 *generated = attr->data_float3();
size_t i = 0;
BL::Mesh::vertices_iterator v;
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
generated[i++] = get_float3(v->undeformed_co()) * size - loc;
}
@@ -978,14 +1028,15 @@ static void create_mesh(Scene *scene,
};
/* create faces */
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
if (!subdivision) {
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
const int poly_index = t.polygon_index();
BL::MeshPolygon p = b_mesh.polygons[poly_index];
const MPoly &b_poly = polys[poly_index];
int3 vi = get_int3(t.vertices());
int shader = get_material_index(poly_index);
bool smooth = p.use_smooth() || use_loop_normals;
bool smooth = (b_poly.flag & ME_SMOOTH) || use_loop_normals;
if (use_loop_normals) {
BL::Array<float, 9> loop_normals = t.split_normals();
@@ -1005,16 +1056,19 @@ static void create_mesh(Scene *scene,
else {
vector<int> vi;
for (int poly_index = 0; poly_index < numfaces; poly_index++) {
BL::MeshPolygon p = b_mesh.polygons[poly_index];
int n = p.loop_total();
int shader = get_material_index(poly_index);
bool smooth = p.use_smooth() || use_loop_normals;
const MLoop *loops = static_cast<const MLoop *>(b_mesh.loops[0].ptr.data);
for (int i = 0; i < numfaces; i++) {
const MPoly &b_poly = polys[i];
int n = b_poly.totloop;
int shader = get_material_index(i);
bool smooth = (b_poly.flag & ME_SMOOTH) || use_loop_normals;
vi.resize(n);
for (int i = 0; i < n; i++) {
/* NOTE: Autosmooth is already taken care about. */
vi[i] = b_mesh.loops[p.loop_start() + i].vertex_index();
vi[i] = loops[b_poly.loopstart + i].v;
}
/* create subd faces */
@@ -1067,27 +1121,33 @@ static void create_subd_mesh(Scene *scene,
create_mesh(scene, mesh, b_mesh, used_shaders, need_motion, motion_scale, true, subdivide_uvs);
/* export creases */
size_t num_creases = 0;
const int edges_num = b_mesh.edges.length();
for (BL::MeshEdge &e : b_mesh.edges) {
if (e.crease() != 0.0f) {
num_creases++;
if (edges_num != 0) {
size_t num_creases = 0;
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
for (int i = 0; i < edges_num; i++) {
const MEdge &b_edge = edges[i];
if (b_edge.crease != 0) {
num_creases++;
}
}
}
mesh->reserve_subd_creases(num_creases);
mesh->reserve_subd_creases(num_creases);
for (BL::MeshEdge &e : b_mesh.edges) {
if (e.crease() != 0.0f) {
mesh->add_edge_crease(e.vertices()[0], e.vertices()[1], e.crease());
for (int i = 0; i < edges_num; i++) {
const MEdge &b_edge = edges[i];
if (b_edge.crease != 0) {
mesh->add_edge_crease(b_edge.v1, b_edge.v2, float(b_edge.crease) / 255.0f);
}
}
}
for (BL::MeshVertexCreaseLayer &c : b_mesh.vertex_creases) {
for (int i = 0; i < c.data.length(); ++i) {
if (c.data[i].value() != 0.0f) {
mesh->add_vertex_crease(i, c.data[i].value());
for (BL::MeshVertexCreaseLayer &c : b_mesh.vertex_creases) {
for (int i = 0; i < c.data.length(); ++i) {
if (c.data[i].value() != 0.0f) {
mesh->add_vertex_crease(i, c.data[i].value());
}
}
}
}
@@ -1208,6 +1268,12 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
/* TODO(sergey): Perform preliminary check for number of vertices. */
if (b_mesh) {
const int b_verts_num = b_mesh.vertices.length();
if (b_verts_num == 0) {
free_object_to_mesh(b_data, b_ob_info, b_mesh);
return;
}
/* Export deformed coordinates. */
/* Find attributes. */
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@@ -1225,22 +1291,30 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
/* Load vertex data from mesh. */
float3 *mP = attr_mP->data_float3() + motion_step * numverts;
float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL;
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
/* NOTE: We don't copy more that existing amount of vertices to prevent
* possible memory corruption.
*/
BL::Mesh::vertices_iterator v;
int i = 0;
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
mP[i] = get_float3(v->co());
if (mN)
mN[i] = get_float3(v->normal());
for (int i = 0; i < std::min<size_t>(b_verts_num, numverts); i++) {
const MVert &b_vert = verts[i];
mP[i] = make_float3(b_vert.co[0], b_vert.co[1], b_vert.co[2]);
}
if (mN) {
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
b_mesh.vertex_normals[0].ptr.data);
for (int i = 0; i < std::min<size_t>(b_verts_num, numverts); i++) {
const float *b_vert_normal = b_vert_normals[i];
mN[i] = make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
}
}
if (new_attribute) {
/* In case of new attribute, we verify if there really was any motion. */
if (b_mesh.vertices.length() != numverts ||
if (b_verts_num != numverts ||
memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) {
/* no motion, remove attributes again */
if (b_mesh.vertices.length() != numverts) {
if (b_verts_num != numverts) {
VLOG_WARNING << "Topology differs, disabling motion blur for object " << ob_name;
}
else {
@@ -1264,7 +1338,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
}
}
else {
if (b_mesh.vertices.length() != numverts) {
if (b_verts_num != numverts) {
VLOG_WARNING << "Topology differs, discarding motion blur for object " << ob_name
<< " at time " << motion_step;
memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts);
+1 -1
View File
@@ -79,7 +79,7 @@ typedef struct Cloth {
int last_frame;
float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */
float average_acceleration[3]; /* Moving average of overall acceleration. */
struct MEdge *edges; /* Used for hair collisions. */
const struct MEdge *edges; /* Used for hair collisions. */
struct EdgeSet *sew_edge_graph; /* Sewing edges represented using a GHash */
} Cloth;
+4 -4
View File
@@ -240,23 +240,23 @@ void BKE_defvert_extract_vgroup_to_vertweights(const struct MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_edgeweights(const struct MDeformVert *dvert,
int defgroup,
int num_verts,
struct MEdge *edges,
const struct MEdge *edges,
int num_edges,
bool invert_vgroup,
float *r_weights);
void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert,
int defgroup,
int num_verts,
struct MLoop *loops,
const struct MLoop *loops,
int num_loops,
bool invert_vgroup,
float *r_weights);
void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert,
int defgroup,
int num_verts,
struct MLoop *loops,
const struct MLoop *loops,
int num_loops,
struct MPoly *polys,
const struct MPoly *polys,
int num_polys,
bool invert_vgroup,
float *r_weights);
+127 -15
View File
@@ -6,12 +6,15 @@
* \ingroup bke
*/
#include "BLI_compiler_attrs.h"
#include "BLI_compiler_compat.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_customdata.h"
#include "BKE_mesh_types.h"
#include "BLI_compiler_attrs.h"
#include "BLI_utildefines.h"
struct BLI_Stack;
struct BMesh;
@@ -148,7 +151,6 @@ void BKE_mesh_copy_parameters_for_eval(struct Mesh *me_dst, const struct Mesh *m
* when a new mesh is based on an existing mesh.
*/
void BKE_mesh_copy_parameters(struct Mesh *me_dst, const struct Mesh *me_src);
void BKE_mesh_update_customdata_pointers(struct Mesh *me, bool do_ensure_tess_cd);
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
struct Mesh *BKE_mesh_new_nomain(
@@ -517,9 +519,9 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
int numVerts,
struct MEdge *medges,
int numEdges,
struct MLoop *mloops,
const struct MLoop *mloops,
int numLoops,
struct MPoly *mpolys,
const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
float split_angle);
@@ -637,12 +639,12 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space,
void BKE_mesh_normals_loop_split(const struct MVert *mverts,
const float (*vert_normals)[3],
int numVerts,
struct MEdge *medges,
const struct MEdge *medges,
int numEdges,
struct MLoop *mloops,
const struct MLoop *mloops,
float (*r_loopnors)[3],
int numLoops,
struct MPoly *mpolys,
const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
bool use_split_normals,
@@ -656,10 +658,10 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts,
int numVerts,
struct MEdge *medges,
int numEdges,
struct MLoop *mloops,
const struct MLoop *mloops,
float (*r_custom_loopnors)[3],
int numLoops,
struct MPoly *mpolys,
const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
short (*r_clnors_data)[2]);
@@ -669,9 +671,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(const struct MVert *mverts,
int numVerts,
struct MEdge *medges,
int numEdges,
struct MLoop *mloops,
const struct MLoop *mloops,
int numLoops,
struct MPoly *mpolys,
const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
short (*r_clnors_data)[2]);
@@ -796,19 +798,21 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip);
* \param mloop: the full loops array.
* \param ldata: the loops custom data.
*/
void BKE_mesh_polygon_flip_ex(struct MPoly *mpoly,
void BKE_mesh_polygon_flip_ex(const struct MPoly *mpoly,
struct MLoop *mloop,
struct CustomData *ldata,
float (*lnors)[3],
struct MDisps *mdisp,
bool use_loop_mdisp_flip);
void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata);
void BKE_mesh_polygon_flip(const struct MPoly *mpoly,
struct MLoop *mloop,
struct CustomData *ldata);
/**
* Flip (invert winding of) all polygons (used to inverse their normals).
*
* \note Invalidates tessellation, caller must handle that.
*/
void BKE_mesh_polygons_flip(struct MPoly *mpoly,
void BKE_mesh_polygons_flip(const struct MPoly *mpoly,
struct MLoop *mloop,
struct CustomData *ldata,
int totpoly);
@@ -1022,6 +1026,10 @@ char *BKE_mesh_debug_info(const struct Mesh *me)
void BKE_mesh_debug_print(const struct Mesh *me) ATTR_NONNULL(1);
#endif
/* -------------------------------------------------------------------- */
/** \name Inline Mesh Data Access
* \{ */
/**
* \return The material index for each polygon. May be null.
* \note In C++ code, prefer using the attribute API (#MutableAttributeAccessor)/
@@ -1046,6 +1054,110 @@ BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh)
&mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, NULL, mesh->totpoly, "material_index");
}
BLI_INLINE const MVert *BKE_mesh_vertices(const Mesh *mesh)
{
return (const MVert *)CustomData_get_layer(&mesh->vdata, CD_MVERT);
}
BLI_INLINE MVert *BKE_mesh_vertices_for_write(Mesh *mesh)
{
return (MVert *)CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
}
BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh)
{
return (const MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE);
}
BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh)
{
return (MEdge *)CustomData_duplicate_referenced_layer(&mesh->edata, CD_MEDGE, mesh->totedge);
}
BLI_INLINE const MPoly *BKE_mesh_polygons(const Mesh *mesh)
{
return (const MPoly *)CustomData_get_layer(&mesh->pdata, CD_MPOLY);
}
BLI_INLINE MPoly *BKE_mesh_polygons_for_write(Mesh *mesh)
{
return (MPoly *)CustomData_duplicate_referenced_layer(&mesh->pdata, CD_MPOLY, mesh->totpoly);
}
BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh)
{
return (const MLoop *)CustomData_get_layer(&mesh->ldata, CD_MLOOP);
}
BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh)
{
return (MLoop *)CustomData_duplicate_referenced_layer(&mesh->ldata, CD_MLOOP, mesh->totloop);
}
BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh)
{
return (const MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
}
BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh)
{
MDeformVert *dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
if (dvert) {
return dvert;
}
return (MDeformVert *)CustomData_add_layer(
&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, mesh->totvert);
}
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
# include "BLI_span.hh"
inline blender::Span<MVert> Mesh::vertices() const
{
return {BKE_mesh_vertices(this), this->totvert};
}
inline blender::MutableSpan<MVert> Mesh::vertices_for_write()
{
return {BKE_mesh_vertices_for_write(this), this->totvert};
}
inline blender::Span<MEdge> Mesh::edges() const
{
return {BKE_mesh_edges(this), this->totedge};
}
inline blender::MutableSpan<MEdge> Mesh::edges_for_write()
{
return {BKE_mesh_edges_for_write(this), this->totedge};
}
inline blender::Span<MPoly> Mesh::polygons() const
{
return {BKE_mesh_polygons(this), this->totpoly};
}
inline blender::MutableSpan<MPoly> Mesh::polygons_for_write()
{
return {BKE_mesh_polygons_for_write(this), this->totpoly};
}
inline blender::Span<MLoop> Mesh::loops() const
{
return {BKE_mesh_loops(this), this->totloop};
}
inline blender::MutableSpan<MLoop> Mesh::loops_for_write()
{
return {BKE_mesh_loops_for_write(this), this->totloop};
}
inline blender::Span<MDeformVert> Mesh::deform_verts() const
{
return {BKE_mesh_deform_verts(this), this->totvert};
}
inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
{
return {BKE_mesh_deform_verts_for_write(this), this->totvert};
}
#endif
/** \} */
+8 -8
View File
@@ -248,13 +248,13 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
int num_innercut_items,
int *innercut_item_indices);
typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts,
typedef bool (*MeshRemapIslandsCalc)(const struct MVert *verts,
int totvert,
struct MEdge *edges,
const struct MEdge *edges,
int totedge,
struct MPoly *polys,
const struct MPoly *polys,
int totpoly,
struct MLoop *loops,
const struct MLoop *loops,
int totloop,
struct MeshIslandStore *r_island_store);
@@ -265,13 +265,13 @@ typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts,
* Calculate 'generic' UV islands, i.e. based only on actual geometry data (edge seams),
* not some UV layers coordinates.
*/
bool BKE_mesh_calc_islands_loop_poly_edgeseam(struct MVert *verts,
bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts,
int totvert,
struct MEdge *edges,
const struct MEdge *edges,
int totedge,
struct MPoly *polys,
const struct MPoly *polys,
int totpoly,
struct MLoop *loops,
const struct MLoop *loops,
int totloop,
MeshIslandStore *r_island_store);
+8 -8
View File
@@ -199,13 +199,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode,
float max_dist,
float ray_radius,
struct Mesh *mesh_dst,
struct MVert *verts_dst,
const struct MVert *verts_dst,
int numverts_dst,
struct MEdge *edges_dst,
const struct MEdge *edges_dst,
int numedges_dst,
struct MLoop *loops_dst,
const struct MLoop *loops_dst,
int numloops_dst,
struct MPoly *polys_dst,
const struct MPoly *polys_dst,
int numpolys_dst,
struct CustomData *ldata_dst,
bool use_split_nors_dst,
@@ -220,10 +220,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode,
const struct SpaceTransform *space_transform,
float max_dist,
float ray_radius,
struct Mesh *mesh_dst,
struct MVert *verts_dst,
struct MLoop *loops_dst,
struct MPoly *polys_dst,
const struct Mesh *mesh_dst,
const struct MVert *verts_dst,
const struct MLoop *loops_dst,
const struct MPoly *polys_dst,
int numpolys_dst,
struct Mesh *me_src,
struct MeshPairRemap *r_map);
+2 -1
View File
@@ -127,7 +127,8 @@ int sample_surface_points_projected(
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions);
float3 compute_bary_coord_in_triangle(const Mesh &mesh,
float3 compute_bary_coord_in_triangle(Span<MVert> verts,
Span<MLoop> loops,
const MLoopTri &looptri,
const float3 &position);
+2 -2
View File
@@ -500,8 +500,8 @@ typedef struct SculptSession {
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
struct MPoly *mpoly;
struct MLoop *mloop;
const struct MPoly *mpoly;
const struct MLoop *mloop;
/* These contain the vertex and poly counts of the final mesh. */
int totvert, totpoly;
+1 -1
View File
@@ -579,7 +579,7 @@ void psys_get_texture(struct ParticleSimulationData *sim,
* Interpolate a location on a face based on face coordinates.
*/
void psys_interpolate_face(struct Mesh *mesh,
struct MVert *mvert,
const struct MVert *mvert,
const float (*vert_normals)[3],
struct MFace *mface,
struct MTFace *tface,
+4 -2
View File
@@ -29,7 +29,8 @@ extern "C" {
struct BVHTree;
struct MDeformVert;
struct Mesh;
struct ModifierEvalContext;
struct ModifierEvalContext;
struct MPoly;
struct Object;
struct ShrinkwrapGpencilModifierData;
struct ShrinkwrapModifierData;
@@ -72,6 +73,7 @@ typedef struct ShrinkwrapTreeData {
BVHTree *bvh;
BVHTreeFromMesh treeData;
const struct MPoly *polys;
const float (*pnors)[3];
const float (*clnors)[3];
ShrinkwrapBoundaryData *boundary;
@@ -104,7 +106,7 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd,
struct Scene *scene,
struct Object *ob,
struct Mesh *mesh,
struct MDeformVert *dvert,
const struct MDeformVert *dvert,
int defgrp_index,
float (*vertexCos)[3],
int numVerts);
+13 -10
View File
@@ -68,6 +68,8 @@
using blender::float3;
using blender::IndexRange;
using blender::Span;
using blender::VArray;
/* very slow! enable for testing only! */
//#define USE_MODIFIER_VALIDATE
@@ -585,7 +587,6 @@ static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orc
if (!(layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer))) {
CustomData_add_layer(&mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert);
BKE_mesh_update_customdata_pointers(mesh, false);
layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer);
}
@@ -2002,9 +2003,9 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to
MEM_freeN(userData.vertex_visit);
}
else {
MVert *mv = me_eval->mvert;
for (int i = 0; i < totcos; i++, mv++) {
copy_v3_v3(r_cos[i], mv->co);
const Span<MVert> verts = me_eval->vertices();
for (int i = 0; i < totcos; i++) {
copy_v3_v3(r_cos[i], verts[i].co);
}
}
}
@@ -2017,9 +2018,11 @@ static void mesh_init_origspace(Mesh *mesh)
CD_ORIGSPACE_MLOOP);
const int numpoly = mesh->totpoly;
// const int numloop = mesh->totloop;
MVert *mv = mesh->mvert;
MLoop *ml = mesh->mloop;
MPoly *mp = mesh->mpoly;
const Span<MVert> verts = mesh->vertices();
const Span<MPoly> polys = mesh->polygons();
const Span<MLoop> loops = mesh->loops();
const MPoly *mp = polys.data();
int i, j, k;
blender::Vector<blender::float2, 64> vcos_2d;
@@ -2033,19 +2036,19 @@ static void mesh_init_origspace(Mesh *mesh)
}
}
else {
MLoop *l = &ml[mp->loopstart];
const MLoop *l = &loops[mp->loopstart];
float p_nor[3], co[3];
float mat[3][3];
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
BKE_mesh_calc_poly_normal(mp, l, mv, p_nor);
BKE_mesh_calc_poly_normal(mp, l, verts.data(), p_nor);
axis_dominant_v3_to_m3(mat, p_nor);
vcos_2d.resize(mp->totloop);
for (j = 0; j < mp->totloop; j++, l++) {
mul_v3_m3v3(co, mat, mv[l->v].co);
mul_v3_m3v3(co, mat, verts[l->v].co);
copy_v2_v2(vcos_2d[j], co);
for (k = 0; k < 2; k++) {
@@ -35,6 +35,7 @@
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
#include "DEG_depsgraph_build.h"
@@ -406,8 +407,8 @@ static void armature_vert_task(void *__restrict userdata,
if (data->use_dverts || data->armature_def_nr != -1) {
if (data->me_target) {
BLI_assert(i < data->me_target->totvert);
if (data->me_target->dvert != NULL) {
dvert = data->me_target->dvert + i;
if (data->dverts != NULL) {
dvert = data->dverts + i;
}
else {
dvert = NULL;
@@ -488,7 +489,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
target_data_id = me_target == NULL ? (const ID *)ob_target->data : &me_target->id;
if (em_target == NULL) {
const Mesh *me = (const Mesh *)target_data_id;
dverts = me->dvert;
dverts = BKE_mesh_deform_verts(me);
if (dverts) {
dverts_len = me->totvert;
}
@@ -523,7 +524,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
use_dverts = (cd_dvert_offset != -1);
}
else if (me_target) {
use_dverts = (me_target->dvert != NULL);
use_dverts = (BKE_mesh_deform_verts(me_target) != NULL);
}
else if (dverts) {
use_dverts = true;
+24 -12
View File
@@ -15,6 +15,7 @@
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_span.hh"
#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -27,6 +28,7 @@
#include "MEM_guardedalloc.h"
using blender::Span;
using blender::VArray;
/* -------------------------------------------------------------------- */
@@ -1229,14 +1231,17 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
looptri_len = BKE_mesh_runtime_looptri_len(mesh);
}
const Span<MVert> verts = mesh->vertices();
const Span<MEdge> edges = mesh->edges();
const Span<MLoop> loops = mesh->loops();
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(nullptr,
bvh_cache_type,
mesh->mvert,
mesh->medge,
mesh->mface,
mesh->mloop,
verts.data(),
edges.data(),
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
loops.data(),
looptri,
BKE_mesh_vertex_normals_ensure(mesh),
data);
@@ -1260,31 +1265,38 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
switch (bvh_cache_type) {
case BVHTREE_FROM_LOOSEVERTS:
mask = loose_verts_map_get(
mesh->medge, mesh->totedge, mesh->mvert, mesh->totvert, &mask_bits_act_len);
edges.data(), mesh->totedge, verts.data(), mesh->totvert, &mask_bits_act_len);
ATTR_FALLTHROUGH;
case BVHTREE_FROM_VERTS:
data->tree = bvhtree_from_mesh_verts_create_tree(
0.0f, tree_type, 6, mesh->mvert, mesh->totvert, mask, mask_bits_act_len);
0.0f, tree_type, 6, verts.data(), mesh->totvert, mask, mask_bits_act_len);
break;
case BVHTREE_FROM_LOOSEEDGES:
mask = loose_edges_map_get(mesh->medge, mesh->totedge, &mask_bits_act_len);
mask = loose_edges_map_get(edges.data(), mesh->totedge, &mask_bits_act_len);
ATTR_FALLTHROUGH;
case BVHTREE_FROM_EDGES:
data->tree = bvhtree_from_mesh_edges_create_tree(
mesh->mvert, mesh->medge, mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6);
verts.data(), edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6);
break;
case BVHTREE_FROM_FACES:
BLI_assert(!(mesh->totface == 0 && mesh->totpoly != 0));
data->tree = bvhtree_from_mesh_faces_create_tree(
0.0f, tree_type, 6, mesh->mvert, mesh->mface, mesh->totface, nullptr, -1);
0.0f,
tree_type,
6,
verts.data(),
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
mesh->totface,
nullptr,
-1);
break;
case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: {
blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh);
mask = looptri_no_hidden_map_get(
mesh->mpoly,
mesh->polygons().data(),
attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
looptri_len,
&mask_bits_act_len);
@@ -1294,8 +1306,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f,
tree_type,
6,
mesh->mvert,
mesh->mloop,
verts.data(),
loops.data(),
looptri,
looptri_len,
mask,
+11 -12
View File
@@ -97,7 +97,7 @@ static BVHTree *bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
}
}
else {
MEdge *edges = cloth->edges;
const MEdge *edges = cloth->edges;
for (int i = 0; i < cloth->primitive_num; i++) {
float co[2][3];
@@ -177,7 +177,7 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving, bool self)
}
else {
if (verts) {
MEdge *edges = cloth->edges;
const MEdge *edges = cloth->edges;
for (i = 0; i < cloth->primitive_num; i++) {
float co[2][3];
@@ -258,7 +258,7 @@ static int do_step_cloth(
cloth = clmd->clothObject;
verts = cloth->verts;
mvert = result->mvert;
mvert = BKE_mesh_vertices_for_write(result);
vert_mass_changed = verts->mass != clmd->sim_parms->mass;
/* force any pinned verts to their constrained location. */
@@ -713,7 +713,6 @@ static bool cloth_from_object(
Object *ob, ClothModifierData *clmd, Mesh *mesh, float UNUSED(framenr), int first)
{
int i = 0;
MVert *mvert = NULL;
ClothVertex *verts = NULL;
const float(*shapekey_rest)[3] = NULL;
const float tnull[3] = {0, 0, 0};
@@ -755,7 +754,7 @@ static bool cloth_from_object(
shapekey_rest = CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO);
}
mvert = mesh->mvert;
MVert *mvert = BKE_mesh_vertices_for_write(mesh);
verts = clmd->clothObject->verts;
@@ -824,7 +823,7 @@ static bool cloth_from_object(
static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
{
const MLoop *mloop = mesh->mloop;
const MLoop *mloop = BKE_mesh_loops(mesh);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
const unsigned int mvert_num = mesh->totvert;
const unsigned int looptri_num = mesh->runtime.looptris.len;
@@ -859,7 +858,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
}
BKE_mesh_runtime_verttri_from_looptri(clmd->clothObject->tri, mloop, looptri, looptri_num);
clmd->clothObject->edges = mesh->medge;
clmd->clothObject->edges = BKE_mesh_edges(mesh);
/* Free the springs since they can't be correct if the vertices
* changed.
@@ -1150,7 +1149,7 @@ static void cloth_update_springs(ClothModifierData *clmd)
static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
{
unsigned int i = 0;
MVert *mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
ClothVertex *verts = clmd->clothObject->verts;
/* vertex count is already ensured to match */
@@ -1165,7 +1164,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
{
Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false);
ClothVertex *verts = clmd->clothObject->verts;
MVert *mvert = new_mesh->mvert;
MVert *mvert = BKE_mesh_vertices_for_write(mesh);
/* vertex count is already ensured to match */
for (unsigned i = 0; i < mesh->totvert; i++, verts++) {
@@ -1459,9 +1458,9 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
unsigned int numedges = (unsigned int)mesh->totedge;
unsigned int numpolys = (unsigned int)mesh->totpoly;
float shrink_factor;
const MEdge *medge = mesh->medge;
const MPoly *mpoly = mesh->mpoly;
const MLoop *mloop = mesh->mloop;
const MEdge *medge = BKE_mesh_edges(mesh);
const MPoly *mpoly = BKE_mesh_polygons(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
int index2 = 0; /* our second vertex index */
LinkNodePair *edgelist = NULL;
EdgeSet *edgeset = NULL;
@@ -531,6 +531,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
if (me_eval) {
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
const MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
const MVert *verts = BKE_mesh_vertices(me_eval);
int numVerts = me_eval->totvert;
/* check that dvert is a valid pointers (just in case) */
@@ -539,7 +540,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* get the average of all verts with that are in the vertex-group */
for (int i = 0; i < numVerts; i++) {
const MDeformVert *dv = &dvert[i];
const MVert *mv = &me_eval->mvert[i];
const MVert *mv = &verts[i];
const MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
if (dw && dw->weight > 0.0f) {
+14 -11
View File
@@ -182,19 +182,22 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me,
float (*mappedcos)[3],
float (*quats)[4])
{
using namespace blender;
using namespace blender::bke;
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__);
/* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
MVert *mvert = me->mvert;
MPoly *mp = me->mpoly;
MLoop *mloop = me->mloop;
const Span<MVert> verts = me->vertices();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
for (int i = 0; i < me->totpoly; i++, mp++) {
MLoop *ml_next = &mloop[mp->loopstart];
MLoop *ml_curr = &ml_next[mp->totloop - 1];
MLoop *ml_prev = &ml_next[mp->totloop - 2];
for (int i = 0; i < me->totpoly; i++) {
const MPoly *poly = &polys[i];
const MLoop *ml_next = &loops[poly->loopstart];
const MLoop *ml_curr = &ml_next[poly->totloop - 1];
const MLoop *ml_prev = &ml_next[poly->totloop - 2];
for (int j = 0; j < mp->totloop; j++) {
for (int j = 0; j < poly->totloop; j++) {
if (!BLI_BITMAP_TEST(vert_tag, ml_curr->v)) {
const float *co_prev, *co_curr, *co_next; /* orig */
const float *vd_prev, *vd_curr, *vd_next; /* deform */
@@ -210,9 +213,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me,
co_next = origcos[ml_next->v];
}
else {
co_prev = mvert[ml_prev->v].co;
co_curr = mvert[ml_curr->v].co;
co_next = mvert[ml_next->v].co;
co_prev = verts[ml_prev->v].co;
co_curr = verts[ml_curr->v].co;
co_next = verts[ml_next->v].co;
}
set_crazy_vertex_quat(
@@ -640,10 +640,10 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
offsets.vert.last(), offsets.edge.last(), 0, offsets.loop.last(), offsets.poly.last());
mesh->flag |= ME_AUTOSMOOTH;
mesh->smoothresh = DEG2RADF(180.0f);
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop);
MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
MutableSpan<MVert> verts = mesh->vertices_for_write();
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MPoly> polys = mesh->polygons_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
fill_mesh_topology(info.vert_range.start(),
@@ -256,13 +256,14 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
{
if (dtdata_type == DT_TYPE_LNOR) {
/* Compute custom normals into regular loop normals, which will be used for the transfer. */
MVert *verts_dst = me_dst->mvert;
const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
MEdge *edges_dst = me_dst->medge;
const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
MPoly *polys_dst = me_dst->mpoly;
const MPoly *polys_dst = BKE_mesh_polygons(me_dst);
const int num_polys_dst = me_dst->totpoly;
MLoop *loops_dst = me_dst->mloop;
const MLoop *loops_dst = BKE_mesh_loops(me_dst);
const int num_loops_dst = me_dst->totloop;
CustomData *ldata_dst = &me_dst->ldata;
@@ -318,13 +319,13 @@ static void data_transfer_dtdata_type_postprocess(Object *UNUSED(ob_src),
}
/* Bake edited destination loop normals into custom normals again. */
MVert *verts_dst = me_dst->mvert;
const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
MEdge *edges_dst = me_dst->medge;
MEdge *edges_dst = BKE_mesh_edges_for_write(me_dst);
const int num_edges_dst = me_dst->totedge;
MPoly *polys_dst = me_dst->mpoly;
MPoly *polys_dst = BKE_mesh_polygons_for_write(me_dst);
const int num_polys_dst = me_dst->totpoly;
MLoop *loops_dst = me_dst->mloop;
MLoop *loops_dst = BKE_mesh_loops_for_write(me_dst);
const int num_loops_dst = me_dst->totloop;
CustomData *ldata_dst = &me_dst->ldata;
@@ -946,8 +947,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
me_src->mvert,
me_dst->mvert,
BKE_mesh_vertices(me_src),
BKE_mesh_vertices_for_write(me_dst),
me_src->totvert,
me_dst->totvert,
elem_size,
@@ -979,9 +980,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
me_dst != ob_dst->data,
fromlayers,
tolayers);
/* Mesh stores its dvert in a specific pointer too. :( */
me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
return ret;
}
if (cddata_type == CD_FAKE_SHAPEKEY) {
@@ -1034,8 +1032,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
me_src->medge,
me_dst->medge,
BKE_mesh_edges(me_src),
BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
@@ -1066,8 +1064,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
me_src->medge,
me_dst->medge,
BKE_mesh_edges(me_src),
BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
@@ -1090,8 +1088,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
me_src->medge,
me_dst->medge,
BKE_mesh_edges(me_src),
BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
@@ -1184,8 +1182,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
me_src->mpoly,
me_dst->mpoly,
BKE_mesh_polygons(me_src),
BKE_mesh_polygons_for_write(me_dst),
me_src->totpoly,
me_dst->totpoly,
elem_size,
@@ -1432,7 +1430,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
BKE_mesh_remap_find_best_match_from_mesh(
me_dst->mvert, me_dst->totvert, me_src, space_transform);
BKE_mesh_vertices(me_dst), me_dst->totvert, me_src, space_transform);
}
/* Check all possible data types.
@@ -1460,7 +1458,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
if (DT_DATATYPE_IS_VERT(dtdata_type)) {
MVert *verts_dst = me_dst->mvert;
MVert *verts_dst = BKE_mesh_vertices_for_write(me_dst);
const int num_verts_dst = me_dst->totvert;
if (!geom_map_init[VDATA]) {
@@ -1542,9 +1540,9 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
MVert *verts_dst = me_dst->mvert;
const MVert *verts_dst = BKE_mesh_vertices_for_write(me_dst);
const int num_verts_dst = me_dst->totvert;
MEdge *edges_dst = me_dst->medge;
const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
if (!geom_map_init[EDATA]) {
@@ -1621,13 +1619,13 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
MVert *verts_dst = me_dst->mvert;
const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
MEdge *edges_dst = me_dst->medge;
const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
MPoly *polys_dst = me_dst->mpoly;
const MPoly *polys_dst = BKE_mesh_polygons(me_dst);
const int num_polys_dst = me_dst->totpoly;
MLoop *loops_dst = me_dst->mloop;
const MLoop *loops_dst = BKE_mesh_loops(me_dst);
const int num_loops_dst = me_dst->totloop;
CustomData *ldata_dst = &me_dst->ldata;
@@ -1716,11 +1714,11 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
MVert *verts_dst = me_dst->mvert;
const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
MPoly *polys_dst = me_dst->mpoly;
const MPoly *polys_dst = BKE_mesh_polygons(me_dst);
const int num_polys_dst = me_dst->totpoly;
MLoop *loops_dst = me_dst->mloop;
const MLoop *loops_dst = BKE_mesh_loops(me_dst);
const int num_loops_dst = me_dst->totloop;
if (!geom_map_init[PDATA]) {
+8 -8
View File
@@ -1030,7 +1030,7 @@ void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
const int defgroup,
const int num_verts,
MEdge *edges,
const MEdge *edges,
const int num_edges,
const bool invert_vgroup,
float *r_weights)
@@ -1043,7 +1043,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
while (i--) {
MEdge *me = &edges[i];
const MEdge *me = &edges[i];
r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f;
}
@@ -1058,7 +1058,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
const int defgroup,
const int num_verts,
MLoop *loops,
const MLoop *loops,
const int num_loops,
const bool invert_vgroup,
float *r_weights)
@@ -1071,7 +1071,7 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
while (i--) {
MLoop *ml = &loops[i];
const MLoop *ml = &loops[i];
r_weights[i] = tmp_weights[ml->v];
}
@@ -1086,9 +1086,9 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
const int defgroup,
const int num_verts,
MLoop *loops,
const MLoop *loops,
const int UNUSED(num_loops),
MPoly *polys,
const MPoly *polys,
const int num_polys,
const bool invert_vgroup,
float *r_weights)
@@ -1101,8 +1101,8 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
while (i--) {
MPoly *mp = &polys[i];
MLoop *ml = &loops[mp->loopstart];
const MPoly *mp = &polys[i];
const MLoop *ml = &loops[mp->loopstart];
int j = mp->totloop;
float w = 0.0f;
+29 -30
View File
@@ -1402,24 +1402,24 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
/* For vertex format, count every vertex that is connected by an edge */
int numOfEdges = mesh->totedge;
int numOfPolys = mesh->totpoly;
struct MEdge *edge = mesh->medge;
struct MPoly *mpoly = mesh->mpoly;
struct MLoop *mloop = mesh->mloop;
const MEdge *edges = BKE_mesh_edges(mesh);
const MPoly *polys = BKE_mesh_polygons(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
/* count number of edges per vertex */
for (int i = 0; i < numOfEdges; i++) {
ad->n_num[edge[i].v1]++;
ad->n_num[edge[i].v2]++;
ad->n_num[edges[i].v1]++;
ad->n_num[edges[i].v2]++;
temp_data[edge[i].v1]++;
temp_data[edge[i].v2]++;
temp_data[edges[i].v1]++;
temp_data[edges[i].v2]++;
}
/* also add number of vertices to temp_data
* to locate points on "mesh edge" */
for (int i = 0; i < numOfPolys; i++) {
for (int j = 0; j < mpoly[i].totloop; j++) {
temp_data[mloop[mpoly[i].loopstart + j].v]++;
for (int j = 0; j < polys[i].totloop; j++) {
temp_data[loops[polys[i].loopstart + j].v]++;
}
}
@@ -1444,15 +1444,15 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
/* and now add neighbor data using that info */
for (int i = 0; i < numOfEdges; i++) {
/* first vertex */
int index = edge[i].v1;
int index = edges[i].v1;
n_pos = ad->n_index[index] + temp_data[index];
ad->n_target[n_pos] = edge[i].v2;
ad->n_target[n_pos] = edges[i].v2;
temp_data[index]++;
/* second vertex */
index = edge[i].v2;
index = edges[i].v2;
n_pos = ad->n_index[index] + temp_data[index];
ad->n_target[n_pos] = edge[i].v1;
ad->n_target[n_pos] = edges[i].v1;
temp_data[index]++;
}
}
@@ -1604,7 +1604,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
Tex *tex = surface->init_texture;
const MLoop *mloop = mesh->mloop;
const MLoop *mloop = BKE_mesh_loops(mesh);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
@@ -1660,7 +1660,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* for vertex surface, just copy colors from mcol */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
const MLoop *mloop = mesh->mloop;
const MLoop *mloop = BKE_mesh_loops(mesh);
const int totloop = mesh->totloop;
const MLoopCol *col = CustomData_get_layer_named(
&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername);
@@ -1811,7 +1811,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
/* displace paint */
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
MVert *mvert = result->mvert;
MVert *mvert = BKE_mesh_vertices_for_write(result);
DynamicPaintModifierApplyData data = {
.surface = surface,
@@ -1913,9 +1913,9 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
/* vertex color paint */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
MLoop *mloop = result->mloop;
const MLoop *mloop = BKE_mesh_loops(result);
const int totloop = result->totloop;
MPoly *mpoly = result->mpoly;
const MPoly *mpoly = BKE_mesh_polygons(result);
const int totpoly = result->totpoly;
/* paint is stored on dry and wet layers, so mix final color first */
@@ -1989,8 +1989,6 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) {
dvert = CustomData_add_layer(
&result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, sData->total_points);
/* Make the dvert layer easily accessible from the mesh data. */
result->dvert = dvert;
}
if (defgrp_index != -1 && dvert) {
for (int i = 0; i < sData->total_points; i++) {
@@ -2012,7 +2010,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
/* wave simulation */
else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
MVert *mvert = result->mvert;
MVert *mvert = BKE_mesh_vertices_for_write(result);
DynamicPaintModifierApplyData data = {
.surface = surface,
@@ -2823,7 +2821,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
return setError(canvas, N_("Cannot bake non-'image sequence' formats"));
}
mloop = mesh->mloop;
mloop = BKE_mesh_loops(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
@@ -2963,7 +2961,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map,
&vert_to_looptri_map_mem,
mesh->mvert,
BKE_mesh_vertices_for_write(mesh),
mesh->totvert,
mlooptri,
tottri,
@@ -3783,7 +3781,8 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
eModifierType_DynamicPaint);
mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false);
numOfVerts_p = mesh_p->totvert;
mvert_p = mesh_p->mvert;
mvert_p = BKE_mesh_vertices_for_write(mesh_p);
copy_m4_m4(prev_obmat, ob->obmat);
/* current frame mesh */
@@ -3799,7 +3798,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
eModifierType_DynamicPaint);
mesh_c = dynamicPaint_brush_mesh_get(brush);
numOfVerts_c = mesh_c->totvert;
mvert_c = mesh_c->mvert;
mvert_c = BKE_mesh_vertices_for_write(mesh_c);
(*brushVel) = (struct Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f),
"Dynamic Paint brush velocity");
@@ -4270,10 +4269,10 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
VolumeGrid *grid = bData->grid;
mesh = BKE_mesh_copy_for_eval(brush_mesh, false);
mvert = mesh->mvert;
mvert = BKE_mesh_vertices_for_write(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
mloop = mesh->mloop;
mloop = BKE_mesh_loops(mesh);
numOfVerts = mesh->totvert;
/* Transform collider vertices to global space
@@ -4759,7 +4758,7 @@ static bool dynamicPaint_paintSinglePoint(
}
const Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush);
const MVert *mvert = brush_mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(brush_mesh);
/*
* Loop through every surface point
@@ -5862,7 +5861,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
Mesh *mesh = dynamicPaint_canvas_mesh_get(surface->canvas);
MVert *mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
int numOfVerts = mesh->totvert;
@@ -6022,7 +6021,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0;
int canvasNumOfVerts = mesh->totvert;
MVert *mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
Vec3f *canvas_verts;
if (bData) {
+2 -1
View File
@@ -700,9 +700,10 @@ bool get_effector_data(EffectorCache *eff,
else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
/* TODO: hair and points object support */
const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
const MVert *verts = BKE_mesh_vertices(me_eval);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
if (me_eval != NULL) {
copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
copy_v3_v3(efd->loc, verts[*efd->index].co);
copy_v3_v3(efd->nor, vert_normals[*efd->index]);
mul_m4_v3(eff->ob->obmat, efd->loc);
+28 -41
View File
@@ -403,7 +403,8 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
size_t i;
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
float size[3];
MVert *verts = me->mvert;
MVert *verts = BKE_mesh_vertices_for_write(me);
float scale = 0.0;
int res;
@@ -994,9 +995,7 @@ static void obstacles_from_mesh(Object *coll_ob,
{
if (fes->mesh) {
Mesh *me = NULL;
MVert *mvert = NULL;
const MLoopTri *looptri;
const MLoop *mloop;
BVHTreeFromMesh tree_data = {NULL};
int numverts, i;
@@ -1008,13 +1007,9 @@ static void obstacles_from_mesh(Object *coll_ob,
int min[3], max[3], res[3];
/* Duplicate vertices to modify. */
if (me->mvert) {
me->mvert = MEM_dupallocN(me->mvert);
CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
}
MVert *verts = MEM_dupallocN(BKE_mesh_vertices(me));
mvert = me->mvert;
mloop = me->mloop;
const MLoop *mloop = BKE_mesh_loops(me);
looptri = BKE_mesh_runtime_looptri_ensure(me);
numverts = me->totvert;
@@ -1041,11 +1036,11 @@ static void obstacles_from_mesh(Object *coll_ob,
float co[3];
/* Vertex position. */
mul_m4_v3(coll_ob->obmat, mvert[i].co);
manta_pos_to_cell(fds, mvert[i].co);
mul_m4_v3(coll_ob->obmat, verts[i].co);
manta_pos_to_cell(fds, verts[i].co);
/* Vertex velocity. */
add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift);
add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift);
if (has_velocity) {
sub_v3_v3v3(&vert_vel[i * 3], co, &fes->verts_old[i * 3]);
mul_v3_fl(&vert_vel[i * 3], 1.0f / dt);
@@ -1053,7 +1048,7 @@ static void obstacles_from_mesh(Object *coll_ob,
copy_v3_v3(&fes->verts_old[i * 3], co);
/* Calculate emission map bounds. */
bb_boundInsert(bb, mvert[i].co);
bb_boundInsert(bb, verts[i].co);
}
/* Set emission map.
@@ -1075,7 +1070,7 @@ static void obstacles_from_mesh(Object *coll_ob,
ObstaclesFromDMData data = {
.fes = fes,
.mvert = mvert,
.mvert = verts,
.mloop = mloop,
.mlooptri = looptri,
.tree = &tree_data,
@@ -1098,9 +1093,7 @@ static void obstacles_from_mesh(Object *coll_ob,
if (vert_vel) {
MEM_freeN(vert_vel);
}
if (me->mvert) {
MEM_freeN(me->mvert);
}
MEM_SAFE_FREE(verts);
BKE_id_free(NULL, me);
}
}
@@ -2080,16 +2073,12 @@ static void emit_from_mesh(
Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, true);
/* Duplicate vertices to modify. */
if (me->mvert) {
me->mvert = MEM_dupallocN(me->mvert);
CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
}
MVert *verts = MEM_dupallocN(BKE_mesh_vertices(me));
MVert *mvert = me->mvert;
const MLoop *mloop = me->mloop;
const MLoop *mloop = BKE_mesh_loops(me);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
const int numverts = me->totvert;
const MDeformVert *dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
const MDeformVert *dvert = BKE_mesh_deform_verts(me);
const MLoopUV *mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ffs->uvlayer_name);
if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
@@ -2109,12 +2098,11 @@ static void emit_from_mesh(
/* Transform mesh vertices to domain grid space for fast lookups.
* This is valid because the mesh is copied above. */
BKE_mesh_vertex_normals_ensure(me);
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
float(*vert_normals)[3] = MEM_dupallocN(BKE_mesh_vertex_normals_ensure(me));
for (i = 0; i < numverts; i++) {
/* Vertex position. */
mul_m4_v3(flow_ob->obmat, mvert[i].co);
manta_pos_to_cell(fds, mvert[i].co);
mul_m4_v3(flow_ob->obmat, verts[i].co);
manta_pos_to_cell(fds, verts[i].co);
/* Vertex normal. */
mul_mat3_m4_v3(flow_ob->obmat, vert_normals[i]);
@@ -2124,7 +2112,7 @@ static void emit_from_mesh(
/* Vertex velocity. */
if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
float co[3];
add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift);
add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift);
if (has_velocity) {
sub_v3_v3v3(&vert_vel[i * 3], co, &ffs->verts_old[i * 3]);
mul_v3_fl(&vert_vel[i * 3], 1.0 / dt);
@@ -2133,7 +2121,7 @@ static void emit_from_mesh(
}
/* Calculate emission map bounds. */
bb_boundInsert(bb, mvert[i].co);
bb_boundInsert(bb, verts[i].co);
}
mul_m4_v3(flow_ob->obmat, flow_center);
manta_pos_to_cell(fds, flow_center);
@@ -2158,7 +2146,7 @@ static void emit_from_mesh(
EmitFromDMData data = {
.fds = fds,
.ffs = ffs,
.mvert = mvert,
.mvert = verts,
.vert_normals = vert_normals,
.mloop = mloop,
.mlooptri = mlooptri,
@@ -2186,9 +2174,8 @@ static void emit_from_mesh(
if (vert_vel) {
MEM_freeN(vert_vel);
}
if (me->mvert) {
MEM_freeN(me->mvert);
}
MEM_SAFE_FREE(verts);
MEM_SAFE_FREE(vert_normals);
BKE_id_free(NULL, me);
}
}
@@ -3241,7 +3228,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
* If there are no faces in original mesh, keep materials and flags unchanged. */
MPoly *mpoly;
MPoly mp_example = {0};
mpoly = orgmesh->mpoly;
mpoly = BKE_mesh_polygons_for_write(orgmesh);
if (mpoly) {
mp_example = *mpoly;
}
@@ -3273,9 +3260,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
if (!me) {
return NULL;
}
mverts = me->mvert;
mpolys = me->mpoly;
mloops = me->mloop;
mverts = BKE_mesh_vertices_for_write(me);
mpolys = BKE_mesh_polygons_for_write(me);
mloops = BKE_mesh_loops_for_write(me);
/* Get size (dimension) but considering scaling. */
copy_v3_v3(cell_size_scaled, fds->cell_size);
@@ -3409,9 +3396,9 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
}
result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces);
mverts = result->mvert;
mpolys = result->mpoly;
mloops = result->mloop;
mverts = BKE_mesh_vertices_for_write(result);
mpolys = BKE_mesh_polygons_for_write(result);
mloops = BKE_mesh_loops_for_write(result);
if (num_verts) {
/* Volume bounds. */
@@ -134,8 +134,8 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
* instead of the GeometryComponent API to avoid calculating unnecessary values and to
* allow normalizing the result more simply. */
Span<float3> vert_normals{(float3 *)BKE_mesh_vertex_normals_ensure(&mesh), mesh.totvert};
const Span<MEdge> edges = mesh.edges();
Array<float3> edge_normals(mask.min_array_size());
Span<MEdge> edges{mesh.medge, mesh.totedge};
for (const int i : mask) {
const MEdge &edge = edges[i];
edge_normals[i] = math::normalize(
@@ -175,11 +175,13 @@ static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MLoop> loops = mesh.loops();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int loop_index : IndexRange(mesh.totloop)) {
const T value = old_values[loop_index];
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const int point_index = loop.v;
mixer.mix_in(point_index, value);
}
@@ -193,11 +195,13 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MLoop> loops = mesh.loops();
Array<bool> loose_verts(mesh.totvert, true);
r_values.fill(true);
for (const int loop_index : IndexRange(mesh.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const int point_index = loop.v;
loose_verts[point_index] = false;
@@ -235,12 +239,14 @@ static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray
*/
static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray &varray)
{
const Span<MLoop> loops = mesh.loops();
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
new_varray = VArray<T>::ForFunc(mesh.totloop,
[&mesh, varray = varray.typed<T>()](const int64_t loop_index) {
const int vertex_index = mesh.mloop[loop_index].v;
[loops, varray = varray.typed<T>()](const int64_t loop_index) {
const int vertex_index = loops[loop_index].v;
return varray[vertex_index];
});
});
@@ -249,15 +255,17 @@ static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray
static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray &varray)
{
const Span<MPoly> polys = mesh.polygons();
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
if constexpr (std::is_same_v<T, bool>) {
new_varray = VArray<T>::ForFunc(
mesh.totpoly, [&mesh, varray = varray.typed<bool>()](const int face_index) {
polys.size(), [polys, varray = varray.typed<bool>()](const int face_index) {
/* A face is selected if all of its corners were selected. */
const MPoly &poly = mesh.mpoly[face_index];
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
if (!varray[loop_index]) {
return false;
@@ -268,10 +276,10 @@ static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray
}
else {
new_varray = VArray<T>::ForFunc(
mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
polys.size(), [polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MPoly &poly = mesh.mpoly[face_index];
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const T value = varray[loop_index];
mixer.mix_in(0, value);
@@ -291,17 +299,20 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
/* For every edge, mix values from the two adjacent corners (the current and next corner). */
for (const int i : IndexRange(poly.totloop)) {
const int next_i = (i + 1) % poly.totloop;
const int loop_i = poly.loopstart + i;
const int next_loop_i = poly.loopstart + next_i;
const MLoop &loop = mesh.mloop[loop_i];
const MLoop &loop = loops[loop_i];
const int edge_index = loop.e;
mixer.mix_in(edge_index, old_values[loop_i]);
mixer.mix_in(edge_index, old_values[next_loop_i]);
@@ -318,19 +329,21 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
/* It may be possible to rely on the #ME_LOOSEEDGE flag, but that seems error-prone. */
Array<bool> loose_edges(mesh.totedge, true);
r_values.fill(true);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
for (const int i : IndexRange(poly.totloop)) {
const int next_i = (i + 1) % poly.totloop;
const int loop_i = poly.loopstart + i;
const int next_loop_i = poly.loopstart + next_i;
const MLoop &loop = mesh.mloop[loop_i];
const MLoop &loop = loops[loop_i];
const int edge_index = loop.e;
loose_edges[edge_index] = false;
@@ -371,13 +384,16 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
const T value = old_values[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const int point_index = loop.v;
mixer.mix_in(point_index, value);
}
@@ -393,13 +409,15 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const int vert_index = loop.v;
r_values[vert_index] = true;
}
@@ -428,10 +446,11 @@ void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
const Span<MPoly> polys = mesh.polygons();
threading::parallel_for(IndexRange(mesh.totpoly), 1024, [&](const IndexRange range) {
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
for (const int poly_index : range) {
const MPoly &poly = mesh.mpoly[poly_index];
const MPoly &poly = polys[poly_index];
MutableSpan<T> poly_corner_values = r_values.slice(poly.loopstart, poly.totloop);
poly_corner_values.fill(old_values[poly_index]);
}
@@ -458,13 +477,16 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
const T value = old_values[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
mixer.mix_in(loop.e, value);
}
}
@@ -478,13 +500,15 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const int edge_index = loop.e;
r_values[edge_index] = true;
}
@@ -508,17 +532,20 @@ static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &v
static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &varray)
{
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
if constexpr (std::is_same_v<T, bool>) {
new_varray = VArray<T>::ForFunc(
mesh.totpoly, [&mesh, varray = varray.typed<bool>()](const int face_index) {
mesh.totpoly, [loops, polys, varray = varray.typed<bool>()](const int face_index) {
/* A face is selected if all of its vertices were selected. */
const MPoly &poly = mesh.mpoly[face_index];
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
if (!varray[loop.v]) {
return false;
}
@@ -528,12 +555,12 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &
}
else {
new_varray = VArray<T>::ForFunc(
mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
mesh.totpoly, [loops, polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MPoly &poly = mesh.mpoly[face_index];
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const T value = varray[loop.v];
mixer.mix_in(0, value);
}
@@ -548,6 +575,8 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &
static GVArray adapt_mesh_domain_point_to_edge(const Mesh &mesh, const GVArray &varray)
{
const Span<MEdge> edges = mesh.edges();
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
@@ -555,17 +584,17 @@ static GVArray adapt_mesh_domain_point_to_edge(const Mesh &mesh, const GVArray &
if constexpr (std::is_same_v<T, bool>) {
/* An edge is selected if both of its vertices were selected. */
new_varray = VArray<bool>::ForFunc(
mesh.totedge, [&mesh, varray = varray.typed<bool>()](const int edge_index) {
const MEdge &edge = mesh.medge[edge_index];
edges.size(), [edges, varray = varray.typed<bool>()](const int edge_index) {
const MEdge &edge = edges[edge_index];
return varray[edge.v1] && varray[edge.v2];
});
}
else {
new_varray = VArray<T>::ForFunc(
mesh.totedge, [&mesh, varray = varray.typed<T>()](const int edge_index) {
edges.size(), [edges, varray = varray.typed<T>()](const int edge_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MEdge &edge = mesh.medge[edge_index];
const MEdge &edge = edges[edge_index];
mixer.mix_in(0, varray[edge.v1]);
mixer.mix_in(0, varray[edge.v2]);
mixer.finalize();
@@ -583,16 +612,19 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
/* For every corner, mix the values from the adjacent edges on the face. */
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop_prev = mesh.mloop[loop_index_prev];
const MLoop &loop = loops[loop_index];
const MLoop &loop_prev = loops[loop_index_prev];
mixer.mix_in(loop_index, old_values[loop.e]);
mixer.mix_in(loop_index, old_values[loop_prev.e]);
}
@@ -608,15 +640,17 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop_prev = mesh.mloop[loop_index_prev];
const MLoop &loop = loops[loop_index];
const MLoop &loop_prev = loops[loop_index_prev];
if (old_values[loop.e] && old_values[loop_prev.e]) {
r_values[loop_index] = true;
}
@@ -644,10 +678,12 @@ static void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MEdge> edges = mesh.edges();
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int edge_index : IndexRange(mesh.totedge)) {
const MEdge &edge = mesh.medge[edge_index];
const MEdge &edge = edges[edge_index];
const T value = old_values[edge_index];
mixer.mix_in(edge.v1, value);
mixer.mix_in(edge.v2, value);
@@ -663,10 +699,11 @@ void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
const Span<MEdge> edges = mesh.edges();
r_values.fill(false);
for (const int edge_index : IndexRange(mesh.totedge)) {
const MEdge &edge = mesh.medge[edge_index];
for (const int edge_index : edges.index_range()) {
const MEdge &edge = edges[edge_index];
if (old_values[edge_index]) {
r_values[edge.v1] = true;
r_values[edge.v2] = true;
@@ -690,6 +727,9 @@ static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray &
static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &varray)
{
const Span<MPoly> polys = mesh.polygons();
const Span<MLoop> loops = mesh.loops();
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
@@ -697,10 +737,10 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
if constexpr (std::is_same_v<T, bool>) {
/* A face is selected if all of its edges are selected. */
new_varray = VArray<bool>::ForFunc(
mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
const MPoly &poly = mesh.mpoly[face_index];
polys.size(), [loops, polys, varray = varray.typed<T>()](const int face_index) {
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
if (!varray[loop.e]) {
return false;
}
@@ -710,12 +750,12 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
}
else {
new_varray = VArray<T>::ForFunc(
mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
polys.size(), [loops, polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
const MPoly &poly = mesh.mpoly[face_index];
const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop = loops[loop_index];
const T value = varray[loop.e];
mixer.mix_in(0, value);
}
@@ -878,8 +918,15 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
const int dvert_index_;
public:
VArrayImpl_For_VertexWeights(MDeformVert *dverts, const int totvert, const int dvert_index)
: VMutableArrayImpl<float>(totvert), dverts_(dverts), dvert_index_(dvert_index)
VArrayImpl_For_VertexWeights(MutableSpan<MDeformVert> dverts, const int dvert_index)
: VMutableArrayImpl<float>(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index)
{
}
VArrayImpl_For_VertexWeights(Span<MDeformVert> dverts, const int dvert_index)
: VMutableArrayImpl<float>(dverts.size()),
dverts_(const_cast<MDeformVert *>(dverts.data())),
dvert_index_(dvert_index)
{
}
@@ -977,12 +1024,12 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
if (vertex_group_index < 0) {
return {};
}
if (mesh->dvert == nullptr) {
const Span<MDeformVert> dverts = mesh->deform_verts();
if (dverts.is_empty()) {
static const float default_value = 0.0f;
return {VArray<float>::ForSingle(default_value, mesh->totvert), ATTR_DOMAIN_POINT};
}
return {VArray<float>::For<VArrayImpl_For_VertexWeights>(
mesh->dvert, mesh->totvert, vertex_group_index),
return {VArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, vertex_group_index),
ATTR_DOMAIN_POINT};
}
@@ -1002,16 +1049,8 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
if (vertex_group_index < 0) {
return {};
}
if (mesh->dvert == nullptr) {
BKE_object_defgroup_data_create(&mesh->id);
}
else {
/* Copy the data layer if it is shared with some other mesh. */
mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
}
return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(
mesh->dvert, mesh->totvert, vertex_group_index),
MutableSpan<MDeformVert> dverts = mesh->deform_verts_for_write();
return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, vertex_group_index),
ATTR_DOMAIN_POINT};
}
@@ -1034,15 +1073,11 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
}
BLI_remlink(&mesh->vertex_group_names, group);
MEM_freeN(group);
if (mesh->dvert == nullptr) {
if (mesh->deform_verts().is_empty()) {
return true;
}
/* Copy the data layer if it is shared with some other mesh. */
mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
for (MDeformVert &dvert : MutableSpan(mesh->dvert, mesh->totvert)) {
for (MDeformVert &dvert : mesh->deform_verts_for_write()) {
MDeformWeight *weight = BKE_defvert_find_index(&dvert, index);
BKE_defvert_remove_group(&dvert, weight);
for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) {
@@ -1123,10 +1158,7 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider {
*/
static ComponentAttributeProviders create_attribute_providers_for_mesh()
{
static auto update_custom_data_pointers = [](void *owner) {
Mesh *mesh = static_cast<Mesh *>(owner);
BKE_mesh_update_customdata_pointers(mesh, false);
};
static auto update_custom_data_pointers = [](void * /*owner*/) {};
#define MAKE_MUTABLE_CUSTOM_DATA_GETTER(NAME) \
[](void *owner) -> CustomData * { \
@@ -2464,6 +2464,9 @@ static void gpencil_generate_edgeloops(Object *ob,
if (me->totedge == 0) {
return;
}
const Span<MVert> verts = me->vertices();
const Span<MEdge> edges = me->edges();
const Span<MDeformVert> dverts = me->deform_verts();
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me);
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
@@ -2476,15 +2479,15 @@ static void gpencil_generate_edgeloops(Object *ob,
GpEdge *gp_edges = (GpEdge *)MEM_callocN(sizeof(GpEdge) * me->totedge, __func__);
GpEdge *gped = nullptr;
for (int i = 0; i < me->totedge; i++) {
MEdge *ed = &me->medge[i];
const MEdge *ed = &edges[i];
gped = &gp_edges[i];
MVert *mv1 = &me->mvert[ed->v1];
const MVert *mv1 = &verts[ed->v1];
copy_v3_v3(gped->n1, vert_normals[ed->v1]);
gped->v1 = ed->v1;
copy_v3_v3(gped->v1_co, mv1->co);
MVert *mv2 = &me->mvert[ed->v2];
const MVert *mv2 = &verts[ed->v2];
copy_v3_v3(gped->n2, vert_normals[ed->v2]);
gped->v2 = ed->v2;
copy_v3_v3(gped->v2_co, mv2->co);
@@ -2540,8 +2543,7 @@ static void gpencil_generate_edgeloops(Object *ob,
gpf_stroke, MAX2(stroke_mat_index, 0), array_len + 1, thickness * thickness, false);
/* Create dvert data. */
MDeformVert *me_dvert = me->dvert;
if (use_vgroups && me_dvert) {
if (use_vgroups && !dverts.is_empty()) {
gps_stroke->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * (array_len + 1),
"gp_stroke_dverts");
}
@@ -2550,7 +2552,7 @@ static void gpencil_generate_edgeloops(Object *ob,
float fpt[3];
for (int i = 0; i < array_len + 1; i++) {
int vertex_index = i == 0 ? gp_edges[stroke[0]].v1 : gp_edges[stroke[i - 1]].v2;
MVert *mv = &me->mvert[vertex_index];
const MVert *mv = &verts[vertex_index];
/* Add segment. */
bGPDspoint *pt = &gps_stroke->points[i];
@@ -2563,9 +2565,9 @@ static void gpencil_generate_edgeloops(Object *ob,
pt->strength = 1.0f;
/* Copy vertex groups from mesh. Assuming they already exist in the same order. */
if (use_vgroups && me_dvert) {
if (use_vgroups && !dverts.is_empty()) {
MDeformVert *dv = &gps_stroke->dvert[i];
MDeformVert *src_dv = &me_dvert[vertex_index];
const MDeformVert *src_dv = &dverts[vertex_index];
dv->totweight = src_dv->totweight;
dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
"gp_stroke_dverts_dw");
@@ -2674,8 +2676,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
/* Use evaluated data to get mesh with all modifiers on top. */
Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh);
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
const MPoly *mpoly = me_eval->mpoly;
const MLoop *mloop = me_eval->mloop;
const Span<MVert> verts = me_eval->vertices();
const Span<MPoly> polys = me_eval->polygons();
const Span<MLoop> loops = me_eval->loops();
int mpoly_len = me_eval->totpoly;
char element_name[200];
@@ -2715,7 +2718,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
const VArray<int> mesh_material_indices = mesh_attributes(*me_eval).lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
for (i = 0; i < mpoly_len; i++) {
const MPoly *mp = &mpoly[i];
const MPoly *mp = &polys[i];
/* Find material. */
int mat_idx = 0;
@@ -2739,16 +2742,16 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
gps_fill->flag |= GP_STROKE_CYCLIC;
/* Create dvert data. */
MDeformVert *me_dvert = me_eval->dvert;
if (use_vgroups && me_dvert) {
const Span<MDeformVert> dverts = me_eval->deform_verts();
if (use_vgroups && !dverts.is_empty()) {
gps_fill->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * mp->totloop,
"gp_fill_dverts");
}
/* Add points to strokes. */
for (int j = 0; j < mp->totloop; j++) {
const MLoop *ml = &mloop[mp->loopstart + j];
const MVert *mv = &me_eval->mvert[ml->v];
const MLoop *ml = &loops[mp->loopstart + j];
const MVert *mv = &verts[ml->v];
bGPDspoint *pt = &gps_fill->points[j];
copy_v3_v3(&pt->x, mv->co);
@@ -2757,9 +2760,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
pt->strength = 1.0f;
/* Copy vertex groups from mesh. Assuming they already exist in the same order. */
if (use_vgroups && me_dvert) {
if (use_vgroups && !dverts.is_empty()) {
MDeformVert *dv = &gps_fill->dvert[j];
MDeformVert *src_dv = &me_dvert[ml->v];
const MDeformVert *src_dv = &dverts[ml->v];
dv->totweight = src_dv->totweight;
dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
"gp_fill_dverts_dw");
+20 -22
View File
@@ -1258,7 +1258,7 @@ static void do_key(const int start,
static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cache)
{
MDeformVert *dvert = NULL;
const MDeformVert *dvert = NULL;
BMEditMesh *em = NULL;
BMIter iter;
BMVert *eve;
@@ -1272,7 +1272,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac
/* gather dvert and totvert */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
dvert = me->dvert;
dvert = BKE_mesh_deform_verts(me);
totvert = me->totvert;
if (me->edit_mesh && me->edit_mesh->bm->totvert == totvert) {
@@ -1602,8 +1602,9 @@ float *BKE_key_evaluate_object_ex(
switch (GS(obdata->name)) {
case ID_ME: {
Mesh *mesh = (Mesh *)obdata;
MVert *verts = BKE_mesh_vertices_for_write(mesh);
const int totvert = min_ii(tot, mesh->totvert);
keyblock_data_convert_to_mesh((const float(*)[3])out, mesh->mvert, totvert);
keyblock_data_convert_to_mesh((const float(*)[3])out, verts, totvert);
break;
}
case ID_LT: {
@@ -2168,7 +2169,6 @@ void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nu
void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb)
{
MVert *mvert;
float(*fp)[3];
int a, tot;
@@ -2179,7 +2179,7 @@ void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb)
return;
}
mvert = me->mvert;
const MVert *mvert = BKE_mesh_vertices(me);
fp = kb->data;
for (a = 0; a < tot; a++, fp++, mvert++) {
copy_v3_v3(*fp, mvert->co);
@@ -2227,8 +2227,11 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
return;
}
MVert *mvert = MEM_dupallocN(mesh->mvert);
BKE_keyblock_convert_to_mesh(kb, mvert, mesh->totvert);
MVert *verts = MEM_dupallocN(BKE_mesh_vertices(mesh));
BKE_keyblock_convert_to_mesh(kb, verts, mesh->totvert);
const MEdge *edges = BKE_mesh_edges(mesh);
const MPoly *polys = BKE_mesh_polygons(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
const bool loop_normals_needed = r_loopnors != NULL;
const bool vert_normals_needed = r_vertnors != NULL || loop_normals_needed;
@@ -2249,35 +2252,30 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
}
if (poly_normals_needed) {
BKE_mesh_calc_normals_poly(mvert,
mesh->totvert,
mesh->mloop,
mesh->totloop,
mesh->mpoly,
mesh->totpoly,
poly_normals);
BKE_mesh_calc_normals_poly(
verts, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals);
}
if (vert_normals_needed) {
BKE_mesh_calc_normals_poly_and_vertex(mvert,
BKE_mesh_calc_normals_poly_and_vertex(verts,
mesh->totvert,
mesh->mloop,
loops,
mesh->totloop,
mesh->mpoly,
polys,
mesh->totpoly,
poly_normals,
vert_normals);
}
if (loop_normals_needed) {
short(*clnors)[2] = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* May be NULL. */
BKE_mesh_normals_loop_split(mvert,
BKE_mesh_normals_loop_split(verts,
vert_normals,
mesh->totvert,
mesh->medge,
edges,
mesh->totedge,
mesh->mloop,
loops,
r_loopnors,
mesh->totloop,
mesh->mpoly,
polys,
poly_normals,
mesh->totpoly,
(mesh->flag & ME_AUTOSMOOTH) != 0,
@@ -2293,7 +2291,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
if (free_poly_normals) {
MEM_freeN(poly_normals);
}
MEM_freeN(mvert);
MEM_freeN(verts);
}
/************************* raw coords ************************/
@@ -30,6 +30,7 @@
#include "BKE_editmesh.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -363,7 +364,7 @@ static void lattice_deform_coords_impl(const Object *ob_lattice,
dvert = ((Lattice *)ob_target->data)->dvert;
}
else {
dvert = ((Mesh *)ob_target->data)->dvert;
dvert = BKE_mesh_deform_verts((Mesh *)ob_target->data);
}
}
}
@@ -1485,8 +1485,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
mesh->totloop = loop_offset;
BKE_mesh_update_customdata_pointers(mesh, false);
BKE_mesh_calc_edges(mesh, false, false);
return mesh;
+97 -192
View File
@@ -66,6 +66,7 @@
using blender::float3;
using blender::MutableSpan;
using blender::Span;
using blender::VArray;
using blender::Vector;
@@ -146,8 +147,6 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
mesh_tessface_clear_intern(mesh_dst, false);
}
BKE_mesh_update_customdata_pointers(mesh_dst, do_tessface);
mesh_dst->cd_flag = mesh_src->cd_flag;
mesh_dst->edit_mesh = nullptr;
@@ -234,29 +233,32 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
/* Do not store actual geometry data in case this is a library override ID. */
if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) {
mesh->mvert = nullptr;
mesh->totvert = 0;
memset(&mesh->vdata, 0, sizeof(mesh->vdata));
mesh->medge = nullptr;
mesh->totedge = 0;
memset(&mesh->edata, 0, sizeof(mesh->edata));
mesh->mloop = nullptr;
mesh->totloop = 0;
memset(&mesh->ldata, 0, sizeof(mesh->ldata));
mesh->mpoly = nullptr;
mesh->totpoly = 0;
memset(&mesh->pdata, 0, sizeof(mesh->pdata));
}
else {
Set<std::string> names_to_skip;
if (!BLO_write_is_undo(writer)) {
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
/* When converting to the old mesh format, don't save redundant attributes. */
names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly"});
/* Set deprecated mesh data pointers for forward compatibility. */
mesh->mvert = const_cast<MVert *>(mesh->vertices().data());
mesh->medge = const_cast<MEdge *>(mesh->edges().data());
mesh->mpoly = const_cast<MPoly *>(mesh->polygons().data());
mesh->mloop = const_cast<MLoop *>(mesh->loops().data());
}
CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip);
@@ -295,17 +297,16 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
Mesh *mesh = (Mesh *)id;
BLO_read_pointer_array(reader, (void **)&mesh->mat);
/* Deprecated pointers to custom data layers are read here for backward compatibility
* with files where these were owning pointers rather than a view into custom data. */
BLO_read_data_address(reader, &mesh->mvert);
BLO_read_data_address(reader, &mesh->medge);
BLO_read_data_address(reader, &mesh->mface);
BLO_read_data_address(reader, &mesh->mloop);
BLO_read_data_address(reader, &mesh->mpoly);
BLO_read_data_address(reader, &mesh->tface);
BLO_read_data_address(reader, &mesh->mtface);
BLO_read_data_address(reader, &mesh->mcol);
BLO_read_data_address(reader, &mesh->dvert);
BLO_read_data_address(reader, &mesh->mloopcol);
BLO_read_data_address(reader, &mesh->mloopuv);
BLO_read_data_address(reader, &mesh->tface);
BLO_read_data_address(reader, &mesh->mcol);
BLO_read_data_address(reader, &mesh->mselect);
/* animdata */
@@ -468,6 +469,8 @@ static int customdata_compare(
CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR |
CD_MASK_MDEFORMVERT;
const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic;
const Span<MLoop> loops_1 = m1->loops();
const Span<MLoop> loops_2 = m2->loops();
for (int i = 0; i < c1->totlayer; i++) {
l1 = &c1->layers[i];
@@ -543,15 +546,14 @@ static int customdata_compare(
int ptot = m1->totpoly;
for (j = 0; j < ptot; j++, p1++, p2++) {
MLoop *lp1, *lp2;
int k;
if (p1->totloop != p2->totloop) {
return MESHCMP_POLYMISMATCH;
}
lp1 = m1->mloop + p1->loopstart;
lp2 = m2->mloop + p2->loopstart;
const MLoop *lp1 = &loops_1[p1->loopstart];
const MLoop *lp2 = &loops_2[p2->loopstart];
for (k = 0; k < p1->totloop; k++, lp1++, lp2++) {
if (lp1->v != lp2->v) {
@@ -762,47 +764,6 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
return nullptr;
}
static void mesh_ensure_tessellation_customdata(Mesh *me)
{
if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
/* Pass, otherwise this function clears 'mface' before
* versioning 'mface -> mpoly' code kicks in T30583.
*
* Callers could also check but safer to do here - campbell */
}
else {
const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL);
if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) {
BKE_mesh_tessface_clear(me);
BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface);
/* TODO: add some `--debug-mesh` option. */
if (G.debug & G_DEBUG) {
/* NOTE(@campbellbarton): this warning may be un-called for if we are initializing the mesh
* for the first time from #BMesh, rather than giving a warning about this we could be
* smarter and check if there was any data to begin with, for now just print the warning
* with some info to help troubleshoot what's going on. */
printf(
"%s: warning! Tessellation uvs or vcol data got out of sync, "
"had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
"CD_PROP_BYTE_COLOR: "
"%d\n",
__func__,
tottex_tessface,
tottex_original,
totcol_tessface,
totcol_original);
}
}
}
}
void BKE_mesh_ensure_skin_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
@@ -874,43 +835,6 @@ bool BKE_mesh_clear_facemap_customdata(struct Mesh *me)
return changed;
}
/**
* This ensures grouped custom-data (e.g. #CD_MLOOPUV and #CD_MTFACE, or
* #CD_PROP_BYTE_COLOR and #CD_MCOL) have the same relative active/render/clone/mask indices.
*
* NOTE(@campbellbarton): that for undo mesh data we want to skip 'ensure_tess_cd' call since
* we don't want to store memory for #MFace data when its only used for older
* versions of the mesh.
*/
static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
{
if (do_ensure_tess_cd) {
mesh_ensure_tessellation_customdata(me);
}
CustomData_bmesh_update_active_layers(&me->fdata, &me->ldata);
}
void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
{
mesh_update_linked_customdata(me, do_ensure_tess_cd);
me->mvert = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT);
me->dvert = (MDeformVert *)CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
me->medge = (MEdge *)CustomData_get_layer(&me->edata, CD_MEDGE);
me->mface = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
me->mcol = (MCol *)CustomData_get_layer(&me->fdata, CD_MCOL);
me->mtface = (MTFace *)CustomData_get_layer(&me->fdata, CD_MTFACE);
me->mpoly = (MPoly *)CustomData_get_layer(&me->pdata, CD_MPOLY);
me->mloop = (MLoop *)CustomData_get_layer(&me->ldata, CD_MLOOP);
me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR);
me->mloopuv = (MLoopUV *)CustomData_get_layer(&me->ldata, CD_MLOOPUV);
}
bool BKE_mesh_has_custom_loop_normals(Mesh *me)
{
if (me->edit_mesh) {
@@ -954,8 +878,6 @@ static void mesh_clear_geometry(Mesh *mesh)
mesh->totpoly = 0;
mesh->act_face = -1;
mesh->totselect = 0;
BKE_mesh_update_customdata_pointers(mesh, false);
}
void BKE_mesh_clear_geometry(Mesh *mesh)
@@ -974,9 +896,6 @@ static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
CustomData_reset(&mesh->fdata);
}
mesh->mface = nullptr;
mesh->mtface = nullptr;
mesh->mcol = nullptr;
mesh->totface = 0;
}
@@ -1029,7 +948,6 @@ Mesh *BKE_mesh_new_nomain(
mesh->totpoly = polys_len;
mesh_ensure_cdlayers_primary(mesh, true);
BKE_mesh_update_customdata_pointers(mesh, false);
return mesh;
}
@@ -1115,7 +1033,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
/* The destination mesh should at least have valid primary CD layers,
* even in cases where the source mesh does not. */
mesh_ensure_cdlayers_primary(me_dst, do_tessface);
BKE_mesh_update_customdata_pointers(me_dst, false);
/* Expect that normals aren't copied at all, since the destination mesh is new. */
BLI_assert(BKE_mesh_vertex_normals_are_dirty(me_dst));
@@ -1338,11 +1255,12 @@ float (*BKE_mesh_orco_verts_get(Object *ob))[3]
/* Get appropriate vertex coordinates */
float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(me->totvert, sizeof(*vcos), "orco mesh");
MVert *mvert = tme->mvert;
const Span<MVert> verts = tme->vertices();
int totvert = min_ii(tme->totvert, me->totvert);
for (int a = 0; a < totvert; a++, mvert++) {
copy_v3_v3(vcos[a], mvert->co);
for (int a = 0; a < totvert; a++) {
copy_v3_v3(vcos[a], verts[a].co);
}
return vcos;
@@ -1512,14 +1430,15 @@ void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len)
void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth)
{
MutableSpan<MPoly> polys = me->polygons_for_write();
if (use_smooth) {
for (int i = 0; i < me->totpoly; i++) {
me->mpoly[i].flag |= ME_SMOOTH;
for (MPoly &poly : polys) {
poly.flag |= ME_SMOOTH;
}
}
else {
for (int i = 0; i < me->totpoly; i++) {
me->mpoly[i].flag &= ~ME_SMOOTH;
for (MPoly &poly : polys) {
poly.flag &= ~ME_SMOOTH;
}
}
}
@@ -1575,9 +1494,12 @@ int BKE_mesh_edge_other_vert(const MEdge *e, int v)
void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, int r_edges[3])
{
const Span<MEdge> edges = mesh->edges();
const Span<MLoop> loops = mesh->loops();
for (int i = 2, i_next = 0; i_next < 3; i = i_next++) {
const MLoop *l1 = &mesh->mloop[looptri->tri[i]], *l2 = &mesh->mloop[looptri->tri[i_next]];
const MEdge *e = &mesh->medge[l1->e];
const MLoop *l1 = &loops[looptri->tri[i]], *l2 = &loops[looptri->tri[i_next]];
const MEdge *e = &edges[l1->e];
bool is_real = (l1->v == e->v1 && l2->v == e->v2) || (l1->v == e->v2 && l2->v == e->v1);
@@ -1596,15 +1518,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
float3 min;
float3 max;
};
const Span<MVert> verts = me->vertices();
const Result minmax = threading::parallel_reduce(
IndexRange(me->totvert),
verts.index_range(),
1024,
Result{float3(FLT_MAX), float3(-FLT_MAX)},
[&](IndexRange range, const Result &init) {
[verts](IndexRange range, const Result &init) {
Result result = init;
for (const int i : range) {
math::min_max(float3(me->mvert[i].co), result.min, result.max);
math::min_max(float3(verts[i].co), result.min, result.max);
}
return result;
},
@@ -1620,22 +1543,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
{
int i;
MVert *mvert = (MVert *)CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert);
float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer(
&me->ldata, CD_NORMAL, me->totloop);
MutableSpan<MVert> verts = me->vertices_for_write();
/* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
BKE_mesh_update_customdata_pointers(me, false);
for (i = 0; i < me->totvert; i++, mvert++) {
mul_m4_v3(mat, mvert->co);
for (MVert &vert : verts) {
mul_m4_v3(mat, vert.co);
}
if (do_keys && me->key) {
LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
float *fp = (float *)kb->data;
for (i = kb->totelem; i--; fp += 3) {
for (int i = kb->totelem; i--; fp += 3) {
mul_m4_v3(mat, fp);
}
}
@@ -1644,12 +1561,14 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
/* don't update normals, caller can do this explicitly.
* We do update loop normals though, those may not be auto-generated
* (see e.g. STL import script)! */
float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer(
&me->ldata, CD_NORMAL, me->totloop);
if (lnors) {
float m3[3][3];
copy_m3_m4(m3, mat);
normalize_m3(m3);
for (i = 0; i < me->totloop; i++, lnors++) {
for (int i = 0; i < me->totloop; i++, lnors++) {
mul_m3_v3(m3, *lnors);
}
}
@@ -1658,15 +1577,12 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
{
CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert);
/* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
BKE_mesh_update_customdata_pointers(me, false);
int i = me->totvert;
for (MVert *mvert = me->mvert; i--; mvert++) {
add_v3_v3(mvert->co, offset);
MutableSpan<MVert> verts = me->vertices_for_write();
for (MVert &vert : verts) {
add_v3_v3(vert.co, offset);
}
int i;
if (do_keys && me->key) {
LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
float *fp = (float *)kb->data;
@@ -1689,25 +1605,24 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
return;
}
MVert *mv;
MEdge *med;
int i;
const Span<MVert> verts = mesh->vertices();
const Span<MEdge> edges = mesh->edges();
for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
if (mv->bweight != 0) {
for (const MVert &vert : verts) {
if (vert.bweight != 0) {
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
break;
}
}
for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
if (med->bweight != 0) {
for (const MEdge &edge : edges) {
if (edge.bweight != 0) {
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
break;
}
}
if (med->crease != 0) {
if (edge.crease != 0) {
mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
break;
@@ -1733,6 +1648,9 @@ void BKE_mesh_mselect_validate(Mesh *me)
if (me->totselect == 0) {
return;
}
const Span<MVert> verts = me->vertices();
const Span<MEdge> edges = me->edges();
const Span<MPoly> polys = me->polygons();
mselect_src = me->mselect;
mselect_dst = (MSelect *)MEM_malloc_arrayN(
@@ -1742,21 +1660,21 @@ void BKE_mesh_mselect_validate(Mesh *me)
int index = mselect_src[i_src].index;
switch (mselect_src[i_src].type) {
case ME_VSEL: {
if (me->mvert[index].flag & SELECT) {
if (verts[index].flag & SELECT) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_ESEL: {
if (me->medge[index].flag & SELECT) {
if (edges[index].flag & SELECT) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_FSEL: {
if (me->mpoly[index].flag & SELECT) {
if (polys[index].flag & SELECT) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
@@ -1842,10 +1760,10 @@ void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3])
void BKE_mesh_vert_coords_get(const Mesh *mesh, float (*vert_coords)[3])
{
const MVert *mv = mesh->mvert;
for (int i = 0; i < mesh->totvert; i++, mv++) {
copy_v3_v3(vert_coords[i], mv->co);
}
blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh);
VArray<float3> positions = attributes.lookup_or_default(
"position", ATTR_DOMAIN_POINT, float3(0));
positions.materialize({(float3 *)vert_coords, mesh->totvert});
}
float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3]
@@ -1860,12 +1778,9 @@ float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3]
void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3])
{
/* This will just return the pointer if it wasn't a referenced layer. */
MVert *mv = (MVert *)CustomData_duplicate_referenced_layer(
&mesh->vdata, CD_MVERT, mesh->totvert);
mesh->mvert = mv;
for (int i = 0; i < mesh->totvert; i++, mv++) {
copy_v3_v3(mv->co, vert_coords[i]);
MutableSpan<MVert> verts = mesh->vertices_for_write();
for (const int i : verts.index_range()) {
copy_v3_v3(verts[i].co, vert_coords[i]);
}
BKE_mesh_tag_coords_changed(mesh);
}
@@ -1874,12 +1789,9 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
const float (*vert_coords)[3],
const float mat[4][4])
{
/* This will just return the pointer if it wasn't a referenced layer. */
MVert *mv = (MVert *)CustomData_duplicate_referenced_layer(
&mesh->vdata, CD_MVERT, mesh->totvert);
mesh->mvert = mv;
for (int i = 0; i < mesh->totvert; i++, mv++) {
mul_v3_m4v3(mv->co, mat, vert_coords[i]);
MutableSpan<MVert> verts = mesh->vertices_for_write();
for (const int i : verts.index_range()) {
mul_v3_m4v3(verts[i].co, mat, vert_coords[i]);
}
BKE_mesh_tag_coords_changed(mesh);
}
@@ -1915,17 +1827,22 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
/* may be nullptr */
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
BKE_mesh_normals_loop_split(mesh->mvert,
const Span<MVert> verts = mesh->vertices();
const Span<MEdge> edges = mesh->edges();
const Span<MPoly> polys = mesh->polygons();
const Span<MLoop> loops = mesh->loops();
BKE_mesh_normals_loop_split(verts.data(),
BKE_mesh_vertex_normals_ensure(mesh),
mesh->totvert,
mesh->medge,
mesh->totedge,
mesh->mloop,
verts.size(),
edges.data(),
edges.size(),
loops.data(),
r_corner_normals,
mesh->totloop,
mesh->mpoly,
loops.size(),
polys.data(),
BKE_mesh_poly_normals_ensure(mesh),
mesh->totpoly,
polys.size(),
use_split_normals,
split_angle,
r_lnors_spacearr,
@@ -1971,14 +1888,14 @@ static int split_faces_prepare_new_verts(Mesh *mesh,
const int loops_len = mesh->totloop;
int verts_len = mesh->totvert;
MLoop *mloop = mesh->mloop;
MutableSpan<MLoop> loops = mesh->loops_for_write();
BKE_mesh_vertex_normals_ensure(mesh);
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
BLI_bitmap *verts_used = BLI_BITMAP_NEW(verts_len, __func__);
BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_len, __func__);
MLoop *ml = mloop;
MLoop *ml = loops.data();
MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX);
@@ -2005,7 +1922,7 @@ static int split_faces_prepare_new_verts(Mesh *mesh,
const int ml_fan_idx = POINTER_AS_INT(lnode->link);
BLI_BITMAP_ENABLE(done_loops, ml_fan_idx);
if (vert_used) {
mloop[ml_fan_idx].v = new_vert_idx;
loops[ml_fan_idx].v = new_vert_idx;
}
}
}
@@ -2040,23 +1957,23 @@ static int split_faces_prepare_new_verts(Mesh *mesh,
/* Detect needed new edges, and update accordingly loops' edge indices.
* WARNING! Leaves mesh in invalid state. */
static int split_faces_prepare_new_edges(const Mesh *mesh,
static int split_faces_prepare_new_edges(Mesh *mesh,
SplitFaceNewEdge **new_edges,
MemArena *memarena)
{
const int num_polys = mesh->totpoly;
int num_edges = mesh->totedge;
MEdge *medge = mesh->medge;
MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
const Span<MPoly> polys = mesh->polygons();
BLI_bitmap *edges_used = BLI_BITMAP_NEW(num_edges, __func__);
EdgeHash *edges_hash = BLI_edgehash_new_ex(__func__, num_edges);
const MPoly *mp = mpoly;
const MPoly *mp = polys.data();
for (int poly_idx = 0; poly_idx < num_polys; poly_idx++, mp++) {
MLoop *ml_prev = &mloop[mp->loopstart + mp->totloop - 1];
MLoop *ml = &mloop[mp->loopstart];
MLoop *ml_prev = &loops[mp->loopstart + mp->totloop - 1];
MLoop *ml = &loops[mp->loopstart];
for (int loop_idx = 0; loop_idx < mp->totloop; loop_idx++, ml++) {
void **eval;
if (!BLI_edgehash_ensure_p(edges_hash, ml_prev->v, ml->v, &eval)) {
@@ -2080,8 +1997,8 @@ static int split_faces_prepare_new_edges(const Mesh *mesh,
}
else {
/* We can re-use original edge. */
medge[edge_idx].v1 = ml_prev->v;
medge[edge_idx].v2 = ml->v;
edges[edge_idx].v1 = ml_prev->v;
edges[edge_idx].v2 = ml->v;
*eval = POINTER_FROM_INT(edge_idx);
BLI_BITMAP_ENABLE(edges_used, edge_idx);
}
@@ -2107,7 +2024,6 @@ static void split_faces_split_new_verts(Mesh *mesh,
const int num_new_verts)
{
const int verts_len = mesh->totvert - num_new_verts;
MVert *mvert = mesh->mvert;
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
/* Normals were already calculated at the beginning of this operation, we rely on that to update
@@ -2115,8 +2031,7 @@ static void split_faces_split_new_verts(Mesh *mesh,
BLI_assert(!BKE_mesh_vertex_normals_are_dirty(mesh));
/* Remember new_verts is a single linklist, so its items are in reversed order... */
MVert *new_mv = &mvert[mesh->totvert - 1];
for (int i = mesh->totvert - 1; i >= verts_len; i--, new_mv--, new_verts = new_verts->next) {
for (int i = mesh->totvert - 1; i >= verts_len; i--, new_verts = new_verts->next) {
BLI_assert(new_verts->new_index == i);
BLI_assert(new_verts->new_index != new_verts->orig_index);
CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1);
@@ -2132,10 +2047,10 @@ static void split_faces_split_new_edges(Mesh *mesh,
const int num_new_edges)
{
const int num_edges = mesh->totedge - num_new_edges;
MEdge *medge = mesh->medge;
MutableSpan<MEdge> edges = mesh->edges_for_write();
/* Remember new_edges is a single linklist, so its items are in reversed order... */
MEdge *new_med = &medge[mesh->totedge - 1];
MEdge *new_med = &edges[mesh->totedge - 1];
for (int i = mesh->totedge - 1; i >= num_edges; i--, new_med--, new_edges = new_edges->next) {
BLI_assert(new_edges->new_index == i);
BLI_assert(new_edges->new_index != new_edges->orig_index);
@@ -2163,14 +2078,6 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
SplitFaceNewVert *new_verts = nullptr;
SplitFaceNewEdge *new_edges = nullptr;
/* Ensure we own the layers, we need to do this before split_faces_prepare_new_verts as it will
* directly assign new indices to existing edges and loops. */
CustomData_duplicate_referenced_layers(&mesh->vdata, mesh->totvert);
CustomData_duplicate_referenced_layers(&mesh->edata, mesh->totedge);
CustomData_duplicate_referenced_layers(&mesh->ldata, mesh->totloop);
/* Update pointers in case we duplicated referenced layers. */
BKE_mesh_update_customdata_pointers(mesh, false);
/* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */
const int num_new_verts = split_faces_prepare_new_verts(
mesh, &lnors_spacearr, &new_verts, memarena);
@@ -2191,8 +2098,6 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
mesh->totedge += num_new_edges;
CustomData_realloc(&mesh->edata, mesh->totedge);
}
/* Update pointers to a newly allocated memory. */
BKE_mesh_update_customdata_pointers(mesh, false);
/* Update normals manually to avoid recalculation after this operation. */
mesh->runtime.vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime.vert_normals,
@@ -162,9 +162,10 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
int orig_mesh_index = input_mesh_for_imesh_face(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
const Span<MPoly> polys = me->polygons();
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 = &me->mpoly[index_in_mesh];
const MPoly *mp = &polys[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -188,9 +189,10 @@ const MVert *MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index,
int orig_mesh_index = input_mesh_for_imesh_vert(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
const Span<MVert> verts = me->vertices();
int index_in_mesh = orig_index - mesh_vert_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totvert);
const MVert *mv = &me->mvert[index_in_mesh];
const MVert *mv = &verts[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -208,9 +210,10 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
int orig_mesh_index = input_mesh_for_imesh_edge(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
const Span<MEdge> edges = me->edges();
int index_in_mesh = orig_index - mesh_edge_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totedge);
const MEdge *medge = &me->medge[index_in_mesh];
const MEdge *medge = &edges[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -306,17 +309,19 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
bool need_face_flip = r_info->has_negative_transform[mi] != r_info->has_negative_transform[0];
Vector<Vert *> verts(me->totvert);
Span<MVert> mverts = Span(me->mvert, me->totvert);
const Span<MVert> mesh_verts = me->vertices();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
/* Allocate verts
* Skip the matrix multiplication for each point when there is no transform for a mesh,
* for example when the first mesh is already in the target space. (Note the logic
* directly above, which uses an identity matrix with a null input transform). */
if (obmats[mi] == nullptr) {
threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) {
threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) {
float3 co;
for (int i : range) {
co = float3(mverts[i].co);
co = float3(mesh_verts[i].co);
mpq3 mco = mpq3(co.x, co.y, co.z);
double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d());
verts[i] = new Vert(mco, dco, NO_INDEX, i);
@@ -324,26 +329,26 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
});
}
else {
threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) {
threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) {
float3 co;
for (int i : range) {
co = r_info->to_target_transform[mi] * float3(mverts[i].co);
co = r_info->to_target_transform[mi] * float3(mesh_verts[i].co);
mpq3 mco = mpq3(co.x, co.y, co.z);
double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d());
verts[i] = new Vert(mco, dco, NO_INDEX, i);
}
});
}
for (int i : mverts.index_range()) {
for (int i : mesh_verts.index_range()) {
r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]);
++v;
}
for (const MPoly &poly : Span(me->mpoly, me->totpoly)) {
for (const MPoly &poly : polys) {
int flen = poly.totloop;
face_vert.resize(flen);
face_edge_orig.resize(flen);
const MLoop *l = &me->mloop[poly.loopstart];
const MLoop *l = &loops[poly.loopstart];
for (int i = 0; i < flen; ++i) {
int mverti = r_info->mesh_vert_offset[mi] + l->v;
const Vert *fv = r_info->mesh_to_imesh_vert[mverti];
@@ -479,14 +484,16 @@ static int fill_orig_loops(const Face *f,
const Mesh *orig_me,
int orig_me_index,
MeshesToIMeshInfo &mim,
Array<int> &orig_loops)
MutableSpan<int> r_orig_loops)
{
orig_loops.fill(-1);
r_orig_loops.fill(-1);
const Span<MLoop> orig_loops = orig_me->loops();
int orig_mplen = orig_mp->totloop;
if (f->size() != orig_mplen) {
return 0;
}
BLI_assert(orig_loops.size() == orig_mplen);
BLI_assert(r_orig_loops.size() == orig_mplen);
/* We'll look for the case where the first vertex in f has an original vertex
* that is the same as one in orig_me (after correcting for offset in mim meshes).
* Then see that loop and any subsequent ones have the same start and end vertex.
@@ -508,7 +515,7 @@ static int fill_orig_loops(const Face *f,
int offset = -1;
for (int i = 0; i < orig_mplen; ++i) {
int loop_i = i + orig_mp->loopstart;
if (orig_me->mloop[loop_i].v == first_orig_v_in_orig_me) {
if (orig_loops[loop_i].v == first_orig_v_in_orig_me) {
offset = i;
break;
}
@@ -519,7 +526,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;
MLoop *l = &orig_me->mloop[orig_mp->loopstart + orig_mp_loop_index];
const MLoop *l = &orig_loops[orig_mp->loopstart + orig_mp_loop_index];
int fv_orig = f->vert[mp_loop_index]->orig;
if (fv_orig != NO_INDEX) {
fv_orig -= orig_me_vert_offset;
@@ -528,7 +535,8 @@ static int fill_orig_loops(const Face *f,
}
}
if (l->v == fv_orig) {
MLoop *lnext = &orig_me->mloop[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
const MLoop *lnext =
&orig_loops[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
int fvnext_orig = f->vert[(mp_loop_index + 1) % orig_mplen]->orig;
if (fvnext_orig != NO_INDEX) {
fvnext_orig -= orig_me_vert_offset;
@@ -537,7 +545,7 @@ static int fill_orig_loops(const Face *f,
}
}
if (lnext->v == fvnext_orig) {
orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index;
r_orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index;
++num_orig_loops_found;
}
}
@@ -555,19 +563,18 @@ static void get_poly2d_cos(const Mesh *me,
const float4x4 &trans_mat,
float r_axis_mat[3][3])
{
int n = mp->totloop;
const Span<MVert> verts = me->vertices();
const Span<MLoop> loops = me->loops();
const Span<MLoop> poly_loops = loops.slice(mp->loopstart, mp->totloop);
/* Project coordinates to 2d in cos_2d, using normal as projection axis. */
float axis_dominant[3];
BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, axis_dominant);
BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts.data(), axis_dominant);
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
MLoop *ml = &me->mloop[mp->loopstart];
const MVert *mverts = me->mvert;
for (int i = 0; i < n; ++i) {
float3 co = mverts[ml->v].co;
for (const int i : poly_loops.index_range()) {
float3 co = verts[poly_loops[i].v].co;
co = trans_mat * co;
mul_v2_m3v3(cos_2d[i], r_axis_mat, co);
++ml;
}
}
@@ -602,6 +609,8 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
get_poly2d_cos(orig_me, orig_mp, cos_2d, mim.to_target_transform[orig_me_index], axis_mat);
}
CustomData *target_cd = &dest_mesh->ldata;
const Span<MVert> dst_vertices = dest_mesh->vertices();
const Span<MLoop> dst_loops = dest_mesh->loops();
for (int i = 0; i < mp->totloop; ++i) {
int loop_index = mp->loopstart + i;
int orig_loop_index = norig > 0 ? orig_loops[i] : -1;
@@ -611,7 +620,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
* The coordinate needs to be projected into 2d, just like the interpolating polygon's
* coordinates were. The `dest_mesh` coordinates are already in object 0 local space. */
float co[2];
mul_v2_m3v3(co, axis_mat, dest_mesh->mvert[dest_mesh->mloop[loop_index].v].co);
mul_v2_m3v3(co, axis_mat, dst_vertices[dst_loops[loop_index].v].co);
interp_weights_poly_v2(weights.data(), cos_2d, orig_mp->totloop, co);
}
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
@@ -714,9 +723,10 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
merge_vertex_loop_poly_customdata_layers(result, mim);
/* Set the vertex coordinate values and other data. */
MutableSpan<MVert> vertices = result->vertices_for_write();
for (int vi : im->vert_index_range()) {
const Vert *v = im->vert(vi);
MVert *mv = &result->mvert[vi];
MVert *mv = &vertices[vi];
copy_v3fl_v3db(mv->co, v->co);
if (v->orig != NO_INDEX) {
const Mesh *orig_me;
@@ -732,7 +742,9 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
bke::mesh_attributes_for_write(*result).lookup_or_add_for_write_only_span<int>(
"material_index", ATTR_DOMAIN_FACE);
int cur_loop_index = 0;
MLoop *l = result->mloop;
MutableSpan<MLoop> dst_loops = result->loops_for_write();
MutableSpan<MPoly> dst_polys = result->polygons_for_write();
MLoop *l = dst_loops.data();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
const Mesh *orig_me;
@@ -740,7 +752,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
int orig_me_index;
const MPoly *orig_mp = mim.input_mpoly_for_orig_index(
f->orig, &orig_me, &orig_me_index, &index_in_orig_me);
MPoly *mp = &result->mpoly[fi];
MPoly *mp = &dst_polys[fi];
mp->totloop = f->size();
mp->loopstart = cur_loop_index;
for (int j : f->index_range()) {
@@ -772,17 +784,18 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
/* Now that the MEdges are populated, we can copy over the required attributes and custom layers.
*/
MutableSpan<MEdge> edges = result->edges_for_write();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
MPoly *mp = &result->mpoly[fi];
const MPoly *mp = &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 = result->mloop[mp->loopstart + j].e;
MEdge *medge = &result->medge[e_index];
int e_index = dst_loops[mp->loopstart + j].e;
MEdge *medge = &edges[e_index];
copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me);
}
}
@@ -844,12 +857,14 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
/* Store intersecting edge indices. */
if (r_intersecting_edges != nullptr) {
const Span<MPoly> polys = result->polygons();
const Span<MLoop> loops = result->loops();
for (int fi : m_out.face_index_range()) {
const Face &face = *m_out.face(fi);
const MPoly &poly = result->mpoly[fi];
const MPoly &poly = polys[fi];
for (int corner_i : face.index_range()) {
if (face.is_intersect[corner_i]) {
int e_index = result->mloop[poly.loopstart + corner_i].e;
int e_index = loops[poly.loopstart + corner_i].e;
r_intersecting_edges->append(e_index);
}
}
@@ -80,9 +80,10 @@ static void add_existing_edges_to_hash_maps(Mesh *mesh,
uint32_t parallel_mask)
{
/* Assume existing edges are valid. */
const Span<MEdge> edges = mesh->edges();
threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) {
const int task_index = &edge_map - edge_maps.data();
for (const MEdge &edge : Span(mesh->medge, mesh->totedge)) {
for (const MEdge &edge : edges) {
OrderedEdge ordered_edge{edge.v1, edge.v2};
/* Only add the edge when it belongs into this map. */
if (task_index == (parallel_mask & ordered_edge.hash2())) {
@@ -96,10 +97,11 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh,
MutableSpan<EdgeMap> edge_maps,
uint32_t parallel_mask)
{
const Span<MLoop> loops{mesh->mloop, mesh->totloop};
const Span<MPoly> polys = mesh->polygons();
const Span<MLoop> loops = mesh->loops();
threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) {
const int task_index = &edge_map - edge_maps.data();
for (const MPoly &poly : Span(mesh->mpoly, mesh->totpoly)) {
for (const MPoly &poly : polys) {
Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
const MLoop *prev_loop = &poly_loops.last();
for (const MLoop &next_loop : poly_loops) {
@@ -157,10 +159,11 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh,
Span<EdgeMap> edge_maps,
uint32_t parallel_mask)
{
const MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop};
const Span<MPoly> polys = mesh->polygons();
MutableSpan<MLoop> loops = mesh->loops_for_write();
threading::parallel_for(IndexRange(mesh->totpoly), 100, [&](IndexRange range) {
for (const int poly_index : range) {
MPoly &poly = mesh->mpoly[poly_index];
const MPoly &poly = polys[poly_index];
MutableSpan<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
MLoop *prev_loop = &poly_loops.last();
@@ -242,7 +245,6 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
CustomData_reset(&mesh->edata);
CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge);
mesh->totedge = new_totedge;
mesh->medge = new_edges.data();
/* Explicitly clear edge maps, because that way it can be parallelized. */
clear_hash_tables(edge_maps);
@@ -81,8 +81,8 @@ static void make_edges_mdata_extend(Mesh &mesh)
const MPoly *mp;
int i;
Span<MPoly> polys(mesh.mpoly, mesh.totpoly);
MutableSpan<MLoop> loops(mesh.mloop, mesh.totloop);
const Span<MPoly> polys = mesh.polygons();
MutableSpan<MLoop> loops = mesh.loops_for_write();
const int eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh.totpoly));
EdgeHash *eh = BLI_edgehash_new_ex(__func__, eh_reserve);
@@ -96,20 +96,18 @@ static void make_edges_mdata_extend(Mesh &mesh)
#ifdef DEBUG
/* ensure that there's no overlap! */
if (totedge_new) {
MEdge *medge = mesh.medge;
for (i = 0; i < totedge; i++, medge++) {
BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false);
for (const MEdge &edge : mesh.edges()) {
BLI_assert(BLI_edgehash_haskey(eh, edge.v1, edge.v2) == false);
}
}
#endif
if (totedge_new) {
CustomData_realloc(&mesh.edata, totedge + totedge_new);
BKE_mesh_update_customdata_pointers(&mesh, false);
MEdge *medge = mesh.medge + totedge;
mesh.totedge += totedge_new;
MutableSpan<MEdge> edges = mesh.edges_for_write();
MEdge *medge = &edges[totedge];
EdgeHashIterator *ehi;
uint e_index = totedge;
@@ -123,7 +121,7 @@ static void make_edges_mdata_extend(Mesh &mesh)
}
BLI_edgehashIterator_free(ehi);
for (i = 0, mp = mesh.mpoly; i < mesh.totpoly; i++, mp++) {
for (i = 0, mp = polys.data(); i < mesh.totpoly; i++, mp++) {
MLoop *l = &loops[mp->loopstart];
MLoop *l_prev = (l + (mp->totloop - 1));
int j;
@@ -186,10 +184,10 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
}
Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop);
MutableSpan<MVert> verts = mesh->vertices_for_write();
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MPoly> polys = mesh->polygons_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
MVert *mvert = verts.data();
MEdge *medge = edges.data();
@@ -434,7 +432,7 @@ Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob)
struct EdgeLink {
struct EdgeLink *next, *prev;
void *edge;
const void *edge;
};
struct VertLink {
@@ -458,10 +456,13 @@ static void appendPolyLineVert(ListBase *lb, uint index)
void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
{
MVert *mvert = me->mvert;
MEdge *med, *medge = me->medge;
MPoly *mp, *mpoly = me->mpoly;
MLoop *mloop = me->mloop;
const Span<MVert> verts = me->vertices();
const Span<MEdge> mesh_edges = me->edges();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
const MEdge *med;
const MPoly *mp;
int medge_len = me->totedge;
int mpoly_len = me->totpoly;
@@ -475,8 +476,8 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
/* get boundary edges */
edge_users = (int *)MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
MLoop *ml = &mloop[mp->loopstart];
for (i = 0, mp = polys.data(); i < mpoly_len; i++, mp++) {
const MLoop *ml = &loops[mp->loopstart];
int j;
for (j = 0; j < mp->totloop; j++, ml++) {
edge_users[ml->e]++;
@@ -484,7 +485,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
}
/* create edges from all faces (so as to find edges not in any faces) */
med = medge;
med = mesh_edges.data();
for (i = 0; i < medge_len; i++, med++) {
if (edge_users[i] == edge_users_test) {
EdgeLink *edl = MEM_cnew<EdgeLink>("EdgeLink");
@@ -587,7 +588,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
/* add points */
vl = (VertLink *)polyline.first;
for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
copy_v3_v3(bp->vec, mvert[vl->index].co);
copy_v3_v3(bp->vec, verts[vl->index].co);
bp->f1 = SELECT;
bp->radius = bp->weight = 1.0;
}
@@ -682,19 +683,16 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
/* Convert the Position attribute to a mesh vertex. */
me->mvert = (MVert *)CustomData_add_layer(
&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
CustomData_update_typemap(&me->vdata);
CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
const int layer_idx = CustomData_get_named_layer_index(
&me->vdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION);
CustomDataLayer *pos_layer = &me->vdata.layers[layer_idx];
float(*positions)[3] = (float(*)[3])pos_layer->data;
MVert *mvert;
mvert = me->mvert;
for (int i = 0; i < me->totvert; i++, mvert++) {
copy_v3_v3(mvert->co, positions[i]);
MutableSpan<MVert> verts = me->vertices_for_write();
for (int i = 0; i < me->totvert; i++) {
copy_v3_v3(verts[i].co, positions[i]);
}
/* Delete Position attribute since it is now in vertex coordinates. */
@@ -703,9 +701,9 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
void BKE_mesh_edges_set_draw_render(Mesh *mesh)
{
MEdge *med = mesh->medge;
for (int i = 0; i < mesh->totedge; i++, med++) {
med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
MutableSpan<MEdge> edges = mesh->edges_for_write();
for (int i = 0; i < mesh->totedge; i++) {
edges[i].flag |= ME_EDGEDRAW | ME_EDGERENDER;
}
}
@@ -1171,7 +1169,8 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
if (build_shapekey_layers && me->key &&
(kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) {
BKE_keyblock_convert_to_mesh(kb, me->mvert, me->totvert);
MutableSpan<MVert> verts = me->vertices_for_write();
BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert);
}
Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE);
@@ -1274,10 +1273,9 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act
kb->data = kbcos = (float(*)[3])MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
if (kb->uid == actshape_uid) {
MVert *mvert = mesh_src->mvert;
for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) {
copy_v3_v3(*kbcos, mvert->co);
const Span<MVert> verts = mesh_src->vertices();
for (j = 0; j < mesh_src->totvert; j++, kbcos++) {
copy_v3_v3(*kbcos, verts[j].co);
}
}
else {
@@ -1306,6 +1304,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
const CustomData_MeshMasks *mask,
bool take_ownership)
{
using namespace blender::bke;
BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
/* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
@@ -1385,30 +1384,30 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
CustomData_add_layer(&tmp.vdata,
CD_MVERT,
CD_ASSIGN,
(alloctype == CD_ASSIGN) ? mesh_src->mvert :
MEM_dupallocN(mesh_src->mvert),
(alloctype == CD_ASSIGN) ? mesh_src->vertices_for_write().data() :
MEM_dupallocN(mesh_src->vertices().data()),
totvert);
}
if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
CustomData_add_layer(&tmp.edata,
CD_MEDGE,
CD_ASSIGN,
(alloctype == CD_ASSIGN) ? mesh_src->medge :
MEM_dupallocN(mesh_src->medge),
(alloctype == CD_ASSIGN) ? mesh_src->edges_for_write().data() :
MEM_dupallocN(mesh_src->edges().data()),
totedge);
}
if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
CustomData_add_layer(&tmp.ldata,
CD_MLOOP,
CD_ASSIGN,
(alloctype == CD_ASSIGN) ? mesh_src->mloop :
MEM_dupallocN(mesh_src->mloop),
(alloctype == CD_ASSIGN) ? mesh_src->loops_for_write().data() :
MEM_dupallocN(mesh_src->loops().data()),
tmp.totloop);
CustomData_add_layer(&tmp.pdata,
CD_MPOLY,
CD_ASSIGN,
(alloctype == CD_ASSIGN) ? mesh_src->mpoly :
MEM_dupallocN(mesh_src->mpoly),
(alloctype == CD_ASSIGN) ? mesh_src->polygons_for_write().data() :
MEM_dupallocN(mesh_src->polygons().data()),
tmp.totpoly);
}
@@ -1425,9 +1424,6 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
}
}
/* yes, must be before _and_ after tessellate */
BKE_mesh_update_customdata_pointers(&tmp, false);
CustomData_free(&mesh_dst->vdata, mesh_dst->totvert);
CustomData_free(&mesh_dst->edata, mesh_dst->totedge);
CustomData_free(&mesh_dst->fdata, mesh_dst->totface);
@@ -1481,7 +1477,6 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
int a, totvert = mesh_src->totvert;
float *fp;
MVert *mvert;
if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) {
return;
@@ -1494,9 +1489,8 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
kb->totelem = totvert;
fp = (float *)kb->data;
mvert = mesh_src->mvert;
for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
copy_v3_v3(fp, mvert->co);
const Span<MVert> verts = mesh_src->vertices();
for (a = 0; a < kb->totelem; a++, fp += 3) {
copy_v3_v3(fp, verts[a].co);
}
}
@@ -205,18 +205,13 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
float BKE_mesh_calc_area(const Mesh *me)
{
MVert *mvert = me->mvert;
MLoop *mloop = me->mloop;
MPoly *mpoly = me->mpoly;
const Span<MVert> verts = me->vertices();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
MPoly *mp;
int i = me->totpoly;
float total_area = 0;
for (mp = mpoly; i--; mp++) {
MLoop *ml_start = &mloop[mp->loopstart];
total_area += BKE_mesh_calc_poly_area(mp, ml_start, mvert);
float total_area = 0.0f;
for (const MPoly &poly : polys) {
total_area += BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data());
}
return total_area;
}
@@ -405,11 +400,10 @@ void BKE_mesh_poly_edgebitmap_insert(uint *edge_bitmap, const MPoly *mp, const M
bool BKE_mesh_center_median(const Mesh *me, float r_cent[3])
{
int i = me->totvert;
const MVert *mvert;
const Span<MVert> verts = me->vertices();
zero_v3(r_cent);
for (mvert = me->mvert; i--; mvert++) {
add_v3_v3(r_cent, mvert->co);
for (const MVert &vert : verts) {
add_v3_v3(r_cent, vert.co);
}
/* otherwise we get NAN for 0 verts */
if (me->totvert) {
@@ -420,18 +414,17 @@ bool BKE_mesh_center_median(const Mesh *me, float r_cent[3])
bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3])
{
int i = me->totpoly;
int tot = 0;
const MPoly *mpoly = me->mpoly;
const MLoop *mloop = me->mloop;
const MVert *mvert = me->mvert;
const Span<MVert> verts = me->vertices();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
zero_v3(r_cent);
for (; i--; mpoly++) {
int loopend = mpoly->loopstart + mpoly->totloop;
for (int j = mpoly->loopstart; j < loopend; j++) {
add_v3_v3(r_cent, mvert[mloop[j].v].co);
for (const MPoly &poly : polys) {
int loopend = poly.loopstart + poly.totloop;
for (int j = poly.loopstart; j < loopend; j++) {
add_v3_v3(r_cent, verts[loops[j].v].co);
}
tot += mpoly->totloop;
tot += poly.totloop;
}
/* otherwise we get NAN for 0 verts */
if (me->totpoly) {
@@ -455,17 +448,19 @@ bool BKE_mesh_center_bounds(const Mesh *me, float r_cent[3])
bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
{
int i = me->totpoly;
MPoly *mpoly;
const MPoly *mpoly;
float poly_area;
float total_area = 0.0f;
float poly_cent[3];
const MVert *verts = BKE_mesh_vertices(me);
const MPoly *polys = BKE_mesh_polygons(me);
const MLoop *loops = BKE_mesh_loops(me);
zero_v3(r_cent);
/* calculate a weighted average of polygon centroids */
for (mpoly = me->mpoly; i--; mpoly++) {
poly_area = mesh_calc_poly_area_centroid(
mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
for (mpoly = polys; i--; mpoly++) {
poly_area = mesh_calc_poly_area_centroid(mpoly, loops + mpoly->loopstart, verts, poly_cent);
madd_v3_v3fl(r_cent, poly_cent, poly_area);
total_area += poly_area;
@@ -486,10 +481,13 @@ 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;
MPoly *mpoly;
const MPoly *mpoly;
float poly_volume;
float total_volume = 0.0f;
float poly_cent[3];
const MVert *verts = BKE_mesh_vertices(me);
const MPoly *polys = BKE_mesh_polygons(me);
const MLoop *loops = BKE_mesh_loops(me);
/* Use an initial center to avoid numeric instability of geometry far away from the center. */
float init_cent[3];
@@ -498,9 +496,9 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
zero_v3(r_cent);
/* calculate a weighted average of polyhedron centroids */
for (mpoly = me->mpoly; i--; mpoly++) {
for (mpoly = polys; i--; mpoly++) {
poly_volume = mesh_calc_poly_volume_centroid_with_reference_center(
mpoly, me->mloop + mpoly->loopstart, me->mvert, init_cent, poly_cent);
mpoly, loops + mpoly->loopstart, verts, init_cent, poly_cent);
/* poly_cent is already volume-weighted, so no need to multiply by the volume */
add_v3_v3(r_cent, poly_cent);
@@ -670,7 +668,7 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
}
}
void BKE_mesh_polygon_flip_ex(MPoly *mpoly,
void BKE_mesh_polygon_flip_ex(const MPoly *mpoly,
MLoop *mloop,
CustomData *ldata,
float (*lnors)[3],
@@ -713,16 +711,16 @@ void BKE_mesh_polygon_flip_ex(MPoly *mpoly,
}
}
void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata)
void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata)
{
MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS);
BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true);
}
void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
void BKE_mesh_polygons_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
{
MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS);
MPoly *mp;
const MPoly *mp;
int i;
for (mp = mpoly, i = 0; i < totpoly; mp++, i++) {
@@ -748,9 +746,9 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
return;
}
const VArraySpan<bool> hide_vert_span{hide_vert};
const Span<MEdge> edges(me->medge, me->totedge);
const Span<MPoly> polys(me->mpoly, me->totpoly);
const Span<MLoop> loops(me->mloop, me->totloop);
const Span<MEdge> edges = me->edges();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
/* Hide edges when either of their vertices are hidden. */
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -788,8 +786,8 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
return;
}
const VArraySpan<bool> hide_poly_span{hide_poly};
const Span<MPoly> polys(me->mpoly, me->totpoly);
const Span<MLoop> loops(me->mloop, me->totloop);
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -859,8 +857,13 @@ void BKE_mesh_flush_select_from_polys_ex(MVert *mvert,
}
void BKE_mesh_flush_select_from_polys(Mesh *me)
{
BKE_mesh_flush_select_from_polys_ex(
me->mvert, me->totvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly);
BKE_mesh_flush_select_from_polys_ex(me->vertices_for_write().data(),
me->totvert,
me->loops().data(),
me->edges_for_write().data(),
me->totedge,
me->polygons().data(),
me->totpoly);
}
static void mesh_flush_select_from_verts(const Span<MVert> verts,
@@ -906,12 +909,12 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
{
const blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*me);
mesh_flush_select_from_verts(
{me->mvert, me->totvert},
{me->mloop, me->totloop},
me->vertices(),
me->loops(),
attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
{me->medge, me->totedge},
{me->mpoly, me->totpoly});
me->edges_for_write(),
me->polygons_for_write());
}
/** \} */
+15 -12
View File
@@ -27,6 +27,8 @@
#include "eigen_capi.h"
using blender::Map;
using blender::MutableSpan;
using blender::Span;
using blender::Vector;
using std::array;
@@ -193,13 +195,14 @@ class MeshFairingContext : public FairingContext {
totvert_ = mesh->totvert;
totloop_ = mesh->totloop;
medge_ = mesh->medge;
mpoly_ = mesh->mpoly;
mloop_ = mesh->mloop;
MutableSpan<MVert> verts = mesh->vertices_for_write();
medge_ = mesh->edges();
mpoly_ = mesh->polygons();
mloop_ = mesh->loops();
BKE_mesh_vert_loop_map_create(&vlmap_,
&vlmap_mem_,
mesh->mpoly,
mesh->mloop,
mpoly_.data(),
mloop_.data(),
mesh->totvert,
mesh->totpoly,
mesh->totloop);
@@ -213,14 +216,14 @@ class MeshFairingContext : public FairingContext {
}
else {
for (int i = 0; i < mesh->totvert; i++) {
co_[i] = mesh->mvert[i].co;
co_[i] = verts[i].co;
}
}
loop_to_poly_map_.reserve(mesh->totloop);
for (int i = 0; i < mesh->totpoly; i++) {
for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
loop_to_poly_map_[l + mesh->mpoly[i].loopstart] = i;
for (int l = 0; l < mpoly_[i].totloop; l++) {
loop_to_poly_map_[l + mpoly_[i].loopstart] = i;
}
}
}
@@ -244,7 +247,7 @@ class MeshFairingContext : public FairingContext {
int other_vertex_index_from_loop(const int loop, const uint v) override
{
MEdge *e = &medge_[mloop_[loop].e];
const MEdge *e = &medge_[mloop_[loop].e];
if (e->v1 == v) {
return e->v2;
}
@@ -253,9 +256,9 @@ class MeshFairingContext : public FairingContext {
protected:
Mesh *mesh_;
MLoop *mloop_;
MPoly *mpoly_;
MEdge *medge_;
Span<MLoop> mloop_;
Span<MPoly> mpoly_;
Span<MEdge> medge_;
Vector<int> loop_to_poly_map_;
};
@@ -65,7 +65,7 @@ void BKE_mesh_foreach_mapped_vert(
}
}
else {
const MVert *mv = mesh->mvert;
const MVert *mv = BKE_mesh_vertices(mesh);
const int *index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
BKE_mesh_vertex_normals_ensure(mesh) :
@@ -120,8 +120,8 @@ void BKE_mesh_foreach_mapped_edge(
}
}
else {
const MVert *mv = mesh->mvert;
const MEdge *med = mesh->medge;
const MVert *mv = BKE_mesh_vertices(mesh);
const MEdge *med = BKE_mesh_edges(mesh);
const int *index = CustomData_get_layer(&mesh->edata, CD_ORIGINDEX);
if (index) {
@@ -188,9 +188,9 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
CustomData_get_layer(&mesh->ldata, CD_NORMAL) :
NULL;
const MVert *mv = mesh->mvert;
const MLoop *ml = mesh->mloop;
const MPoly *mp = mesh->mpoly;
const MVert *mv = BKE_mesh_vertices(mesh);
const MLoop *ml = BKE_mesh_loops(mesh);
const MPoly *mp = BKE_mesh_polygons(mesh);
const int *v_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
const int *f_index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
int p_idx, i;
@@ -261,8 +261,9 @@ void BKE_mesh_foreach_mapped_face_center(
}
}
else {
const MVert *mvert = mesh->mvert;
const MPoly *mp = mesh->mpoly;
const MVert *mvert = BKE_mesh_vertices(mesh);
const MPoly *mp = BKE_mesh_polygons(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
float _no_buf[3];
float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : NULL;
@@ -275,7 +276,7 @@ void BKE_mesh_foreach_mapped_face_center(
continue;
}
float cent[3];
ml = &mesh->mloop[mp->loopstart];
ml = &loops[mp->loopstart];
BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(mp, ml, mvert, no);
@@ -286,7 +287,7 @@ void BKE_mesh_foreach_mapped_face_center(
else {
for (int i = 0; i < mesh->totpoly; i++, mp++) {
float cent[3];
ml = &mesh->mloop[mp->loopstart];
ml = &loops[mp->loopstart];
BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(mp, ml, mvert, no);
@@ -303,7 +304,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
void *userData,
MeshForeachFlag flag)
{
const MPoly *mp = mesh->mpoly;
const MVert *verts = BKE_mesh_vertices(mesh);
const MPoly *mp = BKE_mesh_polygons(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
const MVert *mv;
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
@@ -319,9 +322,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
if (orig == ORIGINDEX_NONE) {
continue;
}
ml = &mesh->mloop[mp->loopstart];
ml = &loops[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
mv = &mesh->mvert[ml->v];
mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
func(userData,
orig,
@@ -333,9 +336,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
}
else {
for (int i = 0; i < mesh->totpoly; i++, mp++) {
ml = &mesh->mloop[mp->loopstart];
ml = &loops[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
mv = &mesh->mvert[ml->v];
mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
func(userData, i, mv->co, (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : NULL);
}
@@ -23,6 +23,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh_legacy_convert.h"
#include "BKE_multires.h"
@@ -165,9 +166,7 @@ static void convert_mfaces_to_mpolys(ID *id,
MEdge *medge,
MFace *mface,
int *r_totloop,
int *r_totpoly,
MLoop **r_mloop,
MPoly **r_mpoly)
int *r_totpoly)
{
MFace *mf;
MLoop *ml, *mloop;
@@ -185,8 +184,7 @@ static void convert_mfaces_to_mpolys(ID *id,
CustomData_free(pdata, totpoly_i);
totpoly = totface_i;
mpoly = (MPoly *)MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted");
CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, totpoly);
mpoly = (MPoly *)CustomData_add_layer(pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly);
int *material_indices = static_cast<int *>(
CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index"));
if (material_indices == nullptr) {
@@ -203,9 +201,7 @@ static void convert_mfaces_to_mpolys(ID *id,
totloop += mf->v4 ? 4 : 3;
}
mloop = (MLoop *)MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted");
CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop);
mloop = (MLoop *)CustomData_add_layer(ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, totloop);
CustomData_to_bmeshpoly(fdata, ldata, totloop);
@@ -277,12 +273,51 @@ static void convert_mfaces_to_mpolys(ID *id,
*r_totpoly = totpoly;
*r_totloop = totloop;
*r_mpoly = mpoly;
*r_mloop = mloop;
#undef ME_FGON
}
static void mesh_ensure_tessellation_customdata(Mesh *me)
{
if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
/* Pass, otherwise this function clears 'mface' before
* versioning 'mface -> mpoly' code kicks in T30583.
*
* Callers could also check but safer to do here - campbell */
}
else {
const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL);
if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) {
BKE_mesh_tessface_clear(me);
BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface);
/* TODO: add some `--debug-mesh` option. */
if (G.debug & G_DEBUG) {
/* NOTE(campbell): this warning may be un-called for if we are initializing the mesh for
* the first time from #BMesh, rather than giving a warning about this we could be smarter
* and check if there was any data to begin with, for now just print the warning with
* some info to help troubleshoot what's going on. */
printf(
"%s: warning! Tessellation uvs or vcol data got out of sync, "
"had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
"CD_PROP_BYTE_COLOR: "
"%d\n",
__func__,
tottex_tessface,
tottex_original,
totcol_tessface,
totcol_original);
}
}
}
}
void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
{
convert_mfaces_to_mpolys(&mesh->id,
@@ -293,14 +328,12 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
mesh->totface,
mesh->totloop,
mesh->totpoly,
mesh->medge,
mesh->mface,
mesh->edges_for_write().data(),
(MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
&mesh->totloop,
&mesh->totpoly,
&mesh->mloop,
&mesh->mpoly);
&mesh->totpoly);
BKE_mesh_update_customdata_pointers(mesh, true);
mesh_ensure_tessellation_customdata(mesh);
}
/**
@@ -352,16 +385,14 @@ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh)
mesh->totface,
mesh->totloop,
mesh->totpoly,
mesh->medge,
mesh->mface,
mesh->edges_for_write().data(),
(MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
&mesh->totloop,
&mesh->totpoly,
&mesh->mloop,
&mesh->mpoly);
&mesh->totpoly);
CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->ldata);
BKE_mesh_update_customdata_pointers(mesh, true);
mesh_ensure_tessellation_customdata(mesh);
}
/** \} */
@@ -793,12 +824,12 @@ void BKE_mesh_tessface_calc(Mesh *mesh)
mesh->totface = mesh_tessface_calc(&mesh->fdata,
&mesh->ldata,
&mesh->pdata,
mesh->mvert,
BKE_mesh_vertices_for_write(mesh),
mesh->totface,
mesh->totloop,
mesh->totpoly);
BKE_mesh_update_customdata_pointers(mesh, true);
mesh_ensure_tessellation_customdata(mesh);
}
void BKE_mesh_tessface_ensure(struct Mesh *mesh)
@@ -896,7 +927,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
using namespace blender::bke;
const AttributeAccessor attributes = mesh_attributes(*mesh);
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
MutableSpan<MVert> verts = mesh->vertices_for_write();
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
@@ -905,7 +936,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
}
});
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
MutableSpan<MEdge> edges = mesh->edges_for_write();
const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
".hide_edge", ATTR_DOMAIN_EDGE, false);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
@@ -914,7 +945,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
}
});
MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
MutableSpan<MPoly> polys = mesh->polygons_for_write();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
@@ -930,7 +961,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
const Span<MVert> verts(mesh->mvert, mesh->totvert);
const Span<MVert> verts = mesh->vertices();
if (std::any_of(
verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag & ME_HIDE; })) {
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -943,7 +974,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
hide_vert.finish();
}
const Span<MEdge> edges(mesh->medge, mesh->totedge);
const Span<MEdge> edges = mesh->edges();
if (std::any_of(
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) {
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -956,7 +987,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
hide_edge.finish();
}
const Span<MPoly> polys(mesh->mpoly, mesh->totpoly);
const Span<MPoly> polys = mesh->polygons();
if (std::any_of(
polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_HIDE; })) {
SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -980,7 +1011,7 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
const AttributeAccessor attributes = mesh_attributes(*mesh);
MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
MutableSpan<MPoly> polys = mesh->polygons_for_write();
const VArray<int> material_indices = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
@@ -995,7 +1026,7 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
const Span<MPoly> polys(mesh->mpoly, mesh->totpoly);
const Span<MPoly> polys = mesh->polygons();
if (std::any_of(
polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr != 0; })) {
SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_only_span<int>(
+10 -13
View File
@@ -976,13 +976,13 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
return (me->flag & ME_SEAM) != 0;
}
static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
const int UNUSED(totvert),
MEdge *edges,
const MEdge *edges,
const int totedge,
MPoly *polys,
const MPoly *polys,
const int totpoly,
MLoop *loops,
const MLoop *loops,
const int totloop,
const MLoopUV *luvs,
MeshIslandStore *r_island_store)
@@ -1073,16 +1073,13 @@ static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
}
for (p_idx = 0; p_idx < totpoly; p_idx++) {
MPoly *mp;
if (poly_groups[p_idx] != grp_idx) {
continue;
}
mp = &polys[p_idx];
const MPoly *mp = &polys[p_idx];
poly_indices[num_pidx++] = p_idx;
for (l_idx = mp->loopstart, pl_idx = 0; pl_idx < mp->totloop; l_idx++, pl_idx++) {
MLoop *ml = &loops[l_idx];
const MLoop *ml = &loops[l_idx];
loop_indices[num_lidx++] = l_idx;
if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, ml->e) &&
(edge_border_count[ml->e] < 2)) {
@@ -1126,13 +1123,13 @@ static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
return true;
}
bool BKE_mesh_calc_islands_loop_poly_edgeseam(MVert *verts,
bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts,
const int totvert,
MEdge *edges,
const MEdge *edges,
const int totedge,
MPoly *polys,
const MPoly *polys,
const int totpoly,
MLoop *loops,
const MLoop *loops,
const int totloop,
MeshIslandStore *r_island_store)
{
+49 -41
View File
@@ -32,9 +32,9 @@
* and may be called again with direct_reverse=-1 for reverse order.
* \return 1 if polys are identical, 0 if polys are different.
*/
static int cddm_poly_compare(MLoop *mloop_array,
MPoly *mpoly_source,
MPoly *mpoly_target,
static int cddm_poly_compare(const MLoop *mloop_array,
const MPoly *mpoly_source,
const MPoly *mpoly_target,
const int *vtargetmap,
const int direct_reverse)
{
@@ -44,7 +44,7 @@ static int cddm_poly_compare(MLoop *mloop_array,
bool compare_completed = false;
bool same_loops = false;
MLoop *mloop_source, *mloop_target;
const MLoop *mloop_source, *mloop_target;
BLI_assert(ELEM(direct_reverse, 1, -1));
@@ -203,10 +203,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
const int totedge = mesh->totedge;
const int totloop = mesh->totloop;
const int totpoly = mesh->totpoly;
const MVert *src_verts = BKE_mesh_vertices(mesh);
const MEdge *src_edges = BKE_mesh_edges(mesh);
const MPoly *src_polys = BKE_mesh_polygons(mesh);
const MLoop *src_loops = BKE_mesh_loops(mesh);
const int totvert_final = totvert - tot_vtargetmap;
MVert *mv, *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__);
const MVert *mv;
MVert *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__);
int *oldv = MEM_malloc_arrayN(totvert_final, sizeof(*oldv), __func__);
int *newv = MEM_malloc_arrayN(totvert, sizeof(*newv), __func__);
STACK_DECLARE(mvert);
@@ -215,13 +220,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* NOTE: create (totedge + totloop) elements because partially invalid polys due to merge may
* require generating new edges, and while in 99% cases we'll still end with less final edges
* than totedge, cases can be forged that would end requiring more. */
MEdge *med, *medge = MEM_malloc_arrayN((totedge + totloop), sizeof(*medge), __func__);
const MEdge *med;
MEdge *medge = MEM_malloc_arrayN((totedge + totloop), sizeof(*medge), __func__);
int *olde = MEM_malloc_arrayN((totedge + totloop), sizeof(*olde), __func__);
int *newe = MEM_malloc_arrayN((totedge + totloop), sizeof(*newe), __func__);
STACK_DECLARE(medge);
STACK_DECLARE(olde);
MLoop *ml, *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__);
const MLoop *ml;
MLoop *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__);
int *oldl = MEM_malloc_arrayN(totloop, sizeof(*oldl), __func__);
#ifdef USE_LOOPS
int *newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__);
@@ -229,7 +236,8 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
STACK_DECLARE(mloop);
STACK_DECLARE(oldl);
MPoly *mp, *mpoly = MEM_malloc_arrayN(totpoly, sizeof(*medge), __func__);
const MPoly *mp;
MPoly *mpoly = MEM_malloc_arrayN(totpoly, sizeof(*medge), __func__);
int *oldp = MEM_malloc_arrayN(totpoly, sizeof(*oldp), __func__);
STACK_DECLARE(mpoly);
STACK_DECLARE(oldp);
@@ -254,7 +262,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
STACK_INIT(mpoly, totpoly);
/* fill newv with destination vertex indices */
mv = mesh->mvert;
mv = src_verts;
c = 0;
for (i = 0; i < totvert; i++, mv++) {
if (vtargetmap[i] == -1) {
@@ -281,7 +289,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
*/
/* now go through and fix edges and faces */
med = mesh->medge;
med = src_edges;
c = 0;
for (i = 0; i < totedge; i++, med++) {
const uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
@@ -316,12 +324,12 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Duplicates allowed because our compare function is not pure equality */
BLI_gset_flag_set(poly_gset, GHASH_FLAG_ALLOW_DUPES);
mp = mesh->mpoly;
mp = src_polys;
mpgh = poly_keys;
for (i = 0; i < totpoly; i++, mp++, mpgh++) {
mpgh->poly_index = i;
mpgh->totloops = mp->totloop;
ml = mesh->mloop + mp->loopstart;
ml = src_loops + mp->loopstart;
mpgh->hash_sum = mpgh->hash_xor = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
mpgh->hash_sum += ml->v;
@@ -333,17 +341,17 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Can we optimize by reusing an old `pmap`? How do we know an old `pmap` is stale? */
/* When called by `MOD_array.c` the `cddm` has just been created, so it has no valid `pmap`. */
BKE_mesh_vert_poly_map_create(
&poly_map, &poly_map_mem, mesh->mpoly, mesh->mloop, totvert, totpoly, totloop);
&poly_map, &poly_map_mem, src_polys, src_loops, totvert, totpoly, totloop);
} /* done preparing for fast poly compare */
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__);
mp = mesh->mpoly;
mv = mesh->mvert;
mp = src_polys;
mv = src_verts;
for (i = 0; i < totpoly; i++, mp++) {
MPoly *mp_new;
ml = mesh->mloop + mp->loopstart;
ml = src_loops + mp->loopstart;
/* check faces with all vertices merged */
bool all_vertices_merged = true;
@@ -376,7 +384,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Use poly_gset for fast (although not 100% certain) identification of same poly */
/* First, make up a poly_summary structure */
ml = mesh->mloop + mp->loopstart;
ml = src_loops + mp->loopstart;
pkey.hash_sum = pkey.hash_xor = 0;
pkey.totloops = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
@@ -394,17 +402,17 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
*/
/* Consider current loop again */
ml = mesh->mloop + mp->loopstart;
ml = src_loops + mp->loopstart;
/* Consider the target of the loop's first vert */
v_target = vtargetmap[ml->v];
/* Now see if v_target belongs to a poly that shares all vertices with source poly,
* in same order, or reverse order */
for (i_poly = 0; i_poly < poly_map[v_target].count; i_poly++) {
MPoly *target_poly = mesh->mpoly + *(poly_map[v_target].indices + i_poly);
const MPoly *target_poly = src_polys + *(poly_map[v_target].indices + i_poly);
if (cddm_poly_compare(mesh->mloop, mp, target_poly, vtargetmap, +1) ||
cddm_poly_compare(mesh->mloop, mp, target_poly, vtargetmap, -1)) {
if (cddm_poly_compare(src_loops, mp, target_poly, vtargetmap, +1) ||
cddm_poly_compare(src_loops, mp, target_poly, vtargetmap, -1)) {
found = true;
break;
}
@@ -422,7 +430,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
* or they were all merged, but targets do not make up an identical poly,
* the poly is retained.
*/
ml = mesh->mloop + mp->loopstart;
ml = src_loops + mp->loopstart;
c = 0;
MLoop *last_valid_ml = NULL;
@@ -434,9 +442,9 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
const uint mlv = (vtargetmap[ml->v] != -1) ? vtargetmap[ml->v] : ml->v;
#ifndef NDEBUG
{
MLoop *next_ml = mesh->mloop + mp->loopstart + ((j + 1) % mp->totloop);
const MLoop *next_ml = src_loops + mp->loopstart + ((j + 1) % mp->totloop);
uint next_mlv = (vtargetmap[next_ml->v] != -1) ? vtargetmap[next_ml->v] : next_ml->v;
med = mesh->medge + ml->e;
med = src_edges + ml->e;
uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
uint v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
BLI_assert((mlv == v1 && next_mlv == v2) || (mlv == v2 && next_mlv == v1));
@@ -461,7 +469,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
else {
const int new_eidx = STACK_SIZE(medge);
STACK_PUSH(olde, olde[last_valid_ml->e]);
STACK_PUSH(medge, mesh->medge[last_valid_ml->e]);
STACK_PUSH(medge, src_edges[last_valid_ml->e]);
medge[new_eidx].v1 = last_valid_ml->v;
medge[new_eidx].v2 = ml->v;
/* DO NOT change newe mapping,
@@ -515,7 +523,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
else {
const int new_eidx = STACK_SIZE(medge);
STACK_PUSH(olde, olde[last_valid_ml->e]);
STACK_PUSH(medge, mesh->medge[last_valid_ml->e]);
STACK_PUSH(medge, src_edges[last_valid_ml->e]);
medge[new_eidx].v1 = last_valid_ml->v;
medge[new_eidx].v2 = first_valid_ml->v;
/* DO NOT change newe mapping,
@@ -566,25 +574,25 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
mesh, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
/* Update edge indices and copy customdata. */
med = medge;
for (i = 0; i < result->totedge; i++, med++) {
BLI_assert(newv[med->v1] != -1);
med->v1 = newv[med->v1];
BLI_assert(newv[med->v2] != -1);
med->v2 = newv[med->v2];
MEdge *new_med = medge;
for (i = 0; i < result->totedge; i++, new_med++) {
BLI_assert(newv[new_med->v1] != -1);
new_med->v1 = newv[new_med->v1];
BLI_assert(newv[new_med->v2] != -1);
new_med->v2 = newv[new_med->v2];
/* Can happen in case vtargetmap contains some double chains, we do not support that. */
BLI_assert(med->v1 != med->v2);
BLI_assert(new_med->v1 != new_med->v2);
CustomData_copy_data(&mesh->edata, &result->edata, olde[i], i, 1);
}
/* Update loop indices and copy customdata. */
ml = mloop;
for (i = 0; i < result->totloop; i++, ml++) {
MLoop *new_ml = mloop;
for (i = 0; i < result->totloop; i++, new_ml++) {
/* Edge remapping has already be done in main loop handling part above. */
BLI_assert(newv[ml->v] != -1);
ml->v = newv[ml->v];
BLI_assert(newv[new_ml->v] != -1);
new_ml->v = newv[new_ml->v];
CustomData_copy_data(&mesh->ldata, &result->ldata, oldl[i], i, 1);
}
@@ -603,16 +611,16 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Copy over data. #CustomData_add_layer can do this, need to look it up. */
if (STACK_SIZE(mvert)) {
memcpy(result->mvert, mvert, sizeof(MVert) * STACK_SIZE(mvert));
memcpy(BKE_mesh_vertices_for_write(result), mvert, sizeof(MVert) * STACK_SIZE(mvert));
}
if (STACK_SIZE(medge)) {
memcpy(result->medge, medge, sizeof(MEdge) * STACK_SIZE(medge));
memcpy(BKE_mesh_edges_for_write(result), medge, sizeof(MEdge) * STACK_SIZE(medge));
}
if (STACK_SIZE(mloop)) {
memcpy(result->mloop, mloop, sizeof(MLoop) * STACK_SIZE(mloop));
memcpy(BKE_mesh_loops_for_write(result), mloop, sizeof(MLoop) * STACK_SIZE(mloop));
}
if (STACK_SIZE(mpoly)) {
memcpy(result->mpoly, mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
memcpy(BKE_mesh_polygons_for_write(result), mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
}
MEM_freeN(mvert);
@@ -113,8 +113,13 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
int *vert_map_mem;
struct MeshElemMap *vert_to_loop;
BKE_mesh_vert_loop_map_create(
&vert_to_loop, &vert_map_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
BKE_mesh_vert_loop_map_create(&vert_to_loop,
&vert_map_mem,
BKE_mesh_polygons(me),
BKE_mesh_loops(me),
me->totvert,
me->totpoly,
me->totloop);
Vector<MLoopUV *> mloopuv_layers;
mloopuv_layers.reserve(mloopuv_layers_num);
+21 -17
View File
@@ -211,14 +211,18 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* Subsurf for eg won't have mesh data in the custom-data arrays.
* now add mvert/medge/mpoly layers. */
if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert);
memcpy(BKE_mesh_vertices_for_write(result),
BKE_mesh_vertices(mesh),
sizeof(MVert) * mesh->totvert);
}
if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge);
memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge);
}
if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop);
memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly);
memcpy(BKE_mesh_loops_for_write(result), BKE_mesh_loops(mesh), sizeof(MLoop) * mesh->totloop);
memcpy(BKE_mesh_polygons_for_write(result),
BKE_mesh_polygons(mesh),
sizeof(MPoly) * mesh->totpoly);
}
/* Copy custom-data to new geometry,
@@ -237,7 +241,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* mirror vertex coordinates */
mv_prev = result->mvert;
mv_prev = BKE_mesh_vertices_for_write(result);
mv = mv_prev + maxVerts;
for (i = 0; i < maxVerts; i++, mv++, mv_prev++) {
mul_m4_v3(mtx, mv->co);
@@ -304,15 +308,15 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* adjust mirrored edge vertex indices */
me = result->medge + maxEdges;
me = BKE_mesh_edges_for_write(result) + maxEdges;
for (i = 0; i < maxEdges; i++, me++) {
me->v1 += maxVerts;
me->v2 += maxVerts;
}
/* adjust mirrored poly loopstart indices, and reverse loop order (normals) */
mp = result->mpoly + maxPolys;
ml = result->mloop;
mp = BKE_mesh_polygons_for_write(result) + maxPolys;
ml = BKE_mesh_loops_for_write(result);
for (i = 0; i < maxPolys; i++, mp++) {
MLoop *ml2;
int j, e;
@@ -341,7 +345,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* adjust mirrored loop vertex and edge indices */
ml = result->mloop + maxLoops;
ml = BKE_mesh_loops_for_write(result) + maxLoops;
for (i = 0; i < maxLoops; i++, ml++) {
ml->v += maxVerts;
ml->e += maxEdges;
@@ -405,15 +409,15 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* calculate custom normals into loop_normals, then mirror first half into second half */
BKE_mesh_normals_loop_split(result->mvert,
BKE_mesh_normals_loop_split(BKE_mesh_vertices(result),
BKE_mesh_vertex_normals_ensure(result),
result->totvert,
result->medge,
BKE_mesh_edges(result),
result->totedge,
result->mloop,
BKE_mesh_loops(result),
loop_normals,
totloop,
result->mpoly,
BKE_mesh_polygons(result),
BKE_mesh_poly_normals_ensure(result),
totpoly,
true,
@@ -423,9 +427,10 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
NULL);
/* mirroring has to account for loops being reversed in polys in second half */
mp = result->mpoly;
MPoly *result_polys = BKE_mesh_polygons_for_write(result);
mp = result_polys;
for (i = 0; i < maxPolys; i++, mp++) {
MPoly *mpmirror = result->mpoly + maxPolys + i;
MPoly *mpmirror = result_polys + maxPolys + i;
int j;
for (j = mp->loopstart; j < mp->loopstart + mp->totloop; j++) {
@@ -446,8 +451,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* handle vgroup stuff */
if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) {
MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&result->vdata, CD_MDEFORMVERT) +
maxVerts;
MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result) + maxVerts;
int *flip_map = NULL, flip_map_len = 0;
flip_map = BKE_object_defgroup_flip_map(ob, &flip_map_len, false);
@@ -37,6 +37,7 @@
#include "atomic_ops.h"
using blender::MutableSpan;
using blender::Span;
// #define DEBUG_TIME
@@ -368,16 +369,19 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
const Span<MVert> verts = mesh_mutable.vertices();
const Span<MPoly> polys = mesh_mutable.polygons();
const Span<MLoop> loops = mesh_mutable.loops();
vert_normals = BKE_mesh_vertex_normals_for_write(&mesh_mutable);
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_calc_normals_poly_and_vertex(mesh_mutable.mvert,
mesh_mutable.totvert,
mesh_mutable.mloop,
mesh_mutable.totloop,
mesh_mutable.mpoly,
mesh_mutable.totpoly,
BKE_mesh_calc_normals_poly_and_vertex(verts.data(),
verts.size(),
loops.data(),
loops.size(),
polys.data(),
polys.size(),
poly_normals,
vert_normals);
@@ -413,15 +417,18 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
const Span<MVert> verts = mesh_mutable.vertices();
const Span<MPoly> polys = mesh_mutable.polygons();
const Span<MLoop> loops = mesh_mutable.loops();
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_calc_normals_poly(mesh_mutable.mvert,
mesh_mutable.totvert,
mesh_mutable.mloop,
mesh_mutable.totloop,
mesh_mutable.mpoly,
mesh_mutable.totpoly,
BKE_mesh_calc_normals_poly(verts.data(),
verts.size(),
loops.data(),
loops.size(),
polys.data(),
polys.size(),
poly_normals);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
@@ -940,9 +947,9 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
const int UNUSED(numVerts),
struct MEdge *medges,
const int numEdges,
struct MLoop *mloops,
const struct MLoop *mloops,
const int numLoops,
struct MPoly *mpolys,
const struct MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
const float split_angle)
@@ -1600,12 +1607,12 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
void BKE_mesh_normals_loop_split(const MVert *mverts,
const float (*vert_normals)[3],
const int UNUSED(numVerts),
MEdge *medges,
const MEdge *medges,
const int numEdges,
MLoop *mloops,
const MLoop *mloops,
float (*r_loopnors)[3],
const int numLoops,
MPoly *mpolys,
const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
const bool use_split_normals,
@@ -1628,7 +1635,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
int mp_index;
for (mp_index = 0; mp_index < numPolys; mp_index++) {
MPoly *mp = &mpolys[mp_index];
const MPoly *mp = &mpolys[mp_index];
int ml_index = mp->loopstart;
const int ml_index_end = ml_index + mp->totloop;
const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
@@ -1755,10 +1762,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
const int numVerts,
MEdge *medges,
const int numEdges,
MLoop *mloops,
const MLoop *mloops,
float (*r_custom_loopnors)[3],
const int numLoops,
MPoly *mpolys,
const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
short (*r_clnors_data)[2],
@@ -1852,12 +1859,12 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
}
LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
MLoop *prev_ml = nullptr;
const MLoop *prev_ml = nullptr;
const float *org_nor = nullptr;
while (loops) {
const int lidx = POINTER_AS_INT(loops->link);
MLoop *ml = &mloops[lidx];
const MLoop *ml = &mloops[lidx];
const int nidx = lidx;
float *nor = r_custom_loopnors[nidx];
@@ -1889,7 +1896,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
loops = lnors_spacearr.lspacearr[i]->loops;
if (loops && org_nor) {
const int lidx = POINTER_AS_INT(loops->link);
MLoop *ml = &mloops[lidx];
const MLoop *ml = &mloops[lidx];
const int nidx = lidx;
float *nor = r_custom_loopnors[nidx];
@@ -1992,10 +1999,10 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
const int numVerts,
MEdge *medges,
const int numEdges,
MLoop *mloops,
const MLoop *mloops,
float (*r_custom_loopnors)[3],
const int numLoops,
MPoly *mpolys,
const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
short (*r_clnors_data)[2])
@@ -2021,9 +2028,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(const MVert *mverts,
const int numVerts,
MEdge *medges,
const int numEdges,
MLoop *mloops,
const MLoop *mloops,
const int numLoops,
MPoly *mpolys,
const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
short (*r_clnors_data)[2])
@@ -2056,18 +2063,22 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
clnors = (short(*)[2])CustomData_add_layer(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, numloops);
}
const Span<MVert> verts = mesh->vertices();
MutableSpan<MEdge> edges = mesh->edges_for_write();
const Span<MPoly> polys = mesh->polygons();
const Span<MLoop> loops = mesh->loops();
mesh_normals_loop_custom_set(mesh->mvert,
mesh_normals_loop_custom_set(verts.data(),
BKE_mesh_vertex_normals_ensure(mesh),
mesh->totvert,
mesh->medge,
mesh->totedge,
mesh->mloop,
verts.size(),
edges.data(),
edges.size(),
loops.data(),
r_custom_nors,
mesh->totloop,
mesh->mpoly,
loops.size(),
polys.data(),
BKE_mesh_poly_normals_ensure(mesh),
mesh->totpoly,
polys.size(),
clnors,
use_vertices);
}
+45 -43
View File
@@ -377,7 +377,7 @@ void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index)
}
static int mesh_remap_interp_poly_data_get(const MPoly *mp,
MLoop *mloops,
const MLoop *mloops,
const float (*vcos_src)[3],
const float point[3],
size_t *buff_size,
@@ -388,7 +388,7 @@ static int mesh_remap_interp_poly_data_get(const MPoly *mp,
const bool do_weights,
int *r_closest_index)
{
MLoop *ml;
const MLoop *ml;
float(*vco)[3];
float ref_dist_sq = FLT_MAX;
int *index;
@@ -520,7 +520,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
}
}
else if (ELEM(mode, MREMAP_MODE_VERT_EDGE_NEAREST, MREMAP_MODE_VERT_EDGEINTERP_NEAREST)) {
MEdge *edges_src = me_src->medge;
const MEdge *edges_src = BKE_mesh_edges(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2);
@@ -536,7 +536,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
MEdge *me = &edges_src[nearest.index];
const MEdge *me = &edges_src[nearest.index];
const float *v1cos = vcos_src[me->v1];
const float *v2cos = vcos_src[me->v2];
@@ -573,8 +573,8 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
MREMAP_MODE_VERT_POLY_NEAREST,
MREMAP_MODE_VERT_POLYINTERP_NEAREST,
MREMAP_MODE_VERT_POLYINTERP_VNORPROJ)) {
MPoly *polys_src = me_src->mpoly;
MLoop *loops_src = me_src->mloop;
const MPoly *polys_src = BKE_mesh_polygons(me_src);
const MLoop *loops_src = BKE_mesh_loops(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst);
@@ -599,7 +599,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_raycast(
&treedata, &rayhit, tmp_co, tmp_no, ray_radius, max_dist, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[rayhit.index];
MPoly *mp_src = &polys_src[lt->poly];
const MPoly *mp_src = &polys_src[lt->poly];
const int sources_num = mesh_remap_interp_poly_data_get(mp_src,
loops_src,
(const float(*)[3])vcos_src,
@@ -634,7 +634,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[nearest.index];
MPoly *mp = &polys_src[lt->poly];
const MPoly *mp = &polys_src[lt->poly];
if (mode == MREMAP_MODE_VERT_POLY_NEAREST) {
int index;
@@ -726,7 +726,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
if (mode == MREMAP_MODE_EDGE_VERT_NEAREST) {
const int num_verts_src = me_src->totvert;
const int num_edges_src = me_src->totedge;
MEdge *edges_src = me_src->medge;
const MEdge *edges_src = BKE_mesh_edges(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
MeshElemMap *vert_to_edge_src_map;
@@ -797,7 +797,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
k = vert_to_edge_src_map[vidx_src].count;
for (; k--; eidx_src++) {
MEdge *e_src = &edges_src[*eidx_src];
const MEdge *e_src = &edges_src[*eidx_src];
const float *other_co_src = vcos_src[BKE_mesh_edge_other_vert(e_src, vidx_src)];
const float *other_co_dst =
verts_dst[BKE_mesh_edge_other_vert(e_dst, (int)vidx_dst)].co;
@@ -873,9 +873,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
}
}
else if (mode == MREMAP_MODE_EDGE_POLY_NEAREST) {
MEdge *edges_src = me_src->medge;
MPoly *polys_src = me_src->mpoly;
MLoop *loops_src = me_src->mloop;
const MEdge *edges_src = BKE_mesh_edges(me_src);
const MPoly *polys_src = BKE_mesh_polygons(me_src);
const MLoop *loops_src = BKE_mesh_loops(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_LOOPTRI, 2);
@@ -891,14 +891,14 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[nearest.index];
MPoly *mp_src = &polys_src[lt->poly];
MLoop *ml_src = &loops_src[mp_src->loopstart];
const MPoly *mp_src = &polys_src[lt->poly];
const MLoop *ml_src = &loops_src[mp_src->loopstart];
int nloops = mp_src->totloop;
float best_dist_sq = FLT_MAX;
int best_eidx_src = -1;
for (; nloops--; ml_src++) {
MEdge *med_src = &edges_src[ml_src->e];
const MEdge *med_src = &edges_src[ml_src->e];
float *co1_src = vcos_src[med_src->v1];
float *co2_src = vcos_src[med_src->v2];
float co_src[3];
@@ -1041,9 +1041,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
const int island_index,
BLI_AStarGraph *as_graph,
MVert *verts,
MPoly *polys,
MLoop *loops,
const MVert *verts,
const MPoly *polys,
const MLoop *loops,
const int edge_idx,
BLI_bitmap *done_edges,
MeshElemMap *edge_to_poly_map,
@@ -1058,7 +1058,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
for (i = 0; i < edge_to_poly_map[edge_idx].count; i++) {
const int pidx = edge_to_poly_map[edge_idx].indices[i];
MPoly *mp = &polys[pidx];
const MPoly *mp = &polys[pidx];
const int pidx_isld = islands ? poly_island_index_map[pidx] : pidx;
void *custom_data = is_edge_innercut ? POINTER_FROM_INT(edge_idx) : POINTER_FROM_INT(-1);
@@ -1099,11 +1099,11 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
static void mesh_island_to_astar_graph(MeshIslandStore *islands,
const int island_index,
MVert *verts,
const MVert *verts,
MeshElemMap *edge_to_poly_map,
const int numedges,
MLoop *loops,
MPoly *polys,
const MLoop *loops,
const MPoly *polys,
const int numpolys,
BLI_AStarGraph *r_as_graph)
{
@@ -1153,7 +1153,7 @@ 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;
MPoly *mp = &polys[pidx];
const MPoly *mp = &polys[pidx];
int pl_idx, l_idx;
if (poly_status[pidx_isld] == POLY_COMPLETE) {
@@ -1161,7 +1161,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
}
for (pl_idx = 0, l_idx = mp->loopstart; pl_idx < mp->totloop; pl_idx++, l_idx++) {
MLoop *ml = &loops[l_idx];
const MLoop *ml = &loops[l_idx];
if (BLI_BITMAP_TEST(done_edges, ml->e)) {
continue;
@@ -1229,13 +1229,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const float max_dist,
const float ray_radius,
Mesh *mesh_dst,
MVert *verts_dst,
const MVert *verts_dst,
const int numverts_dst,
MEdge *edges_dst,
const MEdge *edges_dst,
const int numedges_dst,
MLoop *loops_dst,
const MLoop *loops_dst,
const int numloops_dst,
MPoly *polys_dst,
const MPoly *polys_dst,
const int numpolys_dst,
CustomData *ldata_dst,
const bool use_split_nors_dst,
@@ -1302,14 +1302,14 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
/* Unlike above, those are one-to-one mappings, simpler! */
int *loop_to_poly_map_src = NULL;
MVert *verts_src = me_src->mvert;
const MVert *verts_src = BKE_mesh_vertices(me_src);
const int num_verts_src = me_src->totvert;
float(*vcos_src)[3] = NULL;
MEdge *edges_src = me_src->medge;
const MEdge *edges_src = BKE_mesh_edges(me_src);
const int num_edges_src = me_src->totedge;
MLoop *loops_src = me_src->mloop;
const MLoop *loops_src = BKE_mesh_loops(me_src);
const int num_loops_src = me_src->totloop;
MPoly *polys_src = me_src->mpoly;
const MPoly *polys_src = BKE_mesh_polygons(me_src);
const int num_polys_src = me_src->totpoly;
const MLoopTri *looptri_src = NULL;
int num_looptri_src = 0;
@@ -1319,8 +1319,10 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int *indices_interp = NULL;
float *weights_interp = NULL;
MLoop *ml_src, *ml_dst;
MPoly *mp_src, *mp_dst;
const MLoop *ml_src;
const MLoop *ml_dst;
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;
@@ -2148,10 +2150,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const SpaceTransform *space_transform,
const float max_dist,
const float ray_radius,
Mesh *mesh_dst,
MVert *verts_dst,
MLoop *loops_dst,
MPoly *polys_dst,
const Mesh *mesh_dst,
const MVert *verts_dst,
const MLoop *loops_dst,
const MPoly *polys_dst,
const int numpolys_dst,
Mesh *me_src,
MeshPairRemap *r_map)
@@ -2188,7 +2190,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
nearest.index = -1;
for (i = 0; i < numpolys_dst; i++) {
MPoly *mp = &polys_dst[i];
const MPoly *mp = &polys_dst[i];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
@@ -2213,7 +2215,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
BLI_assert(poly_nors_dst);
for (i = 0; i < numpolys_dst; i++) {
MPoly *mp = &polys_dst[i];
const MPoly *mp = &polys_dst[i];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
@@ -2259,7 +2261,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! */
MPoly *mp = &polys_dst[i];
const MPoly *mp = &polys_dst[i];
int tot_rays, done_rays = 0;
float poly_area_2d_inv, done_area = 0.0f;
@@ -2302,7 +2304,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
INIT_MINMAX2(poly_dst_2d_min, poly_dst_2d_max);
for (j = 0; j < mp->totloop; j++) {
MLoop *ml = &loops_dst[j + mp->loopstart];
const MLoop *ml = &loops_dst[j + mp->loopstart];
copy_v3_v3(tmp_co, verts_dst[ml->v].co);
if (space_transform) {
BLI_space_transform_apply(space_transform, tmp_co);
@@ -61,14 +61,15 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
void (*update_cb)(void *, float progress, int *cancel),
void *update_cb_data)
{
/* Ensure that the triangulated mesh data is up to data */
const Span<MVert> input_verts = input_mesh->vertices();
const Span<MLoop> input_loops = input_mesh->loops();
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
/* Gather the required data for export to the internal quadriflow mesh format. */
MVertTri *verttri = (MVertTri *)MEM_callocN(
sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh), "remesh_looptri");
BKE_mesh_runtime_verttri_from_looptri(
verttri, input_mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(input_mesh));
verttri, input_loops.data(), looptri, BKE_mesh_runtime_looptri_len(input_mesh));
const int totfaces = BKE_mesh_runtime_looptri_len(input_mesh);
const int totverts = input_mesh->totvert;
@@ -76,7 +77,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
Array<int> faces(totfaces * 3);
for (const int i : IndexRange(totverts)) {
verts[i] = input_mesh->mvert[i].co;
verts[i] = input_verts[i].co;
}
for (const int i : IndexRange(totfaces)) {
@@ -123,20 +124,23 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
/* Construct the new output mesh */
Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, 0, qrd.out_totfaces * 4, qrd.out_totfaces);
MutableSpan<MVert> mesh_verts = mesh->vertices_for_write();
MutableSpan<MPoly> polys = mesh->polygons_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
for (const int i : IndexRange(qrd.out_totverts)) {
copy_v3_v3(mesh->mvert[i].co, &qrd.out_verts[i * 3]);
copy_v3_v3(mesh_verts[i].co, &qrd.out_verts[i * 3]);
}
for (const int i : IndexRange(qrd.out_totfaces)) {
MPoly &poly = mesh->mpoly[i];
MPoly &poly = polys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
mesh->mloop[loopstart].v = qrd.out_faces[loopstart];
mesh->mloop[loopstart + 1].v = qrd.out_faces[loopstart + 1];
mesh->mloop[loopstart + 2].v = qrd.out_faces[loopstart + 2];
mesh->mloop[loopstart + 3].v = qrd.out_faces[loopstart + 3];
loops[loopstart].v = qrd.out_faces[loopstart];
loops[loopstart + 1].v = qrd.out_faces[loopstart + 1];
loops[loopstart + 2].v = qrd.out_faces[loopstart + 2];
loops[loopstart + 3].v = qrd.out_faces[loopstart + 3];
}
BKE_mesh_calc_edges(mesh, false, false);
@@ -186,7 +190,8 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh,
static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
const float voxel_size)
{
Span<MLoop> mloop{mesh->mloop, mesh->totloop};
const Span<MVert> verts = mesh->vertices();
const Span<MLoop> loops = mesh->loops();
Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh),
BKE_mesh_runtime_looptri_len(mesh)};
@@ -194,14 +199,14 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
std::vector<openvdb::Vec3I> triangles(looptris.size());
for (const int i : IndexRange(mesh->totvert)) {
const float3 co = mesh->mvert[i].co;
const float3 co = verts[i].co;
points[i] = openvdb::Vec3s(co.x, co.y, co.z);
}
for (const int i : IndexRange(looptris.size())) {
const MLoopTri &loop_tri = looptris[i];
triangles[i] = openvdb::Vec3I(
mloop[loop_tri.tri[0]].v, mloop[loop_tri.tri[1]].v, mloop[loop_tri.tri[2]].v);
loops[loop_tri.tri[0]].v, loops[loop_tri.tri[1]].v, loops[loop_tri.tri[2]].v);
}
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
@@ -225,34 +230,34 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set
Mesh *mesh = BKE_mesh_new_nomain(
vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size());
MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert};
MutableSpan<MLoop> mloops{mesh->mloop, mesh->totloop};
MutableSpan<MPoly> mpolys{mesh->mpoly, mesh->totpoly};
MutableSpan<MVert> mesh_verts = mesh->vertices_for_write();
MutableSpan<MPoly> mesh_polys = mesh->polygons_for_write();
MutableSpan<MLoop> mesh_loops = mesh->loops_for_write();
for (const int i : mverts.index_range()) {
copy_v3_v3(mverts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z()));
for (const int i : mesh_verts.index_range()) {
copy_v3_v3(mesh_verts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z()));
}
for (const int i : IndexRange(quads.size())) {
MPoly &poly = mpolys[i];
MPoly &poly = mesh_polys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
mloops[loopstart].v = quads[i][0];
mloops[loopstart + 1].v = quads[i][3];
mloops[loopstart + 2].v = quads[i][2];
mloops[loopstart + 3].v = quads[i][1];
mesh_loops[loopstart].v = quads[i][0];
mesh_loops[loopstart + 1].v = quads[i][3];
mesh_loops[loopstart + 2].v = quads[i][2];
mesh_loops[loopstart + 3].v = quads[i][1];
}
const int triangle_loop_start = quads.size() * 4;
for (const int i : IndexRange(tris.size())) {
MPoly &poly = mpolys[quads.size() + i];
MPoly &poly = mesh_polys[quads.size() + i];
const int loopstart = triangle_loop_start + i * 3;
poly.loopstart = loopstart;
poly.totloop = 3;
mloops[loopstart].v = tris[i][2];
mloops[loopstart + 1].v = tris[i][1];
mloops[loopstart + 2].v = tris[i][0];
mesh_loops[loopstart].v = tris[i][2];
mesh_loops[loopstart + 1].v = tris[i][1];
mesh_loops[loopstart + 2].v = tris[i][0];
}
BKE_mesh_calc_edges(mesh, false, false);
@@ -23,6 +23,9 @@
#include "BKE_shrinkwrap.h"
#include "BKE_subdiv_ccg.h"
using blender::MutableSpan;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Mesh Runtime Struct Utils
* \{ */
@@ -147,10 +150,13 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
{
mesh_ensure_looptri_data(mesh);
BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != nullptr);
const Span<MVert> verts = mesh->vertices();
const Span<MPoly> polys = mesh->polygons();
const Span<MLoop> loops = mesh->loops();
BKE_mesh_recalc_looptri(mesh->mloop,
mesh->mpoly,
mesh->mvert,
BKE_mesh_recalc_looptri(loops.data(),
polys.data(),
verts.data(),
mesh->totloop,
mesh->totpoly,
mesh->runtime.looptris.array_wip);
@@ -272,7 +278,7 @@ void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh)
const bool poly_normals_were_dirty = BKE_mesh_poly_normals_are_dirty(mesh);
BKE_mesh_tag_coords_changed(mesh);
/* The normals didn't change, since all vertices moved by the same amount. */
/* The normals didn't change, since all verts moved by the same amount. */
if (!vert_normals_were_dirty) {
BKE_mesh_poly_normals_clear_dirty(mesh);
}
@@ -324,6 +330,11 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
printf("MESH: %s\n", me_eval->id.name + 2);
}
MutableSpan<MVert> verts = me_eval->vertices_for_write();
MutableSpan<MEdge> edges = me_eval->edges_for_write();
MutableSpan<MPoly> polys = me_eval->polygons_for_write();
MutableSpan<MLoop> loops = me_eval->loops_for_write();
is_valid &= BKE_mesh_validate_all_customdata(
&me_eval->vdata,
me_eval->totvert,
@@ -338,21 +349,22 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
do_fixes,
&changed);
is_valid &= BKE_mesh_validate_arrays(me_eval,
me_eval->mvert,
me_eval->totvert,
me_eval->medge,
me_eval->totedge,
me_eval->mface,
me_eval->totface,
me_eval->mloop,
me_eval->totloop,
me_eval->mpoly,
me_eval->totpoly,
me_eval->dvert,
do_verbose,
do_fixes,
&changed);
is_valid &= BKE_mesh_validate_arrays(
me_eval,
verts.data(),
verts.size(),
edges.data(),
edges.size(),
static_cast<MFace *>(CustomData_get_layer(&me_eval->fdata, CD_MFACE)),
me_eval->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me_eval->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
BLI_assert(changed == false);
+35 -23
View File
@@ -2,6 +2,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_sample.hh"
@@ -20,6 +21,7 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const IndexMask mask,
const MutableSpan<T> dst)
{
const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -28,9 +30,9 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const MLoopTri &looptri = looptris[looptri_index];
const float3 &bary_coord = bary_coords[i];
const int v0_index = mesh.mloop[looptri.tri[0]].v;
const int v1_index = mesh.mloop[looptri.tri[1]].v;
const int v2_index = mesh.mloop[looptri.tri[2]].v;
const int v0_index = loops[looptri.tri[0]].v;
const int v1_index = loops[looptri.tri[1]].v;
const int v2_index = loops[looptri.tri[2]].v;
const T v0 = src[v0_index];
const T v1 = src[v1_index];
@@ -157,6 +159,8 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
}
bary_coords_.reinitialize(mask_.min_array_size());
const Span<MVert> verts = mesh_->vertices();
const Span<MLoop> loops = mesh_->loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
BKE_mesh_runtime_looptri_len(mesh_)};
@@ -164,14 +168,14 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
const int looptri_index = looptri_indices_[i];
const MLoopTri &looptri = looptris[looptri_index];
const int v0_index = mesh_->mloop[looptri.tri[0]].v;
const int v1_index = mesh_->mloop[looptri.tri[1]].v;
const int v2_index = mesh_->mloop[looptri.tri[2]].v;
const int v0_index = loops[looptri.tri[0]].v;
const int v1_index = loops[looptri.tri[1]].v;
const int v2_index = loops[looptri.tri[2]].v;
interp_weights_tri_v3(bary_coords_[i],
mesh_->mvert[v0_index].co,
mesh_->mvert[v1_index].co,
mesh_->mvert[v2_index].co,
verts[v0_index].co,
verts[v1_index].co,
verts[v2_index].co,
positions_[i]);
}
return bary_coords_;
@@ -185,6 +189,8 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
}
nearest_weights_.reinitialize(mask_.min_array_size());
const Span<MVert> verts = mesh_->vertices();
const Span<MLoop> loops = mesh_->loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
BKE_mesh_runtime_looptri_len(mesh_)};
@@ -192,13 +198,13 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
const int looptri_index = looptri_indices_[i];
const MLoopTri &looptri = looptris[looptri_index];
const int v0_index = mesh_->mloop[looptri.tri[0]].v;
const int v1_index = mesh_->mloop[looptri.tri[1]].v;
const int v2_index = mesh_->mloop[looptri.tri[2]].v;
const int v0_index = loops[looptri.tri[0]].v;
const int v1_index = loops[looptri.tri[1]].v;
const int v2_index = loops[looptri.tri[2]].v;
const float d0 = len_squared_v3v3(positions_[i], mesh_->mvert[v0_index].co);
const float d1 = len_squared_v3v3(positions_[i], mesh_->mvert[v1_index].co);
const float d2 = len_squared_v3v3(positions_[i], mesh_->mvert[v2_index].co);
const float d0 = len_squared_v3v3(positions_[i], verts[v0_index].co);
const float d1 = len_squared_v3v3(positions_[i], verts[v1_index].co);
const float d2 = len_squared_v3v3(positions_[i], verts[v2_index].co);
nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
}
@@ -257,6 +263,8 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng,
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions)
{
const Span<MVert> verts = mesh.vertices();
const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -270,9 +278,9 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng,
for (const int looptri_index : looptri_indices_to_sample) {
const MLoopTri &looptri = looptris[looptri_index];
const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
const float3 &v0 = verts[loops[looptri.tri[0]].v].co;
const float3 &v1 = verts[loops[looptri.tri[1]].v].co;
const float3 &v2 = verts[loops[looptri.tri[2]].v].co;
const float looptri_area = area_tri_v3(v0, v1, v2);
@@ -353,6 +361,8 @@ int sample_surface_points_projected(
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions)
{
const Span<MVert> verts = mesh.vertices();
const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -394,7 +404,8 @@ int sample_surface_points_projected(
const int looptri_index = ray_hit.index;
const float3 pos = ray_hit.co;
const float3 bary_coords = compute_bary_coord_in_triangle(mesh, looptris[looptri_index], pos);
const float3 bary_coords = compute_bary_coord_in_triangle(
verts, loops, looptris[looptri_index], pos);
r_positions.append(pos);
r_bary_coords.append(bary_coords);
@@ -404,13 +415,14 @@ int sample_surface_points_projected(
return point_count;
}
float3 compute_bary_coord_in_triangle(const Mesh &mesh,
float3 compute_bary_coord_in_triangle(const Span<MVert> verts,
const Span<MLoop> loops,
const MLoopTri &looptri,
const float3 &position)
{
const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
const float3 &v0 = verts[loops[looptri.tri[0]].v].co;
const float3 &v1 = verts[loops[looptri.tri[1]].v].co;
const float3 &v2 = verts[loops[looptri.tri[2]].v].co;
float3 bary_coords;
interp_weights_tri_v3(bary_coords, v0, v1, v2, position);
return bary_coords;
@@ -179,14 +179,14 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
return;
}
BKE_mesh_calc_loop_tangent_single_ex(mesh->mvert,
BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_vertices(mesh),
mesh->totvert,
mesh->mloop,
BKE_mesh_loops(mesh),
r_looptangents,
loopnors,
loopuvs,
mesh->totloop,
mesh->mpoly,
BKE_mesh_polygons(mesh),
mesh->totpoly,
reports);
}
@@ -719,10 +719,10 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
/* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */
short tangent_mask = 0;
BKE_mesh_calc_loop_tangent_ex(me_eval->mvert,
me_eval->mpoly,
BKE_mesh_calc_loop_tangent_ex(BKE_mesh_vertices(me_eval),
BKE_mesh_polygons(me_eval),
(uint)me_eval->totpoly,
me_eval->mloop,
BKE_mesh_loops(me_eval),
me_eval->runtime.looptris.array,
(uint)me_eval->runtime.looptris.len,
&me_eval->ldata,
@@ -33,6 +33,9 @@
#include "MEM_guardedalloc.h"
using blender::MutableSpan;
using blender::Span;
/* loop v/e are unsigned, so using max uint_32 value as invalid marker... */
#define INVALID_LOOP_EDGE_MARKER 4294967295u
@@ -1064,19 +1067,23 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
do_verbose,
true,
&changed);
MutableSpan<MVert> verts = me->vertices_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polygons_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
BKE_mesh_validate_arrays(me,
me->mvert,
me->totvert,
me->medge,
me->totedge,
me->mface,
verts.data(),
verts.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
me->mloop,
me->totloop,
me->mpoly,
me->totpoly,
me->dvert,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
do_verbose,
true,
&changed);
@@ -1113,18 +1120,23 @@ bool BKE_mesh_is_valid(Mesh *me)
do_fixes,
&changed);
MutableSpan<MVert> verts = me->vertices_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polygons_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
is_valid &= BKE_mesh_validate_arrays(me,
me->mvert,
me->totvert,
me->medge,
me->totedge,
me->mface,
verts.data(),
verts.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
me->mloop,
me->totloop,
me->mpoly,
me->totpoly,
me->dvert,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
@@ -1170,11 +1182,12 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
/* NOTE: We need to keep this for edge creation (for now?), and some old `readfile.c` code. */
MFace *f;
int a, b;
MFace *mfaces = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
for (a = b = 0, f = me->mface; a < me->totface; a++, f++) {
for (a = b = 0, f = mfaces; a < me->totface; a++, f++) {
if (f->v3) {
if (a != b) {
memcpy(&me->mface[b], f, sizeof(me->mface[b]));
memcpy(&mfaces[b], f, sizeof(mfaces[b]));
CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1);
}
b++;
@@ -1188,13 +1201,16 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
void BKE_mesh_strip_loose_polysloops(Mesh *me)
{
MutableSpan<MPoly> polys = me->polygons_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
MPoly *p;
MLoop *l;
int a, b;
/* New loops idx! */
int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__);
for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
for (a = b = 0, p = polys.data(); a < me->totpoly; a++, p++) {
bool invalid = false;
int i = p->loopstart;
int stop = i + p->totloop;
@@ -1203,7 +1219,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
invalid = true;
}
else {
l = &me->mloop[i];
l = &loops[i];
i = stop - i;
/* If one of the poly's loops is invalid, the whole poly is invalid! */
for (; i--; l++) {
@@ -1216,7 +1232,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
if (p->totloop >= 3 && !invalid) {
if (a != b) {
memcpy(&me->mpoly[b], p, sizeof(me->mpoly[b]));
memcpy(&polys[b], p, sizeof(polys[b]));
CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
}
b++;
@@ -1228,10 +1244,10 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
}
/* And now, get rid of invalid loops. */
for (a = b = 0, l = me->mloop; a < me->totloop; a++, l++) {
for (a = b = 0, l = loops.data(); a < me->totloop; a++, l++) {
if (l->e != INVALID_LOOP_EDGE_MARKER) {
if (a != b) {
memcpy(&me->mloop[b], l, sizeof(me->mloop[b]));
memcpy(&loops[b], l, sizeof(loops[b]));
CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1);
}
new_idx[a] = b;
@@ -1250,8 +1266,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 (a = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
p->loopstart = new_idx[p->loopstart];
for (const int i : polys.index_range()) {
polys[i].loopstart = new_idx[polys[i].loopstart];
}
MEM_freeN(new_idx);
@@ -1260,14 +1276,14 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
void BKE_mesh_strip_loose_edges(Mesh *me)
{
MEdge *e;
MLoop *l;
int a, b;
uint *new_idx = (uint *)MEM_mallocN(sizeof(int) * me->totedge, __func__);
MutableSpan<MEdge> edges = me->edges_for_write();
for (a = b = 0, e = me->medge; a < me->totedge; a++, e++) {
for (a = b = 0, e = edges.data(); a < me->totedge; a++, e++) {
if (e->v1 != e->v2) {
if (a != b) {
memcpy(&me->medge[b], e, sizeof(me->medge[b]));
memcpy(&edges[b], e, sizeof(edges[b]));
CustomData_copy_data(&me->edata, &me->edata, a, b, 1);
}
new_idx[a] = b;
@@ -1285,8 +1301,9 @@ void BKE_mesh_strip_loose_edges(Mesh *me)
/* And now, update loops' edge indices. */
/* XXX We hope no loop was pointing to a striped edge!
* Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */
for (a = 0, l = me->mloop; a < me->totloop; a++, l++) {
l->e = new_idx[l->e];
MutableSpan<MLoop> loops = me->loops_for_write();
for (MLoop &loop : loops) {
loop.e = new_idx[loop.e];
}
MEM_freeN(new_idx);
@@ -1344,10 +1361,10 @@ static int vergedgesort(const void *v1, const void *v2)
/* Create edges based on known verts and faces,
* this function is only used when loading very old blend files */
static void mesh_calc_edges_mdata(MVert *UNUSED(allvert),
MFace *allface,
static void mesh_calc_edges_mdata(const MVert *UNUSED(allvert),
const MFace *allface,
MLoop *allloop,
MPoly *allpoly,
const MPoly *allpoly,
int UNUSED(totvert),
int totface,
int UNUSED(totloop),
@@ -1356,8 +1373,8 @@ static void mesh_calc_edges_mdata(MVert *UNUSED(allvert),
MEdge **r_medge,
int *r_totedge)
{
MPoly *mpoly;
MFace *mface;
const MPoly *mpoly;
const MFace *mface;
MEdge *medge, *med;
EdgeHash *hash;
struct EdgeSort *edsort, *ed;
@@ -1480,28 +1497,29 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
{
MEdge *medge;
int totedge = 0;
const Span<MVert> verts = me->vertices();
const Span<MPoly> polys = me->polygons();
MutableSpan<MLoop> loops = me->loops_for_write();
mesh_calc_edges_mdata(me->mvert,
me->mface,
me->mloop,
me->mpoly,
me->totvert,
mesh_calc_edges_mdata(verts.data(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
loops.data(),
polys.data(),
verts.size(),
me->totface,
me->totloop,
me->totpoly,
loops.size(),
polys.size(),
use_old,
&medge,
&totedge);
if (totedge == 0) {
/* flag that mesh has edges */
me->medge = medge;
me->totedge = 0;
return;
}
medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
me->medge = medge;
me->totedge = totedge;
BKE_mesh_strip_loose_faces(me);
@@ -1509,18 +1527,18 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
void BKE_mesh_calc_edges_loose(Mesh *mesh)
{
MEdge *med = mesh->medge;
for (int i = 0; i < mesh->totedge; i++, med++) {
med->flag |= ME_LOOSEEDGE;
const Span<MLoop> loops = mesh->loops();
MutableSpan<MEdge> edges = mesh->edges_for_write();
for (const int i : edges.index_range()) {
edges[i].flag |= ME_LOOSEEDGE;
}
MLoop *ml = mesh->mloop;
for (int i = 0; i < mesh->totloop; i++, ml++) {
mesh->medge[ml->e].flag &= ~ME_LOOSEEDGE;
for (const int i : loops.index_range()) {
edges[loops[i].e].flag &= ~ME_LOOSEEDGE;
}
med = mesh->medge;
for (int i = 0; i < mesh->totedge; i++, med++) {
if (med->flag & ME_LOOSEEDGE) {
med->flag |= ME_EDGEDRAW;
for (const int i : edges.index_range()) {
if (edges[i].flag & ME_LOOSEEDGE) {
edges[i].flag |= ME_EDGEDRAW;
}
}
}
@@ -1529,8 +1547,9 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
{
const int numFaces = mesh->totface;
EdgeSet *eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces));
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mf = mesh->mface;
MFace *mf = mfaces;
for (int i = 0; i < numFaces; i++, mf++) {
BLI_edgeset_add(eh, mf->v1, mf->v2);
BLI_edgeset_add(eh, mf->v2, mf->v3);
@@ -1570,8 +1589,6 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
mesh->edata = edgeData;
mesh->totedge = numEdges;
mesh->medge = (MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE);
BLI_edgeset_free(eh);
}
@@ -46,6 +46,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
using blender::Span;
Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
const CustomData_MeshMasks *cd_mask_extra,
const float (*vert_coords)[3],
@@ -195,9 +197,9 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me,
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD: {
BLI_assert(vert_coords_len <= me->totvert);
const MVert *mvert = me->mvert;
const Span<MVert> verts = me->vertices();
for (int i = 0; i < vert_coords_len; i++) {
copy_v3_v3(vert_coords[i], mvert[i].co);
copy_v3_v3(vert_coords[i], verts[i].co);
}
return;
}
@@ -233,9 +235,9 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD: {
BLI_assert(vert_coords_len == me->totvert);
const MVert *mvert = me->mvert;
const Span<MVert> verts = me->vertices();
for (int i = 0; i < vert_coords_len; i++) {
mul_v3_m4v3(vert_coords[i], mat, mvert[i].co);
mul_v3_m4v3(vert_coords[i], mat, verts[i].co);
}
return;
}
+11 -8
View File
@@ -183,6 +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 MPoly *polys = BKE_mesh_polygons(me);
const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
BLI_bitmap **grid_hidden = ccgdm->gridHidden;
int *gridOffset;
@@ -191,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 < me->mpoly[i].totloop; j++) {
for (j = 0; j < polys[i].totloop; j++) {
int g = gridOffset[i] + j;
const MDisps *md = &mdisps[g];
BLI_bitmap *gh = md->hidden;
@@ -466,15 +467,16 @@ void multires_force_external_reload(Object *object)
static int get_levels_from_disps(Object *ob)
{
Mesh *me = ob->data;
const MPoly *polys = BKE_mesh_polygons(me);
MDisps *mdisp, *md;
int i, j, totlvl = 0;
mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
for (i = 0; i < me->totpoly; i++) {
md = mdisp + me->mpoly[i].loopstart;
md = mdisp + polys[i].loopstart;
for (j = 0; j < me->mpoly[i].totloop; j++, md++) {
for (j = 0; j < polys[i].totloop; j++, md++) {
if (md->totdisp == 0) {
continue;
}
@@ -633,6 +635,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 MPoly *polys = BKE_mesh_polygons(me);
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
GridPaintMask *gpm;
@@ -652,8 +655,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 < me->mpoly[i].totloop; j++) {
int g = me->mpoly[i].loopstart + j;
for (j = 0; j < polys[i].totloop; j++) {
int g = polys[i].loopstart + j;
MDisps *mdisp = &mdisps[g];
float(*disps)[3], (*ndisps)[3], (*hdisps)[3];
int totdisp = multires_grid_tot[lvl];
@@ -828,7 +831,7 @@ typedef struct MultiresThreadedData {
CCGElem **gridData, **subGridData;
CCGKey *key;
CCGKey *sub_key;
MPoly *mpoly;
const MPoly *mpoly;
MDisps *mdisps;
GridPaintMask *grid_paint_mask;
int *gridOffset;
@@ -846,7 +849,7 @@ static void multires_disp_run_cb(void *__restrict userdata,
CCGElem **gridData = tdata->gridData;
CCGElem **subGridData = tdata->subGridData;
CCGKey *key = tdata->key;
MPoly *mpoly = tdata->mpoly;
const MPoly *mpoly = tdata->mpoly;
MDisps *mdisps = tdata->mdisps;
GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
int *gridOffset = tdata->gridOffset;
@@ -939,7 +942,7 @@ static void multiresModifier_disp_run(
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGElem **gridData, **subGridData;
CCGKey key;
MPoly *mpoly = me->mpoly;
const MPoly *mpoly = BKE_mesh_polygons(me);
MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
GridPaintMask *grid_paint_mask = NULL;
int *gridOffset;
@@ -14,8 +14,12 @@
struct Depsgraph;
struct GridPaintMask;
struct MDisps;
struct MEdge;
struct Mesh;
struct MLoop;
struct MPoly;
struct MultiresModifierData;
struct MVert;
struct Object;
struct Subdiv;
struct SubdivCCG;
@@ -30,6 +34,10 @@ typedef struct MultiresReshapeContext {
/* Base mesh from original object.
* NOTE: Does NOT include any leading modifiers in it. */
struct Mesh *base_mesh;
const struct MVert *base_verts;
const struct MEdge *base_edges;
const struct MPoly *base_polys;
const struct MLoop *base_loops;
/* Subdivision surface created for multires modifier.
*
@@ -30,11 +30,14 @@
void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context)
{
Mesh *base_mesh = reshape_context->base_mesh;
const MLoop *mloop = base_mesh->mloop;
MVert *mvert = base_mesh->mvert;
MVert *base_verts = BKE_mesh_vertices_for_write(base_mesh);
/* Update the context in case the vertices were duplicated. */
reshape_context->base_verts = base_verts;
const MLoop *mloop = reshape_context->base_loops;
for (int loop_index = 0; loop_index < base_mesh->totloop; ++loop_index) {
const MLoop *loop = &mloop[loop_index];
MVert *vert = &mvert[loop->v];
MVert *vert = &base_verts[loop->v];
GridCoord grid_coord;
grid_coord.grid_index = loop_index;
@@ -66,13 +69,15 @@ static float v3_dist_from_plane(const float v[3], const float center[3], const f
void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context)
{
Mesh *base_mesh = reshape_context->base_mesh;
MVert *base_verts = BKE_mesh_vertices_for_write(base_mesh);
/* Update the context in case the vertices were duplicated. */
reshape_context->base_verts = base_verts;
MeshElemMap *pmap;
int *pmap_mem;
BKE_mesh_vert_poly_map_create(&pmap,
&pmap_mem,
base_mesh->mpoly,
base_mesh->mloop,
reshape_context->base_polys,
reshape_context->base_loops,
base_mesh->totvert,
base_mesh->totpoly,
base_mesh->totloop);
@@ -80,7 +85,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
float(*origco)[3] = MEM_calloc_arrayN(
base_mesh->totvert, sizeof(float[3]), "multires apply base origco");
for (int i = 0; i < base_mesh->totvert; i++) {
copy_v3_v3(origco[i], base_mesh->mvert[i].co);
copy_v3_v3(origco[i], base_verts[i].co);
}
for (int i = 0; i < base_mesh->totvert; i++) {
@@ -94,11 +99,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 = &base_mesh->mpoly[pmap[i].indices[j]];
const MPoly *p = &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 = base_mesh->mloop[p->loopstart + k].v;
const int vndx = reshape_context->base_loops[p->loopstart + k].v;
if (vndx != i) {
add_v3_v3(center, origco[vndx]);
tot++;
@@ -109,7 +114,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find normal. */
for (int j = 0; j < pmap[i].count; j++) {
const MPoly *p = &base_mesh->mpoly[pmap[i].indices[j]];
const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]];
MPoly fake_poly;
MLoop *fake_loops;
float(*fake_co)[3];
@@ -122,7 +127,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
fake_co = MEM_malloc_arrayN(p->totloop, sizeof(float[3]), "fake_co");
for (int k = 0; k < p->totloop; k++) {
const int vndx = base_mesh->mloop[p->loopstart + k].v;
const int vndx = reshape_context->base_loops[p->loopstart + k].v;
fake_loops[k].v = k;
@@ -143,10 +148,10 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
normalize_v3(avg_no);
/* Push vertex away from the plane. */
const float dist = v3_dist_from_plane(base_mesh->mvert[i].co, center, avg_no);
const float dist = v3_dist_from_plane(base_verts[i].co, center, avg_no);
copy_v3_v3(push, avg_no);
mul_v3_fl(push, dist);
add_v3_v3(base_mesh->mvert[i].co, push);
add_v3_v3(base_verts[i].co, push);
}
MEM_freeN(origco);
@@ -643,8 +643,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 Mesh *base_mesh = reshape_context->base_mesh;
const MPoly *base_poly = &base_mesh->mpoly[face_index];
const MPoly *base_poly = &reshape_context->base_polys[face_index];
const int num_corners = base_poly->totloop;
const int start_grid_index = reshape_context->face_start_grid_index[face_index];
const int corner = grid_coord.grid_index - start_grid_index;
@@ -834,8 +833,7 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context,
return;
}
/* Edges without crease are to be ignored as well. */
const Mesh *base_mesh = reshape_context->base_mesh;
const MEdge *base_edge = &base_mesh->medge[coarse_edge_index];
const MEdge *base_edge = &reshape_context->base_edges[coarse_edge_index];
const char crease = get_effective_crease_char(reshape_smooth_context, base_edge);
if (crease == 0) {
return;
@@ -847,9 +845,9 @@ 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 = base_mesh->mpoly;
const MLoop *base_mloop = base_mesh->mloop;
const MEdge *base_edge = base_mesh->medge;
const MPoly *base_mpoly = reshape_context->base_polys;
const MLoop *base_mloop = reshape_context->base_loops;
const MEdge *base_edge = reshape_context->base_edges;
reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge,
"non_loose_base_edge_map");
@@ -28,12 +28,16 @@
static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
{
const MVert *verts = BKE_mesh_vertices(mesh);
const MPoly *polys = BKE_mesh_polygons(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
const int totpoly = mesh->totpoly;
for (int p = 0; p < totpoly; p++) {
MPoly *poly = &mesh->mpoly[p];
const MPoly *poly = &polys[p];
float poly_center[3];
BKE_mesh_calc_poly_center(poly, &mesh->mloop[poly->loopstart], mesh->mvert, poly_center);
BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], verts, poly_center);
for (int l = 0; l < poly->totloop; l++) {
const int loop_index = poly->loopstart + l;
@@ -44,14 +48,14 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
int prev_loop_index = l - 1 >= 0 ? loop_index - 1 : loop_index + poly->totloop - 1;
int next_loop_index = l + 1 < poly->totloop ? loop_index + 1 : poly->loopstart;
MLoop *loop = &mesh->mloop[loop_index];
MLoop *loop_next = &mesh->mloop[next_loop_index];
MLoop *loop_prev = &mesh->mloop[prev_loop_index];
const MLoop *loop = &loops[loop_index];
const MLoop *loop_next = &loops[next_loop_index];
const MLoop *loop_prev = &loops[prev_loop_index];
copy_v3_v3(disps[0], poly_center);
mid_v3_v3v3(disps[1], mesh->mvert[loop->v].co, mesh->mvert[loop_next->v].co);
mid_v3_v3v3(disps[2], mesh->mvert[loop->v].co, mesh->mvert[loop_prev->v].co);
copy_v3_v3(disps[3], mesh->mvert[loop->v].co);
mid_v3_v3v3(disps[1], verts[loop->v].co, verts[loop_next->v].co);
mid_v3_v3v3(disps[2], verts[loop->v].co, verts[loop_prev->v].co);
copy_v3_v3(disps[3], verts[loop->v].co);
}
}
}
@@ -66,7 +66,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 = base_mesh->mpoly;
const MPoly *mpoly = reshape_context->base_polys;
const int num_faces = base_mesh->totpoly;
reshape_context->face_start_grid_index = MEM_malloc_arrayN(
@@ -152,6 +152,10 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd);
reshape_context->need_free_subdiv = true;
@@ -185,6 +189,10 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = multires_reshape_create_subdiv(depsgraph, object, mmd);
reshape_context->need_free_subdiv = true;
@@ -212,6 +220,10 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co
context_zero(reshape_context);
reshape_context->base_mesh = base_mesh;
reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = subdiv_ccg->subdiv;
reshape_context->need_free_subdiv = false;
@@ -255,6 +267,10 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = subdiv;
reshape_context->need_free_subdiv = false;
@@ -344,7 +360,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_mesh->mpoly[face_index];
const MPoly *base_poly = &reshape_context->base_polys[face_index];
return (base_poly->totloop == 4);
}
@@ -636,8 +652,7 @@ static void foreach_grid_face_coordinate_task(void *__restrict userdata_v,
const MultiresReshapeContext *reshape_context = data->reshape_context;
const Mesh *base_mesh = data->reshape_context->base_mesh;
const MPoly *mpoly = base_mesh->mpoly;
const MPoly *mpoly = reshape_context->base_polys;
const int grid_size = data->grid_size;
const float grid_size_1_inv = 1.0f / (((float)grid_size) - 1.0f);
@@ -52,8 +52,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 Mesh *base_mesh = reshape_context->base_mesh;
const MPoly *base_poly = &base_mesh->mpoly[face_index];
const MPoly *base_poly = &reshape_context->base_polys[face_index];
const int num_corners = base_poly->totloop;
const int start_grid_index = reshape_context->face_start_grid_index[face_index];
const int corner = grid_coord.grid_index - start_grid_index;
@@ -639,9 +639,10 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
int grid_x,
int grid_y)
{
Mesh *original_mesh = context->original_mesh;
MPoly *poly = &original_mesh->mpoly[BM_elem_index_get(f)];
const MPoly *polys = BKE_mesh_polygons(original_mesh);
const MLoop *loops = BKE_mesh_loops(original_mesh);
const MPoly *poly = &polys[BM_elem_index_get(f)];
const int corner_vertex_index = BM_elem_index_get(v);
@@ -650,7 +651,7 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
int loop_offset = 0;
for (int i = 0; i < poly->totloop; i++) {
const int loop_index = poly->loopstart + i;
MLoop *l = &original_mesh->mloop[loop_index];
const MLoop *l = &loops[loop_index];
if (l->v == corner_vertex_index) {
loop_offset = i;
break;
@@ -918,8 +919,9 @@ static void multires_unsubdivide_add_original_index_datalayers(Mesh *mesh)
static void multires_unsubdivide_prepare_original_bmesh_for_extract(
MultiresUnsubdivideContext *context)
{
Mesh *original_mesh = context->original_mesh;
const MPoly *original_polys = BKE_mesh_polygons(original_mesh);
Mesh *base_mesh = context->base_mesh;
BMesh *bm_original_mesh = context->bm_original_mesh = get_bmesh_from_mesh(original_mesh);
@@ -949,7 +951,7 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
context->loop_to_face_map = MEM_calloc_arrayN(original_mesh->totloop, sizeof(int), "loop map");
for (int i = 0; i < original_mesh->totpoly; i++) {
MPoly *poly = &original_mesh->mpoly[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;
@@ -963,16 +965,19 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
*/
static bool multires_unsubdivide_flip_grid_x_axis(Mesh *mesh, int poly, int loop, int v_x)
{
MPoly *p = &mesh->mpoly[poly];
const MPoly *polys = BKE_mesh_polygons(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
MLoop *l_first = &mesh->mloop[p->loopstart];
const MPoly *p = &polys[poly];
const MLoop *l_first = &loops[p->loopstart];
if ((loop == (p->loopstart + (p->totloop - 1))) && l_first->v == v_x) {
return true;
}
int next_l_index = loop + 1;
if (next_l_index < p->loopstart + p->totloop) {
MLoop *l_next = &mesh->mloop[next_l_index];
const MLoop *l_next = &loops[next_l_index];
if (l_next->v == v_x) {
return true;
}
+18 -15
View File
@@ -145,6 +145,8 @@
#include "atomic_ops.h"
using blender::float3;
using blender::MutableSpan;
using blender::Span;
static CLG_LogRef LOG = {"bke.object"};
@@ -3189,6 +3191,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
BKE_object_get_evaluated_mesh(par);
if (me_eval) {
const MVert *verts = BKE_mesh_vertices(me_eval);
int count = 0;
int numVerts = me_eval->totvert;
@@ -3222,14 +3225,14 @@ static void give_parvert(Object *par, int nr, float vec[3])
/* Get the average of all verts with (original index == nr). */
for (int i = 0; i < numVerts; i++) {
if (index[i] == nr) {
add_v3_v3(vec, me_eval->mvert[i].co);
add_v3_v3(vec, verts[i].co);
count++;
}
}
}
else {
if (nr < numVerts) {
add_v3_v3(vec, me_eval->mvert[nr].co);
add_v3_v3(vec, verts[nr].co);
count++;
}
}
@@ -3243,7 +3246,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
else {
/* use first index if its out of range */
if (me_eval->totvert) {
copy_v3_v3(vec, me_eval->mvert[0].co);
copy_v3_v3(vec, verts[0].co);
}
}
}
@@ -4127,10 +4130,10 @@ void BKE_object_foreach_display_point(Object *ob,
float3 co;
if (mesh_eval != nullptr) {
const MVert *mv = mesh_eval->mvert;
const MVert *verts = BKE_mesh_vertices(mesh_eval);
const int totvert = mesh_eval->totvert;
for (int i = 0; i < totvert; i++, mv++) {
mul_v3_m4v3(co, obmat, mv->co);
for (int i = 0; i < totvert; i++) {
mul_v3_m4v3(co, obmat, verts[i].co);
func_cb(co, user_data);
}
}
@@ -4754,7 +4757,8 @@ bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb)
switch (ob->type) {
case OB_MESH: {
Mesh *mesh = (Mesh *)ob->data;
BKE_keyblock_convert_to_mesh(key->refkey, mesh->mvert, mesh->totvert);
MutableSpan<MVert> verts = mesh->vertices_for_write();
BKE_keyblock_convert_to_mesh(key->refkey, verts.data(), mesh->totvert);
break;
}
case OB_CURVES_LEGACY:
@@ -5250,32 +5254,31 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
const int *index;
if (me_eval && (index = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX))) {
MVert *mvert = me_eval->mvert;
uint totvert = me_eval->totvert;
const Span<MVert> verts = me->vertices();
/* Tree over-allocates in case where some verts have #ORIGINDEX_NONE. */
tot = 0;
tree = BLI_kdtree_3d_new(totvert);
tree = BLI_kdtree_3d_new(verts.size());
/* We don't how many verts from the DM we can use. */
for (i = 0; i < totvert; i++) {
for (i = 0; i < verts.size(); i++) {
if (index[i] != ORIGINDEX_NONE) {
float co[3];
mul_v3_m4v3(co, ob->obmat, mvert[i].co);
mul_v3_m4v3(co, ob->obmat, verts[i].co);
BLI_kdtree_3d_insert(tree, index[i], co);
tot++;
}
}
}
else {
MVert *mvert = me->mvert;
const Span<MVert> verts = me->vertices();
tot = me->totvert;
tot = verts.size();
tree = BLI_kdtree_3d_new(tot);
for (i = 0; i < tot; i++) {
float co[3];
mul_v3_m4v3(co, ob->obmat, mvert[i].co);
mul_v3_m4v3(co, ob->obmat, verts[i].co);
BLI_kdtree_3d_insert(tree, i, co);
}
}
@@ -114,10 +114,7 @@ bDeformGroup *BKE_object_defgroup_add(Object *ob)
MDeformVert *BKE_object_defgroup_data_create(ID *id)
{
if (GS(id->name) == ID_ME) {
Mesh *me = (Mesh *)id;
me->dvert = CustomData_add_layer(
&me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, me->totvert);
return me->dvert;
return BKE_mesh_deform_verts_for_write((Mesh *)id);
}
if (GS(id->name) == ID_LT) {
Lattice *lt = (Lattice *)id;
@@ -165,12 +162,12 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele
}
}
else {
if (me->dvert) {
MVert *mv;
if (BKE_mesh_deform_verts(me)) {
const MVert *mv;
int i;
mv = me->mvert;
dv = me->dvert;
mv = BKE_mesh_vertices(me);
dv = BKE_mesh_deform_verts_for_write(me);
for (i = 0; i < me->totvert; i++, mv++, dv++) {
if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
@@ -265,7 +262,6 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
me->dvert = NULL;
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
@@ -413,7 +409,6 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
me->dvert = NULL;
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
@@ -502,7 +497,7 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t
switch (GS(id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)id;
*dvert_arr = me->dvert;
*dvert_arr = BKE_mesh_deform_verts_for_write(me);
*dvert_tot = me->totvert;
return true;
}
@@ -628,7 +628,7 @@ static void make_duplis_verts(const DupliContext *ctx)
VertexDupliData_Mesh vdd{};
vdd.params = vdd_params;
vdd.totvert = me_eval->totvert;
vdd.mvert = me_eval->mvert;
vdd.mvert = me_eval->vertices().data();
vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval);
vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
@@ -1178,9 +1178,9 @@ static void make_duplis_faces(const DupliContext *ctx)
FaceDupliData_Mesh fdd{};
fdd.params = fdd_params;
fdd.totface = me_eval->totpoly;
fdd.mpoly = me_eval->mpoly;
fdd.mloop = me_eval->mloop;
fdd.mvert = me_eval->mvert;
fdd.mpoly = me_eval->polygons().data();
fdd.mloop = me_eval->loops().data();
fdd.mvert = me_eval->vertices().data();
fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n(
&me_eval->ldata, CD_MLOOPUV, uv_idx) :
nullptr;
+36 -20
View File
@@ -64,6 +64,9 @@
#include "bmesh.h"
using blender::MutableSpan;
using blender::Span;
static void palette_init_data(ID *id)
{
Palette *palette = (Palette *)id;
@@ -1624,7 +1627,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
Scene *scene = DEG_get_input_scene(depsgraph);
Sculpt *sd = scene->toolsettings->sculpt;
SculptSession *ss = ob->sculpt;
const Mesh *me = BKE_object_get_original_mesh(ob);
Mesh *me = BKE_object_get_original_mesh(ob);
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
@@ -1664,17 +1667,17 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* These are assigned to the base mesh in Multires. This is needed because Face Sets operators
* and tools use the Face Sets data from the base mesh when Multires is active. */
ss->mvert = me->mvert;
ss->mpoly = me->mpoly;
ss->mloop = me->mloop;
ss->mvert = BKE_mesh_vertices_for_write(me);
ss->mpoly = BKE_mesh_polygons(me);
ss->mloop = BKE_mesh_loops(me);
}
else {
ss->totvert = me->totvert;
ss->totpoly = me->totpoly;
ss->totfaces = me->totpoly;
ss->mvert = me->mvert;
ss->mpoly = me->mpoly;
ss->mloop = me->mloop;
ss->mvert = BKE_mesh_vertices_for_write(me);
ss->mpoly = BKE_mesh_polygons(me);
ss->mloop = BKE_mesh_loops(me);
ss->multires.active = false;
ss->multires.modifier = nullptr;
ss->multires.level = 0;
@@ -1724,8 +1727,13 @@ static void sculpt_update_object(Depsgraph *depsgraph,
BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default);
if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
BKE_mesh_vert_poly_map_create(
&ss->pmap, &ss->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
BKE_mesh_vert_poly_map_create(&ss->pmap,
&ss->pmap_mem,
BKE_mesh_polygons(me),
BKE_mesh_loops(me),
me->totvert,
me->totpoly,
me->totloop);
if (ss->pbvh) {
BKE_pbvh_pmap_set(ss->pbvh, ss->pmap);
@@ -1743,7 +1751,8 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* If the fully evaluated mesh has the same topology as the deform-only version, use it.
* This matters because 'deform eval' is very restrictive and excludes even modifiers that
* simply recompute vertex weights. */
if (me_eval_deform->mpoly == me_eval->mpoly && me_eval_deform->mloop == me_eval->mloop &&
if (me_eval_deform->polygons().data() == me_eval->polygons().data() &&
me_eval_deform->loops().data() == me_eval->loops().data() &&
me_eval_deform->totvert == me_eval->totvert) {
me_eval_deform = me_eval;
}
@@ -1921,7 +1930,7 @@ void BKE_sculpt_color_layer_create_if_needed(Object *object)
CustomDataLayer *layer = orig_me->vdata.layers +
CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR);
BKE_mesh_update_customdata_pointers(orig_me, true);
BKE_mesh_tessface_clear(orig_me);
BKE_id_attributes_active_color_set(&orig_me->id, layer);
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
@@ -1944,6 +1953,8 @@ void BKE_sculpt_update_object_for_edit(
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
{
Mesh *me = static_cast<Mesh *>(ob->data);
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
int ret = 0;
const float *paint_mask = static_cast<const float *>(
@@ -1972,12 +1983,12 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
/* if vertices already have mask, copy into multires data */
if (paint_mask) {
for (i = 0; i < me->totpoly; i++) {
const MPoly *p = &me->mpoly[i];
const MPoly *p = &polys[i];
float avg = 0;
/* mask center */
for (j = 0; j < p->totloop; j++) {
const MLoop *l = &me->mloop[p->loopstart + j];
const MLoop *l = &loops[p->loopstart + j];
avg += paint_mask[l->v];
}
avg /= (float)p->totloop;
@@ -1985,9 +1996,9 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
/* fill in multires mask corner */
for (j = 0; j < p->totloop; j++) {
GridPaintMask *gpm = &gmask[p->loopstart + j];
const MLoop *l = &me->mloop[p->loopstart + j];
const MLoop *prev = ME_POLY_LOOP_PREV(me->mloop, p, j);
const MLoop *next = ME_POLY_LOOP_NEXT(me->mloop, p, j);
const MLoop *l = &loops[p->loopstart + j];
const MLoop *prev = ME_POLY_LOOP_PREV(loops, p, j);
const MLoop *next = ME_POLY_LOOP_NEXT(loops, p, j);
gpm->data[0] = avg;
gpm->data[1] = (paint_mask[l->v] + paint_mask[next->v]) * 0.5f;
@@ -2234,18 +2245,23 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
MutableSpan<MVert> verts = me->vertices_for_write();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
MLoopTri *looptri = static_cast<MLoopTri *>(
MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__));
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
BKE_mesh_recalc_looptri(
loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri);
BKE_sculpt_sync_face_set_visibility(me, nullptr);
BKE_pbvh_build_mesh(pbvh,
me,
me->mpoly,
me->mloop,
me->mvert,
polys.data(),
loops.data(),
verts.data(),
me->totvert,
&me->vdata,
&me->ldata,
+25 -21
View File
@@ -1399,7 +1399,8 @@ static void init_particle_interpolation(Object *ob,
pind->dietime = (key + pa->totkey - 1)->time;
if (pind->mesh) {
pind->mvert[0] = &pind->mesh->mvert[pa->hair_index];
MVert *verts = BKE_mesh_vertices_for_write(pind->mesh);
pind->mvert[0] = &verts[pa->hair_index];
pind->mvert[1] = pind->mvert[0] + 1;
}
}
@@ -1664,7 +1665,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach
/************************************************/
void psys_interpolate_face(Mesh *mesh,
MVert *mvert,
const MVert *mvert,
const float (*vert_normals)[3],
MFace *mface,
MTFace *tface,
@@ -1676,7 +1677,7 @@ void psys_interpolate_face(Mesh *mesh,
float vtan[3],
float orco[3])
{
float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0;
const float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0;
float e1[3], e2[3], s1, s2, t1, t2;
float *uv1, *uv2, *uv3, *uv4;
float n1[3], n2[3], n3[3], n4[3];
@@ -1852,7 +1853,8 @@ static float psys_interpolate_value_from_verts(
return values[index];
case PART_FROM_FACE:
case PART_FROM_VOLUME: {
MFace *mf = &mesh->mface[index];
MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mf = &mfaces[index];
return interpolate_particle_value(
values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4);
}
@@ -1941,7 +1943,7 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final,
index_mf_to_mpoly_deformed = NULL;
mtessface_final = mesh_final->mface;
mtessface_final = CustomData_get_layer(&mesh_final->fdata, CD_MFACE);
osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE);
if (osface_final == NULL) {
@@ -2061,7 +2063,8 @@ static int psys_map_index_on_dm(Mesh *mesh,
/* modify the original weights to become
* weights for the derived mesh face */
OrigSpaceFace *osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE);
const MFace *mface = &mesh->mface[i];
const MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE);
const MFace *mface = &mfaces[i];
if (osface == NULL) {
mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f;
@@ -2117,7 +2120,8 @@ void psys_particle_on_dm(Mesh *mesh_final,
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh_final);
if (from == PART_FROM_VERT) {
copy_v3_v3(vec, mesh_final->mvert[mapindex].co);
const MVert *vertices = BKE_mesh_vertices(mesh_final);
copy_v3_v3(vec, vertices[mapindex].co);
if (nor) {
copy_v3_v3(nor, vert_normals[mapindex]);
@@ -2143,9 +2147,10 @@ void psys_particle_on_dm(Mesh *mesh_final,
MTFace *mtface;
MVert *mvert;
mface = &mesh_final->mface[mapindex];
mvert = mesh_final->mvert;
mtface = mesh_final->mtface;
MFace *mfaces = CustomData_get_layer(&mesh_final->fdata, CD_MFACE);
mface = &mfaces[mapindex];
mvert = BKE_mesh_vertices_for_write(mesh_final);
mtface = CustomData_get_layer(&mesh_final->fdata, CD_MTFACE);
if (mtface) {
mtface += mapindex;
@@ -2634,7 +2639,7 @@ float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup)
/* hair dynamics pinning vgroup */
}
else if (psys->vgroup[vgroup]) {
MDeformVert *dvert = mesh->dvert;
const MDeformVert *dvert = BKE_mesh_deform_verts(mesh);
if (dvert) {
int totvert = mesh->totvert, i;
vg = MEM_callocN(sizeof(float) * totvert, "vg_cache");
@@ -3848,7 +3853,8 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
return;
}
mface = &mesh->mface[i];
MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE);
mface = &mfaces[i];
const OrigSpaceFace *osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE);
if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) {
@@ -3863,9 +3869,10 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
}
}
else {
copy_v3_v3(v[0], mesh->mvert[mface->v1].co);
copy_v3_v3(v[1], mesh->mvert[mface->v2].co);
copy_v3_v3(v[2], mesh->mvert[mface->v3].co);
const MVert *verts = BKE_mesh_vertices(mesh);
copy_v3_v3(v[0], verts[mface->v1].co);
copy_v3_v3(v[1], verts[mface->v2].co);
copy_v3_v3(v[2], verts[mface->v3].co);
}
triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat);
@@ -4155,16 +4162,13 @@ static int get_particle_uv(Mesh *mesh,
float *texco,
bool from_vert)
{
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mf;
const MTFace *tf;
int i;
tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name);
if (tf == NULL) {
tf = mesh->mtface;
}
if (tf == NULL) {
return 0;
}
@@ -4186,7 +4190,7 @@ static int get_particle_uv(Mesh *mesh,
}
else {
if (from_vert) {
mf = mesh->mface;
mf = mfaces;
/* This finds the first face to contain the emitting vertex,
* this is not ideal, but is mostly fine as UV seams generally
@@ -4199,7 +4203,7 @@ static int get_particle_uv(Mesh *mesh,
}
}
else {
mf = &mesh->mface[i];
mf = &mfaces[i];
}
psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco);
@@ -97,7 +97,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
{
ParticleData *pa = NULL;
float min[3], max[3], delta[3], d;
MVert *mv, *mvert = mesh->mvert;
MVert *mv, *mvert = BKE_mesh_vertices_for_write(mesh);
int totvert = mesh->totvert, from = psys->part->from;
int i, j, k, p, res = psys->part->grid_res, size[3], axis;
@@ -181,7 +181,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
int amax = from == PART_FROM_FACE ? 3 : 1;
totface = mesh->totface;
mface = mface_array = mesh->mface;
mface = mface_array = CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (a = 0; a < amax; a++) {
if (a == 0) {
@@ -464,7 +464,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
ParticleThreadContext *ctx = thread->ctx;
MFace *mface;
mface = ctx->mesh->mface;
mface = CustomData_get_layer(&ctx->mesh->fdata, CD_MFACE);
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
@@ -525,10 +525,11 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i
int i;
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mface;
pa->num = i = ctx->index[p];
mface = &mesh->mface[i];
mface = &mfaces[i];
switch (distr) {
case PART_DISTR_JIT:
@@ -575,10 +576,11 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
MFace *mface;
MVert *mvert = mesh->mvert;
MVert *mvert = BKE_mesh_vertices_for_write(mesh);
pa->num = i = ctx->index[p];
mface = &mesh->mface[i];
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
mface = &mfaces[i];
switch (distr) {
case PART_DISTR_JIT:
@@ -619,8 +621,8 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
min_d = FLT_MAX;
intersect = 0;
for (i = 0, mface = mesh->mface; i < tot; i++, mface++) {
mface = CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < tot; i++, mface++) {
if (i == pa->num) {
continue;
}
@@ -689,7 +691,8 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i
return;
}
mf = &mesh->mface[ctx->index[p]];
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
mf = &mfaces[ctx->index[p]];
randu = BLI_rng_get_float(thread->rng);
randv = BLI_rng_get_float(thread->rng);
@@ -989,7 +992,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
BKE_mesh_orco_ensure(ob, mesh);
if (from == PART_FROM_VERT) {
MVert *mv = mesh->mvert;
MVert *mv = BKE_mesh_vertices_for_write(mesh);
const float(*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO);
int totvert = mesh->totvert;
@@ -1042,8 +1045,9 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO);
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < totelem; i++) {
MFace *mf = &mesh->mface[i];
MFace *mf = &mfaces[i];
if (orcodata) {
/* Transform orcos from normalized 0..1 to object space. */
@@ -1059,14 +1063,15 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
}
}
else {
v1 = &mesh->mvert[mf->v1];
v2 = &mesh->mvert[mf->v2];
v3 = &mesh->mvert[mf->v3];
MVert *verts = BKE_mesh_vertices_for_write(mesh);
v1 = &verts[mf->v1];
v2 = &verts[mf->v2];
v3 = &verts[mf->v3];
copy_v3_v3(co1, v1->co);
copy_v3_v3(co2, v2->co);
copy_v3_v3(co3, v3->co);
if (mf->v4) {
v4 = &mesh->mvert[mf->v4];
v4 = &verts[mf->v4];
copy_v3_v3(co4, v4->co);
}
}
@@ -1105,8 +1110,9 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
}
}
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < totelem; i++) {
MFace *mf = &mesh->mface[i];
MFace *mf = &mfaces[i];
tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
if (mf->v4) {
@@ -3322,12 +3322,10 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
mesh = *r_mesh;
if (!mesh) {
*r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0);
CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, mesh->totvert);
BKE_mesh_update_customdata_pointers(mesh, false);
}
mvert = mesh->mvert;
medge = mesh->medge;
dvert = mesh->dvert;
mvert = BKE_mesh_vertices_for_write(mesh);
medge = BKE_mesh_edges_for_write(mesh);
dvert = BKE_mesh_deform_verts_for_write(mesh);
if (psys->clmd->hairdata == NULL) {
psys->clmd->hairdata = MEM_mallocN(sizeof(ClothHairData) * totpoint, "hair data");
@@ -2,6 +2,7 @@
* Copyright 2022 Blender Foundation. All rights reserved. */
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_pbvh.h"
#include "BKE_pbvh_pixels.hh"
@@ -291,7 +292,8 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
for (PBVHNode *node : nodes_to_update) {
NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
init_triangles(pbvh, node, node_data, mesh->mloop);
const Span<MLoop> loops = mesh->loops();
init_triangles(pbvh, node, node_data, loops.data());
}
EncodePixelsUserData user_data;
+8 -14
View File
@@ -364,7 +364,7 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob,
if (ob->type == OB_MESH && ob->data) {
mesh = rigidbody_get_mesh(ob);
mvert = (mesh) ? mesh->mvert : NULL;
mvert = (mesh) ? BKE_mesh_vertices_for_write(mesh) : NULL;
totvert = (mesh) ? mesh->totvert : 0;
}
else {
@@ -390,11 +390,9 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
if (ob->type == OB_MESH) {
Mesh *mesh = NULL;
MVert *mvert;
const MLoopTri *looptri;
int totvert;
int tottri;
const MLoop *mloop;
mesh = rigidbody_get_mesh(ob);
@@ -403,11 +401,11 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
return NULL;
}
mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
mloop = mesh->mloop;
const MLoop *mloop = BKE_mesh_loops(mesh);
/* sanity checking - potential case when no data will be present */
if ((totvert == 0) || (tottri == 0)) {
@@ -670,21 +668,19 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
case RB_SHAPE_TRIMESH: {
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
MVert *mvert;
const MLoopTri *lt = NULL;
int totvert, tottri = 0;
const MLoop *mloop = NULL;
/* ensure mesh validity, then grab data */
if (mesh == NULL) {
return;
}
mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
totvert = mesh->totvert;
lt = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
mloop = mesh->mloop;
const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
@@ -746,21 +742,19 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
case RB_SHAPE_TRIMESH: {
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
MVert *mvert;
const MLoopTri *looptri;
int totvert, tottri;
const MLoop *mloop;
/* ensure mesh validity, then grab data */
if (mesh == NULL) {
return;
}
mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
mloop = mesh->mloop;
const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
@@ -1677,7 +1671,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
Mesh *mesh = ob->runtime.mesh_deform_eval;
if (mesh) {
MVert *mvert = mesh->mvert;
MVert *mvert = BKE_mesh_vertices_for_write(mesh);
int totvert = mesh->totvert;
const BoundBox *bb = BKE_object_boundbox_get(ob);
+12 -11
View File
@@ -64,9 +64,9 @@ typedef struct ShrinkwrapCalcData {
float (*vertexCos)[3]; /* vertexs being shrinkwraped */
int numVerts;
struct MDeformVert *dvert; /* Pointer to mdeform array */
int vgroup; /* Vertex group num */
bool invert_vgroup; /* invert vertex group influence */
const struct MDeformVert *dvert; /* Pointer to mdeform array */
int vgroup; /* Vertex group num */
bool invert_vgroup; /* invert vertex group influence */
struct Mesh *target; /* mesh we are shrinking to */
struct SpaceTransform local2target; /* transform to move between local and target space */
@@ -113,6 +113,7 @@ bool BKE_shrinkwrap_init_tree(
}
data->mesh = mesh;
data->polys = BKE_mesh_polygons(mesh);
if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) {
data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2);
@@ -191,9 +192,9 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
{
const MLoop *mloop = mesh->mloop;
const MEdge *medge = mesh->medge;
const MVert *mvert = mesh->mvert;
const MVert *mvert = BKE_mesh_vertices(mesh);
const MEdge *medge = BKE_mesh_edges(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
/* Count faces per edge (up to 2). */
char *edge_mode = MEM_calloc_arrayN((size_t)mesh->totedge, sizeof(char), __func__);
@@ -937,7 +938,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
int eidx)
{
const BVHTreeFromMesh *data = &tree->treeData;
const MEdge *edge = &tree->mesh->medge[eidx];
const MEdge *edge = &data->edge[eidx];
const float *vedge_co[2] = {data->vert[edge->v1].co, data->vert[edge->v2].co};
#ifdef TRACE_TARGET_PROJECT
@@ -1179,7 +1180,7 @@ void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree,
const float(*vert_normals)[3] = tree->treeData.vert_normals;
/* Interpolate smooth normals if enabled. */
if ((tree->mesh->mpoly[tri->poly].flag & ME_SMOOTH) != 0) {
if ((tree->polys[tri->poly].flag & ME_SMOOTH) != 0) {
const uint32_t vert_indices[3] = {treeData->loop[tri->tri[0]].v,
treeData->loop[tri->tri[1]].v,
treeData->loop[tri->tri[2]].v};
@@ -1369,7 +1370,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
struct Scene *scene,
Object *ob,
Mesh *mesh,
MDeformVert *dvert,
const MDeformVert *dvert,
const int defgrp_index,
float (*vertexCos)[3],
int numVerts)
@@ -1411,7 +1412,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
if (mesh != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
/* Setup arrays to get vertexs positions, normals and deform weights */
calc.vert = mesh->mvert;
calc.vert = BKE_mesh_vertices_for_write(mesh);
calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
/* Using vertexs positions/normals as if a subsurface was applied */
@@ -1574,7 +1575,7 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
calc.vgroup = -1;
calc.target = target_me;
calc.keepDist = ssmd.keepDist;
calc.vert = src_me->mvert;
calc.vert = BKE_mesh_vertices_for_write(src_me);
BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob_target, ob_target);
ShrinkwrapTreeData tree;
+22 -16
View File
@@ -567,7 +567,7 @@ static void ccd_update_deflector_hash(Depsgraph *depsgraph,
static int count_mesh_quads(Mesh *me)
{
int a, result = 0;
const MPoly *mp = me->mpoly;
const MPoly *mp = BKE_mesh_polygons(me);
if (mp) {
for (a = me->totpoly; a > 0; a--, mp++) {
@@ -591,8 +591,8 @@ static void add_mesh_quad_diag_springs(Object *ob)
nofquads = count_mesh_quads(me);
if (nofquads) {
const MLoop *mloop = me->mloop;
const MPoly *mp = me->mpoly;
const MLoop *mloop = BKE_mesh_loops(me);
const MPoly *mp = BKE_mesh_polygons(me);
BodySpring *bs;
/* resize spring-array to hold additional quad springs */
@@ -2632,6 +2632,7 @@ static void springs_from_mesh(Object *ob)
BodyPoint *bp;
int a;
float scale = 1.0f;
const MVert *vertices = BKE_mesh_vertices(me);
sb = ob->soft;
if (me && sb) {
@@ -2642,7 +2643,7 @@ static void springs_from_mesh(Object *ob)
if (me->totvert) {
bp = ob->soft->bpoint;
for (a = 0; a < me->totvert; a++, bp++) {
copy_v3_v3(bp->origS, me->mvert[a].co);
copy_v3_v3(bp->origS, vertices[a].co);
mul_m4_v3(ob->obmat, bp->origS);
}
}
@@ -2663,7 +2664,7 @@ static void mesh_to_softbody(Object *ob)
{
SoftBody *sb;
Mesh *me = ob->data;
MEdge *medge = me->medge;
const MEdge *medge = BKE_mesh_edges(me);
BodyPoint *bp;
BodySpring *bs;
int a, totedge;
@@ -2683,10 +2684,11 @@ static void mesh_to_softbody(Object *ob)
sb = ob->soft;
bp = sb->bpoint;
defgroup_index = me->dvert ? (sb->vertgroup - 1) : -1;
defgroup_index_mass = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1;
defgroup_index_spring = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) :
-1;
const MDeformVert *dvert = BKE_mesh_deform_verts(me);
defgroup_index = dvert ? (sb->vertgroup - 1) : -1;
defgroup_index_mass = dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1;
defgroup_index_spring = dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) : -1;
for (a = 0; a < me->totvert; a++, bp++) {
/* get scalar values needed *per vertex* from vertex group functions,
@@ -2699,7 +2701,7 @@ static void mesh_to_softbody(Object *ob)
BLI_assert(bp->goal == sb->defgoal);
}
if ((ob->softflag & OB_SB_GOAL) && (defgroup_index != -1)) {
bp->goal *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index);
bp->goal *= BKE_defvert_find_weight(&dvert[a], defgroup_index);
}
/* to proof the concept
@@ -2707,11 +2709,11 @@ static void mesh_to_softbody(Object *ob)
*/
if (defgroup_index_mass != -1) {
bp->mass *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_mass);
bp->mass *= BKE_defvert_find_weight(&dvert[a], defgroup_index_mass);
}
if (defgroup_index_spring != -1) {
bp->springweight *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_spring);
bp->springweight *= BKE_defvert_find_weight(&dvert[a], defgroup_index_spring);
}
}
@@ -2753,19 +2755,23 @@ static void mesh_faces_to_scratch(Object *ob)
MLoopTri *looptri, *lt;
BodyFace *bodyface;
int a;
const MVert *vertices = BKE_mesh_vertices(me);
const MPoly *polygons = BKE_mesh_polygons(me);
const MLoop *loops = BKE_mesh_loops(me);
/* Allocate and copy faces. */
sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop);
looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__);
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
BKE_mesh_recalc_looptri(loops, polygons, vertices, me->totloop, me->totpoly, looptri);
bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface,
"SB_body_Faces");
for (a = 0; a < sb->scratch->totface; a++, lt++, bodyface++) {
bodyface->v1 = me->mloop[lt->tri[0]].v;
bodyface->v2 = me->mloop[lt->tri[1]].v;
bodyface->v3 = me->mloop[lt->tri[2]].v;
bodyface->v1 = loops[lt->tri[0]].v;
bodyface->v2 = loops[lt->tri[1]].v;
bodyface->v3 = loops[lt->tri[2]].v;
zero_v3(bodyface->ext_force);
bodyface->ext_force[0] = bodyface->ext_force[1] = bodyface->ext_force[2] = 0.0f;
bodyface->flag = 0;
@@ -17,6 +17,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_subdiv.h"
#include "MEM_guardedalloc.h"
@@ -102,7 +103,7 @@ static void free_mask_data(SubdivCCGMaskEvaluator *mask_evaluator)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
const MPoly *mpoly = mesh->mpoly;
const MPoly *mpoly = BKE_mesh_polygons(mesh);
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;
@@ -113,7 +114,7 @@ static int count_num_ptex_faces(const Mesh *mesh)
static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh)
{
GridPaintMaskData *data = mask_evaluator->user_data;
const MPoly *mpoly = mesh->mpoly;
const MPoly *mpoly = BKE_mesh_polygons(mesh);
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = MEM_malloc_arrayN(
@@ -141,7 +142,7 @@ static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const
static void mask_init_data(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh)
{
GridPaintMaskData *data = mask_evaluator->user_data;
data->mpoly = mesh->mpoly;
data->mpoly = BKE_mesh_polygons(mesh);
data->grid_paint_mask = CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
mask_data_init_mapping(mask_evaluator, mesh);
}
@@ -5,7 +5,7 @@
* \ingroup bke
*/
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_subdiv_ccg.h"
#include "MEM_guardedalloc.h"
@@ -15,6 +15,7 @@
typedef struct CCGMaterialFromMeshData {
const Mesh *mesh;
const MPoly *polys;
const int *material_indices;
} CCGMaterialFromMeshData;
@@ -22,10 +23,8 @@ static DMFlagMat subdiv_ccg_material_flags_eval(
SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator, const int coarse_face_index)
{
CCGMaterialFromMeshData *data = (CCGMaterialFromMeshData *)material_flags_evaluator->user_data;
const Mesh *mesh = data->mesh;
BLI_assert(coarse_face_index < mesh->totpoly);
const MPoly *mpoly = mesh->mpoly;
const MPoly *poly = &mpoly[coarse_face_index];
BLI_assert(coarse_face_index < data->mesh->totpoly);
const MPoly *poly = &data->polys[coarse_face_index];
DMFlagMat material_flags;
material_flags.flag = poly->flag;
material_flags.mat_nr = data->material_indices ? data->material_indices[coarse_face_index] : 0;
@@ -46,6 +45,7 @@ void BKE_subdiv_ccg_material_flags_init_from_mesh(
data->mesh = mesh;
data->material_indices = (const int *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_INT32, "material_index");
data->polys = BKE_mesh_polygons(mesh);
material_flags_evaluator->eval_material_flags = subdiv_ccg_material_flags_eval;
material_flags_evaluator->free = subdiv_ccg_material_flags_free;
material_flags_evaluator->user_data = data;
@@ -16,6 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_subdiv.h"
@@ -33,6 +34,11 @@
typedef struct ConverterStorage {
SubdivSettings settings;
const Mesh *mesh;
const MVert *verts;
const MEdge *edges;
const MPoly *polys;
const MLoop *loops;
/* CustomData layer for vertex sharpnesses. */
const float *cd_vertex_crease;
/* Indexed by loop index, value denotes index of face-varying vertex
@@ -116,7 +122,7 @@ static int get_num_vertices(const OpenSubdiv_Converter *converter)
static int get_num_face_vertices(const OpenSubdiv_Converter *converter, int manifold_face_index)
{
ConverterStorage *storage = converter->user_data;
return storage->mesh->mpoly[manifold_face_index].totloop;
return storage->polys[manifold_face_index].totloop;
}
static void get_face_vertices(const OpenSubdiv_Converter *converter,
@@ -124,8 +130,8 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter,
int *manifold_face_vertices)
{
ConverterStorage *storage = converter->user_data;
const MPoly *poly = &storage->mesh->mpoly[manifold_face_index];
const MLoop *mloop = storage->mesh->mloop;
const MPoly *poly = &storage->polys[manifold_face_index];
const MLoop *mloop = storage->loops;
for (int corner = 0; corner < poly->totloop; corner++) {
manifold_face_vertices[corner] =
storage->manifold_vertex_index[mloop[poly->loopstart + corner].v];
@@ -138,7 +144,7 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter,
{
ConverterStorage *storage = converter->user_data;
const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index];
const MEdge *edge = &storage->mesh->medge[edge_index];
const MEdge *edge = &storage->edges[edge_index];
manifold_edge_vertices[0] = storage->manifold_vertex_index[edge->v1];
manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2];
}
@@ -155,7 +161,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manif
return 0.0f;
}
const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index];
const MEdge *medge = storage->mesh->medge;
const MEdge *medge = storage->edges;
return BKE_subdiv_crease_to_sharpness_char(medge[edge_index].crease);
}
@@ -193,8 +199,6 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
{
ConverterStorage *storage = converter->user_data;
const Mesh *mesh = storage->mesh;
const MPoly *mpoly = mesh->mpoly;
const MLoop *mloop = mesh->mloop;
const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index);
const int num_poly = mesh->totpoly;
const int num_vert = mesh->totvert;
@@ -205,9 +209,9 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
mesh->totloop, sizeof(int), "loop uv vertex index");
}
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
mpoly,
storage->polys,
(const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"),
mloop,
storage->loops,
mloopuv,
num_poly,
num_vert,
@@ -222,7 +226,7 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
if (uv_vert->separate) {
storage->num_uv_coordinates++;
}
const MPoly *mp = &mpoly[uv_vert->poly_index];
const MPoly *mp = &storage->polys[uv_vert->poly_index];
const int global_loop_index = mp->loopstart + uv_vert->loop_of_poly_index;
storage->loop_uv_indices[global_loop_index] = storage->num_uv_coordinates;
uv_vert = uv_vert->next;
@@ -250,7 +254,7 @@ static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
const int corner)
{
ConverterStorage *storage = converter->user_data;
const MPoly *mp = &storage->mesh->mpoly[face_index];
const MPoly *mp = &storage->polys[face_index];
return storage->loop_uv_indices[mp->loopstart + corner];
}
@@ -344,9 +348,9 @@ static void initialize_manifold_index_array(const BLI_bitmap *used_map,
static void initialize_manifold_indices(ConverterStorage *storage)
{
const Mesh *mesh = storage->mesh;
const MEdge *medge = mesh->medge;
const MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
const MEdge *medge = storage->edges;
const MLoop *mloop = storage->loops;
const MPoly *mpoly = storage->polys;
/* Set bits of elements which are not loose. */
BLI_bitmap *vert_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map");
BLI_bitmap *edge_used_map = BLI_BITMAP_NEW(mesh->totedge, "edge used map");
@@ -389,6 +393,10 @@ static void init_user_data(OpenSubdiv_Converter *converter,
ConverterStorage *user_data = MEM_mallocN(sizeof(ConverterStorage), __func__);
user_data->settings = *settings;
user_data->mesh = mesh;
user_data->verts = BKE_mesh_vertices(mesh);
user_data->edges = BKE_mesh_edges(mesh);
user_data->polys = BKE_mesh_polygons(mesh);
user_data->loops = BKE_mesh_loops(mesh);
user_data->cd_vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE);
user_data->loop_uv_indices = NULL;
initialize_manifold_indices(user_data);
@@ -18,6 +18,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_subdiv_eval.h"
@@ -360,7 +361,7 @@ static void free_displacement(SubdivDisplacement *displacement)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
const MPoly *mpoly = mesh->mpoly;
const MPoly *mpoly = BKE_mesh_polygons(mesh);
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;
@@ -371,7 +372,7 @@ static int count_num_ptex_faces(const Mesh *mesh)
static void displacement_data_init_mapping(SubdivDisplacement *displacement, const Mesh *mesh)
{
MultiresDisplacementData *data = displacement->user_data;
const MPoly *mpoly = mesh->mpoly;
const MPoly *mpoly = BKE_mesh_polygons(mesh);
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = MEM_malloc_arrayN(
@@ -406,7 +407,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 = mesh->mpoly;
data->mpoly = BKE_mesh_polygons(mesh);
data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
data->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
data->is_initialized = false;
@@ -16,6 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_subdiv.h"
#include "MEM_guardedalloc.h"
@@ -80,9 +81,9 @@ static void set_coarse_positions(Subdiv *subdiv,
const Mesh *mesh,
const float (*coarse_vertex_cos)[3])
{
const MVert *mvert = mesh->mvert;
const MLoop *mloop = mesh->mloop;
const MPoly *mpoly = mesh->mpoly;
const MVert *mvert = BKE_mesh_vertices(mesh);
const MPoly *mpoly = BKE_mesh_polygons(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
/* Mark vertices which needs new coordinates. */
/* TODO(sergey): This is annoying to calculate this on every update,
* maybe it's better to cache this mapping. Or make it possible to have
@@ -125,6 +126,7 @@ static void set_coarse_positions(Subdiv *subdiv,
typedef struct FaceVaryingDataFromUVContext {
OpenSubdiv_TopologyRefiner *topology_refiner;
const Mesh *mesh;
const MPoly *polys;
const MLoopUV *mloopuv;
float (*buffer)[2];
int layer_index;
@@ -137,8 +139,7 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata,
FaceVaryingDataFromUVContext *ctx = userdata;
OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner;
const int layer_index = ctx->layer_index;
const Mesh *mesh = ctx->mesh;
const MPoly *mpoly = &mesh->mpoly[face_index];
const MPoly *mpoly = &ctx->polys[face_index];
const MLoopUV *mluv = &ctx->mloopuv[mpoly->loopstart];
/* TODO(sergey): OpenSubdiv's C-API converter can change winding of
@@ -171,6 +172,7 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv,
ctx.layer_index = layer_index;
ctx.mloopuv = mluv;
ctx.mesh = mesh;
ctx.polys = BKE_mesh_polygons(mesh);
ctx.buffer = buffer;
TaskParallelSettings parallel_range_settings;
@@ -158,8 +158,8 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx)
const int num_inner_vertices_per_noquad_patch = (no_quad_patch_resolution - 2) *
(no_quad_patch_resolution - 2);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
ctx->num_subdiv_vertices = coarse_mesh->totvert;
ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1);
/* Calculate extra vertices and edges created by non-loose geometry. */
@@ -225,7 +225,7 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx)
ctx->edge_inner_offset = ctx->edge_boundary_offset +
coarse_mesh->totedge * num_subdiv_edges_per_coarse_edge;
/* "Indexed" offsets. */
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
int vertex_offset = 0;
int edge_offset = 0;
int polygon_offset = 0;
@@ -301,8 +301,9 @@ static void subdiv_foreach_corner_vertices_regular_do(
{
const float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
@@ -342,8 +343,9 @@ static void subdiv_foreach_corner_vertices_special_do(
bool check_usage)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
@@ -407,7 +409,7 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx,
return;
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (coarse_poly->totloop == 4) {
@@ -432,11 +434,11 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct
const float inv_resolution_1 = 1.0f / (float)resolution_1;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int poly_index = coarse_poly - coarse_mesh->mpoly;
const int poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_index = ctx->face_ptex_offset[poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
@@ -499,11 +501,11 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct
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 Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int poly_index = coarse_poly - coarse_mesh->mpoly;
const int poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_start_index = ctx->face_ptex_offset[poly_index];
int ptex_face_index = ptex_face_start_index;
for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
@@ -595,7 +597,7 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo
return;
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (coarse_poly->totloop == 4) {
@@ -616,7 +618,8 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx,
const int resolution = ctx->settings->resolution;
const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
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;
@@ -644,7 +647,8 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
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 Mesh *coarse_mesh = ctx->coarse_mesh;
const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
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;
@@ -691,7 +695,7 @@ static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx, void *tls, const int poly_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (ctx->foreach_context->vertex_inner != NULL) {
subdiv_foreach_inner_vertices(ctx, tls, coarse_poly);
@@ -775,9 +779,9 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c
const MPoly *coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int poly_index = coarse_poly - coarse_mpoly;
const int resolution = ctx->settings->resolution;
const int start_vertex_index = ctx->vertices_inner_offset +
@@ -856,9 +860,9 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
const MPoly *coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int poly_index = coarse_poly - coarse_mpoly;
const int resolution = ctx->settings->resolution;
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
@@ -984,7 +988,7 @@ static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_edges(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
subdiv_foreach_edges_all_patches(ctx, tls, coarse_poly);
}
@@ -994,7 +998,7 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
int coarse_edge_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
const int resolution = ctx->settings->resolution;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
@@ -1125,9 +1129,9 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
const int resolution = ctx->settings->resolution;
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_inner_resolution = ptex_resolution - 2;
@@ -1319,9 +1323,9 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
const int resolution = ctx->settings->resolution;
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_face_inner_resolution = ptex_face_resolution - 2;
@@ -1654,7 +1658,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_loops(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (coarse_poly->totloop == 4) {
subdiv_foreach_loops_regular(ctx, tls, coarse_poly);
@@ -1676,7 +1680,7 @@ static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int p
const int start_poly_index = ctx->subdiv_polygon_offset[poly_index];
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[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);
@@ -1731,7 +1735,8 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat
const float inv_resolution_1 = 1.0f / (float)resolution_1;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
const MEdge *coarse_edges = BKE_mesh_edges(coarse_mesh);
const MEdge *coarse_edge = &coarse_edges[coarse_edge_index];
/* Subdivision vertices which corresponds to edge's v1 and v2. */
const int subdiv_v1_index = ctx->vertices_corner_offset + coarse_edge->v1;
const int subdiv_v2_index = ctx->vertices_corner_offset + coarse_edge->v2;
@@ -1768,7 +1773,7 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct
return;
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
subdiv_foreach_corner_vertices(ctx, tls, coarse_poly);
@@ -1779,8 +1784,8 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct
static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+57 -68
View File
@@ -32,8 +32,18 @@
struct SubdivMeshContext {
const SubdivToMeshSettings *settings;
const Mesh *coarse_mesh;
const MVert *coarse_verts;
const MEdge *coarse_edges;
const MPoly *coarse_polys;
const MLoop *coarse_loops;
Subdiv *subdiv;
Mesh *subdiv_mesh;
MVert *subdiv_verts;
MEdge *subdiv_edges;
MPoly *subdiv_polys;
MLoop *subdiv_loops;
/* Cached custom data arrays for faster access. */
int *vert_origindex;
int *edge_origindex;
@@ -63,6 +73,10 @@ static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
{
Mesh *subdiv_mesh = ctx->subdiv_mesh;
ctx->subdiv_verts = BKE_mesh_vertices_for_write(subdiv_mesh);
ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh);
ctx->subdiv_polys = BKE_mesh_polygons_for_write(subdiv_mesh);
ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh);
/* Pointers to original indices layers. */
ctx->vert_origindex = static_cast<int *>(
CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX));
@@ -115,7 +129,7 @@ static void loops_of_ptex_get(const SubdivMeshContext *ctx,
const MPoly *coarse_poly,
const int ptex_of_poly_index)
{
const MLoop *coarse_mloop = ctx->coarse_mesh->mloop;
const MLoop *coarse_mloop = ctx->coarse_loops;
const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index;
/* Loop which look in the (opposite) V direction of the current
* ptex face.
@@ -171,7 +185,7 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
const MPoly *coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MLoop *coarse_mloop = ctx->coarse_loops;
if (coarse_poly->totloop == 4) {
vertex_interpolation->vertex_data = &coarse_mesh->vdata;
vertex_interpolation->vertex_indices[0] = coarse_mloop[coarse_poly->loopstart + 0].v;
@@ -223,8 +237,7 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
}
else {
const CustomData *vertex_data = &ctx->coarse_mesh->vdata;
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MLoop *coarse_mloop = ctx->coarse_loops;
LoopsOfPtex loops_of_ptex;
loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
/* Ptex face corner corresponds to a poly loop with same index. */
@@ -358,8 +371,7 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx,
}
else {
const CustomData *loop_data = &ctx->coarse_mesh->ldata;
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MLoop *coarse_mloop = coarse_mesh->mloop;
const MLoop *coarse_mloop = ctx->coarse_loops;
LoopsOfPtex loops_of_ptex;
loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
/* Ptex face corner corresponds to a poly loop with same index. */
@@ -466,7 +478,7 @@ static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx,
{
/* Accumulate displacement. */
Subdiv *subdiv = ctx->subdiv;
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
float dummy_P[3], dPdu[3], dPdv[3], D[3];
BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
@@ -520,9 +532,8 @@ static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx,
MVert *subdiv_vertex)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
Mesh *subdiv_mesh = ctx->subdiv_mesh;
const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert;
const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert;
const int coarse_vertex_index = coarse_vertex - ctx->coarse_verts;
const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts;
CustomData_copy_data(
&coarse_mesh->vdata, &ctx->subdiv_mesh->vdata, coarse_vertex_index, subdiv_vertex_index, 1);
}
@@ -533,7 +544,7 @@ static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx,
const float u,
const float v)
{
const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts;
const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v};
CustomData_interp(vertex_interpolation->vertex_data,
&ctx->subdiv_mesh->vdata,
@@ -554,7 +565,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
const MVert *coarse_vert,
MVert *subdiv_vert)
{
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
/* Displacement is accumulated in subdiv vertex position.
* Needs to be backed up before copying data from original vertex. */
float D[3] = {0.0f, 0.0f, 0.0f};
@@ -582,7 +593,7 @@ static void evaluate_vertex_and_apply_displacement_interpolate(
VerticesForInterpolation *vertex_interpolation,
MVert *subdiv_vert)
{
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
/* Displacement is accumulated in subdiv vertex position.
* Needs to be backed up before copying data from original vertex. */
float D[3] = {0.0f, 0.0f, 0.0f};
@@ -609,9 +620,7 @@ static void subdiv_mesh_vertex_displacement_every_corner_or_edge(
const int subdiv_vertex_index)
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert);
}
@@ -656,12 +665,8 @@ static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_contex
{
BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MVert *coarse_mvert = coarse_mesh->mvert;
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
const MVert *coarse_vert = &coarse_mvert[coarse_vertex_index];
MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
const MVert *coarse_vert = &ctx->coarse_verts[coarse_vertex_index];
MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
evaluate_vertex_and_apply_displacement_copy(
ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert);
}
@@ -706,12 +711,8 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
evaluate_vertex_and_apply_displacement_interpolate(
ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vert);
@@ -755,12 +756,9 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
Subdiv *subdiv = ctx->subdiv;
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co);
@@ -778,7 +776,7 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
MEdge *subdiv_edge,
const MEdge *coarse_edge)
{
const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges;
if (coarse_edge == nullptr) {
subdiv_edge->crease = 0;
subdiv_edge->bweight = 0;
@@ -791,7 +789,7 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
}
return;
}
const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge;
const int coarse_edge_index = coarse_edge - ctx->coarse_edges;
CustomData_copy_data(
&ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1);
subdiv_edge->flag |= ME_EDGERENDER;
@@ -806,13 +804,11 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
const int subdiv_v2)
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MEdge *subdiv_medge = subdiv_mesh->medge;
MEdge *subdiv_medge = ctx->subdiv_edges;
MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
const MEdge *coarse_edge = nullptr;
if (coarse_edge_index != ORIGINDEX_NONE) {
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
const MEdge *coarse_medge = ctx->coarse_edges;
coarse_edge = &coarse_medge[coarse_edge_index];
}
subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
@@ -832,7 +828,7 @@ static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx,
const float u,
const float v)
{
const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
const int subdiv_loop_index = subdiv_loop - ctx->subdiv_loops;
const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v};
CustomData_interp(loop_interpolation->loop_data,
&ctx->subdiv_mesh->ldata,
@@ -854,7 +850,7 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
return;
}
Subdiv *subdiv = ctx->subdiv;
const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
const int mloop_index = subdiv_loop - ctx->subdiv_loops;
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
BKE_subdiv_eval_face_varying(subdiv, layer_index, ptex_face_index, u, v, subdiv_loopuv->uv);
@@ -903,12 +899,9 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_mpoly = ctx->coarse_polys;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MLoop *subdiv_mloop = subdiv_mesh->mloop;
MLoop *subdiv_loop = &subdiv_mloop[subdiv_loop_index];
MLoop *subdiv_loop = &ctx->subdiv_loops[subdiv_loop_index];
subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly, coarse_corner);
subdiv_interpolate_loop_data(ctx, subdiv_loop, &tls->loop_interpolation, u, v);
subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v);
@@ -926,8 +919,8 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
MPoly *subdiv_poly,
const MPoly *coarse_poly)
{
const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly;
const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly;
const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
const int subdiv_poly_index = subdiv_poly - ctx->subdiv_polys;
CustomData_copy_data(
&ctx->coarse_mesh->pdata, &ctx->subdiv_mesh->pdata, coarse_poly_index, subdiv_poly_index, 1);
}
@@ -941,12 +934,8 @@ static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
{
BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
MPoly *subdiv_poly = &subdiv_mpoly[subdiv_poly_index];
const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
MPoly *subdiv_poly = &ctx->subdiv_polys[subdiv_poly_index];
subdiv_copy_poly_data(ctx, subdiv_poly, coarse_poly);
subdiv_poly->loopstart = start_loop_index;
subdiv_poly->totloop = num_loops;
@@ -964,12 +953,8 @@ static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context
const int subdiv_vertex_index)
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MVert *coarse_mvert = coarse_mesh->mvert;
const MVert *coarse_vertex = &coarse_mvert[coarse_vertex_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
const MVert *coarse_vertex = &ctx->coarse_verts[coarse_vertex_index];
MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex);
}
@@ -980,12 +965,12 @@ static void find_edge_neighbors(const Mesh *coarse_mesh,
const MEdge *edge,
const MEdge *neighbors[2])
{
const MEdge *coarse_medge = coarse_mesh->medge;
const blender::Span<MEdge> coarse_edges = coarse_mesh->edges();
neighbors[0] = nullptr;
neighbors[1] = nullptr;
int neighbor_counters[2] = {0, 0};
for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
const MEdge *current_edge = &coarse_medge[edge_index];
const MEdge *current_edge = &coarse_edges[edge_index];
if (current_edge == edge) {
continue;
}
@@ -1014,7 +999,7 @@ static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh,
const MEdge *neighbors[2],
float points_r[4][3])
{
const MVert *coarse_mvert = coarse_mesh->mvert;
const MVert *coarse_mvert = BKE_mesh_vertices(coarse_mesh);
/* Middle points corresponds to the edge. */
copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co);
copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co);
@@ -1053,7 +1038,7 @@ void BKE_subdiv_mesh_interpolate_position_on_edge(const Mesh *coarse_mesh,
float pos_r[3])
{
if (is_simple) {
const MVert *coarse_mvert = coarse_mesh->mvert;
const MVert *coarse_mvert = BKE_mesh_vertices(coarse_mesh);
const MVert *vert_1 = &coarse_mvert[coarse_edge->v1];
const MVert *vert_2 = &coarse_mvert[coarse_edge->v2];
interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u);
@@ -1103,9 +1088,7 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index];
const bool is_simple = ctx->subdiv->settings.is_simple;
/* Interpolate custom data when not an end point.
* This data has already been copied from the original vertex by #subdiv_mesh_vertex_loose. */
@@ -1113,7 +1096,7 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
subdiv_mesh_vertex_of_loose_edge_interpolate(ctx, coarse_edge, u, subdiv_vertex_index);
}
/* Interpolate coordinate. */
MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index];
BKE_subdiv_mesh_interpolate_position_on_edge(
coarse_mesh, coarse_edge, is_simple, u, subdiv_vertex->co);
/* Reset flags and such. */
@@ -1179,7 +1162,13 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
/* Initialize subdivision mesh creation context. */
SubdivMeshContext subdiv_context = {0};
subdiv_context.settings = settings;
subdiv_context.coarse_mesh = coarse_mesh;
subdiv_context.coarse_verts = BKE_mesh_vertices(coarse_mesh);
subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh);
subdiv_context.coarse_polys = BKE_mesh_polygons(coarse_mesh);
subdiv_context.coarse_loops = BKE_mesh_loops(coarse_mesh);
subdiv_context.subdiv = subdiv;
subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr);
/* Multi-threaded traversal/evaluation. */
@@ -178,9 +178,9 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid,
0,
0,
0,
{mesh->mvert, mesh->totvert},
{mesh->mpoly, mesh->totpoly},
{mesh->mloop, mesh->totloop});
mesh->vertices_for_write(),
mesh->polygons_for_write(),
mesh->loops_for_write());
BKE_mesh_calc_edges(mesh, false, false);
@@ -54,6 +54,7 @@
#include "BKE_global.h" /* for G */
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_node_tree_update.h"
@@ -995,9 +996,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) {
data = key->refkey->data;
tot = MIN2(me->totvert, key->refkey->totelem);
MVert *vertices = BKE_mesh_vertices_for_write(me);
for (a = 0; a < tot; a++, data += 3) {
copy_v3_v3(me->mvert[a].co, data);
copy_v3_v3(vertices[a].co, data);
}
}
}
@@ -1794,10 +1794,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (DNA_struct_find(fd->filesdna, "MTexPoly")) {
for (Mesh *me = bmain->meshes.first; me; me = me->id.next) {
/* If we have UV's, so this file will have MTexPoly layers too! */
if (me->mloopuv != NULL) {
if (CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
CustomData_update_typemap(&me->pdata);
CustomData_free_layers(&me->pdata, CD_MTEXPOLY, me->totpoly);
BKE_mesh_update_customdata_pointers(me, false);
}
}
}
@@ -819,21 +819,22 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (MAIN_VERSION_ATLEAST(bmain, 290, 2) && MAIN_VERSION_OLDER(bmain, 291, 1)) {
/* In this range, the extrude manifold could generate meshes with degenerated face. */
LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
for (MPoly *mp = me->mpoly, *mp_end = mp + me->totpoly; mp < mp_end; mp++) {
for (const MPoly *mp = BKE_mesh_polygons(me), *mp_end = mp + me->totpoly; mp < mp_end;
mp++) {
if (mp->totloop == 2) {
bool changed;
BKE_mesh_validate_arrays(me,
me->mvert,
BKE_mesh_vertices_for_write(me),
me->totvert,
me->medge,
BKE_mesh_edges_for_write(me),
me->totedge,
me->mface,
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
me->mloop,
BKE_mesh_loops_for_write(me),
me->totloop,
me->mpoly,
BKE_mesh_polygons_for_write(me),
me->totpoly,
me->dvert,
BKE_mesh_deform_verts_for_write(me),
false,
true,
&changed);
@@ -345,7 +345,8 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
/* Correct default startup UV's. */
Mesh *me = BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2);
if (me && (me->totloop == 24) && (me->mloopuv != NULL)) {
if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
MLoopUV *mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
const float uv_values[24][2] = {
{0.625, 0.50}, {0.875, 0.50}, {0.875, 0.75}, {0.625, 0.75}, {0.375, 0.75}, {0.625, 0.75},
{0.625, 1.00}, {0.375, 1.00}, {0.375, 0.00}, {0.625, 0.00}, {0.625, 0.25}, {0.375, 0.25},
@@ -353,7 +354,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
{0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50},
};
for (int i = 0; i < ARRAY_SIZE(uv_values); i++) {
copy_v2_v2(me->mloopuv[i].uv, uv_values[i]);
copy_v2_v2(mloopuv[i].uv, uv_values[i]);
}
}
@@ -342,8 +342,6 @@ static void customdata_version_242(Mesh *me)
mcoln++;
}
}
BKE_mesh_update_customdata_pointers(me, true);
}
/* Only copy render texface layer from active. */
@@ -366,7 +366,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
const int *material_indices = (const int *)CustomData_get_layer_named(
&me->pdata, CD_PROP_INT32, "material_index");
Span<MVert> mvert{me->mvert, me->totvert};
Span<MVert> mvert = me->vertices();
Array<BMVert *> vtable(me->totvert);
for (const int i : mvert.index_range()) {
BMVert *v = vtable[i] = BM_vert_create(
@@ -412,7 +412,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm->elem_index_dirty &= ~BM_VERT; /* Added in order, clear dirty flag. */
}
Span<MEdge> medge{me->medge, me->totedge};
const Span<MEdge> medge = me->edges();
Array<BMEdge *> etable(me->totedge);
for (const int i : medge.index_range()) {
BMEdge *e = etable[i] = BM_edge_create(
@@ -444,8 +444,8 @@ 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. */
}
Span<MPoly> mpoly{me->mpoly, me->totpoly};
Span<MLoop> mloop{me->mloop, me->totloop};
const Span<MPoly> mpoly = me->polygons();
const Span<MLoop> mloop = me->loops();
/* Only needed for selection. */
@@ -1049,9 +1049,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
/* This is called again, 'dotess' arg is used there. */
BKE_mesh_update_customdata_pointers(me, false);
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
copy_v3_v3(mvert->co, v->co);
@@ -1226,8 +1223,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
convert_bmesh_hide_flags_to_mesh_attributes(
*bm, need_hide_vert, need_hide_edge, need_hide_poly, *me);
BKE_mesh_update_customdata_pointers(me, false);
{
me->totselect = BLI_listbase_count(&(bm->selected));
@@ -1253,7 +1248,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
if (me->key) {
bm_to_mesh_shape(bm, me->key, me->mvert, params->active_shapekey_to_mvert);
bm_to_mesh_shape(bm, me->key, mvert, params->active_shapekey_to_mvert);
}
/* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */
@@ -1303,16 +1298,15 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
BKE_mesh_update_customdata_pointers(me, false);
BMIter iter;
BMVert *eve;
BMEdge *eed;
BMFace *efa;
MVert *mvert = me->mvert;
MEdge *medge = me->medge;
MLoop *mloop = me->mloop;
MPoly *mpoly = me->mpoly;
MutableSpan<MVert> mvert = me->vertices_for_write();
MutableSpan<MEdge> medge = me->edges_for_write();
MutableSpan<MPoly> mpoly = me->polygons_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
MLoop *mloop = loops.data();
unsigned int i, j;
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
@@ -339,9 +339,9 @@ void mesh_render_data_update_looptris(MeshRenderData *mr,
mr->mlooptri = static_cast<MLoopTri *>(
MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI"));
if (mr->poly_normals != nullptr) {
BKE_mesh_recalc_looptri_with_normals(me->mloop,
me->mpoly,
me->mvert,
BKE_mesh_recalc_looptri_with_normals(mr->mloop,
mr->mpoly,
mr->mvert,
me->totloop,
me->totpoly,
mr->mlooptri,
@@ -349,7 +349,7 @@ void mesh_render_data_update_looptris(MeshRenderData *mr,
}
else {
BKE_mesh_recalc_looptri(
me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mr->mlooptri);
mr->mloop, mr->mpoly, mr->mvert, me->totloop, me->totpoly, mr->mlooptri);
}
}
}
@@ -379,15 +379,15 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__));
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL));
BKE_mesh_normals_loop_split(mr->me->mvert,
BKE_mesh_normals_loop_split(mr->mvert,
mr->vert_normals,
mr->vert_len,
mr->me->medge,
mr->medge,
mr->edge_len,
mr->me->mloop,
mr->mloop,
mr->loop_normals,
mr->loop_len,
mr->me->mpoly,
mr->mpoly,
mr->poly_normals,
mr->poly_len,
is_auto_smooth,
@@ -568,10 +568,10 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->poly_len = mr->me->totpoly;
mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
mr->mvert = static_cast<MVert *>(CustomData_get_layer(&mr->me->vdata, CD_MVERT));
mr->medge = static_cast<MEdge *>(CustomData_get_layer(&mr->me->edata, CD_MEDGE));
mr->mloop = static_cast<MLoop *>(CustomData_get_layer(&mr->me->ldata, CD_MLOOP));
mr->mpoly = static_cast<MPoly *>(CustomData_get_layer(&mr->me->pdata, CD_MPOLY));
mr->mvert = BKE_mesh_vertices(mr->me);
mr->medge = BKE_mesh_edges(mr->me);
mr->mpoly = BKE_mesh_polygons(mr->me);
mr->mloop = BKE_mesh_loops(mr->me);
mr->v_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
@@ -315,7 +315,8 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys,
}
}
if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
MFace *mface = &psmd->mesh_final->mface[num];
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
for (int j = 0; j < num_uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]);
}
@@ -344,7 +345,8 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys,
}
}
if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
MFace *mface = &psmd->mesh_final->mface[num];
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
for (int j = 0; j < num_col_layers; j++) {
/* CustomDataLayer CD_MCOL has 4 structs per face. */
psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]);
@@ -370,7 +372,8 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys,
ChildParticle *particle = &psys->child[child_index];
int num = particle->num;
if (num != DMCACHE_NOTFOUND) {
MFace *mface = &psmd->mesh_final->mface[num];
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
for (int j = 0; j < num_uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]);
}
@@ -394,7 +397,8 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys,
ChildParticle *particle = &psys->child[child_index];
int num = particle->num;
if (num != DMCACHE_NOTFOUND) {
MFace *mface = &psmd->mesh_final->mface[num];
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
for (int j = 0; j < num_col_layers; j++) {
/* CustomDataLayer CD_MCOL has 4 structs per face. */
psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]);
@@ -45,6 +45,8 @@
#include "draw_cache_inline.h"
#include "mesh_extractors/extract_mesh.hh"
using blender::Span;
extern "C" char datatoc_common_subdiv_custom_data_interp_comp_glsl[];
extern "C" char datatoc_common_subdiv_ibo_lines_comp_glsl[];
extern "C" char datatoc_common_subdiv_ibo_tris_comp_glsl[];
@@ -673,18 +675,19 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *
Mesh *mesh,
uint32_t *flags_data)
{
for (int i = 0; i < mesh->totpoly; i++) {
const Span<MPoly> polys = mesh->polygons();
for (const int i : polys.index_range()) {
uint32_t flag = 0;
if ((mesh->mpoly[i].flag & ME_SMOOTH) != 0) {
if ((polys[i].flag & ME_SMOOTH) != 0) {
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
if ((mesh->mpoly[i].flag & ME_FACE_SEL) != 0) {
if ((polys[i].flag & ME_FACE_SEL) != 0) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
if (mr->hide_poly && mr->hide_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN;
}
flags_data[i] = (uint)(mesh->mpoly[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
flags_data[i] = (uint)(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -1092,6 +1095,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
}
/* Only build polygon related data if we have polygons. */
const Span<MPoly> polys = mesh_eval->polygons();
if (cache->num_subdiv_loops != 0) {
/* Build buffers for the PatchMap. */
draw_patch_map_build(&cache->gpu_patch_map, subdiv);
@@ -1105,7 +1109,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
GPU_vertbuf_get_data(cache->fdots_patch_coords);
for (int i = 0; i < mesh_eval->totpoly; i++) {
const int ptex_face_index = cache->face_ptex_offset[i];
if (mesh_eval->mpoly[i].totloop == 4) {
if (polys[i].totloop == 4) {
/* For quads, the center coordinate of the coarse face has `u = v = 0.5`. */
blender_fdots_patch_coords[i] = make_patch_coord(ptex_face_index, 0.5f, 0.5f);
}
@@ -1118,16 +1122,16 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
}
cache->subdiv_polygon_offset_buffer = draw_subdiv_build_origindex_buffer(
cache->subdiv_polygon_offset, mesh_eval->totpoly);
cache->subdiv_polygon_offset, polys.size());
cache->face_ptex_offset_buffer = draw_subdiv_build_origindex_buffer(cache->face_ptex_offset,
mesh_eval->totpoly + 1);
polys.size() + 1);
build_vertex_face_adjacency_maps(cache);
}
cache->resolution = to_mesh_settings.resolution;
cache->num_coarse_poly = mesh_eval->totpoly;
cache->num_coarse_poly = polys.size();
/* To avoid floating point precision issues when evaluating patches at patch boundaries,
* ensure that all loops sharing a vertex use the same patch coordinate. This could cause
@@ -2152,9 +2156,10 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
int subd_vert_offset = 0;
/* Subdivide each loose coarse edge. */
const Span<MEdge> coarse_edges = coarse_mesh->edges();
for (int i = 0; i < coarse_loose_edge_len; i++) {
const int coarse_edge_index = cache->loose_geom.edges[i];
const MEdge *coarse_edge = &coarse_mesh->medge[cache->loose_geom.edges[i]];
const MEdge *coarse_edge = &coarse_edges[cache->loose_geom.edges[i]];
/* Perform interpolation of each vertex. */
for (int i = 0; i < resolution - 1; i++, subd_edge_offset++) {
@@ -2182,9 +2187,10 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
}
/* Copy the remaining loose_verts. */
const Span<MVert> coarse_verts = coarse_mesh->vertices();
for (int i = 0; i < coarse_loose_vert_len; i++) {
const int coarse_vertex_index = cache->loose_geom.verts[i];
const MVert &coarse_vertex = coarse_mesh->mvert[coarse_vertex_index];
const MVert &coarse_vertex = coarse_verts[coarse_vertex_index];
DRWSubdivLooseVertex &subd_v = loose_subd_verts[subd_vert_offset++];
subd_v.coarse_vertex_index = cache->loose_geom.verts[i];
@@ -259,7 +259,8 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness)
}
struct BVHTree_OverlapData {
const Mesh *me;
const MVert *verts;
const MLoop *loops;
const MLoopTri *mlooptri;
float epsilon;
};
@@ -267,7 +268,6 @@ struct BVHTree_OverlapData {
static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
{
struct BVHTree_OverlapData *data = static_cast<struct BVHTree_OverlapData *>(userdata);
const Mesh *me = data->me;
const MLoopTri *tri_a = &data->mlooptri[index_a];
const MLoopTri *tri_b = &data->mlooptri[index_b];
@@ -276,12 +276,12 @@ static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(
return false;
}
const float *tri_a_co[3] = {me->mvert[me->mloop[tri_a->tri[0]].v].co,
me->mvert[me->mloop[tri_a->tri[1]].v].co,
me->mvert[me->mloop[tri_a->tri[2]].v].co};
const float *tri_b_co[3] = {me->mvert[me->mloop[tri_b->tri[0]].v].co,
me->mvert[me->mloop[tri_b->tri[1]].v].co,
me->mvert[me->mloop[tri_b->tri[2]].v].co};
const float *tri_a_co[3] = {data->verts[data->loops[tri_a->tri[0]].v].co,
data->verts[data->loops[tri_a->tri[1]].v].co,
data->verts[data->loops[tri_a->tri[2]].v].co};
const float *tri_b_co[3] = {data->verts[data->loops[tri_b->tri[0]].v].co,
data->verts[data->loops[tri_b->tri[1]].v].co,
data->verts[data->loops[tri_b->tri[2]].v].co};
float ix_pair[2][3];
int verts_shared = 0;
@@ -342,7 +342,8 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect)
BVHTree *tree = BKE_bvhtree_from_mesh_get(&treeData, mr->me, BVHTREE_FROM_LOOPTRI, 4);
struct BVHTree_OverlapData data = {nullptr};
data.me = mr->me;
data.verts = mr->mvert;
data.loops = mr->mloop;
data.mlooptri = mr->mlooptri;
data.epsilon = BLI_bvhtree_get_epsilon(tree);
@@ -9,6 +9,7 @@
#include "BLI_string.h"
#include "BKE_mesh.h"
#include "BKE_paint.h"
#include "draw_subdivision.h"
@@ -128,6 +129,9 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPUVertBuf *subdiv_mask_vbo = nullptr;
const float *cd_mask = (const float *)CustomData_get_layer(cd_vdata, CD_PAINT_MASK);
const Span<MPoly> coarse_polys = coarse_mesh->polygons();
const Span<MLoop> coarse_loops = coarse_mesh->loops();
if (cd_mask) {
GPUVertFormat mask_format = {0};
GPU_vertformat_attr_add(&mask_format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
@@ -138,11 +142,11 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
float *v_mask = static_cast<float *>(GPU_vertbuf_get_data(mask_vbo));
for (int i = 0; i < coarse_mesh->totpoly; i++) {
const MPoly *mpoly = &coarse_mesh->mpoly[i];
const MPoly *mpoly = &coarse_polys[i];
for (int loop_index = mpoly->loopstart; loop_index < mpoly->loopstart + mpoly->totloop;
loop_index++) {
const MLoop *ml = &coarse_mesh->mloop[loop_index];
const MLoop *ml = &coarse_loops[loop_index];
*v_mask++ = cd_mask[ml->v];
}
}
@@ -8,6 +8,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "draw_subdivision.h"
#include "extract_mesh.hh"
@@ -105,7 +106,7 @@ static void extract_weights_init(const MeshRenderData *mr,
data->cd_ofs = CustomData_get_offset(&mr->bm->vdata, CD_MDEFORMVERT);
}
else {
data->dvert = (const MDeformVert *)CustomData_get_layer(&mr->me->vdata, CD_MDEFORMVERT);
data->dvert = mr->me->deform_verts().data();
data->cd_ofs = -1;
}
}
@@ -171,8 +172,9 @@ static void extract_weights_init_subdiv(const DRWSubdivCache *subdiv_cache,
extract_weights_init(mr, cache, coarse_weights, _data);
if (mr->extract_type != MR_EXTRACT_BMESH) {
for (int i = 0; i < coarse_mesh->totpoly; i++) {
const MPoly *mpoly = &coarse_mesh->mpoly[i];
const Span<MPoly> coarse_polys = coarse_mesh->polygons();
for (const int i : coarse_polys.index_range()) {
const MPoly *mpoly = &coarse_polys[i];
extract_weights_iter_poly_mesh(mr, mpoly, i, _data);
}
}
@@ -21,6 +21,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
@@ -203,9 +204,9 @@ static void envelope_bone_weighting(Object *ob,
}
/* for each vertex in the mesh */
const MVert *mesh_verts = BKE_mesh_vertices(mesh);
for (int i = 0; i < mesh->totvert; i++) {
if (use_mask && !(mesh->mvert[i].flag & SELECT)) {
if (use_mask && !(mesh_verts[i].flag & SELECT)) {
continue;
}
@@ -405,9 +406,10 @@ static void add_verts_to_dgroups(ReportList *reports,
}
/* transform verts to global space */
const MVert *mesh_verts = BKE_mesh_vertices(mesh);
for (int i = 0; i < mesh->totvert; i++) {
if (!vertsfilled) {
copy_v3_v3(verts[i], mesh->mvert[i].co);
copy_v3_v3(verts[i], mesh_verts[i].co);
}
mul_m4_v3(ob->obmat, verts[i]);
}
+16 -14
View File
@@ -645,14 +645,16 @@ void heat_bone_weighting(Object *ob,
{
LaplacianSystem *sys;
MLoopTri *mlooptri;
MPoly *mp;
MLoop *ml;
const MPoly *mp;
const MLoop *ml;
float solution, weight;
int *vertsflipped = NULL, *mask = NULL;
int a, tris_num, j, bbone, firstsegment, lastsegment;
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
MVert *mvert = me->mvert;
const MVert *mesh_verts = BKE_mesh_vertices(me);
const MPoly *polys = BKE_mesh_polygons(me);
const MLoop *loops = BKE_mesh_loops(me);
bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
@@ -667,16 +669,16 @@ void heat_bone_weighting(Object *ob,
/* (added selectedVerts content for vertex mask, they used to just equal 1) */
if (use_vert_sel) {
for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0;
for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
mask[ml->v] = (mesh_verts[ml->v].flag & SELECT) != 0;
}
}
}
else if (use_face_sel) {
for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
if (mp->flag & ME_FACE_SEL) {
for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
mask[ml->v] = 1;
}
}
@@ -690,10 +692,10 @@ void heat_bone_weighting(Object *ob,
sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop);
mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__);
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri);
BKE_mesh_recalc_looptri(loops, polys, mesh_verts, me->totloop, me->totpoly, mlooptri);
sys->heat.mlooptri = mlooptri;
sys->heat.mloop = me->mloop;
sys->heat.mloop = loops;
sys->heat.verts_num = me->totvert;
sys->heat.verts = verts;
sys->heat.root = root;
@@ -1606,8 +1608,8 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
/* initialize data from 'cagedm' for reuse */
{
Mesh *me = mdb->cagemesh;
mdb->cagemesh_cache.mpoly = me->mpoly;
mdb->cagemesh_cache.mloop = me->mloop;
mdb->cagemesh_cache.mpoly = BKE_mesh_polygons(me);
mdb->cagemesh_cache.mloop = BKE_mesh_loops(me);
mdb->cagemesh_cache.looptri = BKE_mesh_runtime_looptri_ensure(me);
mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me);
}
@@ -1743,7 +1745,7 @@ void ED_mesh_deform_bind_callback(Object *object,
MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original(
object, &mmd->modifier);
MeshDeformBind mdb;
MVert *mvert;
const MVert *mvert;
int a;
waitcursor(1);
@@ -1763,7 +1765,7 @@ void ED_mesh_deform_bind_callback(Object *object,
mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos");
copy_m4_m4(mdb.cagemat, cagemat);
mvert = mdb.cagemesh->mvert;
mvert = BKE_mesh_vertices(mdb.cagemesh);
for (a = 0; a < mdb.cage_verts_num; a++) {
copy_v3_v3(mdb.cagecos[a], mvert[a].co);
}
@@ -139,7 +139,8 @@ using bke::CurvesGeometry;
namespace convert_to_particle_system {
static int find_mface_for_root_position(const Mesh &mesh,
static int find_mface_for_root_position(const Span<MVert> verts,
const MFace *mface,
const Span<int> possible_mface_indices,
const float3 &root_pos)
{
@@ -151,14 +152,14 @@ static int find_mface_for_root_position(const Mesh &mesh,
int mface_i;
float best_distance_sq = FLT_MAX;
for (const int possible_mface_i : possible_mface_indices) {
const MFace &possible_mface = mesh.mface[possible_mface_i];
const MFace &possible_mface = mface[possible_mface_i];
{
float3 point_in_triangle;
closest_on_tri_to_point_v3(point_in_triangle,
root_pos,
mesh.mvert[possible_mface.v1].co,
mesh.mvert[possible_mface.v2].co,
mesh.mvert[possible_mface.v3].co);
verts[possible_mface.v1].co,
verts[possible_mface.v2].co,
verts[possible_mface.v3].co);
const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle);
if (distance_sq < best_distance_sq) {
best_distance_sq = distance_sq;
@@ -170,9 +171,9 @@ static int find_mface_for_root_position(const Mesh &mesh,
float3 point_in_triangle;
closest_on_tri_to_point_v3(point_in_triangle,
root_pos,
mesh.mvert[possible_mface.v1].co,
mesh.mvert[possible_mface.v3].co,
mesh.mvert[possible_mface.v4].co);
verts[possible_mface.v1].co,
verts[possible_mface.v3].co,
verts[possible_mface.v4].co);
const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle);
if (distance_sq < best_distance_sq) {
best_distance_sq = distance_sq;
@@ -186,25 +187,22 @@ static int find_mface_for_root_position(const Mesh &mesh,
/**
* \return Barycentric coordinates in the #MFace.
*/
static float4 compute_mface_weights_for_position(const Mesh &mesh,
static float4 compute_mface_weights_for_position(const Span<MVert> verts,
const MFace &mface,
const float3 &position)
{
float4 mface_weights;
if (mface.v4) {
float mface_verts_su[4][3];
copy_v3_v3(mface_verts_su[0], mesh.mvert[mface.v1].co);
copy_v3_v3(mface_verts_su[1], mesh.mvert[mface.v2].co);
copy_v3_v3(mface_verts_su[2], mesh.mvert[mface.v3].co);
copy_v3_v3(mface_verts_su[3], mesh.mvert[mface.v4].co);
copy_v3_v3(mface_verts_su[0], verts[mface.v1].co);
copy_v3_v3(mface_verts_su[1], verts[mface.v2].co);
copy_v3_v3(mface_verts_su[2], verts[mface.v3].co);
copy_v3_v3(mface_verts_su[3], verts[mface.v4].co);
interp_weights_poly_v3(mface_weights, mface_verts_su, 4, position);
}
else {
interp_weights_tri_v3(mface_weights,
mesh.mvert[mface.v1].co,
mesh.mvert[mface.v2].co,
mesh.mvert[mface.v3].co,
position);
interp_weights_tri_v3(
mface_weights, verts[mface.v1].co, verts[mface.v2].co, verts[mface.v3].co, position);
mface_weights[3] = 0.0f;
}
return mface_weights;
@@ -287,6 +285,9 @@ static void try_convert_single_object(Object &curves_ob,
/* Prepare transformation matrices. */
const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob};
const MFace *mfaces = (const MFace *)CustomData_get_layer(&surface_me.fdata, CD_MFACE);
const Span<MVert> verts = surface_me.vertices();
for (const int new_hair_i : IndexRange(hair_num)) {
const int curve_i = new_hair_i;
const IndexRange points = curves.points_for_curve(curve_i);
@@ -305,11 +306,10 @@ static void try_convert_single_object(Object &curves_ob,
const int poly_i = looptri.poly;
const int mface_i = find_mface_for_root_position(
surface_me, poly_to_mface_map[poly_i], root_pos_su);
const MFace &mface = surface_me.mface[mface_i];
verts, mfaces, poly_to_mface_map[poly_i], root_pos_su);
const MFace &mface = mfaces[mface_i];
const float4 mface_weights = compute_mface_weights_for_position(
surface_me, mface, root_pos_su);
const float4 mface_weights = compute_mface_weights_for_position(verts, mface, root_pos_su);
ParticleData &particle = particles[new_hair_i];
const int num_keys = points.size();
@@ -541,8 +541,11 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
Mesh &surface_mesh = *static_cast<Mesh *>(surface_ob.data);
const Mesh &surface_mesh = *static_cast<const Mesh *>(surface_ob.data);
const Span<MVert> verts = surface_mesh.vertices();
const Span<MLoop> loops = surface_mesh.loops();
const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
BKE_mesh_runtime_looptri_len(&surface_mesh)};
VArraySpan<float2> surface_uv_map;
if (curves_id.surface_uv_map != nullptr) {
const bke::AttributeAccessor surface_attributes = bke::mesh_attributes(surface_mesh);
@@ -554,9 +557,6 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
MutableSpan<float3> positions_cu = curves.positions_for_write();
MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write();
const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
BKE_mesh_runtime_looptri_len(&surface_mesh)};
const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob};
switch (attach_mode) {
@@ -603,9 +603,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
const float2 &uv0 = surface_uv_map[corner0];
const float2 &uv1 = surface_uv_map[corner1];
const float2 &uv2 = surface_uv_map[corner2];
const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[corner0].v].co;
const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[corner1].v].co;
const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[corner2].v].co;
const float3 &p0_su = verts[loops[corner0].v].co;
const float3 &p1_su = verts[loops[corner1].v].co;
const float3 &p2_su = verts[loops[corner2].v].co;
float3 bary_coords;
interp_weights_tri_v3(bary_coords, p0_su, p1_su, p2_su, new_first_point_pos_su);
const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2);
@@ -639,9 +639,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
const MLoopTri &looptri = *lookup_result.looptri;
const float3 &bary_coords = lookup_result.bary_weights;
const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[0]].v].co;
const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[1]].v].co;
const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[2]].v].co;
const float3 &p0_su = verts[loops[looptri.tri[0]].v].co;
const float3 &p1_su = verts[loops[looptri.tri[1]].v].co;
const float3 &p2_su = verts[loops[looptri.tri[2]].v].co;
float3 new_first_point_pos_su;
interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords);
@@ -471,11 +471,6 @@ static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
if (GS(id->name) == ID_ME) {
Mesh *me = static_cast<Mesh *>(ob->data);
BKE_mesh_update_customdata_pointers(me, true);
}
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
+54 -47
View File
@@ -44,9 +44,7 @@ void paintface_flush_flags(bContext *C,
{
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
MPoly *polys, *mp_orig;
const int *index_array = nullptr;
int totpoly;
BLI_assert(flush_selection || flush_hidden);
@@ -75,11 +73,13 @@ void paintface_flush_flags(bContext *C,
Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval;
bke::MutableAttributeAccessor attributes_eval = bke::mesh_attributes_for_write(*me_eval);
bool updated = false;
const Span<MPoly> me_polys = me->polygons();
if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) {
/* Update the COW copy of the mesh. */
MutableSpan<MPoly> orig_polys = me_orig->polygons_for_write();
for (int i = 0; i < me->totpoly; i++) {
me_orig->mpoly[i].flag = me->mpoly[i].flag;
orig_polys[i].flag = me_polys[i].flag;
}
if (flush_hidden) {
const VArray<bool> hide_poly_me = attributes_me.lookup_or_default<bool>(
@@ -92,15 +92,12 @@ void paintface_flush_flags(bContext *C,
/* Mesh polys => Final derived polys */
if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
polys = me_eval->mpoly;
totpoly = me_eval->totpoly;
MutableSpan<MPoly> eval_polys = me_orig->polygons_for_write();
/* loop over final derived polys */
for (int i = 0; i < totpoly; i++) {
for (const int i : eval_polys.index_range()) {
if (index_array[i] != ORIGINDEX_NONE) {
/* Copy flags onto the final derived poly from the original mesh poly */
mp_orig = me->mpoly + index_array[i];
polys[i].flag = mp_orig->flag;
eval_polys[i].flag = me_polys[index_array[i]].flag;
}
}
const VArray<bool> hide_poly_orig = attributes_orig.lookup_or_default<bool>(
@@ -144,12 +141,13 @@ void paintface_hide(bContext *C, Object *ob, const bool unselected)
return;
}
MutableSpan<MPoly> polys = me->polygons_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
bke::SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_span<bool>(
".hide_poly", ATTR_DOMAIN_FACE);
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
MPoly *mpoly = &polys[i];
if (!hide_poly.span[i]) {
if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) {
hide_poly.span[i] = true;
@@ -176,13 +174,14 @@ void paintface_reveal(bContext *C, Object *ob, const bool select)
return;
}
MutableSpan<MPoly> polys = me->polygons_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
if (select) {
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
MPoly *mpoly = &polys[i];
if (hide_poly[i]) {
mpoly->flag |= ME_FACE_SEL;
}
@@ -207,25 +206,28 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__);
BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
const Span<MEdge> edges = me->edges();
MutableSpan<MPoly> polys = me->polygons_for_write();
const Span<MLoop> loops = me->loops();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
if (index != (uint)-1) {
/* only put face under cursor in array */
MPoly *mp = &me->mpoly[index];
BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
const MPoly *mp = &polys[index];
BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
BLI_BITMAP_ENABLE(poly_tag, index);
}
else {
/* fill array by selection */
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
MPoly *mp = &polys[i];
if (hide_poly[i]) {
/* pass */
}
else if (mp->flag & ME_FACE_SEL) {
BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
BLI_BITMAP_ENABLE(poly_tag, i);
}
}
@@ -236,7 +238,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
/* expand selection */
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
MPoly *mp = &polys[i];
if (hide_poly[i]) {
continue;
}
@@ -244,9 +246,9 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
if (!BLI_BITMAP_TEST(poly_tag, i)) {
mark = false;
MLoop *ml = me->mloop + mp->loopstart;
const MLoop *ml = &loops[mp->loopstart];
for (int b = 0; b < mp->totloop; b++, ml++) {
if ((me->medge[ml->e].flag & ME_SEAM) == 0) {
if ((edges[ml->e].flag & ME_SEAM) == 0) {
if (BLI_BITMAP_TEST(edge_tag, ml->e)) {
mark = true;
break;
@@ -256,7 +258,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
if (mark) {
BLI_BITMAP_ENABLE(poly_tag, i);
BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
do_it = true;
}
}
@@ -266,7 +268,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
MEM_freeN(edge_tag);
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
MPoly *mp = &polys[index];
if (BLI_BITMAP_TEST(poly_tag, i)) {
SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL);
}
@@ -303,6 +305,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
return false;
}
MutableSpan<MPoly> polys = me->polygons_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
@@ -311,7 +314,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
action = SEL_SELECT;
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
MPoly *mpoly = &polys[i];
if (!hide_poly[i] && mpoly->flag & ME_FACE_SEL) {
action = SEL_DESELECT;
break;
@@ -322,7 +325,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
bool changed = false;
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
MPoly *mpoly = &polys[i];
if (!hide_poly[i]) {
switch (action) {
case SEL_SELECT:
@@ -360,26 +363,28 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
float vec[3], bmat[3][3];
const Mesh *me = BKE_mesh_from_object(ob);
if (!me || !me->mloopuv) {
if (!me || !CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
return ok;
}
const MVert *mvert = me->mvert;
copy_m3_m4(bmat, ob->obmat);
const Span<MVert> verts = me->vertices();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
const MPoly *mp = &polys[i];
if (hide_poly[i] || !(mp->flag & ME_FACE_SEL)) {
continue;
}
const MLoop *ml = me->mloop + mp->loopstart;
const MLoop *ml = &loops[mp->loopstart];
for (int b = 0; b < mp->totloop; b++, ml++) {
mul_v3_m3v3(vec, bmat, mvert[ml->v].co);
mul_v3_m3v3(vec, bmat, verts[ml->v].co);
add_v3_v3v3(vec, vec, ob->obmat[3]);
minmax_v3v3_v3(r_min, r_max, vec);
}
@@ -404,13 +409,14 @@ bool paintface_mouse_select(bContext *C,
/* Get the face under the cursor */
Mesh *me = BKE_mesh_from_object(ob);
MutableSpan<MPoly> polys = me->polygons_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
if (index < me->totpoly) {
mpoly_sel = me->mpoly + index;
mpoly_sel = polys.data() + index;
if (!hide_poly[index]) {
found = true;
}
@@ -469,12 +475,10 @@ bool paintface_mouse_select(bContext *C,
void paintvert_flush_flags(Object *ob)
{
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
MVert *mvert_eval, *mv;
const int *index_array = nullptr;
int totvert;
int i;
if (me == nullptr) {
return;
@@ -490,23 +494,21 @@ void paintvert_flush_flags(Object *ob)
index_array = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
mvert_eval = me_eval->mvert;
totvert = me_eval->totvert;
mv = mvert_eval;
const Span<MVert> vertices = me->vertices_for_write();
MutableSpan<MVert> vertices_eval = me_eval->vertices_for_write();
if (index_array) {
int orig_index;
for (i = 0; i < totvert; i++, mv++) {
for (const int i : vertices_eval.index_range()) {
orig_index = index_array[i];
if (orig_index != ORIGINDEX_NONE) {
mv->flag = me->mvert[index_array[i]].flag;
vertices_eval[i].flag = vertices[index_array[i]].flag;
}
}
}
else {
for (i = 0; i < totvert; i++, mv++) {
mv->flag = me->mvert[i].flag;
for (const int i : vertices_eval.index_range()) {
vertices_eval[i].flag = vertices[i].flag;
}
}
@@ -527,6 +529,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
return false;
}
MutableSpan<MVert> verts = me->vertices_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
@@ -535,7 +538,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
action = SEL_SELECT;
for (int i = 0; i < me->totvert; i++) {
MVert *mvert = &me->mvert[i];
MVert *mvert = &verts[i];
if (!hide_vert[i] && mvert->flag & SELECT) {
action = SEL_DESELECT;
break;
@@ -545,7 +548,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
bool changed = false;
for (int i = 0; i < me->totvert; i++) {
MVert *mvert = &me->mvert[i];
MVert *mvert = &verts[i];
if (!hide_vert[i]) {
switch (action) {
case SEL_SELECT:
@@ -591,8 +594,11 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
{
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr || me->dvert == nullptr) {
if (me == nullptr) {
return;
}
const Span<MDeformVert> dverts = me->deform_verts();
if (dverts.is_empty()) {
return;
}
@@ -600,13 +606,14 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
}
MutableSpan<MVert> verts = me->vertices_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
for (int i = 0; i < me->totvert; i++) {
MVert *mv = &me->mvert[i];
MDeformVert *dv = &me->dvert[i];
MVert *mv = &verts[i];
const MDeformVert *dv = &dverts[i];
if (!hide_vert[i]) {
if (dv->dw == nullptr) {
/* if null weight then not grouped */
@@ -628,10 +635,10 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected)
return;
}
MutableSpan<MVert> verts = me->vertices_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
bke::SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
MutableSpan<MVert> verts(me->mvert, me->totvert);
for (const int i : verts.index_range()) {
MVert &vert = verts[i];
@@ -661,10 +668,10 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select)
return;
}
MutableSpan<MVert> verts = me->vertices_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
MutableSpan<MVert> verts(me->mvert, me->totvert);
for (const int i : verts.index_range()) {
MVert &vert = verts[i];
@@ -361,8 +361,6 @@ static void um_arraystore_compact_ex(UndoMesh *um, const UndoMesh *um_ref, bool
if (create) {
um_arraystore.users += 1;
}
BKE_mesh_update_customdata_pointers(me, false);
}
/**
@@ -465,9 +463,6 @@ static void um_arraystore_expand(UndoMesh *um)
BLI_assert(me->totselect == (state_len / stride));
UNUSED_VARS_NDEBUG(stride);
}
/* not essential, but prevents accidental dangling pointer access */
BKE_mesh_update_customdata_pointers(me, false);
}
static void um_arraystore_free(UndoMesh *um)
+56 -51
View File
@@ -18,6 +18,7 @@
#include "BLI_utildefines.h"
#include "BKE_attribute.h"
#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
@@ -44,6 +45,8 @@
#include "mesh_intern.h" /* own include */
using blender::Array;
using blender::MutableSpan;
using blender::Span;
static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot)
{
@@ -128,7 +131,6 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer)
}
else {
CustomData_free_layer(data, type, tot, layer_index + n);
BKE_mesh_update_customdata_pointers(me, true);
}
}
@@ -186,7 +188,7 @@ static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset)
mesh_uv_reset_array(fuv.data(), f->len);
}
static void mesh_uv_reset_mface(MPoly *mp, MLoopUV *mloopuv)
static void mesh_uv_reset_mface(const MPoly *mp, MLoopUV *mloopuv)
{
Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(mp->totloop);
@@ -223,8 +225,9 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, layernum);
const MPoly *polys = BKE_mesh_polygons(me);
for (int i = 0; i < me->totpoly; i++) {
mesh_uv_reset_mface(&me->mpoly[i], mloopuv);
mesh_uv_reset_mface(&polys[i], mloopuv);
}
}
@@ -280,9 +283,13 @@ int ED_mesh_uv_add(
return -1;
}
if (me->mloopuv && do_init) {
CustomData_add_layer_named(
&me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name);
if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) && do_init) {
CustomData_add_layer_named(&me->ldata,
CD_MLOOPUV,
CD_DUPLICATE,
CustomData_get_layer(&me->ldata, CD_MLOOPUV),
me->totloop,
name);
is_init = true;
}
else {
@@ -293,8 +300,6 @@ int ED_mesh_uv_add(
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst);
}
BKE_mesh_update_customdata_pointers(me, true);
}
/* don't overwrite our copied coords */
@@ -399,9 +404,13 @@ int ED_mesh_color_add(Mesh *me,
else {
layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
if (me->mloopcol && do_init) {
CustomData_add_layer_named(
&me->ldata, CD_PROP_BYTE_COLOR, CD_DUPLICATE, me->mloopcol, me->totloop, name);
if (CustomData_get_active_layer(&me->ldata, CD_PROP_BYTE_COLOR) != -1 && do_init) {
CustomData_add_layer_named(&me->ldata,
CD_PROP_BYTE_COLOR,
CD_DUPLICATE,
CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR),
me->totloop,
name);
}
else {
CustomData_add_layer_named(
@@ -412,7 +421,7 @@ int ED_mesh_color_add(Mesh *me,
CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, layernum);
}
BKE_mesh_update_customdata_pointers(me, true);
BKE_mesh_tessface_clear(me);
}
DEG_id_tag_update(&me->id, 0);
@@ -432,7 +441,7 @@ bool ED_mesh_color_ensure(Mesh *me, const char *name)
layer = me->ldata.layers + CustomData_get_layer_index(&me->ldata, CD_PROP_BYTE_COLOR);
BKE_id_attributes_active_color_set(&me->id, layer);
BKE_mesh_update_customdata_pointers(me, true);
BKE_mesh_tessface_clear(me);
}
DEG_id_tag_update(&me->id, 0);
@@ -496,7 +505,7 @@ int ED_mesh_sculpt_color_add(Mesh *me,
CustomData_set_layer_active(&me->vdata, CD_PROP_COLOR, layernum);
}
BKE_mesh_update_customdata_pointers(me, true);
BKE_mesh_tessface_clear(me);
}
DEG_id_tag_update(&me->id, 0);
@@ -767,15 +776,20 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator
/* Tag edges as sharp according to smooth threshold if needed,
* to preserve autosmooth shading. */
if (me->flag & ME_AUTOSMOOTH) {
BKE_edges_sharp_from_angle_set(me->mvert,
me->totvert,
me->medge,
me->totedge,
me->mloop,
me->totloop,
me->mpoly,
const Span<MVert> verts = me->vertices();
MutableSpan<MEdge> edges = me->edges_for_write();
const Span<MPoly> polys = me->polygons();
const Span<MLoop> loops = me->loops();
BKE_edges_sharp_from_angle_set(verts.data(),
verts.size(),
edges.data(),
edges.size(),
loops.data(),
loops.size(),
polys.data(),
BKE_mesh_poly_normals_ensure(me),
me->totpoly,
polys.size(),
me->smoothresh);
}
@@ -873,27 +887,22 @@ static void mesh_add_verts(Mesh *mesh, int len)
CustomData_free(&mesh->vdata, mesh->totvert);
mesh->vdata = vdata;
BKE_mesh_update_customdata_pointers(mesh, false);
BKE_mesh_runtime_clear_cache(mesh);
/* scan the input list and insert the new vertices */
/* set default flags */
MVert *mvert = &mesh->mvert[mesh->totvert];
for (int i = 0; i < len; i++, mvert++) {
mvert->flag |= SELECT;
}
/* set final vertex list size */
const int old_vertex_num = mesh->totvert;
mesh->totvert = totvert;
MutableSpan<MVert> verts = mesh->vertices_for_write();
for (MVert &vert : verts.drop_front(old_vertex_num)) {
vert.flag = SELECT;
}
}
static void mesh_add_edges(Mesh *mesh, int len)
{
CustomData edata;
MEdge *medge;
int i, totedge;
int totedge;
if (len == 0) {
return;
@@ -911,17 +920,16 @@ static void mesh_add_edges(Mesh *mesh, int len)
CustomData_free(&mesh->edata, mesh->totedge);
mesh->edata = edata;
BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */
BKE_mesh_runtime_clear_cache(mesh);
/* set default flags */
medge = &mesh->medge[mesh->totedge];
for (i = 0; i < len; i++, medge++) {
medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
}
const int old_edges_num = mesh->totedge;
mesh->totedge = totedge;
MutableSpan<MEdge> edges = mesh->edges_for_write();
for (MEdge &edge : edges.drop_front(old_edges_num)) {
edge.flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
}
}
static void mesh_add_loops(Mesh *mesh, int len)
@@ -947,7 +955,6 @@ static void mesh_add_loops(Mesh *mesh, int len)
CustomData_free(&mesh->ldata, mesh->totloop);
mesh->ldata = ldata;
BKE_mesh_update_customdata_pointers(mesh, true);
mesh->totloop = totloop;
}
@@ -955,8 +962,7 @@ static void mesh_add_loops(Mesh *mesh, int len)
static void mesh_add_polys(Mesh *mesh, int len)
{
CustomData pdata;
MPoly *mpoly;
int i, totpoly;
int totpoly;
if (len == 0) {
return;
@@ -974,17 +980,16 @@ static void mesh_add_polys(Mesh *mesh, int len)
CustomData_free(&mesh->pdata, mesh->totpoly);
mesh->pdata = pdata;
BKE_mesh_update_customdata_pointers(mesh, true);
BKE_mesh_runtime_clear_cache(mesh);
/* set default flags */
mpoly = &mesh->mpoly[mesh->totpoly];
for (i = 0; i < len; i++, mpoly++) {
mpoly->flag = ME_FACE_SEL;
}
const int old_polys_num = mesh->totpoly;
mesh->totpoly = totpoly;
MutableSpan<MPoly> polys = mesh->polygons_for_write();
for (MPoly &poly : polys.drop_front(old_polys_num)) {
poly.flag = ME_FACE_SEL;
}
}
/* -------------------------------------------------------------------- */
+5 -8
View File
@@ -55,11 +55,9 @@ void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *me_eva
}
}
else {
MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
int i;
for (i = 0; i < totvert; i++, mvert++) {
BLI_kdtree_3d_insert(MirrKdStore.tree, i, mvert->co);
const MVert *verts = BKE_mesh_vertices(me_eval ? me_eval : me);
for (int i = 0; i < totvert; i++) {
BLI_kdtree_3d_insert(MirrKdStore.tree, i, verts[i].co);
}
}
@@ -164,7 +162,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
BLI_assert(me == NULL);
}
const bool is_editmode = (em != NULL);
MEdge *medge = NULL, *med;
const MEdge *medge = NULL, *med;
/* Edit-mode variables. */
BMEdge *eed;
@@ -210,8 +208,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
}
else {
totedge = me->totedge;
medge = me->medge;
medge = BKE_mesh_edges(me);
for (a = 0, med = medge; a < totedge; a++, med++) {
const uint i1 = med->v1, i2 = med->v2;
topo_hash[i1]++;
+28 -40
View File
@@ -55,6 +55,9 @@
#include "WM_api.h"
#include "WM_types.h"
using blender::MutableSpan;
using blender::Span;
/* * ********************** no editmode!!! *********** */
/*********************** JOIN ***************************/
@@ -691,9 +694,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me->ldata = ldata;
me->pdata = pdata;
/* tessface data removed above, no need to update */
BKE_mesh_update_customdata_pointers(me, false);
/* Tag normals dirty because vertex positions could be changed from the original. */
BKE_mesh_normals_tag_dirty(me);
@@ -906,13 +906,13 @@ static bool ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval)
static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *me_eval, int index)
{
Mesh *me = static_cast<Mesh *>(ob->data);
MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
const Span<MVert> verts = me_eval ? me_eval->vertices() : me->vertices();
float vec[3];
mvert = &mvert[index];
vec[0] = -mvert->co[0];
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
vec[0] = -verts[index].co[0];
vec[1] = verts[index].co[1];
vec[2] = verts[index].co[2];
return ED_mesh_mirror_spatial_table_lookup(ob, nullptr, me_eval, vec);
}
@@ -1128,8 +1128,8 @@ static bool mirror_facecmp(const void *a, const void *b)
int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
{
Mesh *me = static_cast<Mesh *>(ob->data);
MVert *mv, *mvert;
MFace mirrormf, *mf, *hashmf, *mface;
const MVert *mv;
MFace mirrormf, *mf, *hashmf;
GHash *fhash;
int *mirrorverts, *mirrorfaces;
@@ -1143,12 +1143,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
mirrorverts = static_cast<int *>(MEM_callocN(sizeof(int) * totvert, "MirrorVerts"));
mirrorfaces = static_cast<int *>(MEM_callocN(sizeof(int[2]) * totface, "MirrorFaces"));
mvert = me_eval ? me_eval->mvert : me->mvert;
mface = me_eval ? me_eval->mface : me->mface;
const Span<MVert> verts = me_eval ? me_eval->vertices() : me->vertices();
MFace *mface = (MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, CD_MFACE);
ED_mesh_mirror_spatial_table_begin(ob, em, me_eval);
for (a = 0, mv = mvert; a < totvert; a++, mv++) {
for (a = 0, mv = verts.data(); a < totvert; a++, mv++) {
mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology);
}
@@ -1275,42 +1275,28 @@ bool ED_mesh_pick_face_vert(
const float mval_f[2] = {(float)mval[0], (float)mval[1]};
float len_best = FLT_MAX;
MPoly *me_eval_mpoly;
MLoop *me_eval_mloop;
MVert *me_eval_mvert;
uint me_eval_mpoly_len;
me_eval_mpoly = me_eval->mpoly;
me_eval_mloop = me_eval->mloop;
me_eval_mvert = me_eval->mvert;
me_eval_mpoly_len = me_eval->totpoly;
const Span<MVert> verts = me_eval->vertices();
const Span<MPoly> polys = me_eval->polygons();
const Span<MLoop> loops = me_eval->loops();
const int *index_mp_to_orig = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
/* tag all verts using this face */
if (index_mp_to_orig) {
uint i;
for (i = 0; i < me_eval_mpoly_len; i++) {
for (const int i : polys.index_range()) {
if (index_mp_to_orig[i] == poly_index) {
ed_mesh_pick_face_vert__mpoly_find(region,
mval_f,
&me_eval_mpoly[i],
me_eval_mvert,
me_eval_mloop,
&len_best,
&v_idx_best);
ed_mesh_pick_face_vert__mpoly_find(
region, mval_f, &polys[i], verts.data(), loops.data(), &len_best, &v_idx_best);
}
}
}
else {
if (poly_index < me_eval_mpoly_len) {
if (poly_index < polys.size()) {
ed_mesh_pick_face_vert__mpoly_find(region,
mval_f,
&me_eval_mpoly[poly_index],
me_eval_mvert,
me_eval_mloop,
&polys[poly_index],
verts.data(),
loops.data(),
&len_best,
&v_idx_best);
}
@@ -1425,7 +1411,8 @@ bool ED_mesh_pick_vert(
}
/* setup data */
data.mvert = me->mvert;
const Span<MVert> verts = me->vertices();
data.mvert = verts.data();
data.region = region;
data.mval_f = mval_f;
data.len_best = FLT_MAX;
@@ -1479,10 +1466,11 @@ MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
if (r_index) {
*r_index = index;
}
if (index == -1 || me->dvert == nullptr) {
if (index == -1 || me->deform_verts().is_empty()) {
return nullptr;
}
return me->dvert + index;
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
return &dverts[index];
}
MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
+1 -1
View File
@@ -155,7 +155,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
break;
}
if (!me->mloopuv) {
if (!CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
ok = false;
@@ -971,7 +971,8 @@ static bool bake_targets_init_vertex_colors(Main *bmain,
return true;
}
static int find_original_loop(const Mesh *me_orig,
static int find_original_loop(const MPoly *orig_polys,
const MLoop *orig_loops,
const int *vert_origindex,
const int *poly_origindex,
const int poly_eval,
@@ -987,8 +988,8 @@ static int find_original_loop(const Mesh *me_orig,
}
/* Find matching loop with original vertex in original polygon. */
MPoly *mpoly_orig = me_orig->mpoly + poly_orig;
MLoop *mloop_orig = me_orig->mloop + mpoly_orig->loopstart;
const MPoly *mpoly_orig = orig_polys + poly_orig;
const MLoop *mloop_orig = orig_loops + mpoly_orig->loopstart;
for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) {
if (mloop_orig->v == vert_orig) {
return mpoly_orig->loopstart + j;
@@ -1025,23 +1026,31 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets,
const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop);
MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
BKE_mesh_recalc_looptri(
me_eval->mloop, me_eval->mpoly, me_eval->mvert, me_eval->totloop, me_eval->totpoly, looptri);
const MLoop *loops = BKE_mesh_loops(me_eval);
BKE_mesh_recalc_looptri(loops,
BKE_mesh_polygons(me_eval),
BKE_mesh_vertices(me_eval),
me_eval->totloop,
me_eval->totpoly,
looptri);
/* For mapping back to original mesh in case there are modifiers. */
const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
const MPoly *orig_polys = BKE_mesh_polygons(me);
const MLoop *orig_loops = BKE_mesh_loops(me);
for (int i = 0; i < tottri; i++) {
const MLoopTri *lt = &looptri[i];
for (int j = 0; j < 3; j++) {
unsigned int l = lt->tri[j];
unsigned int v = me_eval->mloop[l].v;
unsigned int v = loops[l].v;
/* Map back to original loop if there are modifiers. */
if (vert_origindex != NULL && poly_origindex != NULL) {
l = find_original_loop(me, vert_origindex, poly_origindex, lt->poly, v);
l = find_original_loop(
orig_polys, orig_loops, vert_origindex, poly_origindex, lt->poly, v);
if (l == ORIGINDEX_NONE || l >= me->totloop) {
continue;
}
@@ -1135,7 +1144,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex");
memset(mcol, 0, sizeof(MPropCol) * me->totvert);
MLoop *mloop = me->mloop;
const MLoop *mloop = BKE_mesh_loops(me);
for (int i = 0; i < totloop; i++, mloop++) {
const int v = mloop->v;
bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num);
@@ -94,6 +94,8 @@
#include "object_intern.h"
using blender::Span;
static void modifier_skin_customdata_delete(struct Object *ob);
/* ------------------------------------------------------------------- */
@@ -587,14 +589,14 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports),
me->totvert = verts_num;
me->totedge = edges_num;
me->mvert = (MVert *)CustomData_add_layer(
&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num);
me->medge = (MEdge *)CustomData_add_layer(
&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num);
me->mface = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0);
CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num);
CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num);
CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0);
MVert *mvert = me->mvert;
MEdge *medge = me->medge;
blender::MutableSpan<MVert> verts = me->vertices_for_write();
blender::MutableSpan<MEdge> edges = me->edges_for_write();
MVert *mvert = verts.data();
MEdge *medge = edges.data();
/* copy coordinates */
cache = psys_eval->pathcache;
@@ -2591,8 +2593,8 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
}
static void skin_armature_bone_create(Object *skin_ob,
MVert *mvert,
MEdge *medge,
const MVert *mvert,
const MEdge *medge,
bArmature *arm,
BLI_bitmap *edges_visited,
const MeshElemMap *emap,
@@ -2637,12 +2639,15 @@ static void skin_armature_bone_create(Object *skin_ob,
static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob)
{
Mesh *me = static_cast<Mesh *>(skin_ob->data);
const Span<MVert> me_verts = me->vertices();
const Span<MEdge> me_edges = me->edges();
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, skin_ob);
Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
MVert *mvert = me_eval_deform->mvert;
const Mesh *me_eval_deform = mesh_get_eval_deform(
depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
const Span<MVert> verts_eval = me_eval_deform->vertices();
/* add vertex weights to original mesh */
CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, me->totvert);
@@ -2660,7 +2665,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
CustomData_get_layer(&me->vdata, CD_MVERT_SKIN));
int *emap_mem;
MeshElemMap *emap;
BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me_edges.data(), me->totvert, me->totedge);
BLI_bitmap *edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
@@ -2676,15 +2681,16 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
if (emap[v].count > 1) {
bone = ED_armature_ebone_add(arm, "Bone");
copy_v3_v3(bone->head, me->mvert[v].co);
copy_v3_v3(bone->tail, me->mvert[v].co);
copy_v3_v3(bone->head, me_verts[v].co);
copy_v3_v3(bone->tail, me_verts[v].co);
bone->head[1] = 1.0f;
bone->rad_head = bone->rad_tail = 0.25;
}
if (emap[v].count >= 1) {
skin_armature_bone_create(skin_ob, mvert, me->medge, arm, edges_visited, emap, bone, v);
skin_armature_bone_create(
skin_ob, verts_eval.data(), me_edges.data(), arm, edges_visited, emap, bone, v);
}
}
}
+18 -13
View File
@@ -73,6 +73,9 @@
#include "object_intern.h" /* own include */
using blender::IndexRange;
using blender::Span;
/* TODO(sebpa): unstable, can lead to unrecoverable errors. */
// #define USE_MESH_CURVATURE
@@ -128,7 +131,8 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
}
/* Output mesh will be all smooth or all flat shading. */
const bool smooth_normals = mesh->mpoly[0].flag & ME_SMOOTH;
const Span<MPoly> polygons = mesh->polygons();
const bool smooth_normals = polygons.first().flag & ME_SMOOTH;
float isovalue = 0.0f;
if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) {
@@ -678,9 +682,11 @@ static bool mesh_is_manifold_consistent(Mesh *mesh)
* check that the direction of the faces are consistent and doesn't suddenly
* flip
*/
const Span<MVert> verts = mesh->vertices();
const Span<MEdge> edges = mesh->edges();
const Span<MLoop> loops = mesh->loops();
bool is_manifold_consistent = true;
const MLoop *mloop = mesh->mloop;
char *edge_faces = (char *)MEM_callocN(mesh->totedge * sizeof(char), "remesh_manifold_check");
int *edge_vert = (int *)MEM_malloc_arrayN(
mesh->totedge, sizeof(uint), "remesh_consistent_check");
@@ -689,18 +695,17 @@ static bool mesh_is_manifold_consistent(Mesh *mesh)
edge_vert[i] = -1;
}
for (uint loop_idx = 0; loop_idx < mesh->totloop; loop_idx++) {
const MLoop *loop = &mloop[loop_idx];
edge_faces[loop->e] += 1;
if (edge_faces[loop->e] > 2) {
for (const MLoop &loop : loops) {
edge_faces[loop.e] += 1;
if (edge_faces[loop.e] > 2) {
is_manifold_consistent = false;
break;
}
if (edge_vert[loop->e] == -1) {
edge_vert[loop->e] = loop->v;
if (edge_vert[loop.e] == -1) {
edge_vert[loop.e] = loop.v;
}
else if (edge_vert[loop->e] == loop->v) {
else if (edge_vert[loop.e] == loop.v) {
/* Mesh has flips in the surface so it is non consistent */
is_manifold_consistent = false;
break;
@@ -708,16 +713,16 @@ static bool mesh_is_manifold_consistent(Mesh *mesh)
}
if (is_manifold_consistent) {
for (uint i = 0; i < mesh->totedge; i++) {
for (const int i : edges.index_range()) {
/* Check for wire edges. */
if (edge_faces[i] == 0) {
is_manifold_consistent = false;
break;
}
/* Check for zero length edges */
MVert *v1 = &mesh->mvert[mesh->medge[i].v1];
MVert *v2 = &mesh->mvert[mesh->medge[i].v2];
if (compare_v3v3(v1->co, v2->co, 1e-4f)) {
const MVert &v1 = verts[edges[i].v1];
const MVert &v2 = verts[edges[i].v2];
if (compare_v3v3(v1.co, v2.co, 1e-4f)) {
is_manifold_consistent = false;
break;
}
@@ -114,14 +114,13 @@ static bool object_shape_key_mirror(
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
MVert *mv;
int i1, i2;
float *fp1, *fp2;
float tvec[3];
ED_mesh_mirror_spatial_table_begin(ob, NULL, NULL);
for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
for (i1 = 0; i1 < me->totvert; i1++) {
i2 = mesh_get_x_mirror_vert(ob, NULL, i1, use_topology);
if (i2 == i1) {
fp1 = ((float *)kb->data) + i1 * 3;

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