Mesh: Move positions to a generic attribute

**Changes**
As described in T93602, this patch removes all use of the `MVert`
struct, replacing it with a generic named attribute with the name
`"position"`, consistent with other geometry types.

Variable names have been changed from `verts` to `positions`, to align
with the attribute name and the more generic design (positions are not
vertices, they are just an attribute stored on the point domain).

This change is made possible by previous commits that moved all other
data out of `MVert` to runtime data or other generic attributes. What
remains is mostly a simple type change. Though, the type still shows up
859 times, so the patch is quite large.

One compromise is that now `CD_MASK_BAREMESH` now contains
`CD_PROP_FLOAT3`. With the general move towards generic attributes
over custom data types, we are removing use of these type masks anyway.

**Benefits**
The most obvious benefit is reduced memory usage and the benefits
that brings in memory-bound situations. `float3` is only 3 bytes, in
comparison to `MVert` which was 4. When there are millions of vertices
this starts to matter more.

The other benefits come from using a more generic type. Instead of
writing algorithms specifically for `MVert`, code can just use arrays
of vectors. This will allow eliminating many temporary arrays or
wrappers used to extract positions.

Many possible improvements aren't implemented in this patch, though
I did switch simplify or remove the process of creating temporary
position arrays in a few places.

The design clarity that "positions are just another attribute" brings
allows removing explicit copying of vertices in some procedural
operations-- they are just processed like most other attributes.

**Performance**
This touches so many areas that it's hard to benchmark exhaustively,
but I observed some areas as examples.
* The mesh line node with 4 million count was 1.5x (8ms to 12ms) faster.
* The Spring splash screen went from ~4.3 to ~4.5 fps.
* The subdivision surface modifier/node was slightly faster
RNA access through Python may be slightly slower, since now we need
a name lookup instead of just a custom data type lookup for each index.

**Future Improvements**
* Remove uses of "vert_coords" functions:
  * `BKE_mesh_vert_coords_alloc`
  * `BKE_mesh_vert_coords_get`
  * `BKE_mesh_vert_coords_apply{_with_mat4}`
* Remove more hidden copying of positions
* General simplification now possible in many areas
* Convert more code to C++ to use `float3` instead of `float[3]`
  * Currently `reinterpret_cast` is used for those C-API functions

Differential Revision: https://developer.blender.org/D15982
This commit is contained in:
2023-01-10 00:10:43 -05:00
parent 05ddc7daa2
commit 1af62cb3bf
232 changed files with 2391 additions and 2659 deletions
+7 -11
View File
@@ -679,7 +679,7 @@ 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);
const float(*positions)[3] = static_cast<const float(*)[3]>(b_mesh.vertices[0].ptr.data);
/* STEP 1: Find out duplicated vertices and point duplicates to a single
* original vertex.
@@ -765,10 +765,8 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
continue;
}
visited_edges.insert(v0, v1);
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 co0 = make_float3(positions[v0][0], positions[v0][1], positions[v0][2]);
float3 co1 = make_float3(positions[v1][0], positions[v1][1], positions[v1][2]);
float3 edge = normalize(co1 - co0);
edge_accum[v0] += edge;
edge_accum[v1] += -edge;
@@ -919,7 +917,7 @@ static void create_mesh(Scene *scene,
return;
}
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
const float(*positions)[3] = static_cast<const float(*)[3]>(b_mesh.vertices[0].ptr.data);
if (!subdivision) {
numtris = numfaces;
@@ -942,8 +940,7 @@ static void create_mesh(Scene *scene,
/* create vertex coordinates and normals */
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]));
mesh->add_vertex(make_float3(positions[i][0], positions[i][1], positions[i][2]));
}
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
@@ -1252,14 +1249,13 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
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);
const float(*positions)[3] = static_cast<const float(*)[3]>(b_mesh.vertices[0].ptr.data);
/* NOTE: We don't copy more that existing amount of vertices to prevent
* possible memory corruption.
*/
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]);
mP[i] = make_float3(positions[i][0], positions[i][1], positions[i][2]);
}
if (mN) {
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
@@ -605,7 +605,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
colliding_names = []
for collection in (
# Built-in names.
{"position": None, "shade_smooth": None, "normal": None, "crease": None},
{"shade_smooth": None, "normal": None, "crease": None},
mesh.attributes,
mesh.uv_layers,
None if ob is None else ob.vertex_groups,
+5 -3
View File
@@ -61,7 +61,6 @@ struct CustomData_MeshMasks;
struct Depsgraph;
struct MEdge;
struct MFace;
struct MVert;
struct Mesh;
struct ModifierData;
struct Object;
@@ -125,7 +124,10 @@ struct DerivedMesh {
* and freed on the next ->release(). consider using getVert/Edge/Face if
* you are only interested in a few verts/edges/faces.
*/
struct MVert *(*getVertArray)(DerivedMesh *dm);
/**
* \warning The real return type is `float(*)[3]`.
*/
float *(*getVertArray)(DerivedMesh *dm);
struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
struct MLoop *(*getLoopArray)(DerivedMesh *dm);
struct MPoly *(*getPolyArray)(DerivedMesh *dm);
@@ -133,7 +135,7 @@ struct DerivedMesh {
/** Copy all verts/edges/faces from the derived mesh into
* *{vert/edge/face}_r (must point to a buffer large enough)
*/
void (*copyVertArray)(DerivedMesh *dm, struct MVert *r_vert);
void (*copyVertArray)(DerivedMesh *dm, float (*r_positions)[3]);
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge);
void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop);
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly);
+4 -5
View File
@@ -25,7 +25,6 @@ extern "C" {
struct BMEditMesh;
struct MFace;
struct MVert;
struct Mesh;
struct PointCloud;
@@ -59,7 +58,7 @@ typedef struct BVHTreeFromMesh {
BVHTree_RayCastCallback raycast_callback;
/* Vertex array, so that callbacks have instant access to data. */
const struct MVert *vert;
const float (*vert_positions)[3];
const struct MEdge *edge;
const struct MFace *face;
const struct MLoop *loop;
@@ -123,7 +122,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
* (else will be computed from mask).
*/
BVHTree *bvhtree_from_mesh_verts_ex(struct BVHTreeFromMesh *data,
const struct MVert *vert,
const float (*vert_positions)[3],
int verts_num,
const blender::BitVector<> &verts_mask,
int verts_num_active,
@@ -154,7 +153,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data,
* (else will be computed from mask).
*/
BVHTree *bvhtree_from_mesh_edges_ex(struct BVHTreeFromMesh *data,
const struct MVert *vert,
const float (*vert_positions)[3],
const struct MEdge *edge,
int edges_num,
const blender::BitVector<> &edges_mask,
@@ -181,7 +180,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
* Builds a BVH-tree where nodes are the looptri faces of the given mesh.
*/
BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data,
const struct MVert *vert,
const float (*vert_positions)[3],
const struct MLoop *mloop,
const struct MLoopTri *looptri,
int looptri_num,
+3 -4
View File
@@ -14,7 +14,6 @@ struct BVHTree;
struct Collection;
struct CollisionModifierData;
struct Depsgraph;
struct MVert;
struct MVertTri;
struct Object;
struct Scene;
@@ -90,13 +89,13 @@ typedef struct FaceCollPair {
// used in modifier.cc from collision.c
/////////////////////////////////////////////////
struct BVHTree *bvhtree_build_from_mvert(const struct MVert *mvert,
struct BVHTree *bvhtree_build_from_mvert(const float (*positions)[3],
const struct MVertTri *tri,
int tri_num,
float epsilon);
void bvhtree_update_from_mvert(struct BVHTree *bvhtree,
const struct MVert *mvert,
const struct MVert *mvert_moving,
const float (*positions)[3],
const float (*positions_moving)[3],
const struct MVertTri *tri,
int tri_num,
bool moving);
+3 -2
View File
@@ -13,7 +13,6 @@ struct Lattice;
struct ListBase;
struct Main;
struct Mesh;
struct MVert;
struct Object;
/* Kernel prototypes */
@@ -132,7 +131,9 @@ void BKE_keyblock_update_from_mesh(const struct Mesh *me, struct KeyBlock *kb);
void BKE_keyblock_convert_from_mesh(const struct Mesh *me,
const struct Key *key,
struct KeyBlock *kb);
void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb, struct MVert *mvert, int totvert);
void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb,
float (*vert_positions)[3],
int totvert);
/**
* Computes normals (vertices, polygons and/or loops ones) of given mesh for given shape key.
+26 -26
View File
@@ -38,7 +38,6 @@ struct MLoop;
struct MLoopTri;
struct MLoopUV;
struct MPoly;
struct MVert;
struct Main;
struct MemArena;
struct Mesh;
@@ -193,6 +192,8 @@ struct Mesh *BKE_mesh_new_nomain_from_curve(const struct Object *ob);
struct Mesh *BKE_mesh_new_nomain_from_curve_displist(const struct Object *ob,
const struct ListBase *dispbase);
bool BKE_mesh_attribute_required(const char *name);
bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me);
bool BKE_mesh_clear_facemap_customdata(struct Mesh *me);
@@ -324,7 +325,7 @@ void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float (*vert_coords)[3]
*/
void BKE_mesh_recalc_looptri(const struct MLoop *mloop,
const struct MPoly *mpoly,
const struct MVert *mvert,
const float (*vert_positions)[3],
int totloop,
int totpoly,
struct MLoopTri *mlooptri);
@@ -338,7 +339,7 @@ void BKE_mesh_recalc_looptri(const struct MLoop *mloop,
*/
void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
const struct MPoly *mpoly,
const struct MVert *mvert,
const float (*vert_positions)[3],
int totloop,
int totpoly,
struct MLoopTri *mlooptri,
@@ -420,12 +421,8 @@ bool BKE_mesh_poly_normals_are_dirty(const struct Mesh *mesh);
void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray,
const float (*vert_positions)[3],
float r_no[3]);
void BKE_mesh_calc_poly_normal_coords(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const float (*vertex_coords)[3],
float r_no[3]);
/**
* Calculate face normals directly into a result array.
@@ -433,7 +430,7 @@ void BKE_mesh_calc_poly_normal_coords(const struct MPoly *mpoly,
* \note Usually #BKE_mesh_poly_normals_ensure is the preferred way to access face normals,
* since they may already be calculated and cached on the mesh.
*/
void BKE_mesh_calc_normals_poly(const struct MVert *mvert,
void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3],
int mvert_len,
const struct MLoop *mloop,
int mloop_len,
@@ -447,7 +444,7 @@ void BKE_mesh_calc_normals_poly(const struct MVert *mvert,
* \note Usually #BKE_mesh_vertex_normals_ensure is the preferred way to access vertex normals,
* since they may already be calculated and cached on the mesh.
*/
void BKE_mesh_calc_normals_poly_and_vertex(const struct MVert *mvert,
void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3],
int mvert_len,
const struct MLoop *mloop,
int mloop_len,
@@ -597,7 +594,7 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space,
*
* \param loop_to_poly_map: Optional pre-created map from loops to their polygon.
*/
void BKE_mesh_normals_loop_split(const struct MVert *mverts,
void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
const float (*vert_normals)[3],
int numVerts,
const struct MEdge *medges,
@@ -614,7 +611,7 @@ void BKE_mesh_normals_loop_split(const struct MVert *mverts,
MLoopNorSpaceArray *r_lnors_spacearr,
short (*clnors_data)[2]);
void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts,
void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3],
const float (*vert_normals)[3],
int numVerts,
struct MEdge *medges,
@@ -626,7 +623,7 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts,
const float (*poly_normals)[3],
int numPolys,
short (*r_clnors_data)[2]);
void BKE_mesh_normals_loop_custom_from_verts_set(const struct MVert *mverts,
void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3],
const float (*vert_normals)[3],
float (*r_custom_vert_normals)[3],
int numVerts,
@@ -689,17 +686,17 @@ void BKE_mesh_set_custom_normals_from_verts(struct Mesh *mesh, float (*r_custom_
void BKE_mesh_calc_poly_center(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray,
const float (*vert_positions)[3],
float r_cent[3]);
/* NOTE: passing poly-normal is only a speedup so we can skip calculating it. */
float BKE_mesh_calc_poly_area(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray);
const float (*vert_positions)[3]);
float BKE_mesh_calc_area(const struct Mesh *me);
float BKE_mesh_calc_poly_uv_area(const struct MPoly *mpoly, const struct MLoopUV *uv_array);
void BKE_mesh_calc_poly_angles(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray,
const float (*vert_positions)[3],
float angles[]);
void BKE_mesh_poly_edgehash_insert(struct EdgeHash *ehash,
@@ -729,7 +726,7 @@ bool BKE_mesh_center_of_volume(const struct Mesh *me, float r_cent[3]);
* \param r_volume: Volume (unsigned).
* \param r_center: Center of mass.
*/
void BKE_mesh_calc_volume(const struct MVert *mverts,
void BKE_mesh_calc_volume(const float (*vert_positions)[3],
int mverts_num,
const struct MLoopTri *mlooptri,
int looptri_num,
@@ -888,7 +885,7 @@ bool BKE_mesh_validate_material_indices(struct Mesh *me);
* by importers that load normals (for example).
*/
bool BKE_mesh_validate_arrays(struct Mesh *me,
struct MVert *mverts,
float (*vert_positions)[3],
unsigned int totvert,
struct MEdge *medges,
unsigned int totedge,
@@ -992,13 +989,14 @@ 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_verts(const Mesh *mesh)
BLI_INLINE const float (*BKE_mesh_vert_positions(const Mesh *mesh))[3]
{
return (const MVert *)CustomData_get_layer(&mesh->vdata, CD_MVERT);
return (const float(*)[3])CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position");
}
BLI_INLINE MVert *BKE_mesh_verts_for_write(Mesh *mesh)
BLI_INLINE float (*BKE_mesh_vert_positions_for_write(Mesh *mesh))[3]
{
return (MVert *)CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
return (float(*)[3])CustomData_duplicate_referenced_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, "position", mesh->totvert);
}
BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh)
@@ -1049,15 +1047,17 @@ BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh)
#ifdef __cplusplus
# include "BLI_math_vector_types.hh"
# include "BLI_span.hh"
inline blender::Span<MVert> Mesh::verts() const
inline blender::Span<blender::float3> Mesh::vert_positions() const
{
return {BKE_mesh_verts(this), this->totvert};
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vert_positions(this)), this->totvert};
}
inline blender::MutableSpan<MVert> Mesh::verts_for_write()
inline blender::MutableSpan<blender::float3> Mesh::vert_positions_for_write()
{
return {BKE_mesh_verts_for_write(this), this->totvert};
return {reinterpret_cast<blender::float3 *>(BKE_mesh_vert_positions_for_write(this)),
this->totvert};
}
inline blender::Span<MEdge> Mesh::edges() const
+3 -3
View File
@@ -29,10 +29,10 @@ void BKE_bmesh_prefair_and_fair_verts(struct BMesh *bm,
bool *affect_verts,
eMeshFairingDepth depth);
/* This function can optionally use the MVert coordinates of deform_mverts to read and write the
* fairing result. When NULL, the function will use mesh->mverts directly. */
/* This function can optionally use the vertex coordinates of deform_mverts to read and write the
* fairing result. When NULL, the function will use mesh positions directly. */
void BKE_mesh_prefair_and_fair_verts(struct Mesh *mesh,
struct MVert *deform_mverts,
float (*deform_vert_positions)[3],
bool *affect_verts,
eMeshFairingDepth depth);
@@ -10,7 +10,9 @@
#include "BLI_utildefines.h"
#ifdef __cplusplus
# include "BLI_resource_scope.hh"
# include "BLI_span.hh"
# include "BLI_vector.hh"
# include "DNA_customdata_types.h"
#endif
@@ -88,6 +90,13 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh);
void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh);
void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
struct MVert *BKE_mesh_legacy_convert_positions_to_verts(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &vert_layers_to_write);
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh);
#endif
/**
+3 -5
View File
@@ -19,7 +19,6 @@ struct MLoop;
struct MLoopTri;
struct MLoopUV;
struct MPoly;
struct MVert;
/* UvVertMap */
#define STD_UV_CONNECT_LIMIT 0.0001f
@@ -146,7 +145,6 @@ void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map,
*/
void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
int **r_mem,
const struct MVert *mvert,
int totvert,
const struct MLoopTri *mlooptri,
int totlooptri,
@@ -260,7 +258,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
int num_innercut_items,
int *innercut_item_indices);
typedef bool (*MeshRemapIslandsCalc)(const struct MVert *verts,
typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3],
int totvert,
const struct MEdge *edges,
int totedge,
@@ -277,7 +275,7 @@ typedef bool (*MeshRemapIslandsCalc)(const 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(const struct MVert *verts,
bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
int totvert,
const struct MEdge *edges,
int totedge,
@@ -300,7 +298,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts,
* Not sure it would be worth the more complex code, though,
* those loops are supposed to be really quick to do.
*/
bool BKE_mesh_calc_islands_loop_poly_uvmap(struct MVert *verts,
bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
int totvert,
struct MEdge *edges,
int totedge,
+6 -7
View File
@@ -12,7 +12,6 @@ extern "C" {
struct CustomData;
struct CustomData_MeshMasks;
struct MVert;
struct MemArena;
struct Mesh;
@@ -158,14 +157,14 @@ void BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
* in favor of a global good matching.
*/
float BKE_mesh_remap_calc_difference_from_mesh(const struct SpaceTransform *space_transform,
const struct MVert *verts_dst,
const float (*vert_positions_dst)[3],
int numverts_dst,
struct Mesh *me_src);
/**
* Set r_space_transform so that best bbox of dst matches best bbox of src.
*/
void BKE_mesh_remap_find_best_match_from_mesh(const struct MVert *verts_dst,
void BKE_mesh_remap_find_best_match_from_mesh(const float (*vert_positions_dst)[3],
int numverts_dst,
struct Mesh *me_src,
struct SpaceTransform *r_space_transform);
@@ -174,7 +173,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(int mode,
const struct SpaceTransform *space_transform,
float max_dist,
float ray_radius,
const struct MVert *verts_dst,
const float (*vert_positions_dst)[3],
int numverts_dst,
bool dirty_nors_dst,
struct Mesh *me_src,
@@ -185,7 +184,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(int mode,
const struct SpaceTransform *space_transform,
float max_dist,
float ray_radius,
const struct MVert *verts_dst,
const float (*vert_positions_dst)[3],
int numverts_dst,
const struct MEdge *edges_dst,
int numedges_dst,
@@ -199,7 +198,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode,
float max_dist,
float ray_radius,
struct Mesh *mesh_dst,
const struct MVert *verts_dst,
const float (*vert_positions_dst)[3],
int numverts_dst,
const struct MEdge *edges_dst,
int numedges_dst,
@@ -221,7 +220,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode,
float max_dist,
float ray_radius,
const struct Mesh *mesh_dst,
const struct MVert *verts_dst,
const float (*vert_positions_dst)[3],
const struct MLoop *loops_dst,
const struct MPoly *polys_dst,
int numpolys_dst,
+1 -1
View File
@@ -127,7 +127,7 @@ int sample_surface_points_projected(
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions);
float3 compute_bary_coord_in_triangle(Span<MVert> verts,
float3 compute_bary_coord_in_triangle(Span<float3> vert_positions,
Span<MLoop> loops,
const MLoopTri &looptri,
const float3 &position);
+2 -2
View File
@@ -17,7 +17,7 @@ struct ReportList;
* split normals can be used to recreate the full tangent space.
* NOTE: * The mesh should be made of only tris and quads!
*/
void BKE_mesh_calc_loop_tangent_single_ex(const struct MVert *mverts,
void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
int numVerts,
const struct MLoop *mloops,
float (*r_looptangent)[4],
@@ -41,7 +41,7 @@ void BKE_mesh_calc_loop_tangent_single(struct Mesh *mesh,
/**
* See: #BKE_editmesh_loop_tangent_calc (matching logic).
*/
void BKE_mesh_calc_loop_tangent_ex(const struct MVert *mvert,
void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const struct MPoly *mpoly,
uint mpoly_len,
const struct MLoop *mloop,
+1 -1
View File
@@ -47,7 +47,7 @@ typedef enum eMeshBatchDirtyMode {
/** #MeshRuntime.wrapper_type */
typedef enum eMeshWrapperType {
/** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
/** Use mesh data (#Mesh.vert_positions(), #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
ME_WRAPPER_TYPE_MDATA = 0,
/** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */
ME_WRAPPER_TYPE_BMESH = 1,
-1
View File
@@ -27,7 +27,6 @@ struct SubdivCCG;
struct MLoop;
struct MLoopTri;
struct MPoly;
struct MVert;
/**
* Delete mesh mdisps and grid paint masks.
+1 -2
View File
@@ -39,7 +39,6 @@ struct ImageUser;
struct ListBase;
struct MLoop;
struct MLoopTri;
struct MVert;
struct Main;
struct Mesh;
struct MeshElemMap;
@@ -577,7 +576,7 @@ typedef struct SculptSession {
struct Depsgraph *depsgraph;
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
float (*vert_positions)[3];
const struct MPoly *mpoly;
const struct MLoop *mloop;
+1 -2
View File
@@ -36,7 +36,6 @@ struct LinkNode;
struct MCol;
struct MFace;
struct MTFace;
struct MVert;
struct Main;
struct ModifierData;
struct Object;
@@ -583,7 +582,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,
const struct MVert *mvert,
const float (*vert_positions)[3],
const float (*vert_normals)[3],
struct MFace *mface,
struct MTFace *tface,
+7 -12
View File
@@ -32,7 +32,6 @@ struct IsectRayPrecalc;
struct MLoop;
struct MLoopTri;
struct MPoly;
struct MVert;
struct Mesh;
struct MeshElemMap;
struct PBVH;
@@ -267,7 +266,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
struct Mesh *mesh,
const struct MPoly *mpoly,
const struct MLoop *mloop,
struct MVert *verts,
float (*vert_positions)[3],
int totvert,
struct CustomData *vdata,
struct CustomData *ldata,
@@ -478,10 +477,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
int *gridsize,
struct CCGElem ***r_griddata);
void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert);
void BKE_pbvh_node_get_verts(PBVH *pbvh,
PBVHNode *node,
const int **r_vert_indices,
struct MVert **r_verts);
const int *BKE_pbvh_node_get_vert_indices(PBVHNode *node);
void BKE_pbvh_node_get_loops(PBVH *pbvh,
PBVHNode *node,
const int **r_loop_indices,
@@ -587,12 +583,13 @@ typedef struct PBVHVertexIter {
int gridsize;
/* mesh */
struct MVert *mverts;
float (*vert_positions)[3];
float (*vert_normals)[3];
const bool *hide_vert;
int totvert;
const int *vert_indices;
float *vmask;
bool is_mesh;
/* bmesh */
struct GSetIterator bm_unique_verts;
@@ -602,7 +599,6 @@ typedef struct PBVHVertexIter {
/* result: these are all computed in the macro, but we assume
* that compiler optimization's will skip the ones we don't use */
struct MVert *mvert;
struct BMVert *bm_vert;
float *co;
float *no;
@@ -647,8 +643,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
} \
} \
} \
else if (vi.mverts) { \
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
else if (vi.vert_positions) { \
if (vi.respect_hide) { \
vi.visible = !(vi.hide_vert && vi.hide_vert[vi.vert_indices[vi.gx]]); \
if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \
@@ -658,7 +653,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
else { \
BLI_assert(vi.visible); \
} \
vi.co = vi.mvert->co; \
vi.co = vi.vert_positions[vi.vert_indices[vi.gx]]; \
vi.no = vi.vert_normals[vi.vert_indices[vi.gx]]; \
vi.index = vi.vertex.i = vi.vert_indices[vi.i]; \
if (vi.vmask) { \
@@ -770,7 +765,7 @@ void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings,
bool use_threading,
int totnode);
struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh);
float (*BKE_pbvh_get_vert_positions(const PBVH *pbvh))[3];
const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3];
const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh);
bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh);
+1 -1
View File
@@ -94,7 +94,7 @@ typedef struct SubdivStats {
double topology_refiner_creation_time;
/* Total time spent in BKE_subdiv_to_mesh(). */
double subdiv_to_mesh_time;
/* Geometry (MVert and co) creation time during SUBDIV_TYO_MESH. */
/* Geometry (mesh vertices) creation time during SUBDIV_TYO_MESH. */
double subdiv_to_mesh_geometry_time;
/* Time spent on evaluator creation from topology refiner. */
double evaluator_creation_time;
+1 -2
View File
@@ -16,7 +16,6 @@ extern "C" {
struct Mesh;
struct MeshElemMap;
struct MEdge;
struct MVert;
struct Subdiv;
typedef struct SubdivToMeshSettings {
@@ -39,7 +38,7 @@ struct Mesh *BKE_subdiv_to_mesh(struct Subdiv *subdiv,
/* Interpolate a position along the `coarse_edge` at the relative `u` coordinate. If `is_simple` is
* false, this will perform a B-Spline interpolation using the edge neighbors, otherwise a linear
* interpolation will be done base on the edge vertices. */
void BKE_subdiv_mesh_interpolate_position_on_edge(const struct MVert *coarse_verts,
void BKE_subdiv_mesh_interpolate_position_on_edge(const float (*coarse_positions)[3],
const struct MEdge *coarse_edges,
const struct MeshElemMap *vert_to_edge_map,
int coarse_edge_index,
@@ -62,7 +62,7 @@ void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
int vert_offset,
int poly_offset,
int loop_offset,
MutableSpan<MVert> verts,
MutableSpan<float3> vert_positions,
MutableSpan<MPoly> polys,
MutableSpan<MLoop> loops);
+19 -25
View File
@@ -92,18 +92,19 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
/* -------------------------------------------------------------------- */
static MVert *dm_getVertArray(DerivedMesh *dm)
static float *dm_getVertArray(DerivedMesh *dm)
{
MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT);
float(*positions)[3] = (float(*)[3])CustomData_get_layer_named(
&dm->vertData, CD_PROP_FLOAT3, "position");
if (!mvert) {
mvert = (MVert *)CustomData_add_layer(
&dm->vertData, CD_MVERT, CD_SET_DEFAULT, nullptr, dm->getNumVerts(dm));
CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY);
dm->copyVertArray(dm, mvert);
if (!positions) {
positions = (float(*)[3])CustomData_add_layer_named(
&dm->vertData, CD_PROP_FLOAT3, CD_SET_DEFAULT, nullptr, dm->getNumVerts(dm), "position");
CustomData_set_layer_flag(&dm->vertData, CD_PROP_FLOAT3, CD_FLAG_TEMPORARY);
dm->copyVertArray(dm, positions);
}
return mvert;
return (float *)positions;
}
static MEdge *dm_getEdgeArray(DerivedMesh *dm)
@@ -350,10 +351,6 @@ static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask)
void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
{
if (type == CD_MVERT) {
return dm->getVertArray(dm);
}
return CustomData_get_layer(&dm->vertData, type);
}
@@ -672,10 +669,8 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
/* Deformed vertex locations array. Deform only modifier need this type of
* float array rather than MVert*. Tracked along with mesh_final as an
* optimization to avoid copying coordinates back and forth if there are
* multiple sequential deform only modifiers. */
/* TODO: Remove use of `deformed_verts` in mesh modifier stack
* since mesh positions are now stored in a contiguous array. */
float(*deformed_verts)[3] = nullptr;
int num_deformed_verts = mesh_input->totvert;
bool isPrevDeform = false;
@@ -1262,10 +1257,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
GeometrySet geometry_set_final;
/* Deformed vertex locations array. Deform only modifier need this type of
* float array rather than MVert*. Tracked along with mesh_final as an
* optimization to avoid copying coordinates back and forth if there are
* multiple sequential deform only modifiers. */
/* TODO: Remove use of `deformed_verts` in mesh modifier stack
* since mesh positions are now stored in a contiguous array. */
float(*deformed_verts)[3] = nullptr;
int num_deformed_verts = 0;
bool isPrevDeform = false;
@@ -1928,9 +1921,9 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to
MEM_freeN(userData.vertex_visit);
}
else {
const Span<MVert> verts = me_eval->verts();
const Span<float3> positions = me_eval->vert_positions();
for (int i = 0; i < totcos; i++) {
copy_v3_v3(r_cos[i], verts[i].co);
copy_v3_v3(r_cos[i], positions[i]);
}
}
}
@@ -1943,7 +1936,7 @@ static void mesh_init_origspace(Mesh *mesh)
CD_ORIGSPACE_MLOOP);
const int numpoly = mesh->totpoly;
// const int numloop = mesh->totloop;
const Span<MVert> verts = mesh->verts();
const Span<float3> positions = mesh->vert_positions();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
@@ -1968,12 +1961,13 @@ static void mesh_init_origspace(Mesh *mesh)
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
BKE_mesh_calc_poly_normal(mp, l, verts.data(), p_nor);
BKE_mesh_calc_poly_normal(
mp, l, reinterpret_cast<const float(*)[3]>(positions.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, verts[l->v].co);
mul_v3_m3v3(co, mat, positions[l->v]);
copy_v2_v2(vcos_2d[j], co);
for (k = 0; k < 2; k++) {
@@ -31,6 +31,7 @@
#include "BKE_curves.hh"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
#include "BKE_report.h"
@@ -478,6 +479,8 @@ bool BKE_id_attribute_required(const ID *id, const char *name)
return BKE_pointcloud_attribute_required((const PointCloud *)id, name);
case ID_CV:
return BKE_curves_attribute_required((const Curves *)id, name);
case ID_ME:
return BKE_mesh_attribute_required(name);
default:
return false;
}
@@ -220,8 +220,7 @@ template<typename T> GVMutableArray make_array_write_attribute(void *data, const
/**
* This provider is used to provide access to builtin attributes. It supports making internal types
* available as different types. For example, the vertex position attribute is stored as part of
* the #MVert struct, but is exposed as float3 attribute.
* available as different types.
*
* It also supports named builtin attributes, and will look up attributes in #CustomData by name
* if the stored type is the same as the attribute type.
+59 -58
View File
@@ -30,6 +30,7 @@
#include "MEM_guardedalloc.h"
using blender::BitVector;
using blender::float3;
using blender::IndexRange;
using blender::Span;
using blender::VArray;
@@ -236,14 +237,14 @@ static void mesh_faces_nearest_point(void *userdata,
BVHTreeNearest *nearest)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MFace *face = data->face + index;
const float *t0, *t1, *t2, *t3;
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
t3 = face->v4 ? vert[face->v4].co : nullptr;
t0 = positions[face->v1];
t1 = positions[face->v2];
t2 = positions[face->v3];
t3 = face->v4 ? positions[face->v4] : nullptr;
do {
float nearest_tmp[3], dist_sq;
@@ -271,12 +272,12 @@ static void mesh_looptri_nearest_point(void *userdata,
BVHTreeNearest *nearest)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MLoopTri *lt = &data->looptri[index];
const float *vtri_co[3] = {
vert[data->loop[lt->tri[0]].v].co,
vert[data->loop[lt->tri[1]].v].co,
vert[data->loop[lt->tri[2]].v].co,
positions[data->loop[lt->tri[0]].v],
positions[data->loop[lt->tri[1]].v],
positions[data->loop[lt->tri[2]].v],
};
float nearest_tmp[3], dist_sq;
@@ -332,14 +333,14 @@ static void mesh_faces_spherecast(void *userdata,
BVHTreeRayHit *hit)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MFace *face = &data->face[index];
const float *t0, *t1, *t2, *t3;
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
t3 = face->v4 ? vert[face->v4].co : nullptr;
t0 = positions[face->v1];
t1 = positions[face->v2];
t2 = positions[face->v3];
t3 = face->v4 ? positions[face->v4] : nullptr;
do {
float dist;
@@ -371,12 +372,12 @@ static void mesh_looptri_spherecast(void *userdata,
BVHTreeRayHit *hit)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MLoopTri *lt = &data->looptri[index];
const float *vtri_co[3] = {
vert[data->loop[lt->tri[0]].v].co,
vert[data->loop[lt->tri[1]].v].co,
vert[data->loop[lt->tri[2]].v].co,
positions[data->loop[lt->tri[0]].v],
positions[data->loop[lt->tri[1]].v],
positions[data->loop[lt->tri[2]].v],
};
float dist;
@@ -441,13 +442,13 @@ static void mesh_edges_nearest_point(void *userdata,
BVHTreeNearest *nearest)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MEdge *edge = data->edge + index;
float nearest_tmp[3], dist_sq;
const float *t0, *t1;
t0 = vert[edge->v1].co;
t1 = vert[edge->v2].co;
t0 = positions[edge->v1];
t1 = positions[edge->v2];
closest_to_line_segment_v3(nearest_tmp, co, t0, t1);
dist_sq = len_squared_v3v3(nearest_tmp, co);
@@ -506,7 +507,7 @@ static void mesh_verts_spherecast(void *userdata,
BVHTreeRayHit *hit)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const float *v = data->vert[index].co;
const float *v = data->vert_positions[index];
mesh_verts_spherecast_do(index, v, ray, hit);
}
@@ -523,15 +524,15 @@ static void mesh_edges_spherecast(void *userdata,
BVHTreeRayHit *hit)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MEdge *edge = &data->edge[index];
const float radius_sq = square_f(ray->radius);
float dist;
const float *v1, *v2, *r1;
float r2[3], i1[3], i2[3];
v1 = vert[edge->v1].co;
v2 = vert[edge->v2].co;
v1 = positions[edge->v1];
v2 = positions[edge->v2];
/* In case we get a zero-length edge, handle it as a point! */
if (equals_v3v3(v1, v2)) {
@@ -574,7 +575,7 @@ static void mesh_edges_spherecast(void *userdata,
static void bvhtree_from_mesh_setup_data(BVHTree *tree,
const BVHCacheType bvh_cache_type,
const MVert *vert,
const float (*positions)[3],
const MEdge *edge,
const MFace *face,
const MLoop *loop,
@@ -585,7 +586,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
r_data->tree = tree;
r_data->vert = vert;
r_data->vert_positions = positions;
r_data->edge = edge;
r_data->face = face;
r_data->loop = loop;
@@ -703,7 +704,7 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon,
static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon,
int tree_type,
int axis,
const MVert *vert,
const float (*positions)[3],
const int verts_num,
const BitVector<> &verts_mask,
int verts_num_active)
@@ -727,7 +728,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon,
if (!verts_mask.is_empty() && !verts_mask[i]) {
continue;
}
BLI_bvhtree_insert(tree, i, vert[i].co, 1);
BLI_bvhtree_insert(tree, i, positions[i], 1);
}
BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active);
@@ -761,7 +762,7 @@ BVHTree *bvhtree_from_editmesh_verts(
}
BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
const MVert *vert,
const float (*vert_positions)[3],
const int verts_num,
const BitVector<> &verts_mask,
int verts_num_active,
@@ -770,14 +771,14 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
int axis)
{
BVHTree *tree = bvhtree_from_mesh_verts_create_tree(
epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active);
epsilon, tree_type, axis, vert_positions, verts_num, verts_mask, verts_num_active);
bvhtree_balance(tree, false);
if (data) {
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(
tree, BVHTREE_FROM_VERTS, vert, nullptr, nullptr, nullptr, nullptr, data);
tree, BVHTREE_FROM_VERTS, vert_positions, nullptr, nullptr, nullptr, nullptr, data);
}
return tree;
@@ -829,7 +830,7 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon,
return tree;
}
static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert,
static BVHTree *bvhtree_from_mesh_edges_create_tree(const float (*positions)[3],
const MEdge *edge,
const int edge_num,
const BitVector<> &edges_mask,
@@ -859,8 +860,8 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert,
continue;
}
float co[2][3];
copy_v3_v3(co[0], vert[edge[i].v1].co);
copy_v3_v3(co[1], vert[edge[i].v2].co);
copy_v3_v3(co[0], positions[edge[i].v1]);
copy_v3_v3(co[1], positions[edge[i].v2]);
BLI_bvhtree_insert(tree, i, co[0], 2);
}
@@ -895,7 +896,7 @@ BVHTree *bvhtree_from_editmesh_edges(
}
BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
const MVert *vert,
const float (*vert_positions)[3],
const MEdge *edge,
const int edges_num,
const BitVector<> &edges_mask,
@@ -905,14 +906,14 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
int axis)
{
BVHTree *tree = bvhtree_from_mesh_edges_create_tree(
vert, edge, edges_num, edges_mask, edges_num_active, epsilon, tree_type, axis);
vert_positions, edge, edges_num, edges_mask, edges_num_active, epsilon, tree_type, axis);
bvhtree_balance(tree, false);
if (data) {
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(
tree, BVHTREE_FROM_EDGES, vert, edge, nullptr, nullptr, nullptr, data);
tree, BVHTREE_FROM_EDGES, vert_positions, edge, nullptr, nullptr, nullptr, data);
}
return tree;
@@ -927,7 +928,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon,
int tree_type,
int axis,
const MVert *vert,
const float (*positions)[3],
const MFace *face,
const int faces_num,
const BitVector<> &faces_mask,
@@ -951,18 +952,18 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon,
return nullptr;
}
if (vert && face) {
if (positions && face) {
for (int i = 0; i < faces_num; i++) {
float co[4][3];
if (!faces_mask.is_empty() && !faces_mask[i]) {
continue;
}
copy_v3_v3(co[0], vert[face[i].v1].co);
copy_v3_v3(co[1], vert[face[i].v2].co);
copy_v3_v3(co[2], vert[face[i].v3].co);
copy_v3_v3(co[0], positions[face[i].v1]);
copy_v3_v3(co[1], positions[face[i].v2]);
copy_v3_v3(co[2], positions[face[i].v3]);
if (face[i].v4) {
copy_v3_v3(co[3], vert[face[i].v4].co);
copy_v3_v3(co[3], positions[face[i].v4]);
}
BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
@@ -1033,7 +1034,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
int tree_type,
int axis,
const MVert *vert,
const float (*positions)[3],
const MLoop *mloop,
const MLoopTri *looptri,
const int looptri_num,
@@ -1057,16 +1058,16 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
return nullptr;
}
if (vert && looptri) {
if (positions && looptri) {
for (int i = 0; i < looptri_num; i++) {
float co[3][3];
if (!looptri_mask.is_empty() && !looptri_mask[i]) {
continue;
}
copy_v3_v3(co[0], vert[mloop[looptri[i].tri[0]].v].co);
copy_v3_v3(co[1], vert[mloop[looptri[i].tri[1]].v].co);
copy_v3_v3(co[2], vert[mloop[looptri[i].tri[2]].v].co);
copy_v3_v3(co[0], positions[mloop[looptri[i].tri[0]].v]);
copy_v3_v3(co[1], positions[mloop[looptri[i].tri[1]].v]);
copy_v3_v3(co[2], positions[mloop[looptri[i].tri[2]].v]);
BLI_bvhtree_insert(tree, i, co[0], 3);
}
@@ -1104,7 +1105,7 @@ BVHTree *bvhtree_from_editmesh_looptri(
}
BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
const struct MVert *vert,
const float (*vert_positions)[3],
const struct MLoop *mloop,
const struct MLoopTri *looptri,
const int looptri_num,
@@ -1117,7 +1118,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
BVHTree *tree = bvhtree_from_mesh_looptri_create_tree(epsilon,
tree_type,
axis,
vert,
vert_positions,
mloop,
looptri,
looptri_num,
@@ -1129,7 +1130,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
if (data) {
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(
tree, BVHTREE_FROM_LOOPTRI, vert, nullptr, nullptr, mloop, looptri, data);
tree, BVHTREE_FROM_LOOPTRI, vert_positions, nullptr, nullptr, mloop, looptri, data);
}
return tree;
@@ -1212,14 +1213,14 @@ 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->verts();
const float(*positions)[3] = reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data());
const Span<MEdge> edges = mesh->edges();
const Span<MLoop> loops = mesh->loops();
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(nullptr,
bvh_cache_type,
verts.data(),
positions,
edges.data(),
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
loops.data(),
@@ -1247,7 +1248,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
ATTR_FALLTHROUGH;
case BVHTREE_FROM_VERTS:
data->tree = bvhtree_from_mesh_verts_create_tree(
0.0f, tree_type, 6, verts.data(), mesh->totvert, mask, mask_bits_act_len);
0.0f, tree_type, 6, positions, mesh->totvert, mask, mask_bits_act_len);
break;
case BVHTREE_FROM_LOOSEEDGES:
@@ -1255,7 +1256,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
ATTR_FALLTHROUGH;
case BVHTREE_FROM_EDGES:
data->tree = bvhtree_from_mesh_edges_create_tree(
verts.data(), edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6);
positions, edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6);
break;
case BVHTREE_FROM_FACES:
@@ -1264,7 +1265,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
0.0f,
tree_type,
6,
verts.data(),
positions,
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
mesh->totface,
{},
@@ -1284,7 +1285,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f,
tree_type,
6,
verts.data(),
positions,
loops.data(),
looptri,
looptri_len,
@@ -38,7 +38,7 @@ typedef struct {
/* these point to data in the DerivedMesh custom data layers,
* they are only here for efficiency and convenience */
MVert *mvert;
float (*vert_positions)[3];
const float (*vert_normals)[3];
MEdge *medge;
MFace *mface;
@@ -75,10 +75,10 @@ static int cdDM_getNumPolys(DerivedMesh *dm)
return dm->numPolyData;
}
static void cdDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
static void cdDM_copyVertArray(DerivedMesh *dm, float (*r_positions)[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
memcpy(r_vert, cddm->mvert, sizeof(*r_vert) * dm->numVertData);
memcpy(r_positions, cddm->vert_positions, sizeof(float[3]) * dm->numVertData);
}
static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
@@ -103,7 +103,7 @@ static void cdDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
copy_v3_v3(r_co, cddm->mvert[index].co);
copy_v3_v3(r_co, cddm->vert_positions[index]);
}
static void cdDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
@@ -121,8 +121,12 @@ static void cdDM_recalc_looptri(DerivedMesh *dm)
DM_ensure_looptri_data(dm);
BLI_assert(totpoly == 0 || cddm->dm.looptris.array_wip != NULL);
BKE_mesh_recalc_looptri(
cddm->mloop, cddm->mpoly, cddm->mvert, totloop, totpoly, cddm->dm.looptris.array_wip);
BKE_mesh_recalc_looptri(cddm->mloop,
cddm->mpoly,
cddm->vert_positions,
totloop,
totpoly,
cddm->dm.looptris.array_wip);
BLI_assert(cddm->dm.looptris.array == NULL);
atomic_cas_ptr(
@@ -217,7 +221,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
cddm->vert_positions = CustomData_get_layer_named(&dm->vertData, CD_PROP_FLOAT3, "position");
/* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing
* or dirty normals. */
cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
+14 -11
View File
@@ -247,18 +247,18 @@ static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int
static int do_step_cloth(
Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, Mesh *result, int framenr)
{
using namespace blender;
/* simulate 1 frame forward */
ClothVertex *verts = nullptr;
Cloth *cloth;
ListBase *effectors = nullptr;
MVert *mvert;
uint i = 0;
int ret = 0;
bool vert_mass_changed = false;
cloth = clmd->clothObject;
verts = cloth->verts;
mvert = BKE_mesh_verts_for_write(result);
const Span<float3> positions = result->vert_positions();
vert_mass_changed = verts->mass != clmd->sim_parms->mass;
/* force any pinned verts to their constrained location. */
@@ -268,7 +268,7 @@ static int do_step_cloth(
copy_v3_v3(verts->txold, verts->x);
/* Get the current position. */
copy_v3_v3(verts->xconst, mvert[i].co);
copy_v3_v3(verts->xconst, positions[i]);
mul_m4_v3(ob->object_to_world, verts->xconst);
if (vert_mass_changed) {
@@ -715,6 +715,7 @@ static float cloth_shrink_factor(ClothModifierData *clmd, ClothVertex *verts, in
static bool cloth_from_object(
Object *ob, ClothModifierData *clmd, Mesh *mesh, float /*framenr*/, int first)
{
using namespace blender;
int i = 0;
ClothVertex *verts = nullptr;
const float(*shapekey_rest)[3] = nullptr;
@@ -758,14 +759,14 @@ static bool cloth_from_object(
CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO));
}
MVert *mvert = BKE_mesh_verts_for_write(mesh);
const Span<float3> positions = mesh->vert_positions();
verts = clmd->clothObject->verts;
/* set initial values */
for (i = 0; i < mesh->totvert; i++, verts++) {
if (first) {
copy_v3_v3(verts->x, mvert[i].co);
copy_v3_v3(verts->x, positions[i]);
mul_m4_v3(ob->object_to_world, verts->x);
@@ -1159,13 +1160,14 @@ static void cloth_update_springs(ClothModifierData *clmd)
/* Update rest verts, for dynamically deformable cloth */
static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
{
using namespace blender;
uint i = 0;
const MVert *mvert = BKE_mesh_verts(mesh);
const Span<float3> positions = mesh->vert_positions();
ClothVertex *verts = clmd->clothObject->verts;
/* vertex count is already ensured to match */
for (i = 0; i < mesh->totvert; i++, verts++) {
copy_v3_v3(verts->xrest, mvert[i].co);
copy_v3_v3(verts->xrest, positions[i]);
mul_m4_v3(ob->object_to_world, verts->xrest);
}
}
@@ -1173,13 +1175,14 @@ static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
/* Write rest vert locations to a copy of the mesh. */
static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
{
using namespace blender;
Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false);
ClothVertex *verts = clmd->clothObject->verts;
MVert *mvert = BKE_mesh_verts_for_write(new_mesh);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
/* vertex count is already ensured to match */
for (uint i = 0; i < mesh->totvert; i++, verts++) {
copy_v3_v3(mvert[i].co, verts->xrest);
for (const int i : positions.index_range()) {
positions[i] = verts[i].xrest;
}
BKE_mesh_tag_coords_changed(new_mesh);
@@ -1395,7 +1398,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
float co[3], no[3], new_co[3];
float radius;
copy_v3_v3(co, treedata->vert[v_idx].co);
copy_v3_v3(co, treedata->vert_positions[v_idx]);
negate_v3_v3(no, vert_normals[v_idx]);
float vec_len = sin(max_diversion);
+39 -39
View File
@@ -72,16 +72,16 @@ void collision_move_object(CollisionModifierData *collmd,
/* the collider doesn't move this frame */
if (collmd->is_static) {
for (i = 0; i < collmd->mvert_num; i++) {
zero_v3(collmd->current_v[i].co);
zero_v3(collmd->current_v[i]);
}
return;
}
for (i = 0; i < collmd->mvert_num; i++) {
interp_v3_v3v3(collmd->current_x[i].co, collmd->x[i].co, collmd->xnew[i].co, prevstep);
interp_v3_v3v3(collmd->current_xnew[i].co, collmd->x[i].co, collmd->xnew[i].co, step);
sub_v3_v3v3(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
interp_v3_v3v3(collmd->current_x[i], collmd->x[i], collmd->xnew[i], prevstep);
interp_v3_v3v3(collmd->current_xnew[i], collmd->x[i], collmd->xnew[i], step);
sub_v3_v3v3(collmd->current_v[i], collmd->current_xnew[i], collmd->current_x[i]);
}
bvhtree_update_from_mvert(collmd->bvhtree,
@@ -92,7 +92,7 @@ void collision_move_object(CollisionModifierData *collmd,
moving_bvh);
}
BVHTree *bvhtree_build_from_mvert(const MVert *mvert,
BVHTree *bvhtree_build_from_mvert(const float (*positions)[3],
const struct MVertTri *tri,
int tri_num,
float epsilon)
@@ -105,9 +105,9 @@ BVHTree *bvhtree_build_from_mvert(const MVert *mvert,
for (i = 0, vt = tri; i < tri_num; i++, vt++) {
float co[3][3];
copy_v3_v3(co[0], mvert[vt->tri[0]].co);
copy_v3_v3(co[1], mvert[vt->tri[1]].co);
copy_v3_v3(co[2], mvert[vt->tri[2]].co);
copy_v3_v3(co[0], positions[vt->tri[0]]);
copy_v3_v3(co[1], positions[vt->tri[1]]);
copy_v3_v3(co[2], positions[vt->tri[2]]);
BLI_bvhtree_insert(tree, i, co[0], 3);
}
@@ -119,18 +119,18 @@ BVHTree *bvhtree_build_from_mvert(const MVert *mvert,
}
void bvhtree_update_from_mvert(BVHTree *bvhtree,
const MVert *mvert,
const MVert *mvert_moving,
const float (*positions)[3],
const float (*positions_moving)[3],
const MVertTri *tri,
int tri_num,
bool moving)
{
if ((bvhtree == NULL) || (mvert == NULL)) {
if ((bvhtree == NULL) || (positions == NULL)) {
return;
}
if (mvert_moving == NULL) {
if (positions_moving == NULL) {
moving = false;
}
@@ -140,17 +140,17 @@ void bvhtree_update_from_mvert(BVHTree *bvhtree,
float co[3][3];
bool ret;
copy_v3_v3(co[0], mvert[vt->tri[0]].co);
copy_v3_v3(co[1], mvert[vt->tri[1]].co);
copy_v3_v3(co[2], mvert[vt->tri[2]].co);
copy_v3_v3(co[0], positions[vt->tri[0]]);
copy_v3_v3(co[1], positions[vt->tri[1]]);
copy_v3_v3(co[2], positions[vt->tri[2]]);
/* copy new locations into array */
if (moving) {
float co_moving[3][3];
/* update moving positions */
copy_v3_v3(co_moving[0], mvert_moving[vt->tri[0]].co);
copy_v3_v3(co_moving[1], mvert_moving[vt->tri[1]].co);
copy_v3_v3(co_moving[2], mvert_moving[vt->tri[2]].co);
copy_v3_v3(co_moving[0], positions_moving[vt->tri[0]]);
copy_v3_v3(co_moving[1], positions_moving[vt->tri[1]]);
copy_v3_v3(co_moving[2], positions_moving[vt->tri[2]]);
ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], &co_moving[0][0], 3);
}
@@ -698,9 +698,9 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
}
collision_interpolateOnTriangle(v2,
collmd->current_v[collpair->bp1].co,
collmd->current_v[collpair->bp2].co,
collmd->current_v[collpair->bp3].co,
collmd->current_v[collpair->bp1],
collmd->current_v[collpair->bp2],
collmd->current_v[collpair->bp3],
u1,
u2,
u3);
@@ -992,9 +992,9 @@ static void cloth_collision(void *__restrict userdata,
distance = compute_collision_point_tri_tri(verts1[tri_a->tri[0]].tx,
verts1[tri_a->tri[1]].tx,
verts1[tri_a->tri[2]].tx,
collmd->current_xnew[tri_b->tri[0]].co,
collmd->current_xnew[tri_b->tri[1]].co,
collmd->current_xnew[tri_b->tri[2]].co,
collmd->current_xnew[tri_b->tri[0]],
collmd->current_xnew[tri_b->tri[1]],
collmd->current_xnew[tri_b->tri[2]],
data->culling,
data->use_normal,
pa,
@@ -1031,9 +1031,9 @@ static void cloth_collision(void *__restrict userdata,
&collpair[index].aw3);
collision_compute_barycentric(pb,
collmd->current_xnew[tri_b->tri[0]].co,
collmd->current_xnew[tri_b->tri[1]].co,
collmd->current_xnew[tri_b->tri[2]].co,
collmd->current_xnew[tri_b->tri[0]],
collmd->current_xnew[tri_b->tri[1]],
collmd->current_xnew[tri_b->tri[2]],
&collpair[index].bw1,
&collpair[index].bw2,
&collpair[index].bw3);
@@ -1191,9 +1191,9 @@ static void hair_collision(void *__restrict userdata,
/* Compute distance and normal. */
distance = compute_collision_point_edge_tri(verts1[edge_coll->v1].tx,
verts1[edge_coll->v2].tx,
collmd->current_x[tri_coll->tri[0]].co,
collmd->current_x[tri_coll->tri[1]].co,
collmd->current_x[tri_coll->tri[2]].co,
collmd->current_x[tri_coll->tri[0]],
collmd->current_x[tri_coll->tri[1]],
collmd->current_x[tri_coll->tri[2]],
data->culling,
data->use_normal,
pa,
@@ -1226,9 +1226,9 @@ static void hair_collision(void *__restrict userdata,
collpair[index].aw1 = 1.0f - collpair[index].aw2;
collision_compute_barycentric(pb,
collmd->current_xnew[tri_coll->tri[0]].co,
collmd->current_xnew[tri_coll->tri[1]].co,
collmd->current_xnew[tri_coll->tri[2]].co,
collmd->current_xnew[tri_coll->tri[0]],
collmd->current_xnew[tri_coll->tri[1]],
collmd->current_xnew[tri_coll->tri[2]],
&collpair[index].bw1,
&collpair[index].bw2,
&collpair[index].bw3);
@@ -1747,17 +1747,17 @@ void collision_get_collider_velocity(float vel_old[3],
/* compute barycentric coordinates */
collision_compute_barycentric(collpair->pb,
collmd->current_x[collpair->bp1].co,
collmd->current_x[collpair->bp2].co,
collmd->current_x[collpair->bp3].co,
collmd->current_x[collpair->bp1],
collmd->current_x[collpair->bp2],
collmd->current_x[collpair->bp3],
&u1,
&u2,
&u3);
collision_interpolateOnTriangle(vel_new,
collmd->current_v[collpair->bp1].co,
collmd->current_v[collpair->bp2].co,
collmd->current_v[collpair->bp3].co,
collmd->current_v[collpair->bp1],
collmd->current_v[collpair->bp2],
collmd->current_v[collpair->bp3],
u1,
u2,
u3);
@@ -548,7 +548,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
else 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_verts(me_eval);
const float(*positions)[3] = BKE_mesh_vert_positions(me_eval);
int numVerts = me_eval->totvert;
/* check that dvert is a valid pointers (just in case) */
@@ -557,11 +557,10 @@ 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 = &verts[i];
const MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
if (dw && dw->weight > 0.0f) {
madd_v3_v3fl(vec, mv->co, dw->weight);
madd_v3_v3fl(vec, positions[i], dw->weight);
madd_v3_v3fl(normal, vert_normals[i], dw->weight);
weightsum += dw->weight;
}
@@ -188,7 +188,7 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me,
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 */
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
@@ -214,9 +214,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me,
co_next = origcos[ml_next->v];
}
else {
co_prev = verts[ml_prev->v].co;
co_curr = verts[ml_curr->v].co;
co_next = verts[ml_next->v].co;
co_prev = positions[ml_prev->v];
co_curr = positions[ml_curr->v];
co_next = positions[ml_next->v];
}
set_crazy_vertex_quat(
@@ -188,7 +188,7 @@ static void fill_mesh_positions(const int main_point_num,
const Span<float3> tangents,
const Span<float3> normals,
const Span<float> radii,
MutableSpan<MVert> mesh_positions)
MutableSpan<float3> mesh_positions)
{
if (profile_point_num == 1) {
for (const int i_ring : IndexRange(main_point_num)) {
@@ -197,9 +197,7 @@ static void fill_mesh_positions(const int main_point_num,
if (!radii.is_empty()) {
point_matrix.apply_scale(radii[i_ring]);
}
MVert &vert = mesh_positions[i_ring];
copy_v3_v3(vert.co, point_matrix * profile_positions.first());
mesh_positions[i_ring] = point_matrix * profile_positions.first();
}
}
else {
@@ -212,8 +210,7 @@ static void fill_mesh_positions(const int main_point_num,
const int ring_vert_start = i_ring * profile_point_num;
for (const int i_profile : IndexRange(profile_point_num)) {
MVert &vert = mesh_positions[ring_vert_start + i_profile];
copy_v3_v3(vert.co, point_matrix * profile_positions[i_profile]);
mesh_positions[ring_vert_start + i_profile] = point_matrix * profile_positions[i_profile];
}
}
}
@@ -643,7 +640,7 @@ 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->verts_for_write();
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MPoly> polys = mesh->polys_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
@@ -691,7 +688,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
tangents.slice(info.main_points),
normals.slice(info.main_points),
radii.is_empty() ? radii : radii.slice(info.main_points),
verts.slice(info.vert_range));
positions.slice(info.vert_range));
});
if (profile.curve_type_counts()[CURVE_TYPE_BEZIER] > 0) {
@@ -1638,7 +1638,7 @@ static void layerInterp_propbool(const void **sources,
}
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
/* 0: CD_MVERT */ /* DEPRECATED */
{sizeof(MVert), "MVert", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 1: CD_MSTICKY */ /* DEPRECATED */
{sizeof(float[2]), "", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
@@ -2106,22 +2106,22 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
};
const CustomData_MeshMasks CD_MASK_BAREMESH = {
/* vmask */ CD_MASK_MVERT,
/* vmask */ CD_MASK_PROP_FLOAT3,
/* emask */ CD_MASK_MEDGE,
/* fmask */ 0,
/* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP,
/* lmask */ CD_MASK_MLOOP,
};
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
/* vmask */ CD_MASK_MVERT | CD_MASK_ORIGINDEX,
/* vmask */ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX,
/* emask */ CD_MASK_MEDGE | CD_MASK_ORIGINDEX,
/* fmask */ 0,
/* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX,
/* lmask */ CD_MASK_MLOOP,
};
const CustomData_MeshMasks CD_MASK_MESH = {
/* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK |
CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT),
/* vmask */ (CD_MASK_PROP_FLOAT3 | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN |
CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT),
/* emask */
(CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT | CD_MASK_CREASE),
/* fmask */ 0,
@@ -2157,7 +2157,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = {
CD_MASK_PROP_ALL),
};
const CustomData_MeshMasks CD_MASK_EVERYTHING = {
/* vmask */ (CD_MASK_MVERT | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT |
/* vmask */ (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT |
CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO |
CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK |
CD_MASK_PROP_ALL | CD_MASK_CREASE),
@@ -2372,6 +2372,7 @@ bool CustomData_merge(const CustomData *source,
static bool attribute_stored_in_bmesh_flag(const StringRef name)
{
return ELEM(name,
"position",
".hide_vert",
".hide_edge",
".hide_poly",
@@ -257,7 +257,7 @@ 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. */
const MVert *verts_dst = BKE_mesh_verts(me_dst);
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
@@ -287,7 +287,7 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
}
if (dirty_nors_dst || do_loop_nors_dst) {
BKE_mesh_normals_loop_split(verts_dst,
BKE_mesh_normals_loop_split(positions_dst,
BKE_mesh_vertex_normals_ensure(me_dst),
num_verts_dst,
edges_dst,
@@ -320,7 +320,7 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/,
}
/* Bake edited destination loop normals into custom normals again. */
const MVert *verts_dst = BKE_mesh_verts(me_dst);
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
MEdge *edges_dst = BKE_mesh_edges_for_write(me_dst);
const int num_edges_dst = me_dst->totedge;
@@ -342,7 +342,7 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/,
}
/* Note loop_nors_dst contains our custom normals as transferred from source... */
BKE_mesh_normals_loop_custom_set(verts_dst,
BKE_mesh_normals_loop_custom_set(positions_dst,
BKE_mesh_vertex_normals_ensure(me_dst),
num_verts_dst,
edges_dst,
@@ -932,7 +932,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
if (cddata_type == CD_FAKE_SHAPEKEY) {
/* TODO: leaving shape-keys aside for now, quite specific case,
* since we can't access them from #MVert :/ */
* since we can't access them from mesh vertices :/ */
return false;
}
}
@@ -1314,7 +1314,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
BKE_mesh_remap_find_best_match_from_mesh(
BKE_mesh_verts(me_dst), me_dst->totvert, me_src, space_transform);
BKE_mesh_vert_positions(me_dst), me_dst->totvert, me_src, space_transform);
}
/* Check all possible data types.
@@ -1342,7 +1342,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
if (DT_DATATYPE_IS_VERT(dtdata_type)) {
MVert *verts_dst = BKE_mesh_verts_for_write(me_dst);
float(*positions_dst)[3] = BKE_mesh_vert_positions_for_write(me_dst);
const int num_verts_dst = me_dst->totvert;
if (!geom_map_init[VDATA]) {
@@ -1381,7 +1381,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
space_transform,
max_distance,
ray_radius,
verts_dst,
positions_dst,
num_verts_dst,
dirty_nors_dst,
me_src,
@@ -1426,7 +1426,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
const MVert *verts_dst = BKE_mesh_verts_for_write(me_dst);
const float(*positions_dst)[3] = BKE_mesh_vert_positions_for_write(me_dst);
const int num_verts_dst = me_dst->totvert;
const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
@@ -1460,7 +1460,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
space_transform,
max_distance,
ray_radius,
verts_dst,
positions_dst,
num_verts_dst,
edges_dst,
num_edges_dst,
@@ -1507,7 +1507,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
const MVert *verts_dst = BKE_mesh_verts(me_dst);
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
@@ -1549,7 +1549,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
max_distance,
ray_radius,
me_dst,
verts_dst,
positions_dst,
num_verts_dst,
edges_dst,
num_edges_dst,
@@ -1604,7 +1604,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
const MVert *verts_dst = BKE_mesh_verts(me_dst);
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
const MPoly *polys_dst = BKE_mesh_polys(me_dst);
const int num_polys_dst = me_dst->totpoly;
@@ -1641,7 +1641,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
max_distance,
ray_radius,
me_dst,
verts_dst,
positions_dst,
loops_dst,
polys_dst,
num_polys_dst,
+47 -57
View File
@@ -201,7 +201,7 @@ typedef struct PaintBakeData {
* 3 float dir vec + 1 float str */
float *brush_velocity;
/** copy of previous frame vertices. used to observe surface movement. */
MVert *prev_verts;
float (*prev_positions)[3];
/** Previous frame object matrix. */
float prev_obmat[4][4];
/** flag to check if surface was cleared/reset -> have to redo velocity etc. */
@@ -900,8 +900,8 @@ static void free_bakeData(PaintSurfaceData *data)
if (bData->grid) {
freeGrid(data);
}
if (bData->prev_verts) {
MEM_freeN(bData->prev_verts);
if (bData->prev_positions) {
MEM_freeN(bData->prev_positions);
}
if (bData->velocity) {
MEM_freeN(bData->velocity);
@@ -1774,7 +1774,7 @@ typedef struct DynamicPaintModifierApplyData {
const DynamicPaintSurface *surface;
Object *ob;
MVert *mvert;
float (*vert_positions)[3];
const float (*vert_normals)[3];
const MLoop *mloop;
const MPoly *mpoly;
@@ -1791,13 +1791,11 @@ static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata,
const DynamicPaintModifierApplyData *data = userdata;
const DynamicPaintSurface *surface = data->surface;
MVert *mvert = data->mvert;
const float *value = (float *)surface->data->type_data;
const float val = value[i] * surface->disp_factor;
/* same as 'mvert[i].co[0] -= normal[0] * val' etc. */
madd_v3_v3fl(mvert[i].co, data->vert_normals[i], -val);
madd_v3_v3fl(data->vert_positions[i], data->vert_normals[i], -val);
}
/* apply displacing vertex surface to the derived mesh */
@@ -1811,11 +1809,9 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
/* displace paint */
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
MVert *mvert = BKE_mesh_verts_for_write(result);
DynamicPaintModifierApplyData data = {
.surface = surface,
.mvert = mvert,
.vert_positions = BKE_mesh_vert_positions_for_write(result),
.vert_normals = BKE_mesh_vertex_normals_ensure(result),
};
TaskParallelSettings settings;
@@ -1882,9 +1878,8 @@ static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata,
const DynamicPaintModifierApplyData *data = userdata;
PaintWavePoint *wPoint = (PaintWavePoint *)data->surface->data->type_data;
MVert *mvert = data->mvert;
madd_v3_v3fl(mvert[i].co, data->vert_normals[i], wPoint[i].height);
madd_v3_v3fl(data->vert_positions[i], data->vert_normals[i], wPoint[i].height);
}
/*
@@ -2010,11 +2005,9 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
/* wave simulation */
else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
MVert *mvert = BKE_mesh_verts_for_write(result);
DynamicPaintModifierApplyData data = {
.surface = surface,
.mvert = mvert,
.vert_positions = BKE_mesh_vert_positions_for_write(result),
.vert_normals = BKE_mesh_vertex_normals_ensure(result),
};
TaskParallelSettings settings;
@@ -2961,7 +2954,6 @@ int dynamicPaint_createUVSurface(Scene *scene,
BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map,
&vert_to_looptri_map_mem,
BKE_mesh_verts_for_write(mesh),
mesh->totvert,
mlooptri,
tottri,
@@ -3413,16 +3405,16 @@ static void mesh_tris_spherecast_dp(void *userdata,
BVHTreeRayHit *hit)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MLoopTri *mlooptri = data->looptri;
const MLoop *mloop = data->loop;
const float *t0, *t1, *t2;
float dist;
t0 = vert[mloop[mlooptri[index].tri[0]].v].co;
t1 = vert[mloop[mlooptri[index].tri[1]].v].co;
t2 = vert[mloop[mlooptri[index].tri[2]].v].co;
t0 = positions[mloop[mlooptri[index].tri[0]].v];
t1 = positions[mloop[mlooptri[index].tri[1]].v];
t2 = positions[mloop[mlooptri[index].tri[2]].v];
dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
@@ -3445,15 +3437,15 @@ static void mesh_tris_nearest_point_dp(void *userdata,
BVHTreeNearest *nearest)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const MVert *vert = data->vert;
const float(*positions)[3] = data->vert_positions;
const MLoopTri *mlooptri = data->looptri;
const MLoop *mloop = data->loop;
float nearest_tmp[3], dist_sq;
const float *t0, *t1, *t2;
t0 = vert[mloop[mlooptri[index].tri[0]].v].co;
t1 = vert[mloop[mlooptri[index].tri[1]].v].co;
t2 = vert[mloop[mlooptri[index].tri[2]].v].co;
t0 = positions[mloop[mlooptri[index].tri[0]].v];
t1 = positions[mloop[mlooptri[index].tri[1]].v];
t2 = positions[mloop[mlooptri[index].tri[2]].v];
closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2);
dist_sq = len_squared_v3v3(co, nearest_tmp);
@@ -3709,8 +3701,8 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1,
typedef struct DynamicPaintBrushVelocityData {
Vec3f *brush_vel;
const MVert *mvert_p;
const MVert *mvert_c;
const float (*positions_p)[3];
const float (*positions_c)[3];
float (*obmat)[4];
float (*prev_obmat)[4];
@@ -3726,8 +3718,8 @@ static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata,
Vec3f *brush_vel = data->brush_vel;
const MVert *mvert_p = data->mvert_p;
const MVert *mvert_c = data->mvert_c;
const float(*positions_p)[3] = data->positions_p;
const float(*positions_c)[3] = data->positions_c;
float(*obmat)[4] = data->obmat;
float(*prev_obmat)[4] = data->prev_obmat;
@@ -3736,10 +3728,10 @@ static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata,
float p1[3], p2[3];
copy_v3_v3(p1, mvert_p[i].co);
copy_v3_v3(p1, positions_p[i]);
mul_m4_v3(prev_obmat, p1);
copy_v3_v3(p2, mvert_c[i].co);
copy_v3_v3(p2, positions_c[i]);
mul_m4_v3(obmat, p2);
sub_v3_v3v3(brush_vel[i].v, p2, p1);
@@ -3755,7 +3747,6 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
{
float prev_obmat[4][4];
Mesh *mesh_p, *mesh_c;
MVert *mvert_p, *mvert_c;
int numOfVerts_p, numOfVerts_c;
float cur_sfra = scene->r.subframe;
@@ -3782,7 +3773,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false);
numOfVerts_p = mesh_p->totvert;
mvert_p = BKE_mesh_verts_for_write(mesh_p);
float(*positions_p)[3] = BKE_mesh_vert_positions_for_write(mesh_p);
copy_m4_m4(prev_obmat, ob->object_to_world);
/* current frame mesh */
@@ -3798,7 +3789,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
eModifierType_DynamicPaint);
mesh_c = dynamicPaint_brush_mesh_get(brush);
numOfVerts_c = mesh_c->totvert;
mvert_c = BKE_mesh_verts_for_write(mesh_c);
float(*positions_c)[3] = BKE_mesh_vert_positions_for_write(mesh_c);
(*brushVel) = (struct Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f),
"Dynamic Paint brush velocity");
@@ -3808,14 +3799,14 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
/* if mesh is constructive -> num of verts has changed, only use current frame derived mesh */
if (numOfVerts_p != numOfVerts_c) {
mvert_p = mvert_c;
positions_p = positions_c;
}
/* calculate speed */
DynamicPaintBrushVelocityData data = {
.brush_vel = *brushVel,
.mvert_p = mvert_p,
.mvert_c = mvert_c,
.positions_p = positions_p,
.positions_c = positions_c,
.obmat = ob->object_to_world,
.prev_obmat = prev_obmat,
.timescale = timescale,
@@ -3886,7 +3877,7 @@ typedef struct DynamicPaintPaintData {
const int c_index;
Mesh *mesh;
const MVert *mvert;
const float (*positions)[3];
const MLoop *mloop;
const MLoopTri *mlooptri;
const float brush_radius;
@@ -3919,7 +3910,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
const float timescale = data->timescale;
const int c_index = data->c_index;
const MVert *mvert = data->mvert;
const float(*positions)[3] = data->positions;
const MLoop *mloop = data->mloop;
const MLoopTri *mlooptri = data->mlooptri;
const float brush_radius = data->brush_radius;
@@ -4000,7 +3991,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
};
float dot;
normal_tri_v3(hit.no, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co);
normal_tri_v3(hit.no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]);
dot = dot_v3v3(ray_dir, hit.no);
/* If ray and hit face normal are facing same direction
@@ -4149,7 +4140,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
const int v3 = mloop[mlooptri[hitTri].tri[2]].v;
/* calculate barycentric weights for hit point */
interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, hitCoord);
interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord);
/* Simple check based on brush surface velocity,
* TODO: perhaps implement something that handles volume movement as well. */
@@ -4245,7 +4236,6 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
PaintBakeData *bData = sData->bData;
Mesh *mesh = NULL;
Vec3f *brushVelocity = NULL;
MVert *mvert = NULL;
const MLoopTri *mlooptri = NULL;
const MLoop *mloop = NULL;
@@ -4269,7 +4259,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
VolumeGrid *grid = bData->grid;
mesh = BKE_mesh_copy_for_eval(brush_mesh, false);
mvert = BKE_mesh_verts_for_write(mesh);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
mloop = BKE_mesh_loops(mesh);
@@ -4279,8 +4269,8 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
* (Faster than transforming per surface point
* coordinates and normals to object space) */
for (ii = 0; ii < numOfVerts; ii++) {
mul_m4_v3(brushOb->object_to_world, mvert[ii].co);
boundInsert(&mesh_bb, mvert[ii].co);
mul_m4_v3(brushOb->object_to_world, positions[ii]);
boundInsert(&mesh_bb, positions[ii]);
/* for proximity project calculate average normal */
if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) {
@@ -4325,7 +4315,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
.timescale = timescale,
.c_index = c_index,
.mesh = mesh,
.mvert = mvert,
.positions = positions,
.mloop = mloop,
.mlooptri = mlooptri,
.brush_radius = brush_radius,
@@ -4758,7 +4748,7 @@ static bool dynamicPaint_paintSinglePoint(
}
const Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush);
const MVert *mvert = BKE_mesh_verts(brush_mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(brush_mesh);
/*
* Loop through every surface point
@@ -4769,7 +4759,7 @@ static bool dynamicPaint_paintSinglePoint(
.brushOb = brushOb,
.scene = scene,
.timescale = timescale,
.mvert = mvert,
.positions = positions,
.brush_radius = brush_radius,
.brushVelocity = &brushVel,
.pointCoord = pointCoord,
@@ -5861,11 +5851,11 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
Mesh *mesh = dynamicPaint_canvas_mesh_get(surface->canvas);
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
int numOfVerts = mesh->totvert;
if (!bData->prev_verts) {
if (!bData->prev_positions) {
return true;
}
@@ -5876,7 +5866,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o
/* vertices */
for (int i = 0; i < numOfVerts; i++) {
if (!equals_v3v3(bData->prev_verts[i].co, mvert[i].co)) {
if (!equals_v3v3(bData->prev_positions[i], positions[i])) {
return true;
}
}
@@ -5889,7 +5879,7 @@ typedef struct DynamicPaintGenerateBakeData {
const DynamicPaintSurface *surface;
Object *ob;
const MVert *mvert;
const float (*positions)[3];
const float (*vert_normals)[3];
const Vec3f *canvas_verts;
@@ -6021,7 +6011,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0;
int canvasNumOfVerts = mesh->totvert;
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
Vec3f *canvas_verts;
if (bData) {
@@ -6067,8 +6057,8 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
bData->s_num = MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_num");
bData->realCoord = (struct Vec3f *)MEM_mallocN(surface_totalSamples(surface) * sizeof(Vec3f),
"Dynamic Paint point coords");
bData->prev_verts = MEM_mallocN(canvasNumOfVerts * sizeof(MVert),
"Dynamic Paint bData prev_verts");
bData->prev_positions = MEM_mallocN(canvasNumOfVerts * sizeof(float[3]),
"Dynamic Paint bData prev_positions");
/* if any allocation failed, free everything */
if (!bData->bNormal || !bData->s_pos || !bData->s_num || !bData->realCoord || !canvas_verts) {
@@ -6112,7 +6102,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
*/
bData->mesh_bounds.valid = false;
for (index = 0; index < canvasNumOfVerts; index++) {
copy_v3_v3(canvas_verts[index].v, mvert[index].co);
copy_v3_v3(canvas_verts[index].v, positions[index]);
mul_m4_v3(ob->object_to_world, canvas_verts[index].v);
boundInsert(&bData->mesh_bounds, canvas_verts[index].v);
}
@@ -6123,7 +6113,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
DynamicPaintGenerateBakeData data = {
.surface = surface,
.ob = ob,
.mvert = mvert,
.positions = positions,
.vert_normals = BKE_mesh_vertex_normals_ensure(mesh),
.canvas_verts = canvas_verts,
.do_velocity_data = do_velocity_data,
@@ -6144,7 +6134,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
/* Copy current frame vertices to check against in next frame */
copy_m4_m4(bData->prev_obmat, ob->object_to_world);
memcpy(bData->prev_verts, mvert, canvasNumOfVerts * sizeof(MVert));
memcpy(bData->prev_positions, positions, canvasNumOfVerts * sizeof(float[3]));
bData->clear = 0;
+5 -5
View File
@@ -663,9 +663,9 @@ bool closest_point_on_surface(SurfaceModifierData *surmd,
const MLoop *mloop = surmd->bvhtree->loop;
const MLoopTri *lt = &surmd->bvhtree->looptri[nearest.index];
copy_v3_v3(surface_vel, surmd->v[mloop[lt->tri[0]].v].co);
add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[1]].v].co);
add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[2]].v].co);
copy_v3_v3(surface_vel, surmd->v[mloop[lt->tri[0]].v]);
add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[1]].v]);
add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[2]].v]);
mul_v3_fl(surface_vel, (1.0f / 3.0f));
}
@@ -701,10 +701,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_verts(me_eval);
const float(*positions)[3] = BKE_mesh_vert_positions(me_eval);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
if (me_eval != NULL) {
copy_v3_v3(efd->loc, verts[*efd->index].co);
copy_v3_v3(efd->loc, positions[*efd->index]);
copy_v3_v3(efd->nor, vert_normals[*efd->index]);
mul_m4_v3(eff->ob->object_to_world, efd->loc);
+47 -47
View File
@@ -404,7 +404,7 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
float size[3];
MVert *verts = BKE_mesh_verts_for_write(me);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
float scale = 0.0;
int res;
@@ -412,7 +412,7 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
/* Set minimum and maximum coordinates of BB. */
for (i = 0; i < me->totvert; i++) {
minmax_v3v3_v3(min, max, verts[i].co);
minmax_v3v3_v3(min, max, positions[i]);
}
/* Set domain bounds. */
@@ -840,7 +840,7 @@ BLI_INLINE void apply_effector_fields(FluidEffectorSettings *UNUSED(fes),
}
static void update_velocities(FluidEffectorSettings *fes,
const MVert *mvert,
const float (*vert_positions)[3],
const MLoop *mloop,
const MLoopTri *mlooptri,
float *velocity_map,
@@ -870,7 +870,8 @@ static void update_velocities(FluidEffectorSettings *fes,
v1 = mloop[mlooptri[f_index].tri[0]].v;
v2 = mloop[mlooptri[f_index].tri[1]].v;
v3 = mloop[mlooptri[f_index].tri[2]].v;
interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co);
interp_weights_tri_v3(
weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co);
/* Apply object velocity. */
float hit_vel[3];
@@ -937,7 +938,7 @@ static void update_velocities(FluidEffectorSettings *fes,
typedef struct ObstaclesFromDMData {
FluidEffectorSettings *fes;
const MVert *mvert;
const float (*vert_positions)[3];
const MLoop *mloop;
const MLoopTri *mlooptri;
@@ -972,7 +973,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
/* Calculate object velocities. Result in bb->velocity. */
update_velocities(data->fes,
data->mvert,
data->vert_positions,
data->mloop,
data->mlooptri,
bb->velocity,
@@ -1005,7 +1006,7 @@ static void obstacles_from_mesh(Object *coll_ob,
bool has_velocity = false;
Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false);
MVert *verts = BKE_mesh_verts_for_write(me);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
int min[3], max[3], res[3];
@@ -1036,11 +1037,11 @@ static void obstacles_from_mesh(Object *coll_ob,
float co[3];
/* Vertex position. */
mul_m4_v3(coll_ob->object_to_world, verts[i].co);
manta_pos_to_cell(fds, verts[i].co);
mul_m4_v3(coll_ob->object_to_world, positions[i]);
manta_pos_to_cell(fds, positions[i]);
/* Vertex velocity. */
add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift);
add_v3fl_v3fl_v3i(co, positions[i], 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);
@@ -1048,7 +1049,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, verts[i].co);
bb_boundInsert(bb, positions[i]);
}
/* Set emission map.
@@ -1070,7 +1071,7 @@ static void obstacles_from_mesh(Object *coll_ob,
ObstaclesFromDMData data = {
.fes = fes,
.mvert = verts,
.vert_positions = positions,
.mloop = mloop,
.mlooptri = looptri,
.tree = &tree_data,
@@ -1784,7 +1785,7 @@ static void update_distances(int index,
}
static void sample_mesh(FluidFlowSettings *ffs,
const MVert *mvert,
const float (*vert_positions)[3],
const float (*vert_normals)[3],
const MLoop *mloop,
const MLoopTri *mlooptri,
@@ -1872,7 +1873,8 @@ static void sample_mesh(FluidFlowSettings *ffs,
v1 = mloop[mlooptri[f_index].tri[0]].v;
v2 = mloop[mlooptri[f_index].tri[1]].v;
v3 = mloop[mlooptri[f_index].tri[2]].v;
interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co);
interp_weights_tri_v3(
weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co);
/* Compute emission strength for smoke flow. */
if (is_gas_flow) {
@@ -1978,7 +1980,7 @@ typedef struct EmitFromDMData {
FluidDomainSettings *fds;
FluidFlowSettings *ffs;
const MVert *mvert;
const float (*vert_positions)[3];
const float (*vert_normals)[3];
const MLoop *mloop;
const MLoopTri *mlooptri;
@@ -2012,7 +2014,7 @@ static void emit_from_mesh_task_cb(void *__restrict userdata,
* Result in bb->influence. Also computes initial velocities. Result in bb->velocity. */
if (ELEM(data->ffs->behavior, FLUID_FLOW_BEHAVIOR_GEOMETRY, FLUID_FLOW_BEHAVIOR_INFLOW)) {
sample_mesh(data->ffs,
data->mvert,
data->vert_positions,
data->vert_normals,
data->mloop,
data->mlooptri,
@@ -2062,7 +2064,7 @@ static void emit_from_mesh(
/* Copy mesh for thread safety as we modify it.
* Main issue is its VertArray being modified, then replaced and freed. */
Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false);
MVert *verts = BKE_mesh_verts_for_write(me);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
const MLoop *mloop = BKE_mesh_loops(me);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
@@ -2091,8 +2093,8 @@ static void emit_from_mesh(
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
for (i = 0; i < numverts; i++) {
/* Vertex position. */
mul_m4_v3(flow_ob->object_to_world, verts[i].co);
manta_pos_to_cell(fds, verts[i].co);
mul_m4_v3(flow_ob->object_to_world, positions[i]);
manta_pos_to_cell(fds, positions[i]);
/* Vertex normal. */
mul_mat3_m4_v3(flow_ob->object_to_world, vert_normals[i]);
@@ -2102,7 +2104,7 @@ static void emit_from_mesh(
/* Vertex velocity. */
if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
float co[3];
add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift);
add_v3fl_v3fl_v3i(co, positions[i], 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);
@@ -2111,7 +2113,7 @@ static void emit_from_mesh(
}
/* Calculate emission map bounds. */
bb_boundInsert(bb, verts[i].co);
bb_boundInsert(bb, positions[i]);
}
mul_m4_v3(flow_ob->object_to_world, flow_center);
manta_pos_to_cell(fds, flow_center);
@@ -2136,7 +2138,7 @@ static void emit_from_mesh(
EmitFromDMData data = {
.fds = fds,
.ffs = ffs,
.mvert = verts,
.vert_positions = positions,
.vert_normals = vert_normals,
.mloop = mloop,
.mlooptri = mlooptri,
@@ -3204,7 +3206,6 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
Object *ob)
{
Mesh *me;
MVert *mverts;
MPoly *mpolys;
MLoop *mloops;
float min[3];
@@ -3248,7 +3249,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
if (!me) {
return NULL;
}
mverts = BKE_mesh_verts_for_write(me);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
mpolys = BKE_mesh_polys_for_write(me);
mloops = BKE_mesh_loops_for_write(me);
@@ -3285,30 +3286,30 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
}
/* Loop for vertices and normals. */
for (i = 0; i < num_verts; i++, mverts++) {
for (i = 0; i < num_verts; i++) {
/* Vertices (data is normalized cube around domain origin). */
mverts->co[0] = manta_liquid_get_vertex_x_at(fds->fluid, i);
mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i);
mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i);
positions[i][0] = manta_liquid_get_vertex_x_at(fds->fluid, i);
positions[i][1] = manta_liquid_get_vertex_y_at(fds->fluid, i);
positions[i][2] = manta_liquid_get_vertex_z_at(fds->fluid, i);
/* Adjust coordinates from Mantaflow to match viewport scaling. */
float tmp[3] = {(float)fds->res[0], (float)fds->res[1], (float)fds->res[2]};
/* Scale to unit cube around 0. */
mul_v3_fl(tmp, fds->mesh_scale * 0.5f);
sub_v3_v3(mverts->co, tmp);
sub_v3_v3(positions[i], tmp);
/* Apply scaling of domain object. */
mul_v3_fl(mverts->co, fds->dx / fds->mesh_scale);
mul_v3_fl(positions[i], fds->dx / fds->mesh_scale);
mul_v3_v3(mverts->co, co_scale);
add_v3_v3(mverts->co, co_offset);
mul_v3_v3(positions[i], co_scale);
add_v3_v3(positions[i], co_offset);
# ifdef DEBUG_PRINT
/* Debugging: Print coordinates of vertices. */
printf("mverts->co[0]: %f, mverts->co[1]: %f, mverts->co[2]: %f\n",
mverts->co[0],
mverts->co[1],
mverts->co[2]);
printf("positions[i][0]: %f, positions[i][1]: %f, positions[i][2]: %f\n",
positions[i][0],
positions[i][1],
positions[i][2]);
# endif
# ifdef DEBUG_PRINT
@@ -3364,7 +3365,6 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Object *ob)
{
Mesh *result;
MVert *mverts;
MPoly *mpolys;
MLoop *mloops;
float min[3];
@@ -3384,7 +3384,7 @@ 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 = BKE_mesh_verts_for_write(result);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(result);
mpolys = BKE_mesh_polys_for_write(result);
mloops = BKE_mesh_loops_for_write(result);
@@ -3395,36 +3395,36 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
/* Set vertices of smoke BB. Especially important, when BB changes (adaptive domain). */
/* Top slab */
co = mverts[0].co;
co = positions[0];
co[0] = min[0];
co[1] = min[1];
co[2] = max[2];
co = mverts[1].co;
co = positions[1];
co[0] = max[0];
co[1] = min[1];
co[2] = max[2];
co = mverts[2].co;
co = positions[2];
co[0] = max[0];
co[1] = max[1];
co[2] = max[2];
co = mverts[3].co;
co = positions[3];
co[0] = min[0];
co[1] = max[1];
co[2] = max[2];
/* Bottom slab. */
co = mverts[4].co;
co = positions[4];
co[0] = min[0];
co[1] = min[1];
co[2] = min[2];
co = mverts[5].co;
co = positions[5];
co[0] = max[0];
co[1] = min[1];
co[2] = min[2];
co = mverts[6].co;
co = positions[6];
co[0] = max[0];
co[1] = max[1];
co[2] = min[2];
co = mverts[7].co;
co = positions[7];
co[0] = min[0];
co[1] = max[1];
co[2] = min[2];
@@ -3495,7 +3495,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
mul_mat3_m4_v3(ob->world_to_object, fds->obj_shift_f);
/* Apply shift to vertices. */
for (int i = 0; i < num_verts; i++) {
add_v3_v3(mverts[i].co, fds->obj_shift_f);
add_v3_v3(positions[i], fds->obj_shift_f);
}
}
@@ -904,16 +904,6 @@ static GVMutableArray make_derived_write_attribute(void *data, const int domain_
MutableSpan<StructT>((StructT *)data, domain_num));
}
static float3 get_vertex_position(const MVert &vert)
{
return float3(vert.co);
}
static void set_vertex_position(MVert &vert, float3 position)
{
copy_v3_v3(vert.co, position);
}
static void tag_component_positions_changed(void *owner)
{
Mesh *mesh = static_cast<Mesh *>(owner);
@@ -1237,18 +1227,17 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
#undef MAKE_CONST_CUSTOM_DATA_GETTER
#undef MAKE_MUTABLE_CUSTOM_DATA_GETTER
static BuiltinCustomDataLayerProvider position(
"position",
ATTR_DOMAIN_POINT,
CD_PROP_FLOAT3,
CD_MVERT,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_derived_read_attribute<MVert, float3, get_vertex_position>,
make_derived_write_attribute<MVert, float3, get_vertex_position, set_vertex_position>,
tag_component_positions_changed);
static BuiltinCustomDataLayerProvider position("position",
ATTR_DOMAIN_POINT,
CD_PROP_FLOAT3,
CD_PROP_FLOAT3,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static NormalAttributeProvider normal;
@@ -2471,7 +2471,7 @@ static void gpencil_generate_edgeloops(Object *ob,
if (me->totedge == 0) {
return;
}
const Span<MVert> verts = me->verts();
const Span<float3> vert_positions = me->vert_positions();
const Span<MEdge> edges = me->edges();
const Span<MDeformVert> dverts = me->deform_verts();
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me);
@@ -2488,18 +2488,16 @@ static void gpencil_generate_edgeloops(Object *ob,
for (int i = 0; i < me->totedge; i++) {
const MEdge *ed = &edges[i];
gped = &gp_edges[i];
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);
copy_v3_v3(gped->v1_co, vert_positions[ed->v1]);
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);
copy_v3_v3(gped->v2_co, vert_positions[ed->v2]);
sub_v3_v3v3(gped->vec, mv1->co, mv2->co);
sub_v3_v3v3(gped->vec, vert_positions[ed->v1], vert_positions[ed->v2]);
/* If use seams, mark as done if not a seam. */
if ((use_seams) && ((ed->flag & ME_SEAM) == 0)) {
@@ -2559,13 +2557,11 @@ 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;
const MVert *mv = &verts[vertex_index];
/* Add segment. */
bGPDspoint *pt = &gps_stroke->points[i];
copy_v3_v3(fpt, vert_normals[vertex_index]);
mul_v3_v3fl(fpt, fpt, offset);
add_v3_v3v3(&pt->x, mv->co, fpt);
add_v3_v3v3(&pt->x, vert_positions[vertex_index], fpt);
mul_m4_v3(matrix, &pt->x);
pt->pressure = 1.0f;
@@ -2683,7 +2679,7 @@ 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 Span<MVert> verts = me_eval->verts();
const Span<float3> positions = me_eval->vert_positions();
const Span<MPoly> polys = me_eval->polys();
const Span<MLoop> loops = me_eval->loops();
int mpoly_len = me_eval->totpoly;
@@ -2758,10 +2754,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
/* Add points to strokes. */
for (int j = 0; j < mp->totloop; j++) {
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);
copy_v3_v3(&pt->x, positions[ml->v]);
mul_m4_v3(matrix, &pt->x);
pt->pressure = 1.0f;
pt->strength = 1.0f;
+15 -29
View File
@@ -1508,7 +1508,6 @@ static void do_latt_key(Object *ob, Key *key, char *out, const int tot)
}
}
static void keyblock_data_convert_to_mesh(const float (*fp)[3], MVert *mvert, const int totvert);
static void keyblock_data_convert_to_lattice(const float (*fp)[3],
BPoint *bpoint,
const int totpoint);
@@ -1608,9 +1607,9 @@ float *BKE_key_evaluate_object_ex(
switch (GS(obdata->name)) {
case ID_ME: {
Mesh *mesh = (Mesh *)obdata;
MVert *verts = BKE_mesh_verts_for_write(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
const int totvert = min_ii(tot, mesh->totvert);
keyblock_data_convert_to_mesh((const float(*)[3])out, verts, totvert);
memcpy(out, positions, sizeof(float[3]) * totvert);
break;
}
case ID_LT: {
@@ -2187,21 +2186,15 @@ void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve * /*cu*/, ListBase *nurb)
void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb)
{
float(*fp)[3];
int a, tot;
BLI_assert(me->totvert == kb->totelem);
tot = me->totvert;
const int tot = me->totvert;
if (tot == 0) {
return;
}
const MVert *mvert = BKE_mesh_verts(me);
fp = static_cast<float(*)[3]>(kb->data);
for (a = 0; a < tot; a++, fp++, mvert++) {
copy_v3_v3(*fp, mvert->co);
}
const float(*positions)[3] = BKE_mesh_vert_positions(me);
memcpy(kb->data, positions, sizeof(float[3]) * tot);
}
void BKE_keyblock_convert_from_mesh(const Mesh *me, const Key *key, KeyBlock *kb)
@@ -2220,19 +2213,12 @@ void BKE_keyblock_convert_from_mesh(const Mesh *me, const Key *key, KeyBlock *kb
BKE_keyblock_update_from_mesh(me, kb);
}
static void keyblock_data_convert_to_mesh(const float (*fp)[3], MVert *mvert, const int totvert)
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb,
float (*vert_positions)[3],
const int totvert)
{
for (int i = 0; i < totvert; i++, fp++, mvert++) {
copy_v3_v3(mvert->co, *fp);
}
}
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, MVert *mvert, const int totvert)
{
const float(*fp)[3] = static_cast<const float(*)[3]>(kb->data);
const int tot = min_ii(kb->totelem, totvert);
keyblock_data_convert_to_mesh(fp, mvert, tot);
memcpy(kb->data, vert_positions, sizeof(float[3]) * tot);
}
void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
@@ -2245,8 +2231,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
return;
}
MVert *verts = static_cast<MVert *>(MEM_dupallocN(BKE_mesh_verts(mesh)));
BKE_keyblock_convert_to_mesh(kb, verts, mesh->totvert);
float(*positions)[3] = static_cast<float(*)[3]>(MEM_dupallocN(BKE_mesh_vert_positions(mesh)));
BKE_keyblock_convert_to_mesh(kb, positions, mesh->totvert);
const MEdge *edges = BKE_mesh_edges(mesh);
const MPoly *polys = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
@@ -2273,10 +2259,10 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
if (poly_normals_needed) {
BKE_mesh_calc_normals_poly(
verts, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals);
positions, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals);
}
if (vert_normals_needed) {
BKE_mesh_calc_normals_poly_and_vertex(verts,
BKE_mesh_calc_normals_poly_and_vertex(positions,
mesh->totvert,
loops,
mesh->totloop,
@@ -2288,7 +2274,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
if (loop_normals_needed) {
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); /* May be nullptr. */
BKE_mesh_normals_loop_split(verts,
BKE_mesh_normals_loop_split(positions,
vert_normals,
mesh->totvert,
edges,
@@ -2312,7 +2298,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
if (free_poly_normals) {
MEM_freeN(poly_normals);
}
MEM_freeN(verts);
MEM_freeN(positions);
}
/************************* raw coords ************************/
@@ -1463,12 +1463,9 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name + 2);
mesh->totvert = int(process.curvertex);
MVert *mvert = static_cast<MVert *>(
CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, nullptr, mesh->totvert));
for (int i = 0; i < mesh->totvert; i++) {
copy_v3_v3(mvert[i].co, process.co[i]);
}
MEM_freeN(process.co);
CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_ASSIGN, process.co, mesh->totvert, "position");
process.co = nullptr;
mesh->totpoly = int(process.curindex);
MPoly *mpoly = static_cast<MPoly *>(
+44 -64
View File
@@ -18,6 +18,7 @@
#include "DNA_object_types.h"
#include "BLI_bit_vector.hh"
#include "BLI_bounds.hh"
#include "BLI_edgehash.h"
#include "BLI_endian_switch.h"
#include "BLI_ghash.h"
@@ -28,6 +29,7 @@
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_memarena.h"
#include "BLI_resource_scope.hh"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_task.hh"
@@ -228,6 +230,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
Vector<CustomDataLayer, 16> edge_layers;
Vector<CustomDataLayer, 16> loop_layers;
Vector<CustomDataLayer, 16> poly_layers;
blender::ResourceScope temp_arrays_for_legacy_format;
/* cache only - don't write */
mesh->mface = nullptr;
@@ -251,6 +254,18 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
else {
Set<std::string> names_to_skip;
if (!BLO_write_is_undo(writer)) {
/* When converting to the old mesh format, don't save redundant attributes. */
names_to_skip.add_multiple_new({".hide_vert",
".hide_edge",
".hide_poly",
"position",
"material_index",
".select_vert",
".select_edge",
".select_poly"});
mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts(
mesh, temp_arrays_for_legacy_format, vert_layers);
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
@@ -261,17 +276,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->active_color_attribute = nullptr;
mesh->default_color_attribute = nullptr;
BKE_mesh_legacy_convert_loose_edges_to_flag(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",
"material_index",
".select_vert",
".select_edge",
".select_poly"});
/* Set deprecated mesh data pointers for forward compatibility. */
mesh->mvert = const_cast<MVert *>(mesh->verts().data());
mesh->medge = const_cast<MEdge *>(mesh->edges().data());
mesh->mpoly = const_cast<MPoly *>(mesh->polys().data());
mesh->mloop = const_cast<MLoop *>(mesh->loops().data());
@@ -480,9 +486,8 @@ static int customdata_compare(
const float thresh_sq = thresh * thresh;
CustomDataLayer *l1, *l2;
int layer_count1 = 0, layer_count2 = 0, j;
const uint64_t cd_mask_non_generic = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MPOLY |
CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR |
CD_MASK_MDEFORMVERT;
const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | 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();
@@ -525,22 +530,6 @@ static int customdata_compare(
found_corresponding_layer = true;
switch (l1->type) {
case CD_MVERT: {
MVert *v1 = (MVert *)l1->data;
MVert *v2 = (MVert *)l2->data;
int vtot = m1->totvert;
for (j = 0; j < vtot; j++, v1++, v2++) {
for (int k = 0; k < 3; k++) {
if (compare_threshold_relative(v1->co[k], v2->co[k], thresh)) {
return MESHCMP_VERTCOMISMATCH;
}
}
}
break;
}
/* We're order-agnostic for edges here. */
case CD_MEDGE: {
MEdge *e1 = (MEdge *)l1->data;
@@ -788,6 +777,11 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
return nullptr;
}
bool BKE_mesh_attribute_required(const char *name)
{
return StringRef(name) == "position";
}
void BKE_mesh_ensure_skin_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
@@ -936,8 +930,9 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
/* Custom data layer functions; those assume that totXXX are set correctly. */
static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
{
if (!CustomData_get_layer(&mesh->vdata, CD_MVERT)) {
CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert);
if (!CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) {
CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, mesh->totvert, "position");
}
if (!CustomData_get_layer(&mesh->edata, CD_MEDGE)) {
CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, mesh->totedge);
@@ -1293,12 +1288,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");
const Span<MVert> verts = tme->verts();
const Span<float3> positions = tme->vert_positions();
int totvert = min_ii(tme->totvert, me->totvert);
for (int a = 0; a < totvert; a++) {
copy_v3_v3(vcos[a], verts[a].co);
copy_v3_v3(vcos[a], positions[a]);
}
return vcos;
@@ -1548,23 +1543,8 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
return false;
}
me->runtime->bounds_cache.ensure([me](Bounds<float3> &r_bounds) {
const Span<MVert> verts = me->verts();
r_bounds = threading::parallel_reduce(
verts.index_range(),
1024,
Bounds<float3>{float3(FLT_MAX), float3(-FLT_MAX)},
[verts](IndexRange range, const Bounds<float3> &init) {
Bounds<float3> result = init;
for (const int i : range) {
math::min_max(float3(verts[i].co), result.min, result.max);
}
return result;
},
[](const Bounds<float3> &a, const Bounds<float3> &b) {
return Bounds<float3>{math::min(a.min, b.min), math::max(a.max, b.max)};
});
});
me->runtime->bounds_cache.ensure(
[me](Bounds<float3> &r_bounds) { r_bounds = *bounds::min_max(me->vert_positions()); });
const Bounds<float3> &bounds = me->runtime->bounds_cache.data();
copy_v3_v3(r_min, math::min(bounds.min, float3(r_min)));
@@ -1575,10 +1555,10 @@ 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)
{
MutableSpan<MVert> verts = me->verts_for_write();
MutableSpan<float3> positions = me->vert_positions_for_write();
for (MVert &vert : verts) {
mul_m4_v3(mat, vert.co);
for (float3 &position : positions) {
mul_m4_v3(mat, position);
}
if (do_keys && me->key) {
@@ -1609,9 +1589,9 @@ 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)
{
MutableSpan<MVert> verts = me->verts_for_write();
for (MVert &vert : verts) {
add_v3_v3(vert.co, offset);
MutableSpan<float3> positions = me->vert_positions_for_write();
for (float3 &position : positions) {
position += offset;
}
int i;
@@ -1785,9 +1765,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])
{
MutableSpan<MVert> verts = mesh->verts_for_write();
for (const int i : verts.index_range()) {
copy_v3_v3(verts[i].co, vert_coords[i]);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
for (const int i : positions.index_range()) {
copy_v3_v3(positions[i], vert_coords[i]);
}
BKE_mesh_tag_coords_changed(mesh);
}
@@ -1796,9 +1776,9 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
const float (*vert_coords)[3],
const float mat[4][4])
{
MutableSpan<MVert> verts = mesh->verts_for_write();
for (const int i : verts.index_range()) {
mul_v3_m4v3(verts[i].co, mat, vert_coords[i]);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
for (const int i : positions.index_range()) {
mul_v3_m4v3(positions[i], mat, vert_coords[i]);
}
BKE_mesh_tag_coords_changed(mesh);
}
@@ -1834,14 +1814,14 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
/* may be nullptr */
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
const Span<MVert> verts = mesh->verts();
const Span<float3> positions = mesh->vert_positions();
const Span<MEdge> edges = mesh->edges();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
BKE_mesh_normals_loop_split(verts.data(),
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(positions.data()),
BKE_mesh_vertex_normals_ensure(mesh),
verts.size(),
positions.size(),
edges.data(),
edges.size(),
loops.data(),
@@ -102,16 +102,16 @@ class MeshesToIMeshInfo {
const Mesh **r_orig_mesh,
int *r_orig_mesh_index,
int *r_index_in_orig_mesh) const;
const MVert *input_mvert_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
void input_mvert_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
const MEdge *input_medge_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
};
/* Given an index `imesh_v` in the `IMesh`, return the index of the
* input `Mesh` that contained the `MVert` that it came from. */
* input `Mesh` that contained the vertex that it came from. */
int MeshesToIMeshInfo::input_mesh_for_imesh_vert(int imesh_v) const
{
int n = int(mesh_vert_offset.size());
@@ -124,7 +124,7 @@ int MeshesToIMeshInfo::input_mesh_for_imesh_vert(int imesh_v) const
}
/* Given an index `imesh_e` used as an original index in the `IMesh`,
* return the index of the input `Mesh` that contained the `MVert` that it came from. */
* return the index of the input `Mesh` that contained the vertex that it came from. */
int MeshesToIMeshInfo::input_mesh_for_imesh_edge(int imesh_e) const
{
int n = int(mesh_edge_offset.size());
@@ -180,26 +180,23 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
/* Given an index of an original vertex in the `IMesh`, find out the input
* `Mesh` that it came from and return it in `*r_orig_mesh`.
* Also find the index of the `MVert` in that `Mesh` and return it in
* Also find the index of the vertex in that `Mesh` and return it in
* `*r_index_in_orig_mesh`. */
const MVert *MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const
void MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const
{
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->verts();
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 = &verts[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
if (r_index_in_orig_mesh) {
*r_index_in_orig_mesh = index_in_mesh;
}
return mv;
}
/* Similarly for edges. */
@@ -229,7 +226,7 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
* first Mesh. To do this transformation, we also need the transformation
* obmats corresponding to the Meshes, so they are in the `obmats` argument.
* The 'original' indexes in the IMesh are the indexes you get by
* a scheme that offsets each MVert, MEdge, and MPoly index by the sum of the
* a scheme that offsets each vertex, MEdge, and MPoly index by the sum of the
* vertices, edges, and polys in the preceding Meshes in the mesh span.
* The `*r_info class` is filled in with information needed to make the
* correspondence between the Mesh MVerts/MPolys and the IMesh Verts/Faces.
@@ -287,7 +284,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
const float4x4 inv_target_mat = clean_transform(target_transform).inverted();
/* For each input `Mesh`, make `Vert`s and `Face`s for the corresponding
* `MVert`s and `MPoly`s, and keep track of the original indices (using the
* vertices and `MPoly`s, and keep track of the original indices (using the
* concatenating offset scheme) inside the `Vert`s and `Face`s.
* When making `Face`s, we also put in the original indices for `MEdge`s that
* make up the `MPoly`s using the same scheme. */
@@ -309,7 +306,7 @@ 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);
const Span<MVert> mesh_verts = me->verts();
const Span<float3> vert_positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
@@ -318,10 +315,9 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
* 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(mesh_verts.index_range(), 2048, [&](IndexRange range) {
float3 co;
threading::parallel_for(vert_positions.index_range(), 2048, [&](IndexRange range) {
for (int i : range) {
co = float3(mesh_verts[i].co);
float3 co = vert_positions[i];
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);
@@ -329,17 +325,16 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
});
}
else {
threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) {
float3 co;
threading::parallel_for(vert_positions.index_range(), 2048, [&](IndexRange range) {
for (int i : range) {
co = r_info->to_target_transform[mi] * float3(mesh_verts[i].co);
float3 co = r_info->to_target_transform[mi] * vert_positions[i];
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 : mesh_verts.index_range()) {
for (int i : vert_positions.index_range()) {
r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]);
++v;
}
@@ -384,9 +379,7 @@ static void copy_vert_attributes(Mesh *dest_mesh,
const CustomData *source_cd = &orig_me->vdata;
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
int ty = source_cd->layers[source_layer_i].type;
/* The (first) CD_MVERT layer is the same as dest_mesh->vdata, so we've
* already set the coordinate to the right value. */
if (ty == CD_MVERT) {
if (StringRef(source_cd->layers->name) == "position") {
continue;
}
const char *name = source_cd->layers[source_layer_i].name;
@@ -559,16 +552,19 @@ static void get_poly2d_cos(const Mesh *me,
const float4x4 &trans_mat,
float r_axis_mat[3][3])
{
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
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, &loops[mp->loopstart], verts.data(), axis_dominant);
BKE_mesh_calc_poly_normal(mp,
&loops[mp->loopstart],
reinterpret_cast<const float(*)[3]>(positions.data()),
axis_dominant);
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
for (const int i : poly_loops.index_range()) {
float3 co = verts[poly_loops[i].v].co;
float3 co = positions[poly_loops[i].v];
co = trans_mat * co;
mul_v2_m3v3(cos_2d[i], r_axis_mat, co);
}
@@ -605,7 +601,7 @@ 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_verts = dest_mesh->verts();
const Span<float3> dst_positions = dest_mesh->vert_positions();
const Span<MLoop> dst_loops = dest_mesh->loops();
for (int i = 0; i < mp->totloop; ++i) {
int loop_index = mp->loopstart + i;
@@ -616,7 +612,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, dst_verts[dst_loops[loop_index].v].co);
mul_v2_m3v3(co, axis_mat, dst_positions[dst_loops[loop_index].v]);
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) {
@@ -719,7 +715,7 @@ 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> verts = result->verts_for_write();
MutableSpan<float3> positions = result->vert_positions_for_write();
for (int vi : im->vert_index_range()) {
const Vert *v = im->vert(vi);
if (v->orig != NO_INDEX) {
@@ -728,8 +724,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
mim.input_mvert_for_orig_index(v->orig, &orig_me, &index_in_orig_me);
copy_vert_attributes(result, orig_me, vi, index_in_orig_me);
}
MVert *mv = &verts[vi];
copy_v3fl_v3db(mv->co, v->co);
copy_v3fl_v3db(positions[vi], v->co);
}
/* Set the loopstart and totloop for each output poly,
@@ -190,7 +190,7 @@ 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->verts_for_write();
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<MEdge> edges = mesh->edges_for_write();
MutableSpan<MPoly> polys = mesh->polys_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
@@ -213,7 +213,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
a = dl->parts * dl->nr;
const float *data = dl->verts;
while (a--) {
copy_v3_v3(verts[dst_vert].co, data);
copy_v3_v3(positions[dst_vert], data);
data += 3;
dst_vert++;
}
@@ -235,7 +235,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
a = dl->parts * dl->nr;
const float *data = dl->verts;
while (a--) {
copy_v3_v3(verts[dst_vert].co, data);
copy_v3_v3(positions[dst_vert], data);
data += 3;
dst_vert++;
}
@@ -261,7 +261,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
a = dl->nr;
const float *data = dl->verts;
while (a--) {
copy_v3_v3(verts[dst_vert].co, data);
copy_v3_v3(positions[dst_vert], data);
data += 3;
dst_vert++;
}
@@ -296,7 +296,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
a = dl->parts * dl->nr;
const float *data = dl->verts;
while (a--) {
copy_v3_v3(verts[dst_vert].co, data);
copy_v3_v3(positions[dst_vert], data);
data += 3;
dst_vert++;
}
@@ -456,7 +456,7 @@ static void appendPolyLineVert(ListBase *lb, uint index)
void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
{
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
const Span<MEdge> mesh_edges = me->edges();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
@@ -588,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, verts[vl->index].co);
copy_v3_v3(bp->vec, positions[vl->index]);
bp->f1 = SELECT;
bp->radius = bp->weight = 1.0;
}
@@ -644,11 +644,11 @@ void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud)
bke::AttributeAccessor mesh_attributes = me->attributes();
bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write();
const VArray<float3> mesh_positions = mesh_attributes.lookup_or_default<float3>(
const VArray<float3> vert_positions = mesh_attributes.lookup_or_default<float3>(
"position", ATTR_DOMAIN_POINT, float3(0));
bke::SpanAttributeWriter<float3> point_positions =
point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
mesh_positions.materialize(point_positions.span);
vert_positions.materialize(point_positions.span);
point_positions.finish();
}
@@ -679,25 +679,8 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
me->totvert = pointcloud->totpoint;
/* Merge over all attributes. */
CustomData_merge(
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
/* Convert the Position attribute to a mesh vertex. */
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;
MutableSpan<MVert> verts = me->verts_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. */
CustomData_free_layer(&me->vdata, CD_PROP_FLOAT3, me->totvert, layer_idx);
}
void BKE_mesh_edges_set_draw_render(Mesh *mesh)
@@ -1227,8 +1210,7 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
{
BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
int a, totvert = mesh_src->totvert;
float *fp;
const int totvert = mesh_src->totvert;
if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) {
return;
@@ -1239,10 +1221,5 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
}
kb->data = MEM_malloc_arrayN(mesh_dst->key->elemsize, mesh_dst->totvert, "kb->data");
kb->totelem = totvert;
fp = (float *)kb->data;
const Span<MVert> verts = mesh_src->verts();
for (a = 0; a < kb->totelem; a++, fp += 3) {
copy_v3_v3(fp, verts[a].co);
}
MutableSpan(static_cast<float3 *>(kb->data), kb->totelem).copy_from(mesh_src->vert_positions());
}
@@ -30,6 +30,7 @@
#include "BKE_mesh.h"
#include "BKE_multires.h"
using blender::float3;
using blender::MutableSpan;
using blender::Span;
using blender::VArray;
@@ -40,7 +41,7 @@ using blender::VArray;
static void mesh_calc_ngon_center(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvert,
const float (*positions)[3],
float cent[3])
{
const float w = 1.0f / float(mpoly->totloop);
@@ -48,38 +49,41 @@ static void mesh_calc_ngon_center(const MPoly *mpoly,
zero_v3(cent);
for (int i = 0; i < mpoly->totloop; i++) {
madd_v3_v3fl(cent, mvert[(loopstart++)->v].co, w);
madd_v3_v3fl(cent, positions[(loopstart++)->v], w);
}
}
void BKE_mesh_calc_poly_center(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
const float (*vert_positions)[3],
float r_cent[3])
{
if (mpoly->totloop == 3) {
mid_v3_v3v3v3(r_cent,
mvarray[loopstart[0].v].co,
mvarray[loopstart[1].v].co,
mvarray[loopstart[2].v].co);
vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v]);
}
else if (mpoly->totloop == 4) {
mid_v3_v3v3v3v3(r_cent,
mvarray[loopstart[0].v].co,
mvarray[loopstart[1].v].co,
mvarray[loopstart[2].v].co,
mvarray[loopstart[3].v].co);
vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v],
vert_positions[loopstart[3].v]);
}
else {
mesh_calc_ngon_center(mpoly, loopstart, mvarray, r_cent);
mesh_calc_ngon_center(mpoly, loopstart, vert_positions, r_cent);
}
}
float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray)
float BKE_mesh_calc_poly_area(const MPoly *mpoly,
const MLoop *loopstart,
const float (*vert_positions)[3])
{
if (mpoly->totloop == 3) {
return area_tri_v3(
mvarray[loopstart[0].v].co, mvarray[loopstart[1].v].co, mvarray[loopstart[2].v].co);
return area_tri_v3(vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v]);
}
const MLoop *l_iter = loopstart;
@@ -87,7 +91,7 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
/* pack vertex cos into an array for area_poly_v3 */
for (int i = 0; i < mpoly->totloop; i++, l_iter++) {
copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co);
copy_v3_v3(vertexcos[i], vert_positions[l_iter->v]);
}
/* finally calculate the area */
@@ -98,13 +102,14 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
float BKE_mesh_calc_area(const Mesh *me)
{
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
float total_area = 0.0f;
for (const MPoly &poly : polys) {
total_area += BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data());
total_area += BKE_mesh_calc_poly_area(
&poly, &loops[poly.loopstart], reinterpret_cast<const float(*)[3]>(positions.data()));
}
return total_area;
}
@@ -129,7 +134,7 @@ float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array)
static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
const float (*positions)[3],
float r_cent[3])
{
const float *v_pivot, *v_step1;
@@ -137,11 +142,11 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly,
zero_v3(r_cent);
v_pivot = mvarray[loopstart[0].v].co;
v_step1 = mvarray[loopstart[1].v].co;
v_pivot = positions[loopstart[0].v];
v_step1 = positions[loopstart[1].v];
for (int i = 2; i < mpoly->totloop; i++) {
const float *v_step2 = mvarray[loopstart[i].v].co;
const float *v_step2 = positions[loopstart[i].v];
/* Calculate the 6x volume of the tetrahedron formed by the 3 vertices
* of the triangle and the origin as the fourth vertex */
@@ -171,7 +176,7 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly,
*/
static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
const Span<float3> positions,
const float reference_center[3],
float r_cent[3])
{
@@ -179,11 +184,11 @@ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *m
float v_pivot[3], v_step1[3];
float total_volume = 0.0f;
zero_v3(r_cent);
sub_v3_v3v3(v_pivot, mvarray[loopstart[0].v].co, reference_center);
sub_v3_v3v3(v_step1, mvarray[loopstart[1].v].co, reference_center);
sub_v3_v3v3(v_pivot, positions[loopstart[0].v], reference_center);
sub_v3_v3v3(v_step1, positions[loopstart[1].v], reference_center);
for (int i = 2; i < mpoly->totloop; i++) {
float v_step2[3];
sub_v3_v3v3(v_step2, mvarray[loopstart[i].v].co, reference_center);
sub_v3_v3v3(v_step2, positions[loopstart[i].v], reference_center);
const float tetra_volume = volume_tri_tetrahedron_signed_v3_6x(v_pivot, v_step1, v_step2);
total_volume += tetra_volume;
for (uint j = 0; j < 3; j++) {
@@ -202,19 +207,19 @@ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *m
*/
static float mesh_calc_poly_area_centroid(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
const float (*positions)[3],
float r_cent[3])
{
float total_area = 0.0f;
float v1[3], v2[3], v3[3], normal[3], tri_cent[3];
BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal);
copy_v3_v3(v1, mvarray[loopstart[0].v].co);
copy_v3_v3(v2, mvarray[loopstart[1].v].co);
BKE_mesh_calc_poly_normal(mpoly, loopstart, positions, normal);
copy_v3_v3(v1, positions[loopstart[0].v]);
copy_v3_v3(v2, positions[loopstart[1].v]);
zero_v3(r_cent);
for (int i = 2; i < mpoly->totloop; i++) {
copy_v3_v3(v3, mvarray[loopstart[i].v].co);
copy_v3_v3(v3, positions[loopstart[i].v]);
float tri_area = area_tri_signed_v3(v1, v2, v3, normal);
total_area += tri_area;
@@ -232,7 +237,7 @@ static float mesh_calc_poly_area_centroid(const MPoly *mpoly,
void BKE_mesh_calc_poly_angles(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
const float (*vert_positions)[3],
float angles[])
{
float nor_prev[3];
@@ -241,11 +246,13 @@ void BKE_mesh_calc_poly_angles(const MPoly *mpoly,
int i_this = mpoly->totloop - 1;
int i_next = 0;
sub_v3_v3v3(nor_prev, mvarray[loopstart[i_this - 1].v].co, mvarray[loopstart[i_this].v].co);
sub_v3_v3v3(
nor_prev, vert_positions[loopstart[i_this - 1].v], vert_positions[loopstart[i_this].v]);
normalize_v3(nor_prev);
while (i_next < mpoly->totloop) {
sub_v3_v3v3(nor_next, mvarray[loopstart[i_this].v].co, mvarray[loopstart[i_next].v].co);
sub_v3_v3v3(
nor_next, vert_positions[loopstart[i_this].v], vert_positions[loopstart[i_next].v]);
normalize_v3(nor_next);
angles[i_this] = angle_normalized_v3v3(nor_prev, nor_next);
@@ -293,10 +300,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])
{
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
zero_v3(r_cent);
for (const MVert &vert : verts) {
add_v3_v3(r_cent, vert.co);
for (const int i : positions.index_range()) {
add_v3_v3(r_cent, positions[i]);
}
/* otherwise we get NAN for 0 verts */
if (me->totvert) {
@@ -308,14 +315,14 @@ 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 tot = 0;
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
zero_v3(r_cent);
for (const MPoly &poly : polys) {
int loopend = poly.loopstart + poly.totloop;
for (int j = poly.loopstart; j < loopend; j++) {
add_v3_v3(r_cent, verts[loops[j].v].co);
add_v3_v3(r_cent, positions[loops[j].v]);
}
tot += poly.totloop;
}
@@ -345,7 +352,7 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
float poly_area;
float total_area = 0.0f;
float poly_cent[3];
const MVert *verts = BKE_mesh_verts(me);
const float(*positions)[3] = BKE_mesh_vert_positions(me);
const MPoly *polys = BKE_mesh_polys(me);
const MLoop *loops = BKE_mesh_loops(me);
@@ -353,7 +360,8 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
/* calculate a weighted average of polygon centroids */
for (mpoly = polys; i--; mpoly++) {
poly_area = mesh_calc_poly_area_centroid(mpoly, loops + mpoly->loopstart, verts, poly_cent);
poly_area = mesh_calc_poly_area_centroid(
mpoly, loops + mpoly->loopstart, positions, poly_cent);
madd_v3_v3fl(r_cent, poly_cent, poly_area);
total_area += poly_area;
@@ -378,7 +386,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
float poly_volume;
float total_volume = 0.0f;
float poly_cent[3];
const MVert *verts = BKE_mesh_verts(me);
const Span<float3> positions = me->vert_positions();
const MPoly *polys = BKE_mesh_polys(me);
const MLoop *loops = BKE_mesh_loops(me);
@@ -391,7 +399,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
/* calculate a weighted average of polyhedron centroids */
for (mpoly = polys; i--; mpoly++) {
poly_volume = mesh_calc_poly_volume_centroid_with_reference_center(
mpoly, loops + mpoly->loopstart, verts, init_cent, poly_cent);
mpoly, loops + mpoly->loopstart, positions, 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);
@@ -420,7 +428,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
/** \name Mesh Volume Calculation
* \{ */
static bool mesh_calc_center_centroid_ex(const MVert *mverts,
static bool mesh_calc_center_centroid_ex(const float (*positions)[3],
int /*mverts_num*/,
const MLoopTri *looptri,
int looptri_num,
@@ -438,15 +446,15 @@ static bool mesh_calc_center_centroid_ex(const MVert *mverts,
const MLoopTri *lt;
int i;
for (i = 0, lt = looptri; i < looptri_num; i++, lt++) {
const MVert *v1 = &mverts[mloop[lt->tri[0]].v];
const MVert *v2 = &mverts[mloop[lt->tri[1]].v];
const MVert *v3 = &mverts[mloop[lt->tri[2]].v];
const float *v1 = positions[mloop[lt->tri[0]].v];
const float *v2 = positions[mloop[lt->tri[1]].v];
const float *v3 = positions[mloop[lt->tri[2]].v];
float area;
area = area_tri_v3(v1->co, v2->co, v3->co);
madd_v3_v3fl(r_center, v1->co, area);
madd_v3_v3fl(r_center, v2->co, area);
madd_v3_v3fl(r_center, v3->co, area);
area = area_tri_v3(v1, v2, v3);
madd_v3_v3fl(r_center, v1, area);
madd_v3_v3fl(r_center, v2, area);
madd_v3_v3fl(r_center, v3, area);
totweight += area;
}
if (totweight == 0.0f) {
@@ -458,7 +466,7 @@ static bool mesh_calc_center_centroid_ex(const MVert *mverts,
return true;
}
void BKE_mesh_calc_volume(const MVert *mverts,
void BKE_mesh_calc_volume(const float (*vert_positions)[3],
const int mverts_num,
const MLoopTri *looptri,
const int looptri_num,
@@ -482,27 +490,28 @@ void BKE_mesh_calc_volume(const MVert *mverts,
return;
}
if (!mesh_calc_center_centroid_ex(mverts, mverts_num, looptri, looptri_num, mloop, center)) {
if (!mesh_calc_center_centroid_ex(
vert_positions, mverts_num, looptri, looptri_num, mloop, center)) {
return;
}
totvol = 0.0f;
for (i = 0, lt = looptri; i < looptri_num; i++, lt++) {
const MVert *v1 = &mverts[mloop[lt->tri[0]].v];
const MVert *v2 = &mverts[mloop[lt->tri[1]].v];
const MVert *v3 = &mverts[mloop[lt->tri[2]].v];
const float *v1 = vert_positions[mloop[lt->tri[0]].v];
const float *v2 = vert_positions[mloop[lt->tri[1]].v];
const float *v3 = vert_positions[mloop[lt->tri[2]].v];
float vol;
vol = volume_tetrahedron_signed_v3(center, v1->co, v2->co, v3->co);
vol = volume_tetrahedron_signed_v3(center, v1, v2, v3);
if (r_volume) {
totvol += vol;
}
if (r_center) {
/* averaging factor 1/3 is applied in the end */
madd_v3_v3fl(r_center, v1->co, vol);
madd_v3_v3fl(r_center, v2->co, vol);
madd_v3_v3fl(r_center, v3->co, vol);
madd_v3_v3fl(r_center, v1, vol);
madd_v3_v3fl(r_center, v2, vol);
madd_v3_v3fl(r_center, v3, vol);
}
}
+12 -7
View File
@@ -27,6 +27,7 @@
#include "eigen_capi.h"
using blender::Array;
using blender::float3;
using blender::Map;
using blender::MutableSpan;
using blender::Span;
@@ -191,12 +192,12 @@ class FairingContext {
class MeshFairingContext : public FairingContext {
public:
MeshFairingContext(Mesh *mesh, MVert *deform_mverts)
MeshFairingContext(Mesh *mesh, MutableSpan<float3> deform_positions)
{
totvert_ = mesh->totvert;
totloop_ = mesh->totloop;
MutableSpan<MVert> verts = mesh->verts_for_write();
MutableSpan<float3> positions = mesh->vert_positions_for_write();
medge_ = mesh->edges();
mpoly_ = mesh->polys();
mloop_ = mesh->loops();
@@ -210,14 +211,14 @@ class MeshFairingContext : public FairingContext {
/* Deformation coords. */
co_.reserve(mesh->totvert);
if (deform_mverts) {
if (!deform_positions.is_empty()) {
for (int i = 0; i < mesh->totvert; i++) {
co_[i] = deform_mverts[i].co;
co_[i] = deform_positions[i];
}
}
else {
for (int i = 0; i < mesh->totvert; i++) {
co_[i] = verts[i].co;
co_[i] = positions[i];
}
}
@@ -466,11 +467,15 @@ static void prefair_and_fair_verts(FairingContext *fairing_context,
}
void BKE_mesh_prefair_and_fair_verts(struct Mesh *mesh,
struct MVert *deform_mverts,
float (*deform_vert_positions)[3],
bool *affect_verts,
const eMeshFairingDepth depth)
{
MeshFairingContext *fairing_context = new MeshFairingContext(mesh, deform_mverts);
MutableSpan<float3> deform_positions_span;
if (deform_vert_positions) {
deform_positions_span = {reinterpret_cast<float3 *>(deform_vert_positions), mesh->totvert};
}
MeshFairingContext *fairing_context = new MeshFairingContext(mesh, deform_positions_span);
prefair_and_fair_verts(fairing_context, affect_verts, depth);
delete fairing_context;
}
@@ -65,26 +65,26 @@ void BKE_mesh_foreach_mapped_vert(
}
}
else {
const MVert *mv = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX));
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
BKE_mesh_vertex_normals_ensure(mesh) :
nullptr;
if (index) {
for (int i = 0; i < mesh->totvert; i++, mv++) {
for (int i = 0; i < mesh->totvert; i++) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr;
const int orig = *index++;
if (orig == ORIGINDEX_NONE) {
continue;
}
func(userData, orig, mv->co, no);
func(userData, orig, positions[i], no);
}
}
else {
for (int i = 0; i < mesh->totvert; i++, mv++) {
for (int i = 0; i < mesh->totvert; i++) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr;
func(userData, i, mv->co, no);
func(userData, i, positions[i], no);
}
}
}
@@ -120,7 +120,7 @@ void BKE_mesh_foreach_mapped_edge(
}
}
else {
const MVert *mv = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MEdge *med = BKE_mesh_edges(mesh);
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->edata, CD_ORIGINDEX));
@@ -130,12 +130,12 @@ void BKE_mesh_foreach_mapped_edge(
if (orig == ORIGINDEX_NONE) {
continue;
}
func(userData, orig, mv[med->v1].co, mv[med->v2].co);
func(userData, orig, positions[med->v1], positions[med->v2]);
}
}
else if (mesh->totedge == tot_edges) {
for (int i = 0; i < mesh->totedge; i++, med++) {
func(userData, i, mv[med->v1].co, mv[med->v2].co);
func(userData, i, positions[med->v1], positions[med->v2]);
}
}
}
@@ -190,7 +190,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
CustomData_get_layer(&mesh->ldata, CD_NORMAL)) :
nullptr;
const MVert *mv = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MLoop *ml = BKE_mesh_loops(mesh);
const MPoly *mp = BKE_mesh_polys(mesh);
const int *v_index = static_cast<const int *>(
@@ -208,7 +208,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
if (ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
continue;
}
func(userData, v_idx, f_idx, mv[ml->v].co, no);
func(userData, v_idx, f_idx, positions[ml->v], no);
}
}
}
@@ -218,7 +218,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
const int v_idx = ml->v;
const int f_idx = p_idx;
const float *no = loop_normals ? *loop_normals++ : nullptr;
func(userData, v_idx, f_idx, mv[ml->v].co, no);
func(userData, v_idx, f_idx, positions[ml->v], no);
}
}
}
@@ -265,7 +265,7 @@ void BKE_mesh_foreach_mapped_face_center(
}
}
else {
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MPoly *mp = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
@@ -281,9 +281,9 @@ void BKE_mesh_foreach_mapped_face_center(
}
float cent[3];
ml = &loops[mp->loopstart];
BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
BKE_mesh_calc_poly_center(mp, ml, positions, cent);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(mp, ml, mvert, no);
BKE_mesh_calc_poly_normal(mp, ml, positions, no);
}
func(userData, orig, cent, no);
}
@@ -292,9 +292,9 @@ void BKE_mesh_foreach_mapped_face_center(
for (int i = 0; i < mesh->totpoly; i++, mp++) {
float cent[3];
ml = &loops[mp->loopstart];
BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
BKE_mesh_calc_poly_center(mp, ml, positions, cent);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(mp, ml, mvert, no);
BKE_mesh_calc_poly_normal(mp, ml, positions, no);
}
func(userData, i, cent, no);
}
@@ -308,11 +308,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
void *userData,
MeshForeachFlag flag)
{
const MVert *verts = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MPoly *mp = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
const MVert *mv;
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
BKE_mesh_vertex_normals_ensure(mesh) :
nullptr;
@@ -328,11 +327,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
}
ml = &loops[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
func(userData,
orig,
mv->co,
positions[ml->v],
(flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : nullptr);
}
}
@@ -342,11 +340,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
for (int i = 0; i < mesh->totpoly; i++, mp++) {
ml = &loops[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
func(userData,
i,
mv->co,
positions[ml->v],
(flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : nullptr);
}
}
@@ -17,8 +17,10 @@
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_math_vector_types.hh"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
#include "BLI_resource_scope.hh"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
@@ -29,6 +31,9 @@
#include "BKE_mesh_legacy_convert.h"
#include "BKE_multires.h"
using blender::MutableSpan;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Legacy Edge Calculation
* \{ */
@@ -206,7 +211,8 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
using namespace blender;
MEdge *medge;
int totedge = 0;
const Span<MVert> verts = me->verts();
const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&me->vdata, CD_MVERT)),
me->totvert);
const Span<MPoly> polys = me->polys();
MutableSpan<MLoop> loops = me->loops_for_write();
@@ -248,7 +254,8 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
return;
}
const Span<MVert> verts = mesh->verts();
const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&mesh->vdata, CD_MVERT)),
mesh->totvert);
const Span<MEdge> edges = mesh->edges();
for (const MVert &vert : verts) {
@@ -940,7 +947,7 @@ static int mesh_tessface_calc(Mesh &mesh,
CustomData *fdata,
CustomData *ldata,
CustomData *pdata,
MVert *mvert,
float (*positions)[3],
int totface,
int totloop,
int totpoly)
@@ -1070,9 +1077,9 @@ static int mesh_tessface_calc(Mesh &mesh,
/* Calculate the normal, flipped: to get a positive 2D cross product. */
ml = mloop + mp_loopstart;
co_prev = mvert[ml[mp_totloop - 1].v].co;
co_prev = positions[ml[mp_totloop - 1].v];
for (j = 0; j < mp_totloop; j++, ml++) {
co_curr = mvert[ml->v].co;
co_curr = positions[ml->v];
add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
co_prev = co_curr;
}
@@ -1085,7 +1092,7 @@ static int mesh_tessface_calc(Mesh &mesh,
ml = mloop + mp_loopstart;
for (j = 0; j < mp_totloop; j++, ml++) {
mul_v2_m3v3(projverts[j], axis_mat, mvert[ml->v].co);
mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]);
}
BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, arena);
@@ -1188,7 +1195,7 @@ void BKE_mesh_tessface_calc(Mesh *mesh)
&mesh->fdata,
&mesh->ldata,
&mesh->pdata,
BKE_mesh_verts_for_write(mesh),
BKE_mesh_vert_positions_for_write(mesh),
mesh->totface,
mesh->totloop,
mesh->totpoly);
@@ -1242,7 +1249,7 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
{
using namespace blender;
MutableSpan<MVert> verts = mesh->verts_for_write();
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
if (const float *weights = static_cast<const float *>(
CustomData_get_layer(&mesh->vdata, CD_BWEIGHT))) {
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
@@ -1275,7 +1282,7 @@ void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
{
using namespace blender;
const Span<MVert> verts = mesh->verts();
const Span<MVert> verts(mesh->mvert, mesh->totvert);
if (mesh->cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
float *weights = static_cast<float *>(
CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size()));
@@ -1344,7 +1351,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
using namespace blender::bke;
const AttributeAccessor attributes = mesh->attributes();
MutableSpan<MVert> verts = mesh->verts_for_write();
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
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) {
@@ -1378,7 +1385,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh->attributes_for_write();
const Span<MVert> verts = mesh->verts();
const Span<MVert> verts(mesh->mvert, mesh->totvert);
if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) {
return vert.flag_legacy & ME_HIDE;
})) {
@@ -1471,7 +1478,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh)
using namespace blender::bke;
const AttributeAccessor attributes = mesh->attributes();
MutableSpan<MVert> verts = mesh->verts_for_write();
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
".select_vert", ATTR_DOMAIN_POINT, false);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
@@ -1505,7 +1512,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh->attributes_for_write();
const Span<MVert> verts = mesh->verts();
const Span<MVert> verts(mesh->mvert, mesh->totvert);
if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) {
return vert.flag_legacy & SELECT;
})) {
@@ -1513,7 +1520,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
".select_vert", ATTR_DOMAIN_POINT);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
select_vert.span[i] = (verts[i].flag_legacy & SELECT) != 0;
select_vert.span[i] = verts[i].flag_legacy & SELECT;
}
});
select_vert.finish();
@@ -1526,7 +1533,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
".select_edge", ATTR_DOMAIN_EDGE);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
select_edge.span[i] = (edges[i].flag & SELECT) != 0;
select_edge.span[i] = edges[i].flag & SELECT;
}
});
select_edge.finish();
@@ -1539,7 +1546,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
".select_poly", ATTR_DOMAIN_FACE);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
select_poly.span[i] = (polys[i].flag & ME_FACE_SEL) != 0;
select_poly.span[i] = polys[i].flag & ME_FACE_SEL;
}
});
select_poly.finish();
@@ -1575,6 +1582,57 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Vertex and Position Conversion
* \{ */
MVert *BKE_mesh_legacy_convert_positions_to_verts(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &vert_layers_to_write)
{
using namespace blender;
const Span<float3> positions = mesh->vert_positions();
CustomDataLayer mvert_layer{};
mvert_layer.type = CD_MVERT;
MutableSpan<MVert> verts = temp_arrays_for_convert.construct<Array<MVert>>(mesh->totvert);
mvert_layer.data = verts.data();
threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
copy_v3_v3(verts[i].co_legacy, positions[i]);
}
});
vert_layers_to_write.append(mvert_layer);
return verts.data();
}
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
const Span<MVert> verts(static_cast<MVert *>(CustomData_get_layer(&mesh->vdata, CD_MVERT)),
mesh->totvert);
MutableSpan<float3> positions(
static_cast<float3 *>(CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, mesh->totvert, "position")),
mesh->totvert);
threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
positions[i] = verts[i].co_legacy;
}
});
CustomData_free_layers(&mesh->vdata, CD_MVERT, mesh->totvert);
mesh->mvert = nullptr;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Attribute Active Flag to String Conversion
* \{ */
@@ -262,7 +262,6 @@ void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map,
void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
int **r_mem,
const MVert * /*mvert*/,
const int totvert,
const MLoopTri *mlooptri,
const int totlooptri,
@@ -1053,9 +1052,7 @@ static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/,
return (me->flag & ME_SEAM) != 0;
}
static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/,
const int /*totvert*/,
const MEdge *edges,
static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
const int totedge,
const MPoly *polys,
const int totpoly,
@@ -1203,7 +1200,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/,
return true;
}
bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts,
bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
const int totvert,
const MEdge *edges,
const int totedge,
@@ -1213,11 +1210,12 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts,
const int totloop,
MeshIslandStore *r_island_store)
{
UNUSED_VARS(vert_positions, totvert);
return mesh_calc_islands_loop_poly_uv(
verts, totvert, edges, totedge, polys, totpoly, loops, totloop, nullptr, r_island_store);
edges, totedge, polys, totpoly, loops, totloop, nullptr, r_island_store);
}
bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts,
bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
const int totvert,
MEdge *edges,
const int totedge,
@@ -1228,9 +1226,10 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts,
const MLoopUV *luvs,
MeshIslandStore *r_island_store)
{
UNUSED_VARS(vert_positions, totvert);
BLI_assert(luvs != nullptr);
return mesh_calc_islands_loop_poly_uv(
verts, totvert, edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store);
edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store);
}
/** \} */
+4 -16
View File
@@ -14,6 +14,7 @@
#include "BLI_bitmap.h"
#include "BLI_edgehash.h"
#include "BLI_ghash.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "BLI_utildefines_stack.h"
@@ -203,18 +204,14 @@ 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_verts(mesh);
const MEdge *src_edges = BKE_mesh_edges(mesh);
const MPoly *src_polys = BKE_mesh_polys(mesh);
const MLoop *src_loops = BKE_mesh_loops(mesh);
const int totvert_final = totvert - tot_vtargetmap;
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);
STACK_DECLARE(oldv);
/* NOTE: create (totedge + totloop) elements because partially invalid polys due to merge may
@@ -256,18 +253,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
STACK_INIT(oldl, totloop);
STACK_INIT(oldp, totpoly);
STACK_INIT(mvert, totvert_final);
STACK_INIT(medge, totedge);
STACK_INIT(mloop, totloop);
STACK_INIT(mpoly, totpoly);
/* fill newv with destination vertex indices */
mv = src_verts;
c = 0;
for (i = 0; i < totvert; i++, mv++) {
for (i = 0; i < totvert; i++) {
if (vtargetmap[i] == -1) {
STACK_PUSH(oldv, i);
STACK_PUSH(mvert, *mv);
newv[i] = c++;
}
else {
@@ -347,7 +341,6 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__);
mp = src_polys;
mv = src_verts;
for (i = 0; i < totpoly; i++, mp++) {
MPoly *mp_new;
@@ -571,7 +564,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Create new cddm. */
result = BKE_mesh_new_nomain_from_template(
mesh, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
mesh, totvert_final, STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
/* Update edge indices and copy customdata. */
MEdge *new_med = medge;
@@ -598,8 +591,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
}
/* Copy vertex customdata. */
mv = mvert;
for (i = 0; i < result->totvert; i++, mv++) {
for (i = 0; i < result->totvert; i++) {
CustomData_copy_data(&mesh->vdata, &result->vdata, oldv[i], i, 1);
}
@@ -610,9 +602,6 @@ 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(BKE_mesh_verts_for_write(result), mvert, sizeof(MVert) * STACK_SIZE(mvert));
}
if (STACK_SIZE(medge)) {
memcpy(BKE_mesh_edges_for_write(result), medge, sizeof(MEdge) * STACK_SIZE(medge));
}
@@ -623,7 +612,6 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
memcpy(BKE_mesh_polys_for_write(result), mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
}
MEM_freeN(mvert);
MEM_freeN(medge);
MEM_freeN(mloop);
MEM_freeN(mpoly);
+19 -15
View File
@@ -126,7 +126,6 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
(axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z));
Mesh *result;
MVert *mv, *mv_prev;
MEdge *me;
MLoop *ml;
MPoly *mp;
@@ -204,9 +203,11 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, maxPolys);
/* Subdivision-surface for eg won't have mesh data in the custom-data arrays.
* Now add #MVert/#MEdge/#MPoly layers. */
if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
memcpy(BKE_mesh_verts_for_write(result), BKE_mesh_verts(mesh), sizeof(MVert) * mesh->totvert);
* Now add position/#MEdge/#MPoly layers. */
if (BKE_mesh_vert_positions(mesh) != NULL) {
memcpy(BKE_mesh_vert_positions_for_write(result),
BKE_mesh_vert_positions(mesh),
sizeof(float[3]) * mesh->totvert);
}
if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge);
@@ -233,10 +234,11 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* mirror vertex coordinates */
mv_prev = BKE_mesh_verts_for_write(result);
mv = mv_prev + maxVerts;
for (i = 0; i < maxVerts; i++, mv++, mv_prev++) {
mul_m4_v3(mtx, mv->co);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(result);
for (i = 0; i < maxVerts; i++) {
const int vert_index_prev = i;
const int vert_index = maxVerts + i;
mul_m4_v3(mtx, positions[vert_index]);
if (do_vtargetmap) {
/* Compare location of the original and mirrored vertex,
@@ -253,13 +255,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
* old, incorrect behavior of merging the source vertex into its copy.
*/
if (use_correct_order_on_merge) {
if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) {
if (UNLIKELY(len_squared_v3v3(positions[vert_index_prev], positions[vert_index]) <
tolerance_sq)) {
*vtmap_b = i;
tot_vtargetmap++;
/* average location */
mid_v3_v3v3(mv->co, mv_prev->co, mv->co);
copy_v3_v3(mv_prev->co, mv->co);
mid_v3_v3v3(positions[vert_index], positions[vert_index_prev], positions[vert_index]);
copy_v3_v3(positions[vert_index_prev], positions[vert_index]);
}
else {
*vtmap_b = -1;
@@ -269,13 +272,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
*vtmap_a = -1;
}
else {
if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) {
if (UNLIKELY(len_squared_v3v3(positions[vert_index_prev], positions[vert_index]) <
tolerance_sq)) {
*vtmap_a = maxVerts + i;
tot_vtargetmap++;
/* average location */
mid_v3_v3v3(mv->co, mv_prev->co, mv->co);
copy_v3_v3(mv_prev->co, mv->co);
mid_v3_v3v3(positions[vert_index], positions[vert_index_prev], positions[vert_index]);
copy_v3_v3(positions[vert_index_prev], positions[vert_index]);
}
else {
*vtmap_a = -1;
@@ -404,7 +408,7 @@ 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(BKE_mesh_verts(result),
BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result),
BKE_mesh_vertex_normals_ensure(result),
result->totvert,
BKE_mesh_edges(result),
+65 -114
View File
@@ -164,67 +164,18 @@ bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh)
*/
static void mesh_calc_ngon_normal(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvert,
float normal[3])
const float (*positions)[3],
float r_normal[3])
{
const int nverts = mpoly->totloop;
const float *v_prev = mvert[loopstart[nverts - 1].v].co;
const float *v_curr;
zero_v3(normal);
/* Newell's Method */
for (int i = 0; i < nverts; i++) {
v_curr = mvert[loopstart[i].v].co;
add_newell_cross_v3_v3v3(normal, v_prev, v_curr);
v_prev = v_curr;
}
if (UNLIKELY(normalize_v3(normal) == 0.0f)) {
normal[2] = 1.0f; /* other axis set to 0.0 */
}
}
void BKE_mesh_calc_poly_normal(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
float r_no[3])
{
if (mpoly->totloop > 4) {
mesh_calc_ngon_normal(mpoly, loopstart, mvarray, r_no);
}
else if (mpoly->totloop == 3) {
normal_tri_v3(
r_no, mvarray[loopstart[0].v].co, mvarray[loopstart[1].v].co, mvarray[loopstart[2].v].co);
}
else if (mpoly->totloop == 4) {
normal_quad_v3(r_no,
mvarray[loopstart[0].v].co,
mvarray[loopstart[1].v].co,
mvarray[loopstart[2].v].co,
mvarray[loopstart[3].v].co);
}
else { /* horrible, two sided face! */
r_no[0] = 0.0;
r_no[1] = 0.0;
r_no[2] = 1.0;
}
}
/* duplicate of function above _but_ takes coords rather than mverts */
static void mesh_calc_ngon_normal_coords(const MPoly *mpoly,
const MLoop *loopstart,
const float (*vertex_coords)[3],
float r_normal[3])
{
const int nverts = mpoly->totloop;
const float *v_prev = vertex_coords[loopstart[nverts - 1].v];
const float *v_prev = positions[loopstart[nverts - 1].v];
const float *v_curr;
zero_v3(r_normal);
/* Newell's Method */
for (int i = 0; i < nverts; i++) {
v_curr = vertex_coords[loopstart[i].v];
v_curr = positions[loopstart[i].v];
add_newell_cross_v3_v3v3(r_normal, v_prev, v_curr);
v_prev = v_curr;
}
@@ -234,26 +185,26 @@ static void mesh_calc_ngon_normal_coords(const MPoly *mpoly,
}
}
void BKE_mesh_calc_poly_normal_coords(const MPoly *mpoly,
const MLoop *loopstart,
const float (*vertex_coords)[3],
float r_no[3])
void BKE_mesh_calc_poly_normal(const MPoly *mpoly,
const MLoop *loopstart,
const float (*vert_positions)[3],
float r_no[3])
{
if (mpoly->totloop > 4) {
mesh_calc_ngon_normal_coords(mpoly, loopstart, vertex_coords, r_no);
mesh_calc_ngon_normal(mpoly, loopstart, vert_positions, r_no);
}
else if (mpoly->totloop == 3) {
normal_tri_v3(r_no,
vertex_coords[loopstart[0].v],
vertex_coords[loopstart[1].v],
vertex_coords[loopstart[2].v]);
vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v]);
}
else if (mpoly->totloop == 4) {
normal_quad_v3(r_no,
vertex_coords[loopstart[0].v],
vertex_coords[loopstart[1].v],
vertex_coords[loopstart[2].v],
vertex_coords[loopstart[3].v]);
vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v],
vert_positions[loopstart[3].v]);
}
else { /* horrible, two sided face! */
r_no[0] = 0.0;
@@ -262,7 +213,7 @@ void BKE_mesh_calc_poly_normal_coords(const MPoly *mpoly,
}
}
static void calculate_normals_poly(const Span<MVert> verts,
static void calculate_normals_poly(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<float3> poly_normals)
@@ -271,20 +222,23 @@ static void calculate_normals_poly(const Span<MVert> verts,
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
for (const int poly_i : range) {
const MPoly &poly = polys[poly_i];
BKE_mesh_calc_poly_normal(&poly, &loops[poly.loopstart], verts.data(), poly_normals[poly_i]);
BKE_mesh_calc_poly_normal(&poly,
&loops[poly.loopstart],
reinterpret_cast<const float(*)[3]>(positions.data()),
poly_normals[poly_i]);
}
});
}
void BKE_mesh_calc_normals_poly(const MVert *mvert,
const int mvert_len,
void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3],
const int verts_num,
const MLoop *mloop,
const int mloop_len,
const MPoly *mpoly,
int mpoly_len,
float (*r_poly_normals)[3])
{
calculate_normals_poly({mvert, mvert_len},
calculate_normals_poly({reinterpret_cast<const float3 *>(vert_positions), verts_num},
{mpoly, mpoly_len},
{mloop, mloop_len},
{reinterpret_cast<float3 *>(r_poly_normals), mpoly_len});
@@ -299,7 +253,7 @@ void BKE_mesh_calc_normals_poly(const MVert *mvert,
* meshes can slow down high-poly meshes. For details on performance, see D11993.
* \{ */
static void calculate_normals_poly_and_vert(const Span<MVert> verts,
static void calculate_normals_poly_and_vert(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<float3> poly_normals,
@@ -328,9 +282,9 @@ static void calculate_normals_poly_and_vert(const Span<MVert> verts,
{
zero_v3(pnor);
/* Newell's Method */
const float *v_curr = verts[poly_loops[i_end].v].co;
const float *v_curr = positions[poly_loops[i_end].v];
for (int i_next = 0; i_next <= i_end; i_next++) {
const float *v_next = verts[poly_loops[i_next].v].co;
const float *v_next = positions[poly_loops[i_next].v];
add_newell_cross_v3_v3v3(pnor, v_curr, v_next);
v_curr = v_next;
}
@@ -343,13 +297,13 @@ static void calculate_normals_poly_and_vert(const Span<MVert> verts,
/* Inline version of #accumulate_vertex_normals_poly_v3. */
{
float edvec_prev[3], edvec_next[3], edvec_end[3];
const float *v_curr = verts[poly_loops[i_end].v].co;
sub_v3_v3v3(edvec_prev, verts[poly_loops[i_end - 1].v].co, v_curr);
const float *v_curr = positions[poly_loops[i_end].v];
sub_v3_v3v3(edvec_prev, positions[poly_loops[i_end - 1].v], v_curr);
normalize_v3(edvec_prev);
copy_v3_v3(edvec_end, edvec_prev);
for (int i_next = 0, i_curr = i_end; i_next <= i_end; i_curr = i_next++) {
const float *v_next = verts[poly_loops[i_next].v].co;
const float *v_next = positions[poly_loops[i_next].v];
/* Skip an extra normalization by reusing the first calculated edge. */
if (i_next != i_end) {
@@ -376,20 +330,20 @@ static void calculate_normals_poly_and_vert(const Span<MVert> verts,
/* Normalize and validate computed vertex normals. */
{
threading::parallel_for(verts.index_range(), 1024, [&](const IndexRange range) {
threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) {
for (const int vert_i : range) {
float *no = vert_normals[vert_i];
if (UNLIKELY(normalize_v3(no) == 0.0f)) {
/* Following Mesh convention; we use vertex coordinate itself for normal in this case. */
normalize_v3_v3(no, verts[vert_i].co);
normalize_v3_v3(no, positions[vert_i]);
}
}
});
}
}
void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert,
void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3],
const int mvert_len,
const MLoop *mloop,
const int mloop_len,
@@ -398,7 +352,7 @@ void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert,
float (*r_poly_normals)[3],
float (*r_vert_normals)[3])
{
calculate_normals_poly_and_vert({mvert, mvert_len},
calculate_normals_poly_and_vert({reinterpret_cast<const float3 *>(vert_positions), mvert_len},
{mpoly, mpoly_len},
{mloop, mloop_len},
{reinterpret_cast<float3 *>(r_poly_normals), mpoly_len},
@@ -434,15 +388,15 @@ 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.verts();
const Span<float3> positions = mesh_mutable.vert_positions();
const Span<MPoly> polys = mesh_mutable.polys();
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(verts.data(),
verts.size(),
BKE_mesh_calc_normals_poly_and_vertex(reinterpret_cast<const float(*)[3]>(positions.data()),
positions.size(),
loops.data(),
loops.size(),
polys.data(),
@@ -479,14 +433,14 @@ 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.verts();
const Span<float3> positions = mesh_mutable.vert_positions();
const Span<MPoly> polys = mesh_mutable.polys();
const Span<MLoop> loops = mesh_mutable.loops();
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_calc_normals_poly(verts.data(),
verts.size(),
BKE_mesh_calc_normals_poly(reinterpret_cast<const float(*)[3]>(positions.data()),
positions.size(),
loops.data(),
loops.size(),
polys.data(),
@@ -818,7 +772,7 @@ struct LoopSplitTaskDataCommon {
MutableSpan<short2> clnors_data;
/* Read-only. */
Span<MVert> verts;
Span<float3> positions;
Span<MEdge> edges;
Span<MLoop> loops;
Span<MPoly> polys;
@@ -993,7 +947,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS
MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
const Span<short2> clnors_data = common_data->clnors_data;
const Span<MVert> verts = common_data->verts;
const Span<float3> positions = common_data->positions;
const Span<MEdge> edges = common_data->edges;
const Span<MLoop> loops = common_data->loops;
const Span<float3> poly_normals = common_data->poly_normals;
@@ -1022,17 +976,14 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS
float vec_curr[3], vec_prev[3];
const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */
const MVert *mv_pivot = &verts[mv_pivot_index];
const MEdge *me_curr = &edges[loops[ml_curr_index].e];
const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &verts[me_curr->v2] :
&verts[me_curr->v1];
const int vert_2 = me_curr->v1 == mv_pivot_index ? me_curr->v2 : me_curr->v1;
const MEdge *me_prev = &edges[loops[ml_prev_index].e];
const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &verts[me_prev->v2] :
&verts[me_prev->v1];
const int vert_3 = me_prev->v1 == mv_pivot_index ? me_prev->v2 : me_prev->v1;
sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
sub_v3_v3v3(vec_curr, positions[vert_2], positions[mv_pivot_index]);
normalize_v3(vec_curr);
sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co);
sub_v3_v3v3(vec_prev, positions[vert_3], positions[mv_pivot_index]);
normalize_v3(vec_prev);
BKE_lnor_space_define(lnor_space, loop_normals[ml_curr_index], vec_curr, vec_prev, nullptr);
@@ -1054,7 +1005,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
MutableSpan<float3> loop_normals = common_data->loop_normals;
MutableSpan<short2> clnors_data = common_data->clnors_data;
const Span<MVert> verts = common_data->verts;
const Span<float3> positions = common_data->positions;
const Span<MEdge> edges = common_data->edges;
const Span<MPoly> polys = common_data->polys;
const Span<MLoop> loops = common_data->loops;
@@ -1077,7 +1028,6 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
* number of sharp edges per vertex, I doubt the additional memory usage would be worth it,
* especially as it should not be a common case in real-life meshes anyway). */
const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */
const MVert *mv_pivot = &verts[mv_pivot_index];
/* `ml_curr_index` would be mlfan_prev if we needed that one. */
const MEdge *me_org = &edges[loops[ml_curr_index].e];
@@ -1108,9 +1058,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
/* Only need to compute previous edge's vector once, then we can just reuse old current one! */
{
const MVert *mv_2 = (me_org->v1 == mv_pivot_index) ? &verts[me_org->v2] : &verts[me_org->v1];
const float3 &mv_2 = (me_org->v1 == mv_pivot_index) ? positions[me_org->v2] :
positions[me_org->v1];
sub_v3_v3v3(vec_org, mv_2->co, mv_pivot->co);
sub_v3_v3v3(vec_org, mv_2, positions[mv_pivot_index]);
normalize_v3(vec_org);
copy_v3_v3(vec_prev, vec_org);
@@ -1129,10 +1080,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data,
* given the fact that this code should not be called that much in real-life meshes.
*/
{
const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &verts[me_curr->v2] :
&verts[me_curr->v1];
const float3 &mv_2 = (me_curr->v1 == mv_pivot_index) ? positions[me_curr->v2] :
positions[me_curr->v1];
sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
sub_v3_v3v3(vec_curr, mv_2, positions[mv_pivot_index]);
normalize_v3(vec_curr);
}
@@ -1491,7 +1442,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
}
}
void BKE_mesh_normals_loop_split(const MVert *mverts,
void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
const float (*vert_normals)[3],
const int numVerts,
const MEdge *medges,
@@ -1593,7 +1544,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
common_data.lnors_spacearr = r_lnors_spacearr;
common_data.loop_normals = {reinterpret_cast<float3 *>(r_loop_normals), numLoops};
common_data.clnors_data = {reinterpret_cast<short2 *>(clnors_data), clnors_data ? numLoops : 0};
common_data.verts = {mverts, numVerts};
common_data.positions = {reinterpret_cast<const float3 *>(vert_positions), numVerts};
common_data.edges = {medges, numEdges};
common_data.polys = polys;
common_data.loops = loops;
@@ -1658,7 +1609,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
* r_custom_loop_normals is expected to have normalized normals, or zero ones,
* in which case they will be replaced by default loop/vertex normal.
*/
static void mesh_normals_loop_custom_set(const MVert *mverts,
static void mesh_normals_loop_custom_set(const float (*positions)[3],
const float (*vert_normals)[3],
const int numVerts,
MEdge *medges,
@@ -1694,7 +1645,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
BLI_SMALLSTACK_DECLARE(clnors_data, short *);
/* Compute current lnor spacearr. */
BKE_mesh_normals_loop_split(mverts,
BKE_mesh_normals_loop_split(positions,
vert_normals,
numVerts,
medges,
@@ -1821,7 +1772,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
/* And now, recompute our new auto `loop_normals` and lnor spacearr! */
BKE_lnor_spacearr_clear(&lnors_spacearr);
BKE_mesh_normals_loop_split(mverts,
BKE_mesh_normals_loop_split(positions,
vert_normals,
numVerts,
medges,
@@ -1898,7 +1849,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
BKE_lnor_spacearr_free(&lnors_spacearr);
}
void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3],
const float (*vert_normals)[3],
const int numVerts,
MEdge *medges,
@@ -1911,7 +1862,7 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
const int numPolys,
short (*r_clnors_data)[2])
{
mesh_normals_loop_custom_set(mverts,
mesh_normals_loop_custom_set(vert_positions,
vert_normals,
numVerts,
medges,
@@ -1926,7 +1877,7 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
false);
}
void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts,
void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3],
const float (*vert_normals)[3],
float (*r_custom_vert_normals)[3],
const int numVerts,
@@ -1939,7 +1890,7 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts,
const int numPolys,
short (*r_clnors_data)[2])
{
mesh_normals_loop_custom_set(mverts,
mesh_normals_loop_custom_set(vert_positions,
vert_normals,
numVerts,
medges,
@@ -1967,14 +1918,14 @@ 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->verts();
const Span<float3> positions = mesh->vert_positions();
MutableSpan<MEdge> edges = mesh->edges_for_write();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
mesh_normals_loop_custom_set(verts.data(),
mesh_normals_loop_custom_set(reinterpret_cast<const float(*)[3]>(positions.data()),
BKE_mesh_vertex_normals_ensure(mesh),
verts.size(),
positions.size(),
edges.data(),
edges.size(),
loops.data(),
+55 -54
View File
@@ -110,7 +110,7 @@ static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata,
* \{ */
float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_transform,
const MVert *verts_dst,
const float (*vert_positions_dst)[3],
const int numverts_dst,
Mesh *me_src)
{
@@ -127,7 +127,7 @@ float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_trans
for (i = 0; i < numverts_dst; i++) {
float tmp_co[3];
copy_v3_v3(tmp_co, verts_dst[i].co);
copy_v3_v3(tmp_co, vert_positions_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -164,7 +164,7 @@ float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_trans
* axes in those cases. We default to dummy generated orthogonal vectors in this case,
* instead of using eigen vectors.
*/
static void mesh_calc_eigen_matrix(const MVert *verts,
static void mesh_calc_eigen_matrix(const float (*positions)[3],
const float (*vcos)[3],
const int numverts,
float r_mat[4][4])
@@ -176,14 +176,9 @@ static void mesh_calc_eigen_matrix(const MVert *verts,
bool eigen_success;
int i;
if (verts) {
const MVert *mv;
float(*co)[3];
if (positions) {
cos = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*cos) * size_t(numverts), __func__));
for (i = 0, co = cos, mv = verts; i < numverts; i++, co++, mv++) {
copy_v3_v3(*co, mv->co);
}
memcpy(cos, positions, sizeof(float[3]) * size_t(numverts));
/* TODO(sergey): For until we officially drop all compilers which
* doesn't handle casting correct we use workaround to avoid explicit
* cast here.
@@ -244,7 +239,7 @@ static void mesh_calc_eigen_matrix(const MVert *verts,
copy_v3_v3(r_mat[3], center);
}
void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst,
void BKE_mesh_remap_find_best_match_from_mesh(const float (*vert_positions_dst)[3],
const int numverts_dst,
Mesh *me_src,
SpaceTransform *r_space_transform)
@@ -270,11 +265,11 @@ void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst,
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, nullptr);
mesh_calc_eigen_matrix(nullptr, (const float(*)[3])vcos_src, numverts_src, mat_src);
mesh_calc_eigen_matrix(verts_dst, nullptr, numverts_dst, mat_dst);
mesh_calc_eigen_matrix(vert_positions_dst, nullptr, numverts_dst, mat_dst);
BLI_space_transform_global_from_matrices(r_space_transform, mat_dst, mat_src);
match = BKE_mesh_remap_calc_difference_from_mesh(
r_space_transform, verts_dst, numverts_dst, me_src);
r_space_transform, vert_positions_dst, numverts_dst, me_src);
best_match = match;
copy_m4_m4(best_mat_dst, mat_dst);
@@ -286,7 +281,7 @@ void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst,
BLI_space_transform_global_from_matrices(r_space_transform, mat_dst, mat_src);
match = BKE_mesh_remap_calc_difference_from_mesh(
r_space_transform, verts_dst, numverts_dst, me_src);
r_space_transform, vert_positions_dst, numverts_dst, me_src);
if (match < best_match) {
best_match = match;
copy_m4_m4(best_mat_dst, mat_dst);
@@ -469,7 +464,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
const SpaceTransform *space_transform,
const float max_dist,
const float ray_radius,
const MVert *verts_dst,
const float (*vert_positions_dst)[3],
const int numverts_dst,
const bool /*dirty_nors_dst*/,
Mesh *me_src,
@@ -502,7 +497,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
nearest.index = -1;
for (i = 0; i < numverts_dst; i++) {
copy_v3_v3(tmp_co, verts_dst[i].co);
copy_v3_v3(tmp_co, vert_positions_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -527,7 +522,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
nearest.index = -1;
for (i = 0; i < numverts_dst; i++) {
copy_v3_v3(tmp_co, verts_dst[i].co);
copy_v3_v3(tmp_co, vert_positions_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -589,7 +584,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mode == MREMAP_MODE_VERT_POLYINTERP_VNORPROJ) {
for (i = 0; i < numverts_dst; i++) {
copy_v3_v3(tmp_co, verts_dst[i].co);
copy_v3_v3(tmp_co, vert_positions_dst[i]);
copy_v3_v3(tmp_no, vert_normals_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
@@ -626,7 +621,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
nearest.index = -1;
for (i = 0; i < numverts_dst; i++) {
copy_v3_v3(tmp_co, verts_dst[i].co);
copy_v3_v3(tmp_co, vert_positions_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -695,7 +690,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
const SpaceTransform *space_transform,
const float max_dist,
const float ray_radius,
const MVert *verts_dst,
const float (*vert_positions_dst)[3],
const int numverts_dst,
const MEdge *edges_dst,
const int numedges_dst,
@@ -765,7 +760,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
/* Compute closest verts only once! */
if (v_dst_to_src_map[vidx_dst].hit_dist == -1.0f) {
copy_v3_v3(tmp_co, verts_dst[vidx_dst].co);
copy_v3_v3(tmp_co, vert_positions_dst[vidx_dst]);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -803,7 +798,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
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;
vert_positions_dst[BKE_mesh_edge_other_vert(e_dst, int(vidx_dst))];
const float totdist = first_dist + len_v3v3(other_co_src, other_co_dst);
if (totdist < best_totdist) {
@@ -816,8 +811,8 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
if (best_eidx_src >= 0) {
const float *co1_src = vcos_src[edges_src[best_eidx_src].v1];
const float *co2_src = vcos_src[edges_src[best_eidx_src].v2];
const float *co1_dst = verts_dst[e_dst->v1].co;
const float *co2_dst = verts_dst[e_dst->v2].co;
const float *co1_dst = vert_positions_dst[e_dst->v1];
const float *co2_dst = vert_positions_dst[e_dst->v2];
float co_src[3], co_dst[3];
/* TODO: would need an isect_seg_seg_v3(), actually! */
@@ -858,7 +853,10 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
nearest.index = -1;
for (i = 0; i < numedges_dst; i++) {
interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f);
interp_v3_v3v3(tmp_co,
vert_positions_dst[edges_dst[i].v1],
vert_positions_dst[edges_dst[i].v2],
0.5f);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -884,7 +882,10 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_LOOPTRI, 2);
for (i = 0; i < numedges_dst; i++) {
interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f);
interp_v3_v3v3(tmp_co,
vert_positions_dst[edges_dst[i].v1],
vert_positions_dst[edges_dst[i].v2],
0.5f);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -957,8 +958,8 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
int sources_num = 0;
int j;
copy_v3_v3(v1_co, verts_dst[me->v1].co);
copy_v3_v3(v2_co, verts_dst[me->v2].co);
copy_v3_v3(v1_co, vert_positions_dst[me->v1]);
copy_v3_v3(v2_co, vert_positions_dst[me->v2]);
copy_v3_v3(v1_no, vert_normals_dst[me->v1]);
copy_v3_v3(v2_no, vert_normals_dst[me->v2]);
@@ -1045,7 +1046,7 @@ 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,
const MVert *verts,
const float (*positions)[3],
const MPoly *polys,
const MLoop *loops,
const int edge_idx,
@@ -1077,7 +1078,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
}
if (poly_status[pidx_isld] == POLY_UNSET) {
BKE_mesh_calc_poly_center(mp, &loops[mp->loopstart], verts, poly_centers[pidx_isld]);
BKE_mesh_calc_poly_center(mp, &loops[mp->loopstart], positions, poly_centers[pidx_isld]);
BLI_astar_node_init(as_graph, pidx_isld, poly_centers[pidx_isld]);
poly_status[pidx_isld] = POLY_CENTER_INIT;
}
@@ -1102,7 +1103,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
static void mesh_island_to_astar_graph(MeshIslandStore *islands,
const int island_index,
const MVert *verts,
const float (*positions)[3],
MeshElemMap *edge_to_poly_map,
const int numedges,
const MLoop *loops,
@@ -1143,7 +1144,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
mesh_island_to_astar_graph_edge_process(islands,
island_index,
r_as_graph,
verts,
positions,
polys,
loops,
island_einnercut_map->indices[i],
@@ -1175,7 +1176,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
mesh_island_to_astar_graph_edge_process(islands,
island_index,
r_as_graph,
verts,
positions,
polys,
loops,
int(ml->e),
@@ -1234,7 +1235,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const float max_dist,
const float ray_radius,
Mesh *mesh_dst,
const MVert *verts_dst,
const float (*vert_positions_dst)[3],
const int numverts_dst,
const MEdge *edges_dst,
const int numedges_dst,
@@ -1307,7 +1308,7 @@ 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 = nullptr;
const MVert *verts_src = BKE_mesh_verts(me_src);
const float(*positions_src)[3] = BKE_mesh_vert_positions(me_src);
const int num_verts_src = me_src->totvert;
float(*vcos_src)[3] = nullptr;
const MEdge *edges_src = BKE_mesh_edges(me_src);
@@ -1367,7 +1368,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
}
if (dirty_nors_dst || do_loop_nors_dst) {
BKE_mesh_normals_loop_split(verts_dst,
BKE_mesh_normals_loop_split(vert_positions_dst,
BKE_mesh_vertex_normals_ensure(mesh_dst),
numverts_dst,
edges_dst,
@@ -1436,7 +1437,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
plidx_src++, lidx_src++) {
loop_to_poly_map_src[lidx_src] = pidx_src;
}
BKE_mesh_calc_poly_center(mp_src, ml_src, verts_src, poly_cents_src[pidx_src]);
BKE_mesh_calc_poly_center(mp_src, ml_src, positions_src, poly_cents_src[pidx_src]);
}
}
@@ -1449,7 +1450,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
/* First, generate the islands, if possible. */
if (gen_islands_src) {
use_islands = gen_islands_src(verts_src,
use_islands = gen_islands_src(positions_src,
num_verts_src,
edges_src,
num_edges_src,
@@ -1489,7 +1490,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
for (tindex = 0; tindex < num_trees; tindex++) {
mesh_island_to_astar_graph(use_islands ? &island_store : nullptr,
tindex,
verts_src,
positions_src,
edge_to_poly_map_src,
num_edges_src,
loops_src,
@@ -1520,7 +1521,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
}
bvhtree_from_mesh_verts_ex(&treedata[tindex],
verts_src,
positions_src,
num_verts_src,
verts_active,
num_verts_active,
@@ -1552,7 +1553,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
}
bvhtree_from_mesh_looptri_ex(&treedata[tindex],
verts_src,
positions_src,
loops_src,
looptri_src,
num_looptri_src,
@@ -1608,7 +1609,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (use_from_vert) {
MeshElemMap *vert_to_refelem_map_src = nullptr;
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
nearest.index = -1;
/* Convert the vertex to tree coordinates, if needed. */
@@ -1671,7 +1672,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (!pcent_dst_valid) {
BKE_mesh_calc_poly_center(
mp_dst, &loops_dst[mp_dst->loopstart], verts_dst, pcent_dst);
mp_dst, &loops_dst[mp_dst->loopstart], vert_positions_dst, pcent_dst);
pcent_dst_valid = true;
}
pcent_src = poly_cents_src[pidx_src];
@@ -1717,7 +1718,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1;
float w = 1.0f;
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + mp_dst->loopstart]);
/* We do our transform here, since we may do several raycast/nearest queries. */
@@ -1745,7 +1746,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
* is null, it means none of its loop mapped to this source island,
* hence we can skip it later.
*/
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
nearest.index = -1;
/* Convert the vertex to tree coordinates, if needed. */
@@ -1771,7 +1772,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
}
else { /* Nearest poly either to use all its loops/verts or just closest one. */
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
nearest.index = -1;
/* Convert the vertex to tree coordinates, if needed. */
@@ -1901,7 +1902,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
float best_dist_sq = FLT_MAX;
ml_dst = &loops_dst[lidx_dst];
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
/* We do our transform here,
* since we may do several raycast/nearest queries. */
@@ -1914,7 +1915,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
mp_src = &polys_src[pidx_src];
ml_src = &loops_src[mp_src->loopstart];
for (j = 0; j < mp_src->totloop; j++, ml_src++) {
const float dist_sq = len_squared_v3v3(verts_src[ml_src->v].co, tmp_co);
const float dist_sq = len_squared_v3v3(positions_src[ml_src->v], tmp_co);
if (dist_sq < best_dist_sq) {
best_dist_sq = dist_sq;
lidx_src = mp_src->loopstart + j;
@@ -1994,7 +1995,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int j;
ml_dst = &loops_dst[lidx_dst];
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
/* We do our transform here,
* since we may do several raycast/nearest queries. */
@@ -2162,7 +2163,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const float max_dist,
const float ray_radius,
const Mesh *mesh_dst,
const MVert *verts_dst,
const float (*vert_positions_dst)[3],
const MLoop *loops_dst,
const MPoly *polys_dst,
const int numpolys_dst,
@@ -2203,7 +2204,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
for (i = 0; i < numpolys_dst; i++) {
const MPoly *mp = &polys_dst[i];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], vert_positions_dst, tmp_co);
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@@ -2228,7 +2229,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
for (i = 0; i < numpolys_dst; i++) {
const MPoly *mp = &polys_dst[i];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], vert_positions_dst, tmp_co);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
@@ -2291,7 +2292,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const int tris_num = mp->totloop - 2;
int j;
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, pcent_dst);
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], vert_positions_dst, pcent_dst);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
/* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */
@@ -2321,7 +2322,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
for (j = 0; j < mp->totloop; j++) {
const MLoop *ml = &loops_dst[j + mp->loopstart];
copy_v3_v3(tmp_co, verts_dst[ml->v].co);
copy_v3_v3(tmp_co, vert_positions_dst[ml->v]);
if (space_transform) {
BLI_space_transform_apply(space_transform, tmp_co);
}
@@ -63,7 +63,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
void (*update_cb)(void *, float progress, int *cancel),
void *update_cb_data)
{
const Span<MVert> input_verts = input_mesh->verts();
const Span<float3> input_positions = input_mesh->vert_positions();
const Span<MLoop> input_loops = input_mesh->loops();
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
@@ -75,13 +75,8 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
const int totfaces = BKE_mesh_runtime_looptri_len(input_mesh);
const int totverts = input_mesh->totvert;
Array<float3> verts(totverts);
Array<int> faces(totfaces * 3);
for (const int i : IndexRange(totverts)) {
verts[i] = input_verts[i].co;
}
for (const int i : IndexRange(totfaces)) {
MVertTri &vt = verttri[i];
faces[i * 3] = vt.tri[0];
@@ -94,7 +89,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
qrd.totfaces = totfaces;
qrd.totverts = totverts;
qrd.verts = (float *)verts.data();
qrd.verts = (float *)input_positions.data();
qrd.faces = faces.data();
qrd.target_faces = target_faces;
@@ -127,13 +122,11 @@ 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);
BKE_mesh_copy_parameters(mesh, input_mesh);
MutableSpan<MVert> mesh_verts = mesh->verts_for_write();
MutableSpan<MPoly> polys = mesh->polys_for_write();
MutableSpan<MLoop> loops = mesh->loops_for_write();
for (const int i : IndexRange(qrd.out_totverts)) {
copy_v3_v3(mesh_verts[i].co, &qrd.out_verts[i * 3]);
}
mesh->vert_positions_for_write().copy_from(
Span(reinterpret_cast<float3 *>(qrd.out_verts), qrd.out_totverts));
for (const int i : IndexRange(qrd.out_totfaces)) {
MPoly &poly = polys[i];
@@ -193,7 +186,7 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh,
static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
const float voxel_size)
{
const Span<MVert> verts = mesh->verts();
const Span<float3> positions = mesh->vert_positions();
const Span<MLoop> loops = mesh->loops();
const Span<MLoopTri> looptris = mesh->looptris();
@@ -201,7 +194,7 @@ 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 = verts[i].co;
const float3 &co = positions[i];
points[i] = openvdb::Vec3s(co.x, co.y, co.z);
}
@@ -232,12 +225,12 @@ 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> mesh_verts = mesh->verts_for_write();
MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
MutableSpan<MPoly> mesh_polys = mesh->polys_for_write();
MutableSpan<MLoop> mesh_loops = mesh->loops_for_write();
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 : vert_positions.index_range()) {
vert_positions[i] = float3(vertices[i].x(), vertices[i].y(), vertices[i].z());
}
for (const int i : IndexRange(quads.size())) {
@@ -288,7 +281,7 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source)
{
BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
const Span<MVert> target_verts = target->verts();
const Span<float3> target_positions = target->vert_positions();
const float *source_mask = (const float *)CustomData_get_layer(&source->vdata, CD_PAINT_MASK);
if (source_mask == nullptr) {
return;
@@ -309,7 +302,7 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source)
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
target_mask[i] = source_mask[nearest.index];
}
@@ -324,7 +317,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
using namespace blender::bke;
const AttributeAccessor src_attributes = source->attributes();
MutableAttributeAccessor dst_attributes = target->attributes_for_write();
const Span<MVert> target_verts = target->verts();
const Span<float3> target_positions = target->vert_positions();
const Span<MPoly> target_polys = target->polys();
const Span<MLoop> target_loops = target->loops();
@@ -352,9 +345,11 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
const MPoly &poly = target_polys[i];
BKE_mesh_calc_poly_center(
&poly, &target_loops[poly.loopstart], target_verts.data(), from_co);
const MPoly *mpoly = &target_polys[i];
BKE_mesh_calc_poly_center(mpoly,
&target_loops[mpoly->loopstart],
reinterpret_cast<const float(*)[3]>(target_positions.data()),
from_co);
BLI_bvhtree_find_nearest(
bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
@@ -402,7 +397,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
size_t data_size = CustomData_sizeof(layer->type);
void *target_data = target_cdata->layers[layer_i].data;
void *source_data = layer->data;
const Span<MVert> target_verts = target->verts();
const Span<float3> target_positions = target->vert_positions();
if (domain == ATTR_DOMAIN_POINT) {
blender::threading::parallel_for(
@@ -412,8 +407,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
memcpy(POINTER_OFFSET(target_data, size_t(i) * data_size),
POINTER_OFFSET(source_data, size_t(nearest.index) * data_size),
@@ -449,7 +443,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index == -1) {
continue;
@@ -25,6 +25,7 @@
#include "BKE_shrinkwrap.h"
#include "BKE_subdiv_ccg.h"
using blender::float3;
using blender::MutableSpan;
using blender::Span;
@@ -143,20 +144,24 @@ void Mesh::loose_edges_tag_none() const
blender::Span<MLoopTri> Mesh::looptris() const
{
this->runtime->looptris_cache.ensure([&](blender::Array<MLoopTri> &r_data) {
const Span<MVert> verts = this->verts();
const Span<float3> positions = this->vert_positions();
const Span<MPoly> polys = this->polys();
const Span<MLoop> loops = this->loops();
r_data.reinitialize(poly_to_tri_count(polys.size(), loops.size()));
if (BKE_mesh_poly_normals_are_dirty(this)) {
BKE_mesh_recalc_looptri(
loops.data(), polys.data(), verts.data(), loops.size(), polys.size(), r_data.data());
BKE_mesh_recalc_looptri(loops.data(),
polys.data(),
reinterpret_cast<const float(*)[3]>(positions.data()),
loops.size(),
polys.size(),
r_data.data());
}
else {
BKE_mesh_recalc_looptri_with_normals(loops.data(),
polys.data(),
verts.data(),
reinterpret_cast<const float(*)[3]>(positions.data()),
loops.size(),
polys.size(),
r_data.data(),
@@ -317,7 +322,7 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
printf("MESH: %s\n", me_eval->id.name + 2);
}
MutableSpan<MVert> verts = me_eval->verts_for_write();
MutableSpan<float3> positions = me_eval->vert_positions_for_write();
MutableSpan<MEdge> edges = me_eval->edges_for_write();
MutableSpan<MPoly> polys = me_eval->polys_for_write();
MutableSpan<MLoop> loops = me_eval->loops_for_write();
@@ -338,8 +343,8 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
is_valid &= BKE_mesh_validate_arrays(
me_eval,
verts.data(),
verts.size(),
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
static_cast<MFace *>(CustomData_get_layer(&me_eval->fdata, CD_MFACE)),
+18 -18
View File
@@ -156,7 +156,7 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
}
bary_coords_.reinitialize(mask_.min_array_size());
const Span<MVert> verts = mesh_->verts();
const Span<float3> positions = mesh_->vert_positions();
const Span<MLoop> loops = mesh_->loops();
const Span<MLoopTri> looptris = mesh_->looptris();
@@ -169,9 +169,9 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
const int v2_index = loops[looptri.tri[2]].v;
interp_weights_tri_v3(bary_coords_[i],
verts[v0_index].co,
verts[v1_index].co,
verts[v2_index].co,
positions[v0_index],
positions[v1_index],
positions[v2_index],
positions_[i]);
}
return bary_coords_;
@@ -185,7 +185,7 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
}
nearest_weights_.reinitialize(mask_.min_array_size());
const Span<MVert> verts = mesh_->verts();
const Span<float3> positions = mesh_->vert_positions();
const Span<MLoop> loops = mesh_->loops();
const Span<MLoopTri> looptris = mesh_->looptris();
@@ -197,9 +197,9 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
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], 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);
const float d0 = len_squared_v3v3(positions_[i], positions[v0_index]);
const float d1 = len_squared_v3v3(positions_[i], positions[v1_index]);
const float d2 = len_squared_v3v3(positions_[i], positions[v2_index]);
nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
}
@@ -258,7 +258,7 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng,
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions)
{
const Span<MVert> verts = mesh.verts();
const Span<float3> positions = mesh.vert_positions();
const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris = mesh.looptris();
@@ -272,9 +272,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 = 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 float3 &v0 = positions[loops[looptri.tri[0]].v];
const float3 &v1 = positions[loops[looptri.tri[1]].v];
const float3 &v2 = positions[loops[looptri.tri[2]].v];
const float looptri_area = area_tri_v3(v0, v1, v2);
@@ -355,7 +355,7 @@ int sample_surface_points_projected(
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions)
{
const Span<MVert> verts = mesh.verts();
const Span<float3> positions = mesh.vert_positions();
const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris = mesh.looptris();
@@ -398,7 +398,7 @@ int sample_surface_points_projected(
const float3 pos = ray_hit.co;
const float3 bary_coords = compute_bary_coord_in_triangle(
verts, loops, looptris[looptri_index], pos);
positions, loops, looptris[looptri_index], pos);
r_positions.append(pos);
r_bary_coords.append(bary_coords);
@@ -408,14 +408,14 @@ int sample_surface_points_projected(
return point_count;
}
float3 compute_bary_coord_in_triangle(const Span<MVert> verts,
float3 compute_bary_coord_in_triangle(const Span<float3> vert_positions,
const Span<MLoop> loops,
const MLoopTri &looptri,
const float3 &position)
{
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 float3 &v0 = vert_positions[loops[looptri.tri[0]].v];
const float3 &v1 = vert_positions[loops[looptri.tri[1]].v];
const float3 &v2 = vert_positions[loops[looptri.tri[2]].v];
float3 bary_coords;
interp_weights_tri_v3(bary_coords, v0, v1, v2, position);
return bary_coords;
@@ -47,7 +47,7 @@ struct BKEMeshToTangent {
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
{
const uint loop_idx = uint(mpolys[face_num].loopstart) + vert_num;
return mikk::float3(mverts[mloops[loop_idx].v].co);
return mikk::float3(positions[mloops[loop_idx].v]);
}
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
@@ -69,14 +69,14 @@ struct BKEMeshToTangent {
const MPoly *mpolys; /* faces */
const MLoop *mloops; /* faces vertices */
const MVert *mverts; /* vertices */
const float (*positions)[3]; /* vertices */
const MLoopUV *luvs; /* texture coordinates */
const float (*loop_normals)[3]; /* loops' normals */
float (*tangents)[4]; /* output tangents */
int num_polys; /* number of polygons */
};
void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts,
void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
const int /*numVerts*/,
const MLoop *mloops,
float (*r_looptangent)[4],
@@ -91,7 +91,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts,
BKEMeshToTangent mesh_to_tangent;
mesh_to_tangent.mpolys = mpolys;
mesh_to_tangent.mloops = mloops;
mesh_to_tangent.mverts = mverts;
mesh_to_tangent.positions = vert_positions;
mesh_to_tangent.luvs = loopuvs;
mesh_to_tangent.loop_normals = loop_normals;
mesh_to_tangent.tangents = r_looptangent;
@@ -141,7 +141,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
return;
}
BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_verts(mesh),
BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_vert_positions(mesh),
mesh->totvert,
BKE_mesh_loops(mesh),
r_looptangents,
@@ -213,7 +213,7 @@ struct SGLSLMeshToTangent {
{
const MLoopTri *lt;
uint loop_index = GetLoop(face_num, vert_num, lt);
return mikk::float3(mvert[mloop[loop_index].v].co);
return mikk::float3(positions[mloop[loop_index].v]);
}
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
@@ -246,18 +246,18 @@ struct SGLSLMeshToTangent {
float normal[3];
if (mp->totloop == 4) {
normal_quad_v3(normal,
mvert[mloop[mp->loopstart + 0].v].co,
mvert[mloop[mp->loopstart + 1].v].co,
mvert[mloop[mp->loopstart + 2].v].co,
mvert[mloop[mp->loopstart + 3].v].co);
positions[mloop[mp->loopstart + 0].v],
positions[mloop[mp->loopstart + 1].v],
positions[mloop[mp->loopstart + 2].v],
positions[mloop[mp->loopstart + 3].v]);
}
else
#endif
{
normal_tri_v3(normal,
mvert[mloop[lt->tri[0]].v].co,
mvert[mloop[lt->tri[1]].v].co,
mvert[mloop[lt->tri[2]].v].co);
positions[mloop[lt->tri[0]].v],
positions[mloop[lt->tri[1]].v],
positions[mloop[lt->tri[2]].v]);
}
return mikk::float3(normal);
}
@@ -275,10 +275,10 @@ struct SGLSLMeshToTangent {
const float (*precomputedFaceNormals)[3];
const float (*precomputedLoopNormals)[3];
const MLoopTri *looptri;
const MLoopUV *mloopuv; /* texture coordinates */
const MPoly *mpoly; /* indices */
const MLoop *mloop; /* indices */
const MVert *mvert; /* vertex coordinates */
const MLoopUV *mloopuv; /* texture coordinates */
const MPoly *mpoly; /* indices */
const MLoop *mloop; /* indices */
const float (*positions)[3]; /* vertex coordinates */
const float (*vert_normals)[3];
const float (*orco)[3];
float (*tangent)[4]; /* destination */
@@ -385,7 +385,7 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
}
}
void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const MPoly *mpoly,
const uint mpoly_len,
const MLoop *mloop,
@@ -490,7 +490,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
mesh2tangent->face_as_quad_map = face_as_quad_map;
mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
#endif
mesh2tangent->mvert = mvert;
mesh2tangent->positions = vert_positions;
mesh2tangent->vert_normals = vert_normals;
mesh2tangent->mpoly = mpoly;
mesh2tangent->mloop = mloop;
@@ -573,7 +573,7 @@ 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(
BKE_mesh_verts(me_eval),
BKE_mesh_vert_positions(me_eval),
BKE_mesh_polys(me_eval),
uint(me_eval->totpoly),
BKE_mesh_loops(me_eval),
@@ -42,7 +42,7 @@
*/
BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*positions)[3],
uint poly_index,
MLoopTri *mlt,
MemArena **pf_arena_p,
@@ -72,17 +72,17 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
if (UNLIKELY(face_normal ? is_quad_flip_v3_first_third_fast_with_normal(
/* Simpler calculation (using the normal). */
mvert[mloop[mlt_a->tri[0]].v].co,
mvert[mloop[mlt_a->tri[1]].v].co,
mvert[mloop[mlt_a->tri[2]].v].co,
mvert[mloop[mlt_b->tri[2]].v].co,
positions[mloop[mlt_a->tri[0]].v],
positions[mloop[mlt_a->tri[1]].v],
positions[mloop[mlt_a->tri[2]].v],
positions[mloop[mlt_b->tri[2]].v],
normal_precalc) :
is_quad_flip_v3_first_third_fast(
/* Expensive calculation (no normal). */
mvert[mloop[mlt_a->tri[0]].v].co,
mvert[mloop[mlt_a->tri[1]].v].co,
mvert[mloop[mlt_a->tri[2]].v].co,
mvert[mloop[mlt_b->tri[2]].v].co))) {
positions[mloop[mlt_a->tri[0]].v],
positions[mloop[mlt_a->tri[1]].v],
positions[mloop[mlt_a->tri[2]].v],
positions[mloop[mlt_b->tri[2]].v]))) {
/* Flip out of degenerate 0-2 state. */
mlt_a->tri[2] = mlt_b->tri[2];
mlt_b->tri[0] = mlt_a->tri[1];
@@ -102,9 +102,9 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
/* Calc normal, flipped: to get a positive 2D cross product. */
ml = mloop + mp_loopstart;
co_prev = mvert[ml[mp_totloop - 1].v].co;
co_prev = positions[ml[mp_totloop - 1].v];
for (uint j = 0; j < mp_totloop; j++, ml++) {
co_curr = mvert[ml->v].co;
co_curr = positions[ml->v];
add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
co_prev = co_curr;
}
@@ -131,7 +131,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
ml = mloop + mp_loopstart;
for (uint j = 0; j < mp_totloop; j++, ml++) {
mul_v2_m3v3(projverts[j], axis_mat, mvert[ml->v].co);
mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]);
}
BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, pf_arena);
@@ -152,30 +152,30 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
static void mesh_calc_tessellation_for_face(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*positions)[3],
uint poly_index,
MLoopTri *mlt,
MemArena **pf_arena_p)
{
mesh_calc_tessellation_for_face_impl(
mloop, mpoly, mvert, poly_index, mlt, pf_arena_p, false, nullptr);
mloop, mpoly, positions, poly_index, mlt, pf_arena_p, false, nullptr);
}
static void mesh_calc_tessellation_for_face_with_normal(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*positions)[3],
uint poly_index,
MLoopTri *mlt,
MemArena **pf_arena_p,
const float normal_precalc[3])
{
mesh_calc_tessellation_for_face_impl(
mloop, mpoly, mvert, poly_index, mlt, pf_arena_p, true, normal_precalc);
mloop, mpoly, positions, poly_index, mlt, pf_arena_p, true, normal_precalc);
}
static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*positions)[3],
int totloop,
int totpoly,
MLoopTri *mlooptri,
@@ -189,7 +189,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, mp++) {
mesh_calc_tessellation_for_face_with_normal(mloop,
mpoly,
mvert,
positions,
poly_index,
&mlooptri[tri_index],
&pf_arena,
@@ -200,7 +200,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
else {
for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, mp++) {
mesh_calc_tessellation_for_face(
mloop, mpoly, mvert, poly_index, &mlooptri[tri_index], &pf_arena);
mloop, mpoly, positions, poly_index, &mlooptri[tri_index], &pf_arena);
tri_index += uint(mp->totloop - 2);
}
}
@@ -216,7 +216,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
struct TessellationUserData {
const MLoop *mloop;
const MPoly *mpoly;
const MVert *mvert;
const float (*positions)[3];
/** Output array. */
MLoopTri *mlooptri;
@@ -238,7 +238,7 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata,
const int tri_index = poly_to_tri_count(index, data->mpoly[index].loopstart);
mesh_calc_tessellation_for_face_impl(data->mloop,
data->mpoly,
data->mvert,
data->positions,
uint(index),
&data->mlooptri[tri_index],
&tls_data->pf_arena,
@@ -255,7 +255,7 @@ static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict user
const int tri_index = poly_to_tri_count(index, data->mpoly[index].loopstart);
mesh_calc_tessellation_for_face_impl(data->mloop,
data->mpoly,
data->mvert,
data->positions,
uint(index),
&data->mlooptri[tri_index],
&tls_data->pf_arena,
@@ -274,7 +274,7 @@ static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict /*use
static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*positions)[3],
int /*totloop*/,
int totpoly,
MLoopTri *mlooptri,
@@ -286,7 +286,7 @@ static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop,
};
data.mloop = mloop;
data.mpoly = mpoly;
data.mvert = mvert;
data.positions = positions;
data.mlooptri = mlooptri;
data.poly_normals = poly_normals;
@@ -308,22 +308,24 @@ static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop,
void BKE_mesh_recalc_looptri(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*vert_positions)[3],
int totloop,
int totpoly,
MLoopTri *mlooptri)
{
if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
mesh_recalc_looptri__single_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, nullptr);
mesh_recalc_looptri__single_threaded(
mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, nullptr);
}
else {
mesh_recalc_looptri__multi_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, nullptr);
mesh_recalc_looptri__multi_threaded(
mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, nullptr);
}
}
void BKE_mesh_recalc_looptri_with_normals(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
const float (*vert_positions)[3],
int totloop,
int totpoly,
MLoopTri *mlooptri,
@@ -332,11 +334,11 @@ void BKE_mesh_recalc_looptri_with_normals(const MLoop *mloop,
BLI_assert(poly_normals != nullptr);
if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
mesh_recalc_looptri__single_threaded(
mloop, mpoly, mvert, totloop, totpoly, mlooptri, poly_normals);
mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, poly_normals);
}
else {
mesh_recalc_looptri__multi_threaded(
mloop, mpoly, mvert, totloop, totpoly, mlooptri, poly_normals);
mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, poly_normals);
}
}
@@ -33,6 +33,7 @@
#include "MEM_guardedalloc.h"
using blender::float3;
using blender::MutableSpan;
using blender::Span;
@@ -206,7 +207,7 @@ static int search_polyloop_cmp(const void *v1, const void *v2)
/* NOLINTNEXTLINE: readability-function-size */
bool BKE_mesh_validate_arrays(Mesh *mesh,
MVert *mverts,
float (*vert_positions)[3],
uint totvert,
MEdge *medges,
uint totedge,
@@ -246,7 +247,6 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
mesh->attributes_for_write().lookup_for_write<int>("material_index");
blender::MutableVArraySpan<int> material_indices_span(material_indices.varray);
MVert *mv = mverts;
MEdge *me;
MLoop *ml;
MPoly *mp;
@@ -302,15 +302,15 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
}
for (i = 0; i < totvert; i++, mv++) {
for (i = 0; i < totvert; i++) {
bool fix_normal = true;
for (j = 0; j < 3; j++) {
if (!isfinite(mv->co[j])) {
if (!isfinite(vert_positions[i][j])) {
PRINT_ERR("\tVertex %u: has invalid coordinate", i);
if (do_fixes) {
zero_v3(mv->co);
zero_v3(vert_positions[i]);
fix_flag.verts = true;
}
@@ -332,7 +332,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
* although it's also possible degenerate/opposite faces accumulate to a zero vector.
* To detect this a full normal recalculation would be needed, which is out of scope
* for a basic validity check (see "Vertex Normal" in the doc-string). */
if (!is_zero_v3(mv->co)) {
if (!is_zero_v3(vert_positions[i])) {
PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal", i);
if (do_fixes) {
float *normal = (float *)vert_normals[i];
@@ -1066,14 +1066,14 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
do_verbose,
true,
&changed);
MutableSpan<MVert> verts = me->verts_for_write();
MutableSpan<float3> positions = me->vert_positions_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
BKE_mesh_validate_arrays(me,
verts.data(),
verts.size(),
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
@@ -1117,14 +1117,14 @@ bool BKE_mesh_is_valid(Mesh *me)
do_fixes,
&changed);
MutableSpan<MVert> verts = me->verts_for_write();
MutableSpan<float3> positions = me->vert_positions_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
is_valid &= BKE_mesh_validate_arrays(me,
verts.data(),
verts.size(),
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
@@ -7,7 +7,7 @@
* output of a modified mesh.
*
* This API handles the case when the modifier stack outputs a mesh which does not have
* #Mesh data (#MPoly, #MLoop, #MEdge, #MVert).
* #Mesh data (#MPoly, #MLoop, #MEdge, etc).
* Currently this is used so the resulting mesh can have #BMEditMesh data,
* postponing the converting until it's needed or avoiding conversion entirely
* which can be an expensive operation.
@@ -46,6 +46,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
using blender::float3;
using blender::Span;
Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
@@ -192,9 +193,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 Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
for (int i = 0; i < vert_coords_len; i++) {
copy_v3_v3(vert_coords[i], verts[i].co);
copy_v3_v3(vert_coords[i], positions[i]);
}
return;
}
@@ -230,9 +231,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 Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
for (int i = 0; i < vert_coords_len; i++) {
mul_v3_m4v3(vert_coords[i], mat, verts[i].co);
mul_v3_m4v3(vert_coords[i], mat, positions[i]);
}
return;
}
+2 -2
View File
@@ -1189,8 +1189,8 @@ void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase
CollisionModifierData *collmd = (CollisionModifierData *)md;
/* TODO: CollisionModifier should use pointcache
* + have proper reset events before enabling this. */
writestruct(wd, DATA, MVert, collmd->numverts, collmd->x);
writestruct(wd, DATA, MVert, collmd->numverts, collmd->xnew);
writestruct(wd, DATA, float[3], collmd->numverts, collmd->x);
writestruct(wd, DATA, float[3], collmd->numverts, collmd->xnew);
writestruct(wd, DATA, MFace, collmd->numfaces, collmd->mfaces);
#endif
}
+1 -1
View File
@@ -1618,7 +1618,7 @@ int mdisp_rot_face_to_crn(
float mindist = FLT_MAX;
for (i = 0; i < mpoly->totloop; i++) {
float len = len_v3v3(nullptr, mvert[mloop[mpoly->loopstart + i].v].co);
float len = len_v3v3(nullptr, positions[mloop[mpoly->loopstart + i].v]);
if (len < mindist) {
mindist = len;
minS = i;
@@ -19,7 +19,6 @@ struct Mesh;
struct MLoop;
struct MPoly;
struct MultiresModifierData;
struct MVert;
struct Object;
struct Subdiv;
struct SubdivCCG;
@@ -34,7 +33,7 @@ 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 float (*base_positions)[3];
const struct MEdge *base_edges;
const struct MPoly *base_polys;
const struct MLoop *base_loops;
@@ -30,14 +30,13 @@
void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context)
{
Mesh *base_mesh = reshape_context->base_mesh;
MVert *base_verts = BKE_mesh_verts_for_write(base_mesh);
float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh);
/* Update the context in case the vertices were duplicated. */
reshape_context->base_verts = base_verts;
reshape_context->base_positions = base_positions;
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 = &base_verts[loop->v];
GridCoord grid_coord;
grid_coord.grid_index = loop_index;
@@ -53,7 +52,7 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *resh
float D[3];
mul_v3_m3v3(D, tangent_matrix, grid_element.displacement);
add_v3_v3v3(vert->co, P, D);
add_v3_v3v3(base_positions[loop->v], P, D);
}
}
@@ -69,9 +68,9 @@ 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_verts_for_write(base_mesh);
float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh);
/* Update the context in case the vertices were duplicated. */
reshape_context->base_verts = base_verts;
reshape_context->base_positions = base_positions;
MeshElemMap *pmap;
int *pmap_mem;
BKE_mesh_vert_poly_map_create(&pmap,
@@ -85,7 +84,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_verts[i].co);
copy_v3_v3(origco[i], base_positions[i]);
}
for (int i = 0; i < base_mesh->totvert; i++) {
@@ -120,7 +119,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
float(*fake_co)[3];
float no[3];
/* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal_coords(). */
/* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */
fake_poly.totloop = p->totloop;
fake_poly.loopstart = 0;
fake_loops = MEM_malloc_arrayN(p->totloop, sizeof(MLoop), "fake_loops");
@@ -139,7 +138,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
}
}
BKE_mesh_calc_poly_normal_coords(&fake_poly, fake_loops, (const float(*)[3])fake_co, no);
BKE_mesh_calc_poly_normal(&fake_poly, fake_loops, (const float(*)[3])fake_co, no);
MEM_freeN(fake_loops);
MEM_freeN(fake_co);
@@ -148,10 +147,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_verts[i].co, center, avg_no);
const float dist = v3_dist_from_plane(base_positions[i], center, avg_no);
copy_v3_v3(push, avg_no);
mul_v3_fl(push, dist);
add_v3_v3(base_verts[i].co, push);
add_v3_v3(base_positions[i], push);
}
MEM_freeN(origco);
@@ -28,7 +28,7 @@
static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
{
const MVert *verts = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MPoly *polys = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
@@ -37,7 +37,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
for (int p = 0; p < totpoly; p++) {
const MPoly *poly = &polys[p];
float poly_center[3];
BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], verts, poly_center);
BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], positions, poly_center);
for (int l = 0; l < poly->totloop; l++) {
const int loop_index = poly->loopstart + l;
@@ -53,9 +53,9 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
const MLoop *loop_prev = &loops[prev_loop_index];
copy_v3_v3(disps[0], poly_center);
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);
mid_v3_v3v3(disps[1], positions[loop->v], positions[loop_next->v]);
mid_v3_v3v3(disps[2], positions[loop->v], positions[loop_prev->v]);
copy_v3_v3(disps[3], positions[loop->v]);
}
}
}
@@ -152,7 +152,7 @@ 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_verts(base_mesh);
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
@@ -189,7 +189,7 @@ 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_verts(base_mesh);
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
@@ -221,7 +221,7 @@ 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_verts(base_mesh);
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
@@ -268,7 +268,7 @@ 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_verts(base_mesh);
reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
+17 -17
View File
@@ -3242,7 +3242,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_verts(me_eval);
const Span<float3> positions = me_eval->vert_positions();
int count = 0;
int numVerts = me_eval->totvert;
@@ -3276,14 +3276,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, verts[i].co);
add_v3_v3(vec, positions[i]);
count++;
}
}
}
else {
if (nr < numVerts) {
add_v3_v3(vec, verts[nr].co);
add_v3_v3(vec, positions[nr]);
count++;
}
}
@@ -3297,7 +3297,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, verts[0].co);
copy_v3_v3(vec, positions[0]);
}
}
}
@@ -4182,10 +4182,9 @@ void BKE_object_foreach_display_point(Object *ob,
float3 co;
if (mesh_eval != nullptr) {
const MVert *verts = BKE_mesh_verts(mesh_eval);
const int totvert = mesh_eval->totvert;
for (int i = 0; i < totvert; i++) {
mul_v3_m4v3(co, obmat, verts[i].co);
const Span<float3> positions = mesh_eval->vert_positions();
for (const int i : positions.index_range()) {
mul_v3_m4v3(co, obmat, positions[i]);
func_cb(co, user_data);
}
}
@@ -4810,8 +4809,9 @@ bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb)
switch (ob->type) {
case OB_MESH: {
Mesh *mesh = (Mesh *)ob->data;
MutableSpan<MVert> verts = mesh->verts_for_write();
BKE_keyblock_convert_to_mesh(key->refkey, verts.data(), mesh->totvert);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
BKE_keyblock_convert_to_mesh(
key->refkey, reinterpret_cast<float(*)[3]>(positions.data()), mesh->totvert);
break;
}
case OB_CURVES_LEGACY:
@@ -5310,31 +5310,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))) {
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
/* Tree over-allocates in case where some verts have #ORIGINDEX_NONE. */
tot = 0;
tree = BLI_kdtree_3d_new(verts.size());
tree = BLI_kdtree_3d_new(positions.size());
/* We don't how many verts from the DM we can use. */
for (i = 0; i < verts.size(); i++) {
for (i = 0; i < positions.size(); i++) {
if (index[i] != ORIGINDEX_NONE) {
float co[3];
mul_v3_m4v3(co, ob->object_to_world, verts[i].co);
mul_v3_m4v3(co, ob->object_to_world, positions[i]);
BLI_kdtree_3d_insert(tree, index[i], co);
tot++;
}
}
}
else {
const Span<MVert> verts = me->verts();
const Span<float3> positions = me->vert_positions();
tot = verts.size();
tot = positions.size();
tree = BLI_kdtree_3d_new(tot);
for (i = 0; i < tot; i++) {
float co[3];
mul_v3_m4v3(co, ob->object_to_world, verts[i].co);
mul_v3_m4v3(co, ob->object_to_world, positions[i]);
BLI_kdtree_3d_insert(tree, i, co);
}
}
@@ -553,7 +553,7 @@ struct VertexDupliData_Mesh {
VertexDupliData_Params params;
int totvert;
const MVert *mvert;
Span<float3> vert_positions;
const float (*vert_normals)[3];
const float (*orco)[3];
@@ -644,7 +644,6 @@ static void make_child_duplis_verts_from_mesh(const DupliContext *ctx,
VertexDupliData_Mesh *vdd = (VertexDupliData_Mesh *)userdata;
const bool use_rotation = vdd->params.use_rotation;
const MVert *mvert = vdd->mvert;
const int totvert = vdd->totvert;
invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world);
@@ -653,8 +652,13 @@ static void make_child_duplis_verts_from_mesh(const DupliContext *ctx,
mul_m4_m4m4(child_imat, inst_ob->world_to_object, ctx->object->object_to_world);
for (int i = 0; i < totvert; i++) {
DupliObject *dob = vertex_dupli(
vdd->params.ctx, inst_ob, child_imat, i, mvert[i].co, vdd->vert_normals[i], use_rotation);
DupliObject *dob = vertex_dupli(vdd->params.ctx,
inst_ob,
child_imat,
i,
vdd->vert_positions[i],
vdd->vert_normals[i],
use_rotation);
if (vdd->orco) {
copy_v3_v3(dob->orco, vdd->orco[i]);
}
@@ -730,7 +734,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->verts().data();
vdd.vert_positions = me_eval->vert_positions();
vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval);
vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
@@ -1056,7 +1060,7 @@ struct FaceDupliData_Mesh {
int totface;
const MPoly *mpoly;
const MLoop *mloop;
const MVert *mvert;
Span<float3> positions;
const float (*orco)[3];
const MLoopUV *mloopuv;
};
@@ -1155,14 +1159,14 @@ static DupliObject *face_dupli_from_mesh(const DupliContext *ctx,
/* Mesh variables. */
const MPoly *mpoly,
const MLoop *mloopstart,
const MVert *mvert)
const Span<float3> positions)
{
const int coords_len = mpoly->totloop;
Array<float3, 64> coords(coords_len);
const MLoop *ml = mloopstart;
for (int i = 0; i < coords_len; i++, ml++) {
coords[i] = float3(mvert[ml->v].co);
coords[i] = positions[ml->v];
}
return face_dupli(ctx, inst_ob, child_imat, index, use_scale, scale_fac, coords);
@@ -1206,7 +1210,6 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
FaceDupliData_Mesh *fdd = (FaceDupliData_Mesh *)userdata;
const MPoly *mpoly = fdd->mpoly, *mp;
const MLoop *mloop = fdd->mloop;
const MVert *mvert = fdd->mvert;
const float(*orco)[3] = fdd->orco;
const MLoopUV *mloopuv = fdd->mloopuv;
const int totface = fdd->totface;
@@ -1222,8 +1225,15 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
for (a = 0, mp = mpoly; a < totface; a++, mp++) {
const MLoop *loopstart = mloop + mp->loopstart;
DupliObject *dob = face_dupli_from_mesh(
fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, mp, loopstart, mvert);
DupliObject *dob = face_dupli_from_mesh(fdd->params.ctx,
inst_ob,
child_imat,
a,
use_scale,
scale_fac,
mp,
loopstart,
fdd->positions);
const float w = 1.0f / float(mp->totloop);
if (orco) {
@@ -1312,7 +1322,7 @@ static void make_duplis_faces(const DupliContext *ctx)
fdd.totface = me_eval->totpoly;
fdd.mpoly = me_eval->polys().data();
fdd.mloop = me_eval->loops().data();
fdd.mvert = me_eval->verts().data();
fdd.positions = me_eval->vert_positions();
fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n(
&me_eval->ldata, CD_MLOOPUV, uv_idx) :
nullptr;
+14 -9
View File
@@ -67,6 +67,10 @@
#include "bmesh.h"
using blender::float3;
using blender::MutableSpan;
using blender::Span;
static void sculpt_attribute_update_refs(Object *ob);
static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
eAttrDomain domain,
@@ -77,9 +81,6 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
bool flat_array_for_bmesh);
static void sculptsession_bmesh_add_layers(Object *ob);
using blender::MutableSpan;
using blender::Span;
static void palette_init_data(ID *id)
{
Palette *palette = (Palette *)id;
@@ -1694,7 +1695,7 @@ static void sculpt_update_object(
/* 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 = BKE_mesh_verts_for_write(me);
ss->vert_positions = BKE_mesh_vert_positions_for_write(me);
ss->mpoly = BKE_mesh_polys(me);
ss->mloop = BKE_mesh_loops(me);
}
@@ -1702,7 +1703,7 @@ static void sculpt_update_object(
ss->totvert = me->totvert;
ss->totpoly = me->totpoly;
ss->totfaces = me->totpoly;
ss->mvert = BKE_mesh_verts_for_write(me);
ss->vert_positions = BKE_mesh_vert_positions_for_write(me);
ss->mpoly = BKE_mesh_polys(me);
ss->mloop = BKE_mesh_loops(me);
ss->multires.active = false;
@@ -2178,21 +2179,25 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
PBVH *pbvh = BKE_pbvh_new(PBVH_FACES);
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
MutableSpan<MVert> verts = me->verts_for_write();
MutableSpan<float3> positions = me->vert_positions_for_write();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
MLoopTri *looptri = static_cast<MLoopTri *>(
MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__));
BKE_mesh_recalc_looptri(
loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri);
BKE_mesh_recalc_looptri(loops.data(),
polys.data(),
reinterpret_cast<const float(*)[3]>(positions.data()),
me->totloop,
me->totpoly,
looptri);
BKE_pbvh_build_mesh(pbvh,
me,
polys.data(),
loops.data(),
verts.data(),
reinterpret_cast<float(*)[3]>(positions.data()),
me->totvert,
&me->vdata,
&me->ldata,
+31 -30
View File
@@ -78,6 +78,8 @@
#include "particle_private.h"
using blender::float3;
static void fluid_free_settings(SPHFluidSettings *fluid);
static void particle_settings_init(ID *id)
@@ -1272,7 +1274,7 @@ typedef struct ParticleInterpolationData {
HairKey *hkey[2];
Mesh *mesh;
MVert *mvert[2];
float3 *vert_positions[2];
int keyed;
ParticleKey *kkey[2];
@@ -1432,9 +1434,9 @@ static void init_particle_interpolation(Object *ob,
pind->dietime = (key + pa->totkey - 1)->time;
if (pind->mesh) {
MVert *verts = BKE_mesh_verts_for_write(pind->mesh);
pind->mvert[0] = &verts[pa->hair_index];
pind->mvert[1] = pind->mvert[0] + 1;
float3 *positions = pind->mesh->vert_positions_for_write().data();
pind->vert_positions[0] = &positions[pa->hair_index];
pind->vert_positions[1] = pind->vert_positions[0] + 1;
}
}
}
@@ -1452,9 +1454,9 @@ static void hair_to_particle(ParticleKey *key, HairKey *hkey)
key->time = hkey->time;
}
static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey)
static void mvert_to_particle(ParticleKey *key, float3 *position, HairKey *hkey)
{
copy_v3_v3(key->co, mvert->co);
copy_v3_v3(key->co, *position);
key->time = hkey->time;
}
@@ -1552,7 +1554,7 @@ static void do_particle_interpolation(ParticleSystem *psys,
while (pind->hkey[1]->time < real_t) {
pind->hkey[1]++;
pind->mvert[1]++;
pind->vert_positions[1]++;
}
pind->hkey[0] = pind->hkey[1] - 1;
@@ -1564,9 +1566,9 @@ static void do_particle_interpolation(ParticleSystem *psys,
edit_to_particle(keys + 2, pind->ekey[1]);
}
else if (pind->mesh) {
pind->mvert[0] = pind->mvert[1] - 1;
mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]);
mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]);
pind->vert_positions[0] = pind->vert_positions[1] - 1;
mvert_to_particle(keys + 1, pind->vert_positions[0], pind->hkey[0]);
mvert_to_particle(keys + 2, pind->vert_positions[1], pind->hkey[1]);
}
else if (pind->keyed) {
memcpy(keys + 1, pind->kkey[0], sizeof(ParticleKey));
@@ -1592,10 +1594,10 @@ static void do_particle_interpolation(ParticleSystem *psys,
}
else if (pind->mesh) {
if (pind->hkey[0] != pa->hair) {
mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1);
mvert_to_particle(keys, pind->vert_positions[0] - 1, pind->hkey[0] - 1);
}
else {
mvert_to_particle(keys, pind->mvert[0], pind->hkey[0]);
mvert_to_particle(keys, pind->vert_positions[0], pind->hkey[0]);
}
}
else {
@@ -1617,10 +1619,10 @@ static void do_particle_interpolation(ParticleSystem *psys,
}
else if (pind->mesh) {
if (pind->hkey[1] != pa->hair + pa->totkey - 1) {
mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1);
mvert_to_particle(keys + 3, pind->vert_positions[1] + 1, pind->hkey[1] + 1);
}
else {
mvert_to_particle(keys + 3, pind->mvert[1], pind->hkey[1]);
mvert_to_particle(keys + 3, pind->vert_positions[1], pind->hkey[1]);
}
}
else {
@@ -1698,7 +1700,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach
/************************************************/
void psys_interpolate_face(Mesh *mesh,
const MVert *mvert,
const float (*vert_positions)[3],
const float (*vert_normals)[3],
MFace *mface,
MTFace *tface,
@@ -1717,16 +1719,16 @@ void psys_interpolate_face(Mesh *mesh,
float tuv[4][2];
const float *o1, *o2, *o3, *o4;
v1 = mvert[mface->v1].co;
v2 = mvert[mface->v2].co;
v3 = mvert[mface->v3].co;
v1 = vert_positions[mface->v1];
v2 = vert_positions[mface->v2];
v3 = vert_positions[mface->v3];
copy_v3_v3(n1, vert_normals[mface->v1]);
copy_v3_v3(n2, vert_normals[mface->v2]);
copy_v3_v3(n3, vert_normals[mface->v3]);
if (mface->v4) {
v4 = mvert[mface->v4].co;
v4 = vert_positions[mface->v4];
copy_v3_v3(n4, vert_normals[mface->v4]);
interp_v3_v3v3v3v3(vec, v1, v2, v3, v4, w);
@@ -2159,8 +2161,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) {
const MVert *verts = BKE_mesh_verts(mesh_final);
copy_v3_v3(vec, verts[mapindex].co);
const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final);
copy_v3_v3(vec, vert_positions[mapindex]);
if (nor) {
copy_v3_v3(nor, vert_normals[mapindex]);
@@ -2184,11 +2186,10 @@ void psys_particle_on_dm(Mesh *mesh_final,
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
MFace *mface;
MTFace *mtface;
MVert *mvert;
MFace *mfaces = static_cast<MFace *>(CustomData_get_layer(&mesh_final->fdata, CD_MFACE));
mface = &mfaces[mapindex];
mvert = BKE_mesh_verts_for_write(mesh_final);
const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final);
mtface = static_cast<MTFace *>(CustomData_get_layer(&mesh_final->fdata, CD_MTFACE));
if (mtface) {
@@ -2197,7 +2198,7 @@ void psys_particle_on_dm(Mesh *mesh_final,
if (from == PART_FROM_VOLUME) {
psys_interpolate_face(mesh_final,
mvert,
vert_positions,
vert_normals,
mface,
mtface,
@@ -2220,7 +2221,7 @@ void psys_particle_on_dm(Mesh *mesh_final,
}
else {
psys_interpolate_face(mesh_final,
mvert,
vert_positions,
vert_normals,
mface,
mtface,
@@ -3670,7 +3671,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v,
BKE_defvert_weight_to_rgb(ca->col, pind.hkey[1]->weight);
}
else {
/* WARNING: copied from 'do_particle_interpolation' (without 'mvert' array stepping) */
/* WARNING: copied from 'do_particle_interpolation' (without 'vertex' array stepping) */
float real_t;
if (result.time < 0.0f) {
real_t = -result.time;
@@ -3910,10 +3911,10 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
}
}
else {
const MVert *verts = BKE_mesh_verts(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);
const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh);
copy_v3_v3(v[0], vert_positions[mface->v1]);
copy_v3_v3(v[1], vert_positions[mface->v2]);
copy_v3_v3(v[2], vert_positions[mface->v3]);
}
triatomat(v[0], v[1], v[2], (osface) ? osface->uv : nullptr, mat);
@@ -98,18 +98,15 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
{
ParticleData *pa = NULL;
float min[3], max[3], delta[3], d;
MVert *mv, *mvert = BKE_mesh_verts_for_write(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
int totvert = mesh->totvert, from = psys->part->from;
int i, j, k, p, res = psys->part->grid_res, size[3], axis;
/* find bounding box of dm */
if (totvert > 0) {
mv = mvert;
copy_v3_v3(min, mv->co);
copy_v3_v3(max, mv->co);
mv++;
for (i = 1; i < totvert; i++, mv++) {
minmax_v3v3_v3(min, max, mv->co);
INIT_MINMAX(min, max);
for (i = 1; i < totvert; i++) {
minmax_v3v3_v3(min, max, positions[i]);
}
}
else {
@@ -163,8 +160,8 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
min[1] -= d / 2.0f;
min[2] -= d / 2.0f;
for (i = 0, mv = mvert; i < totvert; i++, mv++) {
sub_v3_v3v3(vec, mv->co, min);
for (i = 0; i < totvert; i++) {
sub_v3_v3v3(vec, positions[i], min);
vec[0] /= delta[0];
vec[1] /= delta[1];
vec[2] /= delta[2];
@@ -221,9 +218,9 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
for (i = 0; i < totface; i++, mface++) {
ParticleData *pa1 = NULL, *pa2 = NULL;
copy_v3_v3(v1, mvert[mface->v1].co);
copy_v3_v3(v2, mvert[mface->v2].co);
copy_v3_v3(v3, mvert[mface->v3].co);
copy_v3_v3(v1, positions[mface->v1]);
copy_v3_v3(v2, positions[mface->v2]);
copy_v3_v3(v3, positions[mface->v3]);
bool intersects_tri = isect_ray_tri_watertight_v3(
co1, &isect_precalc, v1, v2, v3, &lambda, NULL);
@@ -232,7 +229,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
}
if (mface->v4 && (!intersects_tri || from == PART_FROM_VOLUME)) {
copy_v3_v3(v4, mvert[mface->v4].co);
copy_v3_v3(v4, positions[mface->v4]);
if (isect_ray_tri_watertight_v3(co1, &isect_precalc, v1, v3, v4, &lambda, NULL)) {
pa2 = (pa + (int)(lambda * size[a]) * a0mul);
@@ -570,14 +567,15 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
{
ParticleThreadContext *ctx = thread->ctx;
Mesh *mesh = ctx->mesh;
float *v1, *v2, *v3, *v4, nor[3], co[3];
const float *v1, *v2, *v3, *v4;
float nor[3], co[3];
float cur_d, min_d, randu, randv;
int distr = ctx->distr;
int i, intersect, tot;
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
MFace *mface;
MVert *mvert = BKE_mesh_verts_for_write(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
pa->num = i = ctx->index[p];
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
@@ -614,8 +612,18 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
/* experimental */
tot = mesh->totface;
psys_interpolate_face(
mesh, mvert, BKE_mesh_vertex_normals_ensure(mesh), mface, 0, 0, pa->fuv, co, nor, 0, 0, 0);
psys_interpolate_face(mesh,
positions,
BKE_mesh_vertex_normals_ensure(mesh),
mface,
0,
0,
pa->fuv,
co,
nor,
0,
0,
0);
normalize_v3(nor);
negate_v3(nor);
@@ -628,9 +636,9 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
continue;
}
v1 = mvert[mface->v1].co;
v2 = mvert[mface->v2].co;
v3 = mvert[mface->v3].co;
v1 = positions[mface->v1];
v2 = positions[mface->v2];
v3 = positions[mface->v3];
if (isect_ray_tri_v3(co, nor, v2, v3, v1, &cur_d, NULL)) {
if (cur_d < min_d) {
@@ -640,7 +648,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
}
}
if (mface->v4) {
v4 = mvert[mface->v4].co;
v4 = positions[mface->v4];
if (isect_ray_tri_v3(co, nor, v4, v1, v3, &cur_d, NULL)) {
if (cur_d < min_d) {
@@ -993,7 +1001,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
BKE_mesh_orco_ensure(ob, mesh);
if (from == PART_FROM_VERT) {
MVert *mv = BKE_mesh_verts_for_write(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const float(*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO);
int totvert = mesh->totvert;
@@ -1005,7 +1013,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
BKE_mesh_orco_verts_transform(ob->data, &co, 1, 1);
}
else {
copy_v3_v3(co, mv[p].co);
copy_v3_v3(co, positions[p]);
}
BLI_kdtree_3d_insert(tree, p, co);
}
@@ -1040,7 +1048,6 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
/* Calculate weights from face areas */
if ((part->flag & PART_EDISTR || children) && from != PART_FROM_VERT) {
MVert *v1, *v2, *v3, *v4;
float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3];
const float(*orcodata)[3];
@@ -1064,16 +1071,12 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
}
}
else {
MVert *verts = BKE_mesh_verts_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);
const float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
copy_v3_v3(co1, positions[mf->v1]);
copy_v3_v3(co2, positions[mf->v2]);
copy_v3_v3(co3, positions[mf->v3]);
if (mf->v4) {
v4 = &verts[mf->v4];
copy_v3_v3(co4, v4->co);
copy_v3_v3(co4, positions[mf->v4]);
}
}
@@ -2779,18 +2779,18 @@ void BKE_psys_collision_neartest_cb(void *userdata,
ParticleCollision *col = (ParticleCollision *)userdata;
ParticleCollisionElement pce;
const MVertTri *vt = &col->md->tri[index];
MVert *x = col->md->x;
MVert *v = col->md->current_v;
float(*x)[3] = col->md->x;
float(*v)[3] = col->md->current_v;
float t = hit->dist / col->original_ray_length;
int collision = 0;
pce.x[0] = x[vt->tri[0]].co;
pce.x[1] = x[vt->tri[1]].co;
pce.x[2] = x[vt->tri[2]].co;
pce.x[0] = x[vt->tri[0]];
pce.x[1] = x[vt->tri[1]];
pce.x[2] = x[vt->tri[2]];
pce.v[0] = v[vt->tri[0]].co;
pce.v[1] = v[vt->tri[1]].co;
pce.v[2] = v[vt->tri[2]].co;
pce.v[0] = v[vt->tri[0]];
pce.v[1] = v[vt->tri[1]];
pce.v[2] = v[vt->tri[2]];
pce.tot = 3;
pce.inside = 0;
@@ -3307,7 +3307,6 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
Mesh *mesh;
MVert *mvert;
MEdge *medge;
MDeformVert *dvert;
HairKey *key;
@@ -3321,7 +3320,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
if (!mesh) {
*r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0);
}
mvert = BKE_mesh_verts_for_write(mesh);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
medge = BKE_mesh_edges_for_write(mesh);
dvert = BKE_mesh_deform_verts_for_write(mesh);
@@ -3345,6 +3344,8 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
psys->clmd->sim_parms->vgroup_mass = 1;
int vert_index = 0;
/* XXX placeholder for more flexible future hair settings */
hair_radius = part->size;
@@ -3383,16 +3384,16 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
hair->radius = hair_radius;
hair->bending_stiffness = bending_stiffness;
add_v3_v3v3(mvert->co, co, co);
sub_v3_v3(mvert->co, co_next);
mul_m4_v3(hairmat, mvert->co);
add_v3_v3v3(positions[vert_index], co, co);
sub_v3_v3(positions[vert_index], co_next);
mul_m4_v3(hairmat, positions[vert_index]);
medge->v1 = pa->hair_index - 1;
medge->v2 = pa->hair_index;
dvert = hair_set_pinning(dvert, 1.0f);
mvert++;
vert_index++;
medge++;
}
@@ -3404,8 +3405,8 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
hair->radius = hair_radius;
hair->bending_stiffness = bending_stiffness;
copy_v3_v3(mvert->co, co);
mul_m4_v3(hairmat, mvert->co);
copy_v3_v3(positions[vert_index], co);
mul_m4_v3(hairmat, positions[vert_index]);
if (k) {
medge->v1 = pa->hair_index + k - 1;
@@ -3420,7 +3421,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
dvert = hair_set_pinning(dvert, 1.0f);
}
mvert++;
vert_index++;
if (k) {
medge++;
}
+35 -52
View File
@@ -674,7 +674,7 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
args->grid_hidden = pbvh->grid_hidden;
args->face_sets_color_default = pbvh->face_sets_color_default;
args->face_sets_color_seed = pbvh->face_sets_color_seed;
args->mvert = pbvh->verts;
args->vert_positions = pbvh->vert_positions;
args->mloop = pbvh->mloop;
args->mpoly = pbvh->mpoly;
args->mlooptri = pbvh->looptri;
@@ -811,7 +811,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
Mesh *mesh,
const MPoly *mpoly,
const MLoop *mloop,
MVert *verts,
float (*vert_positions)[3],
int totvert,
struct CustomData *vdata,
struct CustomData *ldata,
@@ -830,7 +830,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
&mesh->pdata, CD_PROP_INT32, "material_index");
pbvh->mloop = mloop;
pbvh->looptri = looptri;
pbvh->verts = verts;
pbvh->vert_positions = vert_positions;
BKE_mesh_vertex_normals_ensure(mesh);
pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh);
pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert");
@@ -867,7 +867,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
BB_reset((BB *)bbc);
for (int j = 0; j < sides; j++) {
BB_expand((BB *)bbc, verts[pbvh->mloop[lt->tri[j]].v].co);
BB_expand((BB *)bbc, vert_positions[pbvh->mloop[lt->tri[j]].v]);
}
BBC_update_centroid(bbc);
@@ -1024,10 +1024,10 @@ void BKE_pbvh_free(PBVH *pbvh)
}
if (pbvh->deformed) {
if (pbvh->verts) {
if (pbvh->vert_positions) {
/* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
MEM_freeN((void *)pbvh->verts);
MEM_freeN((void *)pbvh->vert_positions);
}
}
@@ -1392,7 +1392,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
/* Face normal and mask */
if (lt->poly != mpoly_prev) {
const MPoly *mp = &pbvh->mpoly[lt->poly];
BKE_mesh_calc_poly_normal(mp, &pbvh->mloop[mp->loopstart], pbvh->verts, fn);
BKE_mesh_calc_poly_normal(mp, &pbvh->mloop[mp->loopstart], pbvh->vert_positions, fn);
mpoly_prev = lt->poly;
}
@@ -1803,11 +1803,9 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
{
MVert *mvert;
const int *vert_indices;
int totvert, i;
BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
const int *vert_indices = BKE_pbvh_node_get_vert_indices(node);
if (pbvh->hide_vert == NULL) {
BKE_pbvh_node_fully_hidden_set(node, false);
@@ -2204,18 +2202,10 @@ int BKE_pbvh_num_faces(const PBVH *pbvh)
return 0;
}
void BKE_pbvh_node_get_verts(PBVH *pbvh,
PBVHNode *node,
const int **r_vert_indices,
MVert **r_verts)
{
if (r_vert_indices) {
*r_vert_indices = node->vert_indices;
}
const int *BKE_pbvh_node_get_vert_indices(PBVHNode *node)
if (r_verts) {
*r_verts = pbvh->verts;
}
{
return node->vert_indices;
}
void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert)
@@ -2526,7 +2516,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
int *r_active_face_index,
float *r_face_normal)
{
const MVert *vert = pbvh->verts;
const float(*positions)[3] = pbvh->vert_positions;
const MLoop *mloop = pbvh->mloop;
const int *faces = node->prim_indices;
int totface = node->totprim;
@@ -2550,9 +2540,9 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
}
else {
/* intersect with current coordinates */
co[0] = vert[mloop[lt->tri[0]].v].co;
co[1] = vert[mloop[lt->tri[1]].v].co;
co[2] = vert[mloop[lt->tri[2]].v].co;
co[0] = positions[mloop[lt->tri[0]].v];
co[1] = positions[mloop[lt->tri[1]].v];
co[2] = positions[mloop[lt->tri[2]].v];
}
if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
@@ -2836,7 +2826,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
float *depth,
float *dist_sq)
{
const MVert *vert = pbvh->verts;
const float(*positions)[3] = pbvh->vert_positions;
const MLoop *mloop = pbvh->mloop;
const int *faces = node->prim_indices;
int i, totface = node->totprim;
@@ -2864,9 +2854,9 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
/* intersect with current coordinates */
hit |= ray_face_nearest_tri(ray_start,
ray_normal,
vert[mloop[lt->tri[0]].v].co,
vert[mloop[lt->tri[1]].v].co,
vert[mloop[lt->tri[2]].v].co,
positions[mloop[lt->tri[0]].v],
positions[mloop[lt->tri[1]].v],
positions[mloop[lt->tri[2]].v],
depth,
dist_sq);
}
@@ -3187,15 +3177,9 @@ float (*BKE_pbvh_vert_coords_alloc(PBVH *pbvh))[3]
{
float(*vertCos)[3] = NULL;
if (pbvh->verts) {
MVert *mvert = pbvh->verts;
vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
float *co = (float *)vertCos;
for (int a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
copy_v3_v3(co, mvert->co);
}
if (pbvh->vert_positions) {
vertCos = MEM_malloc_arrayN(pbvh->totvert, sizeof(float[3]), __func__);
memcpy(vertCos, pbvh->vert_positions, sizeof(float[3]) * pbvh->totvert);
}
return vertCos;
@@ -3209,12 +3193,12 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int
}
if (!pbvh->deformed) {
if (pbvh->verts) {
if (pbvh->vert_positions) {
/* if pbvh is not already deformed, verts/faces points to the */
/* original data and applying new coords to this arrays would lead to */
/* unneeded deformation -- duplicate verts/faces to avoid this */
pbvh->verts = MEM_dupallocN(pbvh->verts);
pbvh->vert_positions = MEM_dupallocN(pbvh->vert_positions);
/* No need to dupalloc pbvh->looptri, this one is 'totally owned' by pbvh,
* it's never some mesh data. */
@@ -3222,13 +3206,13 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int
}
}
if (pbvh->verts) {
MVert *mvert = pbvh->verts;
if (pbvh->vert_positions) {
float(*positions)[3] = pbvh->vert_positions;
/* copy new verts coords */
for (int a = 0; a < pbvh->totvert; a++, mvert++) {
for (int a = 0; a < pbvh->totvert; a++) {
/* no need for float comparison here (memory is exactly equal or not) */
if (memcmp(mvert->co, vertCos[a], sizeof(float[3])) != 0) {
copy_v3_v3(mvert->co, vertCos[a]);
if (memcmp(positions[a], vertCos[a], sizeof(float[3])) != 0) {
copy_v3_v3(positions[a], vertCos[a]);
BKE_pbvh_vert_tag_update_normal(pbvh, BKE_pbvh_make_vref(a));
}
}
@@ -3333,15 +3317,13 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh)
void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
{
struct CCGElem **grids;
struct MVert *verts;
const int *vert_indices;
int *grid_indices;
int totgrid, gridsize, uniq_verts, totvert;
vi->grid = NULL;
vi->no = NULL;
vi->fno = NULL;
vi->mvert = NULL;
vi->vert_positions = NULL;
vi->vertex.i = 0LL;
vi->respect_hide = pbvh->respect_hide;
@@ -3352,7 +3334,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids);
BKE_pbvh_node_num_verts(pbvh, node, &uniq_verts, &totvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &verts);
const int *vert_indices = BKE_pbvh_node_get_vert_indices(node);
vi->key = pbvh->gridkey;
vi->grids = grids;
@@ -3367,7 +3349,8 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->totvert = uniq_verts;
}
vi->vert_indices = vert_indices;
vi->mverts = verts;
vi->vert_positions = pbvh->vert_positions;
vi->is_mesh = pbvh->vert_positions != NULL;
if (pbvh->header.type == PBVH_BMESH) {
BLI_gsetIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
@@ -3443,10 +3426,10 @@ void BKE_pbvh_parallel_range_settings(TaskParallelSettings *settings,
settings->use_threading = use_threading && totnode > 1;
}
MVert *BKE_pbvh_get_verts(const PBVH *pbvh)
float (*BKE_pbvh_get_vert_positions(const PBVH *pbvh))[3]
{
BLI_assert(pbvh->header.type == PBVH_FACES);
return pbvh->verts;
return pbvh->vert_positions;
}
const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]
@@ -15,7 +15,6 @@ extern "C" {
struct MLoop;
struct MLoopTri;
struct MPoly;
struct MVert;
/* Axis-aligned bounding box */
typedef struct {
@@ -56,7 +55,7 @@ struct PBVHNode {
int *prim_indices;
unsigned int totprim; /* Number of primitives inside prim_indices. */
/* Array of indices into the mesh's MVert array. Contains the
/* Array of indices into the mesh's vertex array. Contains the
* indices of all vertices used by faces that are within this
* node's bounding box.
*
@@ -158,7 +157,7 @@ struct PBVH {
/* NOTE: Normals are not `const` because they can be updated for drawing by sculpt code. */
float (*vert_normals)[3];
bool *hide_vert;
struct MVert *verts;
float (*vert_positions)[3];
const struct MPoly *mpoly;
bool *hide_poly;
/** Material indices. Only valid for polygon meshes. */
+14 -13
View File
@@ -359,12 +359,12 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob,
{
rbCollisionShape *shape = NULL;
Mesh *mesh = NULL;
MVert *mvert = NULL;
float(*positions)[3] = NULL;
int totvert = 0;
if (ob->type == OB_MESH && ob->data) {
mesh = rigidbody_get_mesh(ob);
mvert = (mesh) ? BKE_mesh_verts_for_write(mesh) : NULL;
positions = (mesh) ? BKE_mesh_vert_positions_for_write(mesh) : NULL;
totvert = (mesh) ? mesh->totvert : 0;
}
else {
@@ -372,7 +372,8 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob,
}
if (totvert) {
shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed);
shape = RB_shape_new_convex_hull(
(float *)positions, sizeof(float[3]), totvert, margin, can_embed);
}
else {
CLOG_ERROR(&LOG, "no vertices to define Convex Hull collision shape with");
@@ -401,7 +402,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
return NULL;
}
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = BKE_mesh_runtime_looptri_len(mesh);
@@ -419,12 +420,12 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
/* init mesh data for collision shape */
mdata = RB_trimesh_data_new(tottri, totvert);
RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert));
RB_trimesh_add_vertices(mdata, (float *)positions, totvert, sizeof(float[3]));
/* loop over all faces, adding them as triangles to the collision shape
* (so for some faces, more than triangle will get added)
*/
if (mvert && looptri) {
if (positions && looptri) {
for (i = 0; i < tottri; i++) {
/* add first triangle - verts 1,2,3 */
const MLoopTri *lt = &looptri[i];
@@ -676,14 +677,14 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
return;
}
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
totvert = mesh->totvert;
lt = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = BKE_mesh_runtime_looptri_len(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
BKE_mesh_calc_volume(positions, totvert, lt, tottri, mloop, &volume, NULL);
const float volume_scale = mat4_to_volume_scale(ob->object_to_world);
volume *= fabsf(volume_scale);
}
@@ -750,14 +751,14 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
return;
}
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = BKE_mesh_runtime_looptri_len(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
BKE_mesh_calc_volume(positions, totvert, looptri, tottri, mloop, NULL, r_center);
}
}
break;
@@ -1673,14 +1674,14 @@ 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 = BKE_mesh_verts_for_write(mesh);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
int totvert = mesh->totvert;
const BoundBox *bb = BKE_object_boundbox_get(ob);
RB_shape_trimesh_update(rbo->shared->physics_shape,
(float *)mvert,
(float *)positions,
totvert,
sizeof(MVert),
sizeof(float[3]),
bb->vec[0],
bb->vec[6]);
}
+26 -24
View File
@@ -59,7 +59,7 @@ struct ShrinkwrapCalcData {
Object *ob; /* object we are applying shrinkwrap to */
MVert *vert; /* Array of verts being projected. */
float (*vert_positions)[3]; /* Array of verts being projected. */
const float (*vert_normals)[3];
/* Vertices being shrink-wrapped. */
float (*vertexCos)[3];
@@ -188,7 +188,7 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
{
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MEdge *medge = BKE_mesh_edges(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
@@ -285,7 +285,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
const MEdge *edge = &medge[i];
float dir[3];
sub_v3_v3v3(dir, mvert[edge->v2].co, mvert[edge->v1].co);
sub_v3_v3v3(dir, positions[edge->v2], positions[edge->v1]);
normalize_v3(dir);
merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge->v1], dir, 1);
@@ -355,8 +355,8 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata,
}
/* Convert the vertex to tree coordinates */
if (calc->vert) {
copy_v3_v3(tmp_co, calc->vert[i].co);
if (calc->vert_positions) {
copy_v3_v3(tmp_co, calc->vert_positions[i]);
}
else {
copy_v3_v3(tmp_co, co);
@@ -517,12 +517,13 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
return;
}
if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
/* calc->vert contains verts from evaluated mesh. */
if (calc->vert_positions != nullptr &&
calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
/* calc->vert_positions contains verts from evaluated mesh. */
/* These coordinates are deformed by vertexCos only for normal projection
* (to get correct normals) for other cases calc->verts contains undeformed coordinates and
* vertexCos should be used */
copy_v3_v3(tmp_co, calc->vert[i].co);
copy_v3_v3(tmp_co, calc->vert_positions[i]);
copy_v3_v3(tmp_no, calc->vert_normals[i]);
}
else {
@@ -638,7 +639,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
/* Prepare data to retrieve the direction in which we should project each vertex */
if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
if (calc->vert == nullptr) {
if (calc->vert_positions == nullptr) {
return;
}
}
@@ -934,7 +935,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
{
const BVHTreeFromMesh *data = &tree->treeData;
const MEdge *edge = &data->edge[eidx];
const float *vedge_co[2] = {data->vert[edge->v1].co, data->vert[edge->v2].co};
const float *vedge_co[2] = {data->vert_positions[edge->v1], data->vert_positions[edge->v2]};
#ifdef TRACE_TARGET_PROJECT
printf("EDGE %d (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n",
@@ -1012,9 +1013,9 @@ static void mesh_looptri_target_project(void *userdata,
const MLoopTri *lt = &data->looptri[index];
const MLoop *loop[3] = {
&data->loop[lt->tri[0]], &data->loop[lt->tri[1]], &data->loop[lt->tri[2]]};
const MVert *vtri[3] = {
&data->vert[loop[0]->v], &data->vert[loop[1]->v], &data->vert[loop[2]->v]};
const float *vtri_co[3] = {vtri[0]->co, vtri[1]->co, vtri[2]->co};
const float *vtri_co[3] = {data->vert_positions[loop[0]->v],
data->vert_positions[loop[1]->v],
data->vert_positions[loop[2]->v]};
float raw_hit_co[3], hit_co[3], hit_no[3], dist_sq, vtri_no[3][3];
/* First find the closest point and bail out if it's worse than the current solution. */
@@ -1116,8 +1117,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat
}
/* Convert the vertex to tree coordinates */
if (calc->vert) {
copy_v3_v3(tmp_co, calc->vert[i].co);
if (calc->vert_positions) {
copy_v3_v3(tmp_co, calc->vert_positions[i]);
}
else {
copy_v3_v3(tmp_co, co);
@@ -1202,9 +1203,9 @@ void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree,
}
interp_weights_tri_v3(w,
treeData->vert[vert_indices[0]].co,
treeData->vert[vert_indices[1]].co,
treeData->vert[vert_indices[2]].co,
treeData->vert_positions[vert_indices[0]],
treeData->vert_positions[vert_indices[1]],
treeData->vert_positions[vert_indices[2]],
tmp_co);
/* Interpolate using weights. */
@@ -1405,8 +1406,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
calc.aux_target = DEG_get_evaluated_object(ctx->depsgraph, smd->auxTarget);
if (mesh != nullptr && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
/* Setup arrays to get vertices position, normals and deform weights. */
calc.vert = BKE_mesh_verts_for_write(mesh);
/* Setup arrays to get vertexs positions, normals and deform weights */
calc.vert_positions = BKE_mesh_vert_positions_for_write(mesh);
calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
/* Using vertices positions/normals as if a subsurface was applied */
@@ -1426,11 +1427,12 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
(ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : SubsurfFlags(0));
if (ss_mesh) {
calc.vert = static_cast<MVert *>(ss_mesh->getVertDataArray(ss_mesh, CD_MVERT));
if (calc.vert) {
calc.vert_positions = reinterpret_cast<float(*)[3]>(ss_mesh->getVertArray(ss_mesh));
if (calc.vert_positions) {
/* TRICKY: this code assumes subsurface will have the transformed original vertices
* in their original order at the end of the vert array. */
calc.vert = calc.vert + ss_mesh->getNumVerts(ss_mesh) - dm->getNumVerts(dm);
calc.vert_positions = calc.vert_positions + ss_mesh->getNumVerts(ss_mesh) -
dm->getNumVerts(dm);
}
}
@@ -1571,7 +1573,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 = BKE_mesh_verts_for_write(src_me);
calc.vert_positions = BKE_mesh_vert_positions_for_write(src_me);
BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob_target, ob_target);
ShrinkwrapTreeData tree;
+80 -80
View File
@@ -255,8 +255,8 @@ typedef struct ccdf_minmax {
typedef struct ccd_Mesh {
int mvert_num, tri_num;
const MVert *mvert;
const MVert *mprevvert;
const float (*vert_positions)[3];
const float (*vert_positions_prev)[3];
const MVertTri *tri;
int safety;
ccdf_minmax *mima;
@@ -290,20 +290,20 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
pccd_M->safety = CCD_SAFETY;
pccd_M->bbmin[0] = pccd_M->bbmin[1] = pccd_M->bbmin[2] = 1e30f;
pccd_M->bbmax[0] = pccd_M->bbmax[1] = pccd_M->bbmax[2] = -1e30f;
pccd_M->mprevvert = NULL;
pccd_M->vert_positions_prev = NULL;
/* Blow it up with force-field ranges. */
hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
/* Allocate and copy verts. */
pccd_M->mvert = MEM_dupallocN(cmd->xnew);
pccd_M->vert_positions = MEM_dupallocN(cmd->xnew);
/* note that xnew coords are already in global space, */
/* determine the ortho BB */
for (i = 0; i < pccd_M->mvert_num; i++) {
const float *v;
/* evaluate limits */
v = pccd_M->mvert[i].co;
v = pccd_M->vert_positions[i];
pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
@@ -325,7 +325,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
mima->minx = mima->miny = mima->minz = 1e30f;
mima->maxx = mima->maxy = mima->maxz = -1e30f;
v = pccd_M->mvert[vt->tri[0]].co;
v = pccd_M->vert_positions[vt->tri[0]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -333,7 +333,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
v = pccd_M->mvert[vt->tri[1]].co;
v = pccd_M->vert_positions[vt->tri[1]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -341,7 +341,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
v = pccd_M->mvert[vt->tri[2]].co;
v = pccd_M->vert_positions[vt->tri[2]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -381,19 +381,19 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
/* rotate current to previous */
if (pccd_M->mprevvert) {
MEM_freeN((void *)pccd_M->mprevvert);
if (pccd_M->vert_positions_prev) {
MEM_freeN((void *)pccd_M->vert_positions_prev);
}
pccd_M->mprevvert = pccd_M->mvert;
pccd_M->vert_positions_prev = pccd_M->vert_positions;
/* Allocate and copy verts. */
pccd_M->mvert = MEM_dupallocN(cmd->xnew);
pccd_M->vert_positions = MEM_dupallocN(cmd->xnew);
/* note that xnew coords are already in global space, */
/* determine the ortho BB */
for (i = 0; i < pccd_M->mvert_num; i++) {
const float *v;
/* evaluate limits */
v = pccd_M->mvert[i].co;
v = pccd_M->vert_positions[i];
pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
@@ -403,7 +403,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
/* evaluate limits */
v = pccd_M->mprevvert[i].co;
v = pccd_M->vert_positions_prev[i];
pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
@@ -420,8 +420,8 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->minx = mima->miny = mima->minz = 1e30f;
mima->maxx = mima->maxy = mima->maxz = -1e30f;
/* mvert */
v = pccd_M->mvert[vt->tri[0]].co;
/* vert_positions */
v = pccd_M->vert_positions[vt->tri[0]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -429,7 +429,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
v = pccd_M->mvert[vt->tri[1]].co;
v = pccd_M->vert_positions[vt->tri[1]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -437,7 +437,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
v = pccd_M->mvert[vt->tri[2]].co;
v = pccd_M->vert_positions[vt->tri[2]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -445,8 +445,8 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
/* mprevvert */
v = pccd_M->mprevvert[vt->tri[0]].co;
/* vert_positions_prev */
v = pccd_M->vert_positions_prev[vt->tri[0]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -454,7 +454,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
v = pccd_M->mprevvert[vt->tri[1]].co;
v = pccd_M->vert_positions_prev[vt->tri[1]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -462,7 +462,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
v = pccd_M->mprevvert[vt->tri[2]].co;
v = pccd_M->vert_positions_prev[vt->tri[2]];
mima->minx = min_ff(mima->minx, v[0] - hull);
mima->miny = min_ff(mima->miny, v[1] - hull);
mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -476,10 +476,10 @@ static void ccd_mesh_free(ccd_Mesh *ccdm)
{
/* Make sure we're not nuking objects we don't know. */
if (ccdm && (ccdm->safety == CCD_SAFETY)) {
MEM_freeN((void *)ccdm->mvert);
MEM_freeN((void *)ccdm->vert_positions);
MEM_freeN((void *)ccdm->tri);
if (ccdm->mprevvert) {
MEM_freeN((void *)ccdm->mprevvert);
if (ccdm->vert_positions_prev) {
MEM_freeN((void *)ccdm->vert_positions_prev);
}
MEM_freeN(ccdm->mima);
MEM_freeN(ccdm);
@@ -1068,12 +1068,12 @@ static int sb_detect_face_pointCached(const float face_v1[3],
{
/* only with deflecting set */
if (ob->pd && ob->pd->deflect) {
const MVert *mvert = NULL;
const MVert *mprevvert = NULL;
const float(*vert_positions)[3] = NULL;
const float(*vert_positions_prev)[3] = NULL;
if (ccdm) {
mvert = ccdm->mvert;
vert_positions = ccdm->vert_positions;
a = ccdm->mvert_num;
mprevvert = ccdm->mprevvert;
vert_positions_prev = ccdm->vert_positions_prev;
outerfacethickness = ob->pd->pdef_sboft;
if ((aabbmax[0] < ccdm->bbmin[0]) || (aabbmax[1] < ccdm->bbmin[1]) ||
(aabbmax[2] < ccdm->bbmin[2]) || (aabbmin[0] > ccdm->bbmax[0]) ||
@@ -1091,12 +1091,12 @@ static int sb_detect_face_pointCached(const float face_v1[3],
}
/* Use mesh. */
if (mvert) {
if (vert_positions) {
while (a) {
copy_v3_v3(nv1, mvert[a - 1].co);
if (mprevvert) {
copy_v3_v3(nv1, vert_positions[a - 1]);
if (vert_positions_prev) {
mul_v3_fl(nv1, time);
madd_v3_v3fl(nv1, mprevvert[a - 1].co, 1.0f - time);
madd_v3_v3fl(nv1, vert_positions_prev[a - 1], 1.0f - time);
}
/* Origin to face_v2. */
sub_v3_v3(nv1, face_v2);
@@ -1120,7 +1120,7 @@ static int sb_detect_face_pointCached(const float face_v1[3],
}
a--;
} /* while (a) */
} /* if (mvert) */
} /* if (vert_positions) */
} /* if (ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
}
@@ -1160,15 +1160,15 @@ static int sb_detect_face_collisionCached(const float face_v1[3],
{
/* only with deflecting set */
if (ob->pd && ob->pd->deflect) {
const MVert *mvert = NULL;
const MVert *mprevvert = NULL;
const float(*vert_positions)[3] = NULL;
const float(*vert_positions_prev)[3] = NULL;
const MVertTri *vt = NULL;
const ccdf_minmax *mima = NULL;
if (ccdm) {
mvert = ccdm->mvert;
vert_positions = ccdm->vert_positions;
vt = ccdm->tri;
mprevvert = ccdm->mprevvert;
vert_positions_prev = ccdm->vert_positions_prev;
mima = ccdm->mima;
a = ccdm->tri_num;
@@ -1197,21 +1197,21 @@ static int sb_detect_face_collisionCached(const float face_v1[3],
continue;
}
if (mvert) {
if (vert_positions) {
copy_v3_v3(nv1, mvert[vt->tri[0]].co);
copy_v3_v3(nv2, mvert[vt->tri[1]].co);
copy_v3_v3(nv3, mvert[vt->tri[2]].co);
copy_v3_v3(nv1, vert_positions[vt->tri[0]]);
copy_v3_v3(nv2, vert_positions[vt->tri[1]]);
copy_v3_v3(nv3, vert_positions[vt->tri[2]]);
if (mprevvert) {
if (vert_positions_prev) {
mul_v3_fl(nv1, time);
madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
madd_v3_v3fl(nv1, vert_positions_prev[vt->tri[0]], 1.0f - time);
mul_v3_fl(nv2, time);
madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
madd_v3_v3fl(nv2, vert_positions_prev[vt->tri[1]], 1.0f - time);
mul_v3_fl(nv3, time);
madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
madd_v3_v3fl(nv3, vert_positions_prev[vt->tri[2]], 1.0f - time);
}
}
@@ -1336,14 +1336,14 @@ static int sb_detect_edge_collisionCached(const float edge_v1[3],
{
/* only with deflecting set */
if (ob->pd && ob->pd->deflect) {
const MVert *mvert = NULL;
const MVert *mprevvert = NULL;
const float(*vert_positions)[3] = NULL;
const float(*vert_positions_prev)[3] = NULL;
const MVertTri *vt = NULL;
const ccdf_minmax *mima = NULL;
if (ccdm) {
mvert = ccdm->mvert;
mprevvert = ccdm->mprevvert;
vert_positions = ccdm->vert_positions;
vert_positions_prev = ccdm->vert_positions_prev;
vt = ccdm->tri;
mima = ccdm->mima;
a = ccdm->tri_num;
@@ -1373,21 +1373,21 @@ static int sb_detect_edge_collisionCached(const float edge_v1[3],
continue;
}
if (mvert) {
if (vert_positions) {
copy_v3_v3(nv1, mvert[vt->tri[0]].co);
copy_v3_v3(nv2, mvert[vt->tri[1]].co);
copy_v3_v3(nv3, mvert[vt->tri[2]].co);
copy_v3_v3(nv1, vert_positions[vt->tri[0]]);
copy_v3_v3(nv2, vert_positions[vt->tri[1]]);
copy_v3_v3(nv3, vert_positions[vt->tri[2]]);
if (mprevvert) {
if (vert_positions_prev) {
mul_v3_fl(nv1, time);
madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
madd_v3_v3fl(nv1, vert_positions_prev[vt->tri[0]], 1.0f - time);
mul_v3_fl(nv2, time);
madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
madd_v3_v3fl(nv2, vert_positions_prev[vt->tri[1]], 1.0f - time);
mul_v3_fl(nv3, time);
madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
madd_v3_v3fl(nv3, vert_positions_prev[vt->tri[2]], 1.0f - time);
}
}
@@ -1635,14 +1635,14 @@ static int sb_detect_vertex_collisionCached(float opco[3],
{
/* only with deflecting set */
if (ob->pd && ob->pd->deflect) {
const MVert *mvert = NULL;
const MVert *mprevvert = NULL;
const float(*vert_positions)[3] = NULL;
const float(*vert_positions_prev)[3] = NULL;
const MVertTri *vt = NULL;
const ccdf_minmax *mima = NULL;
if (ccdm) {
mvert = ccdm->mvert;
mprevvert = ccdm->mprevvert;
vert_positions = ccdm->vert_positions;
vert_positions_prev = ccdm->vert_positions_prev;
vt = ccdm->tri;
mima = ccdm->mima;
a = ccdm->tri_num;
@@ -1686,30 +1686,30 @@ static int sb_detect_vertex_collisionCached(float opco[3],
continue;
}
if (mvert) {
if (vert_positions) {
copy_v3_v3(nv1, mvert[vt->tri[0]].co);
copy_v3_v3(nv2, mvert[vt->tri[1]].co);
copy_v3_v3(nv3, mvert[vt->tri[2]].co);
copy_v3_v3(nv1, vert_positions[vt->tri[0]]);
copy_v3_v3(nv2, vert_positions[vt->tri[1]]);
copy_v3_v3(nv3, vert_positions[vt->tri[2]]);
if (mprevvert) {
if (vert_positions_prev) {
/* Grab the average speed of the collider vertices before we spoil nvX
* humm could be done once a SB steps but then we' need to store that too
* since the AABB reduced probability to get here drastically
* it might be a nice tradeoff CPU <--> memory.
*/
sub_v3_v3v3(vv1, nv1, mprevvert[vt->tri[0]].co);
sub_v3_v3v3(vv2, nv2, mprevvert[vt->tri[1]].co);
sub_v3_v3v3(vv3, nv3, mprevvert[vt->tri[2]].co);
sub_v3_v3v3(vv1, nv1, vert_positions_prev[vt->tri[0]]);
sub_v3_v3v3(vv2, nv2, vert_positions_prev[vt->tri[1]]);
sub_v3_v3v3(vv3, nv3, vert_positions_prev[vt->tri[2]]);
mul_v3_fl(nv1, time);
madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
madd_v3_v3fl(nv1, vert_positions_prev[vt->tri[0]], 1.0f - time);
mul_v3_fl(nv2, time);
madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
madd_v3_v3fl(nv2, vert_positions_prev[vt->tri[1]], 1.0f - time);
mul_v3_fl(nv3, time);
madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
madd_v3_v3fl(nv3, vert_positions_prev[vt->tri[2]], 1.0f - time);
}
}
@@ -1743,7 +1743,7 @@ static int sb_detect_vertex_collisionCached(float opco[3],
deflected = 2;
}
}
if ((mprevvert) && (*damp > 0.0f)) {
if ((vert_positions_prev) && (*damp > 0.0f)) {
choose_winner(ve, opco, nv1, nv2, nv3, vv1, vv2, vv3);
add_v3_v3(avel, ve);
cavel++;
@@ -2632,18 +2632,18 @@ static void springs_from_mesh(Object *ob)
BodyPoint *bp;
int a;
float scale = 1.0f;
const MVert *verts = BKE_mesh_verts(me);
const float(*vert_positions)[3] = BKE_mesh_vert_positions(me);
sb = ob->soft;
if (me && sb) {
/* using bp->origS as a container for spring calculations here
* will be overwritten sbObjectStep() to receive
* actual modifier stack positions
* actual modifier stack vert_positions
*/
if (me->totvert) {
bp = ob->soft->bpoint;
for (a = 0; a < me->totvert; a++, bp++) {
copy_v3_v3(bp->origS, verts[a].co);
copy_v3_v3(bp->origS, vert_positions[a]);
mul_m4_v3(ob->object_to_world, bp->origS);
}
}
@@ -2755,7 +2755,7 @@ static void mesh_faces_to_scratch(Object *ob)
MLoopTri *looptri, *lt;
BodyFace *bodyface;
int a;
const MVert *verts = BKE_mesh_verts(me);
const float(*vert_positions)[3] = BKE_mesh_vert_positions(me);
const MPoly *polys = BKE_mesh_polys(me);
const MLoop *loops = BKE_mesh_loops(me);
@@ -2763,7 +2763,7 @@ static void mesh_faces_to_scratch(Object *ob)
sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop);
looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__);
BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri);
BKE_mesh_recalc_looptri(loops, polys, vert_positions, me->totloop, me->totpoly, looptri);
bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface,
"SB_body_Faces");
@@ -3564,7 +3564,7 @@ void sbObjectStep(struct Depsgraph *depsgraph,
if (framenr == startframe) {
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
/* first frame, no simulation to do, just set the positions */
/* first frame, no simulation to do, just set the vert_positions */
softbody_update_positions(ob, sb, vertexCos, numVerts);
BKE_ptcache_validate(cache, framenr);
@@ -34,7 +34,7 @@
typedef struct ConverterStorage {
SubdivSettings settings;
const Mesh *mesh;
const MVert *verts;
const float (*vert_positions)[3];
const MEdge *edges;
const MPoly *polys;
const MLoop *loops;
@@ -395,7 +395,7 @@ 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_verts(mesh);
user_data->vert_positions = BKE_mesh_vert_positions(mesh);
user_data->edges = BKE_mesh_edges(mesh);
user_data->polys = BKE_mesh_polys(mesh);
user_data->loops = BKE_mesh_loops(mesh);
@@ -81,7 +81,7 @@ static void set_coarse_positions(Subdiv *subdiv,
const Mesh *mesh,
const float (*coarse_vertex_cos)[3])
{
const MVert *mvert = BKE_mesh_verts(mesh);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
/* Mark vertices which needs new coordinates. */
@@ -109,8 +109,7 @@ static void set_coarse_positions(Subdiv *subdiv,
vertex_co = coarse_vertex_cos[vertex_index];
}
else {
const MVert *vertex = &mvert[vertex_index];
vertex_co = vertex->co;
vertex_co = positions[vertex_index];
}
copy_v3_v3(&buffer[manifold_vertex_index][0], vertex_co);
manifold_vertex_index++;
+42 -54
View File
@@ -28,6 +28,7 @@
#include "MEM_guardedalloc.h"
using blender::float3;
using blender::Span;
/* -------------------------------------------------------------------- */
@@ -37,14 +38,14 @@ using blender::Span;
struct SubdivMeshContext {
const SubdivToMeshSettings *settings;
const Mesh *coarse_mesh;
const MVert *coarse_verts;
const float (*coarse_positions)[3];
const MEdge *coarse_edges;
const MPoly *coarse_polys;
const MLoop *coarse_loops;
Subdiv *subdiv;
Mesh *subdiv_mesh;
MVert *subdiv_verts;
float3 *subdiv_positions;
MEdge *subdiv_edges;
MPoly *subdiv_polys;
MLoop *subdiv_loops;
@@ -83,7 +84,7 @@ 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_verts_for_write(subdiv_mesh);
ctx->subdiv_positions = subdiv_mesh->vert_positions_for_write().data();
ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh);
ctx->subdiv_polys = BKE_mesh_polys_for_write(subdiv_mesh);
ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh);
@@ -485,18 +486,17 @@ static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx,
const int ptex_face_index,
const float u,
const float v,
MVert *subdiv_vert)
const int subdiv_vertex_index)
{
/* Accumulate displacement. */
Subdiv *subdiv = ctx->subdiv;
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);
/* NOTE: The subdivided mesh is allocated in this module, and its vertices are kept at zero
* locations as a default calloc(). */
BKE_subdiv_eval_displacement(subdiv, ptex_face_index, u, v, dPdu, dPdv, D);
add_v3_v3(subdiv_vert->co, D);
ctx->subdiv_positions[subdiv_vertex_index] += D;
if (ctx->accumulated_counters) {
++ctx->accumulated_counters[subdiv_vertex_index];
@@ -543,23 +543,20 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
* \{ */
static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx,
const MVert *coarse_vertex,
MVert *subdiv_vertex)
const int coarse_vertex_index,
const int subdiv_vertex_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
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);
}
static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx,
MVert *subdiv_vertex,
const int subdiv_vertex_index,
const VerticesForInterpolation *vertex_interpolation,
const float u,
const float v)
{
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,
@@ -577,23 +574,23 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
const int ptex_face_index,
const float u,
const float v,
const MVert *coarse_vert,
MVert *subdiv_vert)
const int coarse_vertex_index,
const int subdiv_vertex_index)
{
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
float3 &subdiv_position = ctx->subdiv_positions[subdiv_vertex_index];
/* 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};
if (ctx->have_displacement) {
const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index];
copy_v3_v3(D, subdiv_vert->co);
copy_v3_v3(D, subdiv_position);
mul_v3_fl(D, inv_num_accumulated);
}
/* Copy custom data and evaluate position. */
subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert);
BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
subdiv_vertex_data_copy(ctx, coarse_vertex_index, subdiv_vertex_index);
BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_position);
/* Apply displacement. */
add_v3_v3(subdiv_vert->co, D);
subdiv_position += D;
/* Evaluate undeformed texture coordinate. */
subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
/* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */
@@ -606,22 +603,22 @@ static void evaluate_vertex_and_apply_displacement_interpolate(
const float u,
const float v,
VerticesForInterpolation *vertex_interpolation,
MVert *subdiv_vert)
const int subdiv_vertex_index)
{
const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
float3 &subdiv_position = ctx->subdiv_positions[subdiv_vertex_index];
/* 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};
if (ctx->have_displacement) {
const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index];
copy_v3_v3(D, subdiv_vert->co);
copy_v3_v3(D, subdiv_position);
mul_v3_fl(D, inv_num_accumulated);
}
/* Interpolate custom data and evaluate position. */
subdiv_vertex_data_interpolate(ctx, subdiv_vert, vertex_interpolation, u, v);
BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
subdiv_vertex_data_interpolate(ctx, subdiv_vertex_index, vertex_interpolation, u, v);
BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_position);
/* Apply displacement. */
add_v3_v3(subdiv_vert->co, D);
add_v3_v3(subdiv_position, D);
/* Evaluate undeformed texture coordinate. */
subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
}
@@ -635,8 +632,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);
MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert);
subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vertex_index);
}
static void subdiv_mesh_vertex_displacement_every_corner(
@@ -680,10 +676,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 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);
ctx, ptex_face_index, u, v, coarse_vertex_index, subdiv_vertex_index);
}
static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx,
@@ -727,10 +721,9 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
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);
ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vertex_index);
}
static bool subdiv_mesh_is_center_vertex(const MPoly *coarse_poly, const float u, const float v)
@@ -773,10 +766,10 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
Subdiv *subdiv = ctx->subdiv;
const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
float3 &subdiv_position = ctx->subdiv_positions[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);
subdiv_vertex_data_interpolate(ctx, subdiv_vertex_index, &tls->vertex_interpolation, u, v);
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_position);
subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vertex_index, u, v, subdiv_mesh);
subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
}
@@ -966,9 +959,7 @@ 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 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);
subdiv_vertex_data_copy(ctx, coarse_vertex_index, subdiv_vertex_index);
}
/* Get neighbor edges of the given one.
@@ -1012,21 +1003,21 @@ static void find_edge_neighbors(const MEdge *coarse_edges,
}
}
static void points_for_loose_edges_interpolation_get(const MVert *coarse_mvert,
static void points_for_loose_edges_interpolation_get(const float (*coarse_positions)[3],
const MEdge *coarse_edge,
const MEdge *neighbors[2],
float points_r[4][3])
{
/* 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);
copy_v3_v3(points_r[1], coarse_positions[coarse_edge->v1]);
copy_v3_v3(points_r[2], coarse_positions[coarse_edge->v2]);
/* Start point, duplicate from edge start if no neighbor. */
if (neighbors[0] != nullptr) {
if (neighbors[0]->v1 == coarse_edge->v1) {
copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co);
copy_v3_v3(points_r[0], coarse_positions[neighbors[0]->v2]);
}
else {
copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v1].co);
copy_v3_v3(points_r[0], coarse_positions[neighbors[0]->v1]);
}
}
else {
@@ -1036,10 +1027,10 @@ static void points_for_loose_edges_interpolation_get(const MVert *coarse_mvert,
/* End point, duplicate from edge end if no neighbor. */
if (neighbors[1] != nullptr) {
if (neighbors[1]->v1 == coarse_edge->v2) {
copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co);
copy_v3_v3(points_r[3], coarse_positions[neighbors[1]->v2]);
}
else {
copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v1].co);
copy_v3_v3(points_r[3], coarse_positions[neighbors[1]->v1]);
}
}
else {
@@ -1048,7 +1039,7 @@ static void points_for_loose_edges_interpolation_get(const MVert *coarse_mvert,
}
}
void BKE_subdiv_mesh_interpolate_position_on_edge(const MVert *coarse_verts,
void BKE_subdiv_mesh_interpolate_position_on_edge(const float (*coarse_positions)[3],
const MEdge *coarse_edges,
const MeshElemMap *vert_to_edge_map,
const int coarse_edge_index,
@@ -1058,16 +1049,14 @@ void BKE_subdiv_mesh_interpolate_position_on_edge(const MVert *coarse_verts,
{
const MEdge *coarse_edge = &coarse_edges[coarse_edge_index];
if (is_simple) {
const MVert *vert_1 = &coarse_verts[coarse_edge->v1];
const MVert *vert_2 = &coarse_verts[coarse_edge->v2];
interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u);
interp_v3_v3v3(pos_r, coarse_positions[coarse_edge->v1], coarse_positions[coarse_edge->v2], u);
}
else {
/* Find neighbors of the coarse edge. */
const MEdge *neighbors[2];
find_edge_neighbors(coarse_edges, vert_to_edge_map, coarse_edge_index, neighbors);
float points[4][3];
points_for_loose_edges_interpolation_get(coarse_verts, coarse_edge, neighbors, points);
points_for_loose_edges_interpolation_get(coarse_positions, coarse_edge, neighbors, points);
float weights[4];
key_curve_position_weights(u, weights, KEY_BSPLINE);
interp_v3_v3v3v3v3(pos_r, points[0], points[1], points[2], points[3], weights);
@@ -1128,14 +1117,13 @@ 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 = &ctx->subdiv_verts[subdiv_vertex_index];
BKE_subdiv_mesh_interpolate_position_on_edge(ctx->coarse_verts,
BKE_subdiv_mesh_interpolate_position_on_edge(ctx->coarse_positions,
ctx->coarse_edges,
ctx->vert_to_edge_map,
coarse_edge_index,
is_simple,
u,
subdiv_vertex->co);
ctx->subdiv_positions[subdiv_vertex_index]);
}
/** \} */
@@ -1196,7 +1184,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
subdiv_context.settings = settings;
subdiv_context.coarse_mesh = coarse_mesh;
subdiv_context.coarse_verts = BKE_mesh_verts(coarse_mesh);
subdiv_context.coarse_positions = BKE_mesh_vert_positions(coarse_mesh);
subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh);
subdiv_context.coarse_polys = BKE_mesh_polys(coarse_mesh);
subdiv_context.coarse_loops = BKE_mesh_loops(coarse_mesh);
+11 -13
View File
@@ -562,9 +562,8 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
CCGVertHDL *fVerts = NULL;
BLI_array_declare(fVerts);
#endif
MVert *mvert = dm->getVertArray(dm);
float(*positions)[3] = (float(*)[3])dm->getVertArray(dm);
MEdge *medge = dm->getEdgeArray(dm);
MVert *mv;
MEdge *me;
MLoop *mloop = dm->getLoopArray(dm), *ml;
MPoly *mpoly = dm->getPolyArray(dm), *mp;
@@ -575,16 +574,15 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
ccgSubSurf_initFullSync(ss);
mv = mvert;
index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
for (i = 0; i < totvert; i++, mv++) {
for (i = 0; i < totvert; i++) {
CCGVert *v;
if (vertexCos) {
ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v);
}
else {
ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v);
ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), positions[i], 0, &v);
}
((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
@@ -877,12 +875,12 @@ static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
}
/* utility function */
BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
BLI_INLINE void ccgDM_to_MVert(float mv[3], const CCGKey *key, CCGElem *elem)
{
copy_v3_v3(mv->co, CCG_elem_co(key, elem));
copy_v3_v3(mv, CCG_elem_co(key, elem));
}
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3])
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGSubSurf *ss = ccgdm->ss;
@@ -902,12 +900,12 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
vd = ccgSubSurf_getFaceCenterData(f);
ccgDM_to_MVert(&mvert[i++], &key, vd);
ccgDM_to_MVert(r_positions[i++], &key, vd);
for (S = 0; S < numVerts; S++) {
for (x = 1; x < gridSize - 1; x++) {
vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
ccgDM_to_MVert(&mvert[i++], &key, vd);
ccgDM_to_MVert(r_positions[i++], &key, vd);
}
}
@@ -915,7 +913,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
for (y = 1; y < gridSize - 1; y++) {
for (x = 1; x < gridSize - 1; x++) {
vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
ccgDM_to_MVert(&mvert[i++], &key, vd);
ccgDM_to_MVert(r_positions[i++], &key, vd);
}
}
}
@@ -931,7 +929,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
* unit length. This is most likely caused by edges with no faces which are now zeroed out,
* see comment in: `ccgSubSurf__calcVertNormals()`. */
vd = ccgSubSurf_getEdgeData(ss, e, x);
ccgDM_to_MVert(&mvert[i++], &key, vd);
ccgDM_to_MVert(r_positions[i++], &key, vd);
}
}
@@ -940,7 +938,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
CCGVert *v = ccgdm->vertMap[index].vert;
vd = ccgSubSurf_getVertData(ss, v);
ccgDM_to_MVert(&mvert[i++], &key, vd);
ccgDM_to_MVert(r_positions[i++], &key, vd);
}
}
@@ -113,15 +113,12 @@ void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
const int vert_offset,
const int poly_offset,
const int loop_offset,
MutableSpan<MVert> verts,
MutableSpan<float3> vert_positions,
MutableSpan<MPoly> polys,
MutableSpan<MLoop> loops)
{
/* Write vertices. */
for (const int i : vdb_verts.index_range()) {
const blender::float3 co = blender::float3(vdb_verts[i].asV());
copy_v3_v3(verts[vert_offset + i].co, co);
}
vert_positions.slice(vert_offset, vdb_verts.size()).copy_from(vdb_verts.cast<float3>());
/* Write triangles. */
for (const int i : vdb_tris.index_range()) {
@@ -178,7 +175,7 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid,
0,
0,
0,
mesh->verts_for_write(),
mesh->vert_positions_for_write(),
mesh->polys_for_write(),
mesh->loops_for_write());
@@ -996,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 *verts = BKE_mesh_verts_for_write(me);
MVert *verts = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT);
for (a = 0; a < tot; a++, data += 3) {
copy_v3_v3(verts[a].co, data);
copy_v3_v3(verts[a].co_legacy, data);
}
}
}
@@ -822,7 +822,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mp->totloop == 2) {
bool changed;
BKE_mesh_validate_arrays(me,
BKE_mesh_verts_for_write(me),
BKE_mesh_vert_positions_for_write(me),
me->totvert,
BKE_mesh_edges_for_write(me),
me->totedge,
@@ -33,6 +33,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
BKE_mesh_legacy_bevel_weight_to_layers(&mesh);
BKE_mesh_legacy_face_set_to_generic(&mesh);
BKE_mesh_legacy_edge_crease_to_layers(&mesh);
BKE_mesh_legacy_convert_verts_to_positions(&mesh);
BKE_mesh_legacy_attribute_flags_to_strings(&mesh);
}
@@ -37,7 +37,7 @@
* But basics are as follows.
*
* - Vertex locations (possibly modified from initial active key-block)
* are copied directly into #MVert.co
* are copied directly into the mesh position attribute.
* (special confusing note that these may be restored later, when editing the 'Basis', read on).
* - if the 'Key' is relative, and the active key-block is the basis for ANY other key-blocks -
* get an array of offsets between the new vertex locations and the original shape key
@@ -105,6 +105,7 @@
static CLG_LogRef LOG = {"bmesh.mesh.convert"};
using blender::Array;
using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
@@ -303,11 +304,11 @@ 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->verts();
const Span<float3> positions = me->vert_positions();
Array<BMVert *> vtable(me->totvert);
for (const int i : mvert.index_range()) {
for (const int i : positions.index_range()) {
BMVert *v = vtable[i] = BM_vert_create(
bm, keyco ? keyco[i] : mvert[i].co, nullptr, BM_CREATE_SKIP_CD);
bm, keyco ? keyco[i] : positions[i], nullptr, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
if (hide_vert && hide_vert[i]) {
@@ -614,16 +615,16 @@ static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey)
*
* \param bm: The source BMesh.
* \param key: The destination key.
* \param mvert: The destination vertex array (in some situations it's coordinates are updated).
* \param positions: The destination vertex array (in some situations its coordinates are updated).
* \param active_shapekey_to_mvert: When editing a non-basis shape key, the coordinates for the
* basis are typically copied into the `mvert` array since it makes sense for the meshes
* basis are typically copied into the `positions` array since it makes sense for the meshes
* vertex coordinates to match the "Basis" key.
* When enabled, skip this step and copy #BMVert.co directly to #MVert.co,
* When enabled, skip this step and copy #BMVert.co directly to the mesh position.
* See #BMeshToMeshParams.active_shapekey_to_mvert doc-string.
*/
static void bm_to_mesh_shape(BMesh *bm,
Key *key,
MutableSpan<MVert> mvert,
MutableSpan<float3> positions,
const bool active_shapekey_to_mvert)
{
KeyBlock *actkey = static_cast<KeyBlock *>(BLI_findlink(&key->block, bm->shapenr - 1));
@@ -685,7 +686,7 @@ static void bm_to_mesh_shape(BMesh *bm,
/* Check the vertex existed when entering edit-mode (otherwise don't apply an offset). */
if (keyi != ORIGINDEX_NONE) {
float *co_orig = (float *)BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset);
/* Could use 'eve->co' or the destination #MVert.co, they're the same at this point. */
/* Could use 'eve->co' or the destination position, they're the same at this point. */
sub_v3_v3v3(ofs[i], eve->co, co_orig);
}
else {
@@ -703,7 +704,7 @@ static void bm_to_mesh_shape(BMesh *bm,
* while users might not notice since the shape-key is applied in the viewport,
* exporters for example may still use the underlying coordinates, see: T30771 & T96135.
*
* Needed when editing any shape that isn't the (`key->refkey`), the vertices in `me->mvert`
* Needed when editing any shape that isn't the (`key->refkey`), the vertices in mesh positions
* currently have vertex coordinates set from the current-shape (initialized from #BMVert.co).
* In this case it's important to overwrite these coordinates with the basis-keys coordinates. */
bool update_vertex_coords_from_refkey = false;
@@ -755,7 +756,7 @@ static void bm_to_mesh_shape(BMesh *bm,
keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
if (keyi != ORIGINDEX_NONE) {
float *co_refkey = (float *)BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset_refkey);
copy_v3_v3(mvert[i].co, co_refkey);
copy_v3_v3(positions[i], co_refkey);
}
}
}
@@ -846,6 +847,7 @@ static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attribu
static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm)
{
(void)bm; /* Unused in the release builds. */
BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position") == nullptr);
/* The "hide" attributes are stored as flags on #BMesh. */
BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr);
@@ -924,6 +926,7 @@ static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm,
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
using namespace blender;
BMVert *v, *eve;
BMEdge *e;
BMFace *f;
@@ -962,11 +965,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
}
CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
CustomData_add_layer_named(
&me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position");
CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge);
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly);
MutableSpan<MVert> mvert = me->verts_for_write();
MutableSpan<float3> positions = me->vert_positions_for_write();
MutableSpan<MEdge> medge = me->edges_for_write();
MutableSpan<MPoly> mpoly = me->polys_for_write();
MutableSpan<MLoop> mloop = me->loops_for_write();
@@ -981,7 +985,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
copy_v3_v3(mvert[i].co, v->co);
copy_v3_v3(positions[i], v->co);
if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
need_hide_vert = true;
@@ -1168,7 +1172,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, mvert, params->active_shapekey_to_mvert);
bm_to_mesh_shape(bm, me->key, positions, params->active_shapekey_to_mvert);
}
/* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */
@@ -1204,7 +1208,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
me->totloop = bm->totloop;
me->totpoly = bm->totface;
CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, bm->totvert);
if (!CustomData_get_layer_named(&me->vdata, CD_PROP_FLOAT3, "position")) {
CustomData_add_layer_named(
&me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, bm->totvert, "position");
}
CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, bm->totedge);
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, bm->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, bm->totface);
@@ -1225,7 +1232,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
BMVert *eve;
BMEdge *eed;
BMFace *efa;
MutableSpan<MVert> mvert = me->verts_for_write();
MutableSpan<float3> positions = me->vert_positions_for_write();
MutableSpan<MEdge> medge = me->edges_for_write();
MutableSpan<MPoly> mpoly = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
@@ -1239,9 +1246,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
bke::SpanAttributeWriter<bool> hide_vert_attribute;
bke::SpanAttributeWriter<bool> select_vert_attribute;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
MVert *mv = &mvert[i];
copy_v3_v3(mv->co, eve->co);
copy_v3_v3(positions[i], eve->co);
BM_elem_index_set(eve, i); /* set_inline */
@@ -55,8 +55,8 @@ struct BMeshToMeshParams {
*/
bool update_shapekey_indices;
/**
* Instead of copying the basis shape-key into the #MVert array,
* copy the #BMVert.co directly to #MVert.co (used for reading undo data).
* Instead of copying the basis shape-key into the position array,
* copy the #BMVert.co directly to the #Mesh position (used for reading undo data).
*/
bool active_shapekey_to_mvert;
struct CustomData_MeshMasks cd_mask_extra;
+1 -2
View File
@@ -27,7 +27,6 @@ struct Object;
struct Mesh;
struct MLoopTri;
struct CustomData;
struct MVert;
struct MEdge;
struct MLoop;
struct MPoly;
@@ -41,7 +40,7 @@ typedef struct PBVH_GPU_Args {
struct BMesh *bm;
const struct Mesh *me;
const struct MVert *mvert;
const float (*vert_positions)[3];
const struct MLoop *mloop;
const struct MPoly *mpoly;
int mesh_verts_num, mesh_faces_num, mesh_grids_num;
@@ -368,11 +368,9 @@ static void extract_range_iter_lvert_mesh(void *__restrict userdata,
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData *mr = data->mr;
const int lvert_index = data->loose_elems[iter];
const MVert *mv = &((const MVert *)data->elems)[lvert_index];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_lvert_mesh(
mr, mv, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
mr, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
@@ -406,7 +404,7 @@ BLI_INLINE void extract_task_range_run_iter(const MeshRenderData *mr,
break;
case MR_ITER_LVERT:
range_data.loose_elems = mr->lverts;
range_data.elems = is_mesh ? mr->mvert : (void *)mr->bm->vtable;
range_data.elems = is_mesh ? mr->vert_positions : (void *)mr->bm->vtable;
func = is_mesh ? extract_range_iter_lvert_mesh : extract_range_iter_lvert_bm;
stop = mr->vert_loose_len;
break;
@@ -368,7 +368,7 @@ 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->mvert,
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(mr->vert_positions),
mr->vert_normals,
mr->vert_len,
mr->medge,
@@ -542,7 +542,7 @@ 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 = BKE_mesh_verts(mr->me);
mr->vert_positions = mr->me->vert_positions().data();
mr->medge = BKE_mesh_edges(mr->me);
mr->mpoly = BKE_mesh_polys(mr->me);
mr->mloop = BKE_mesh_loops(mr->me);
@@ -2201,7 +2201,7 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
int subd_vert_offset = 0;
/* Subdivide each loose coarse edge. */
const Span<MVert> coarse_verts = coarse_mesh->verts();
const Span<float3> coarse_positions = coarse_mesh->vert_positions();
const Span<MEdge> coarse_edges = coarse_mesh->edges();
int *vert_to_edge_buffer;
@@ -2225,13 +2225,14 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
DRWSubdivLooseVertex &subd_v1 = loose_subd_verts[subd_vert_offset];
subd_v1.coarse_vertex_index = (i == 0) ? coarse_edge->v1 : -1u;
const float u1 = i * inv_resolution_1;
BKE_subdiv_mesh_interpolate_position_on_edge(coarse_verts.data(),
coarse_edges.data(),
vert_to_edge_map,
coarse_edge_index,
is_simple,
u1,
subd_v1.co);
BKE_subdiv_mesh_interpolate_position_on_edge(
reinterpret_cast<const float(*)[3]>(coarse_positions.data()),
coarse_edges.data(),
vert_to_edge_map,
coarse_edge_index,
is_simple,
u1,
subd_v1.co);
subd_edge.loose_subdiv_v1_index = subd_vert_offset++;
@@ -2239,13 +2240,14 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
DRWSubdivLooseVertex &subd_v2 = loose_subd_verts[subd_vert_offset];
subd_v2.coarse_vertex_index = ((i + 1) == resolution - 1) ? coarse_edge->v2 : -1u;
const float u2 = (i + 1) * inv_resolution_1;
BKE_subdiv_mesh_interpolate_position_on_edge(coarse_verts.data(),
coarse_edges.data(),
vert_to_edge_map,
coarse_edge_index,
is_simple,
u2,
subd_v2.co);
BKE_subdiv_mesh_interpolate_position_on_edge(
reinterpret_cast<const float(*)[3]>(coarse_positions.data()),
coarse_edges.data(),
vert_to_edge_map,
coarse_edge_index,
is_simple,
u2,
subd_v2.co);
subd_edge.loose_subdiv_v2_index = subd_vert_offset++;
}
@@ -2257,11 +2259,10 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
/* Copy the remaining loose_verts. */
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_verts[coarse_vertex_index];
DRWSubdivLooseVertex &subd_v = loose_subd_verts[subd_vert_offset++];
subd_v.coarse_vertex_index = cache->loose_geom.verts[i];
copy_v3_v3(subd_v.co, coarse_vertex.co);
copy_v3_v3(subd_v.co, coarse_positions[coarse_vertex_index]);
}
subdiv_cache->loose_geom.edges = loose_subd_edges;
+3 -2
View File
@@ -346,7 +346,7 @@ struct PBVHBatches {
if (!(mp->flag & ME_SMOOTH)) {
smooth = true;
BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->mvert, fno);
BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->vert_positions, fno);
normal_float_to_short_v3(no, fno);
}
else {
@@ -587,7 +587,8 @@ struct PBVHBatches {
case CD_PBVH_CO_TYPE:
foreach_faces(
[&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
*static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = args->mvert[vertex_i].co;
*static_cast<float3 *>(
GPU_vertbuf_raw_step(&access)) = args->vert_positions[vertex_i];
});
break;
case CD_PBVH_NO_TYPE:
@@ -9,6 +9,8 @@
#pragma once
#include "BLI_math_vector_types.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -72,7 +74,7 @@ struct MeshRenderData {
int freestyle_face_ofs;
/** Mesh */
Mesh *me;
const MVert *mvert;
const blender::float3 *vert_positions;
const MEdge *medge;
const MLoop *mloop;
const MPoly *mpoly;
@@ -267,10 +269,7 @@ using ExtractLVertBMeshFn = void(const MeshRenderData *mr,
const BMVert *eve,
int lvert_index,
void *data);
using ExtractLVertMeshFn = void(const MeshRenderData *mr,
const MVert *mv,
int lvert_index,
void *data);
using ExtractLVertMeshFn = void(const MeshRenderData *mr, int lvert_index, void *data);
using ExtractLooseGeomSubdivFn = void(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *buffer,
@@ -113,7 +113,6 @@ static void extract_points_iter_lvert_bm(const MeshRenderData *mr,
}
static void extract_points_iter_lvert_mesh(const MeshRenderData *mr,
const MVert * /*mv*/,
const int lvert_index,
void *_userdata)
{
@@ -130,10 +130,10 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_last = mp->totloop + mp->loopstart - 1;
const int ml_index_other = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1);
const MLoop *ml_next = &mr->mloop[ml_index_other];
const MVert *v1 = &mr->mvert[ml->v];
const MVert *v2 = &mr->mvert[ml_next->v];
float ratio = loop_edge_factor_get(
mr->poly_normals[mp_index], v1->co, mr->vert_normals[ml->v], v2->co);
float ratio = loop_edge_factor_get(mr->poly_normals[mp_index],
mr->vert_positions[ml->v],
mr->vert_normals[ml->v],
mr->vert_positions[ml_next->v]);
data->vbo_data[ml_index] = ratio * 253 + 1;
}
else {
@@ -223,7 +223,6 @@ static void extract_edit_data_iter_lvert_bm(const MeshRenderData *mr,
}
static void extract_edit_data_iter_lvert_mesh(const MeshRenderData *mr,
const MVert * /*mv*/,
const int lvert_index,
void *_data)
{
@@ -167,15 +167,16 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr
float(*auv)[2] = data->auv, *last_auv = data->last_auv;
float(*av)[3] = data->av, *last_av = data->last_av;
int l_next = ml_index + 1;
const MVert *v, *v_next;
if (ml_index == mp->loopstart) {
/* First loop in face. */
const int ml_index_last = ml_index_end - 1;
const int l_next_tmp = mp->loopstart;
v = &mr->mvert[mr->mloop[ml_index_last].v];
v_next = &mr->mvert[mr->mloop[l_next_tmp].v];
compute_normalize_edge_vectors(
auv, av, data->luv[ml_index_last].uv, data->luv[l_next_tmp].uv, v->co, v_next->co);
compute_normalize_edge_vectors(auv,
av,
data->luv[ml_index_last].uv,
data->luv[l_next_tmp].uv,
mr->vert_positions[mr->mloop[ml_index_last].v],
mr->vert_positions[mr->mloop[l_next_tmp].v]);
/* Save last edge. */
copy_v2_v2(last_auv, auv[1]);
copy_v3_v3(last_av, av[1]);
@@ -190,10 +191,12 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr
copy_v3_v3(av[1], last_av);
}
else {
v = &mr->mvert[mr->mloop[ml_index].v];
v_next = &mr->mvert[mr->mloop[l_next].v];
compute_normalize_edge_vectors(
auv, av, data->luv[ml_index].uv, data->luv[l_next].uv, v->co, v_next->co);
compute_normalize_edge_vectors(auv,
av,
data->luv[ml_index].uv,
data->luv[l_next].uv,
mr->vert_positions[mr->mloop[ml_index].v],
mr->vert_positions[mr->mloop[l_next].v]);
}
edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[ml_index]);
}
@@ -75,7 +75,8 @@ static void compute_area_ratio(const MeshRenderData *mr,
const MLoopUV *uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
const MPoly *mp = mr->mpoly;
for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
float area = BKE_mesh_calc_poly_area(mp, &mr->mloop[mp->loopstart], mr->mvert);
float area = BKE_mesh_calc_poly_area(
mp, &mr->mloop[mp->loopstart], reinterpret_cast<const float(*)[3]>(mr->vert_positions));
float uvarea = BKE_mesh_calc_poly_uv_area(mp, uv_data);
tot_area += area;
tot_uv_area += uvarea;
@@ -75,7 +75,6 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
float *co = center[mp_index];
zero_v3(co);
const MVert *mvert = mr->mvert;
const MLoop *mloop = mr->mloop;
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
@@ -84,13 +83,12 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
const MLoop *ml = &mloop[ml_index];
if (mr->use_subsurf_fdots) {
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
copy_v3_v3(center[mp_index], mvert[ml->v].co);
copy_v3_v3(center[mp_index], mr->vert_positions[ml->v]);
break;
}
}
else {
const MVert *mv = &mvert[ml->v];
add_v3_v3(center[mp_index], mv->co);
add_v3_v3(center[mp_index], mr->vert_positions[ml->v]);
}
}

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