main sync #3

Merged
Patrick Busch merged 318 commits from blender/blender:main into main 2023-03-17 15:52:21 +01:00
28 changed files with 150 additions and 145 deletions
Showing only changes of commit d7ac2a177a - Show all commits

View File

@ -39,7 +39,7 @@ struct CDDerivedMesh {
/* these point to data in the DerivedMesh custom data layers, /* these point to data in the DerivedMesh custom data layers,
* they are only here for efficiency and convenience */ * they are only here for efficiency and convenience */
float (*vert_positions)[3]; float (*vert_positions)[3];
const float (*vert_normals)[3]; const blender::float3 *vert_normals;
MEdge *medge; MEdge *medge;
MFace *mface; MFace *mface;
MLoop *mloop; MLoop *mloop;
@ -221,7 +221,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
&dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert)); &dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert));
/* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing /* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing
* or dirty normals. */ * or dirty normals. */
cddm->vert_normals = BKE_mesh_vert_normals_ensure(mesh); cddm->vert_normals = mesh->vert_normals().data();
cddm->medge = static_cast<MEdge *>( cddm->medge = static_cast<MEdge *>(
CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge)); CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge));
cddm->mloop = static_cast<MLoop *>( cddm->mloop = static_cast<MLoop *>(

View File

@ -1387,7 +1387,7 @@ BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const MLoop
} }
static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata, static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
const float (*vert_normals)[3], const blender::Span<blender::float3> vert_normals,
uint v_idx, uint v_idx,
RNG *rng, RNG *rng,
float max_length, float max_length,
@ -1530,7 +1530,8 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_LOOPTRI, 2); BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_LOOPTRI, 2);
rng = BLI_rng_new_srandom(0); rng = BLI_rng_new_srandom(0);
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(tmp_mesh ? tmp_mesh : mesh); const blender::Span<blender::float3> vert_normals = tmp_mesh ? tmp_mesh->vert_normals() :
mesh->vert_normals();
for (int i = 0; i < mvert_num; i++) { for (int i = 0; i < mvert_num; i++) {
if (find_internal_spring_target_vertex( if (find_internal_spring_target_vertex(

View File

@ -1789,7 +1789,7 @@ struct DynamicPaintModifierApplyData {
Object *ob; Object *ob;
float (*vert_positions)[3]; float (*vert_positions)[3];
const float (*vert_normals)[3]; blender::Span<blender::float3> vert_normals;
blender::Span<MPoly> polys; blender::Span<MPoly> polys;
blender::Span<MLoop> loops; blender::Span<MLoop> loops;
@ -1827,7 +1827,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
DynamicPaintModifierApplyData data{}; DynamicPaintModifierApplyData data{};
data.surface = surface; data.surface = surface;
data.vert_positions = BKE_mesh_vert_positions_for_write(result); data.vert_positions = BKE_mesh_vert_positions_for_write(result);
data.vert_normals = BKE_mesh_vert_normals_ensure(result); data.vert_normals = result->vert_normals();
TaskParallelSettings settings; TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings); BLI_parallel_range_settings_defaults(&settings);
@ -2026,7 +2026,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
DynamicPaintModifierApplyData data{}; DynamicPaintModifierApplyData data{};
data.surface = surface; data.surface = surface;
data.vert_positions = BKE_mesh_vert_positions_for_write(result); data.vert_positions = BKE_mesh_vert_positions_for_write(result);
data.vert_normals = BKE_mesh_vert_normals_ensure(result); data.vert_normals = result->vert_normals();
TaskParallelSettings settings; TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings); BLI_parallel_range_settings_defaults(&settings);
@ -4286,7 +4286,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
mesh = BKE_mesh_copy_for_eval(brush_mesh, false); mesh = BKE_mesh_copy_for_eval(brush_mesh, false);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
const blender::Span<MLoopTri> looptris = mesh->looptris(); const blender::Span<MLoopTri> looptris = mesh->looptris();
const blender::Span<MLoop> loops = mesh->loops(); const blender::Span<MLoop> loops = mesh->loops();
numOfVerts = mesh->totvert; numOfVerts = mesh->totvert;
@ -5910,7 +5910,7 @@ struct DynamicPaintGenerateBakeData {
Object *ob; Object *ob;
const float (*positions)[3]; const float (*positions)[3];
const float (*vert_normals)[3]; blender::Span<blender::float3> vert_normals;
const Vec3f *canvas_verts; const Vec3f *canvas_verts;
bool do_velocity_data; bool do_velocity_data;
@ -6147,7 +6147,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
data.surface = surface; data.surface = surface;
data.ob = ob; data.ob = ob;
data.positions = positions; data.positions = positions;
data.vert_normals = BKE_mesh_vert_normals_ensure(mesh); data.vert_normals = mesh->vert_normals();
data.canvas_verts = canvas_verts; data.canvas_verts = canvas_verts;
data.do_velocity_data = do_velocity_data; data.do_velocity_data = do_velocity_data;
data.new_bdata = new_bdata; data.new_bdata = new_bdata;

View File

@ -1785,7 +1785,7 @@ static void update_distances(int index,
static void sample_mesh(FluidFlowSettings *ffs, static void sample_mesh(FluidFlowSettings *ffs,
const float (*vert_positions)[3], const float (*vert_positions)[3],
const float (*vert_normals)[3], const blender::Span<blender::float3> vert_normals,
const MLoop *mloop, const MLoop *mloop,
const MLoopTri *mlooptri, const MLoopTri *mlooptri,
const float (*mloopuv)[2], const float (*mloopuv)[2],
@ -1980,7 +1980,7 @@ struct EmitFromDMData {
FluidFlowSettings *ffs; FluidFlowSettings *ffs;
const float (*vert_positions)[3]; const float (*vert_positions)[3];
const float (*vert_normals)[3]; blender::Span<blender::float3> vert_normals;
blender::Span<MLoop> loops; blender::Span<MLoop> loops;
blender::Span<MLoopTri> looptris; blender::Span<MLoopTri> looptris;
const float (*mloopuv)[2]; const float (*mloopuv)[2];
@ -2091,18 +2091,11 @@ static void emit_from_mesh(
/* Transform mesh vertices to domain grid space for fast lookups. /* Transform mesh vertices to domain grid space for fast lookups.
* This is valid because the mesh is copied above. */ * This is valid because the mesh is copied above. */
BKE_mesh_vert_normals_ensure(me);
float(*vert_normals)[3] = BKE_mesh_vert_normals_for_write(me);
for (i = 0; i < numverts; i++) { for (i = 0; i < numverts; i++) {
/* Vertex position. */ /* Vertex position. */
mul_m4_v3(flow_ob->object_to_world, positions[i]); mul_m4_v3(flow_ob->object_to_world, positions[i]);
manta_pos_to_cell(fds, positions[i]); manta_pos_to_cell(fds, positions[i]);
/* Vertex normal. */
mul_mat3_m4_v3(flow_ob->object_to_world, vert_normals[i]);
mul_mat3_m4_v3(fds->imat, vert_normals[i]);
normalize_v3(vert_normals[i]);
/* Vertex velocity. */ /* Vertex velocity. */
if (ffs->flags & FLUID_FLOW_INITVELOCITY) { if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
float co[3]; float co[3];
@ -2117,6 +2110,7 @@ static void emit_from_mesh(
/* Calculate emission map bounds. */ /* Calculate emission map bounds. */
bb_boundInsert(bb, positions[i]); bb_boundInsert(bb, positions[i]);
} }
BKE_mesh_tag_positions_changed(me);
mul_m4_v3(flow_ob->object_to_world, flow_center); mul_m4_v3(flow_ob->object_to_world, flow_center);
manta_pos_to_cell(fds, flow_center); manta_pos_to_cell(fds, flow_center);
@ -2141,7 +2135,7 @@ static void emit_from_mesh(
data.fds = fds; data.fds = fds;
data.ffs = ffs; data.ffs = ffs;
data.vert_positions = positions; data.vert_positions = positions;
data.vert_normals = vert_normals; data.vert_normals = me->vert_normals();
data.loops = loops; data.loops = loops;
data.looptris = looptris; data.looptris = looptris;
data.mloopuv = mloopuv; data.mloopuv = mloopuv;

View File

@ -2504,7 +2504,7 @@ static void gpencil_generate_edgeloops(Object *ob,
const Span<float3> vert_positions = me->vert_positions(); const Span<float3> vert_positions = me->vert_positions();
const Span<MEdge> edges = me->edges(); const Span<MEdge> edges = me->edges();
const Span<MDeformVert> dverts = me->deform_verts(); const Span<MDeformVert> dverts = me->deform_verts();
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me); const blender::Span<blender::float3> vert_normals = me->vert_normals();
const bke::AttributeAccessor attributes = me->attributes(); const bke::AttributeAccessor attributes = me->attributes();
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>( const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
".uv_seam", ATTR_DOMAIN_EDGE, false); ".uv_seam", ATTR_DOMAIN_EDGE, false);

View File

@ -67,13 +67,14 @@ void BKE_mesh_foreach_mapped_vert(
else { else {
const float(*positions)[3] = BKE_mesh_vert_positions(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 int *index = static_cast<const int *>(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX));
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? blender::Span<blender::float3> vert_normals;
BKE_mesh_vert_normals_ensure(mesh) : if (flag & MESH_FOREACH_USE_NORMAL) {
nullptr; vert_normals = mesh->vert_normals();
}
if (index) { if (index) {
for (int i = 0; i < mesh->totvert; i++) { for (int i = 0; i < mesh->totvert; i++) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr; const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[i].x : nullptr;
const int orig = *index++; const int orig = *index++;
if (orig == ORIGINDEX_NONE) { if (orig == ORIGINDEX_NONE) {
continue; continue;
@ -83,7 +84,7 @@ void BKE_mesh_foreach_mapped_vert(
} }
else { else {
for (int i = 0; i < mesh->totvert; i++) { for (int i = 0; i < mesh->totvert; i++) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr; const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[i].x : nullptr;
func(userData, i, positions[i], no); func(userData, i, positions[i], no);
} }
} }
@ -315,9 +316,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const blender::Span<MPoly> polys = mesh->polys(); const blender::Span<MPoly> polys = mesh->polys();
const blender::Span<MLoop> loops = mesh->loops(); const blender::Span<MLoop> loops = mesh->loops();
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? blender::Span<blender::float3> vert_normals;
BKE_mesh_vert_normals_ensure(mesh) : if (flag & MESH_FOREACH_USE_NORMAL) {
nullptr; vert_normals = mesh->vert_normals();
}
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX)); const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
const blender::BitSpan facedot_tags = mesh->runtime->subsurf_face_dot_tags; const blender::BitSpan facedot_tags = mesh->runtime->subsurf_face_dot_tags;
@ -332,7 +334,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
func(userData, func(userData,
orig, orig,
positions[loop.v], positions[loop.v],
(flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[loop.v] : nullptr); (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[loop.v].x : nullptr);
} }
} }
} }
@ -344,7 +346,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
func(userData, func(userData,
i, i,
positions[loop.v], positions[loop.v],
(flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[loop.v] : nullptr); (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[loop.v].x : nullptr);
} }
} }
} }

View File

@ -429,8 +429,8 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
switch (mesh->runtime->wrapper_type) { switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD: case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_MDATA:
BKE_mesh_vert_normals_ensure(mesh); mesh->vert_normals();
BKE_mesh_poly_normals_ensure(mesh); mesh->poly_normals();
break; break;
case ME_WRAPPER_TYPE_BMESH: { case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh *em = mesh->edit_mesh; BMEditMesh *em = mesh->edit_mesh;

View File

@ -571,7 +571,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
const blender::Span<MPoly> polys_src = me_src->polys(); const blender::Span<MPoly> polys_src = me_src->polys();
const blender::Span<MLoop> loops_src = me_src->loops(); const blender::Span<MLoop> loops_src = me_src->loops();
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, nullptr); float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, nullptr);
const float(*vert_normals_dst)[3] = BKE_mesh_vert_normals_ensure(me_dst); const blender::Span<blender::float3> vert_normals_dst = me_dst->vert_normals();
size_t tmp_buff_size = MREMAP_DEFAULT_BUFSIZE; size_t tmp_buff_size = MREMAP_DEFAULT_BUFSIZE;
float(*vcos)[3] = static_cast<float(*)[3]>( float(*vcos)[3] = static_cast<float(*)[3]>(
@ -937,7 +937,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2); BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2);
const float(*vert_normals_dst)[3] = BKE_mesh_vert_normals_ensure(me_dst); const blender::Span<blender::float3> vert_normals_dst = me_dst->vert_normals();
for (i = 0; i < numedges_dst; i++) { for (i = 0; i < numedges_dst; i++) {
/* For each dst edge, we sample some rays from it (interpolated from its vertices) /* For each dst edge, we sample some rays from it (interpolated from its vertices)
@ -1286,10 +1286,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
1) : 1) :
0); 0);
const float(*poly_nors_src)[3] = nullptr; blender::Span<blender::float3> poly_normals_src;
const float(*loop_nors_src)[3] = nullptr; blender::Span<blender::float3> loop_normals_src;
const float(*poly_nors_dst)[3] = nullptr;
float(*loop_nors_dst)[3] = nullptr; blender::Span<blender::float3> poly_normals_dst;
blender::float3 *loop_normals_dst;
blender::Array<blender::float3> poly_cents_src; blender::Array<blender::float3> poly_cents_src;
@ -1345,22 +1346,23 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const bool need_pnors_dst = need_lnors_dst || need_pnors_src; const bool need_pnors_dst = need_lnors_dst || need_pnors_src;
if (need_pnors_dst) { if (need_pnors_dst) {
poly_nors_dst = BKE_mesh_poly_normals_ensure(mesh_dst); poly_normals_dst = mesh_dst->poly_normals();
} }
if (need_lnors_dst) { if (need_lnors_dst) {
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>( short(*custom_nors_dst)[2] = static_cast<short(*)[2]>(
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, numloops_dst)); CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, numloops_dst));
/* Cache loop normals into a temporary custom data layer. */ /* Cache loop normals into a temporary custom data layer. */
loop_nors_dst = static_cast<float(*)[3]>( loop_normals_dst = static_cast<blender::float3 *>(
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, numloops_dst)); CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, numloops_dst));
const bool do_loop_nors_dst = (loop_nors_dst == nullptr);
if (!loop_nors_dst) { const bool do_loop_normals_dst = (loop_normals_dst == nullptr);
loop_nors_dst = static_cast<float(*)[3]>( if (!loop_normals_dst) {
loop_normals_dst = static_cast<blender::float3 *>(
CustomData_add_layer(ldata_dst, CD_NORMAL, CD_SET_DEFAULT, numloops_dst)); CustomData_add_layer(ldata_dst, CD_NORMAL, CD_SET_DEFAULT, numloops_dst));
CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY); CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
} }
if (dirty_nors_dst || do_loop_nors_dst) { if (dirty_nors_dst || do_loop_normals_dst) {
const bool *sharp_edges = static_cast<const bool *>( const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mesh_dst->edata, CD_PROP_BOOL, "sharp_edge")); CustomData_get_layer_named(&mesh_dst->edata, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>( const bool *sharp_faces = static_cast<const bool *>(
@ -1379,17 +1381,18 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
split_angle_dst, split_angle_dst,
custom_nors_dst, custom_nors_dst,
nullptr, nullptr,
{reinterpret_cast<blender::float3 *>(loop_nors_dst), numloops_dst}); {loop_normals_dst, numloops_dst});
} }
} }
if (need_pnors_src || need_lnors_src) { if (need_pnors_src || need_lnors_src) {
if (need_pnors_src) { if (need_pnors_src) {
poly_nors_src = BKE_mesh_poly_normals_ensure(me_src); poly_normals_src = me_src->poly_normals();
} }
if (need_lnors_src) { if (need_lnors_src) {
loop_nors_src = static_cast<const float(*)[3]>( loop_normals_src = {static_cast<const blender::float3 *>(
CustomData_get_layer(&me_src->ldata, CD_NORMAL)); CustomData_get_layer(&me_src->ldata, CD_NORMAL)),
BLI_assert(loop_nors_src != nullptr); me_src->totloop};
BLI_assert(loop_normals_src.data() != nullptr);
} }
} }
} }
@ -1583,7 +1586,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
bool pcent_dst_valid = false; bool pcent_dst_valid = false;
if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) { if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) {
copy_v3_v3(pnor_dst, poly_nors_dst[pidx_dst]); copy_v3_v3(pnor_dst, poly_normals_dst[pidx_dst]);
if (space_transform) { if (space_transform) {
BLI_space_transform_apply_normal(space_transform, pnor_dst); BLI_space_transform_apply_normal(space_transform, pnor_dst);
} }
@ -1616,23 +1619,23 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest( if (mesh_remap_bvhtree_query_nearest(
tdata, &nearest, tmp_co, max_dist_sq, &hit_dist)) { tdata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
float(*nor_dst)[3]; float(*nor_dst)[3];
const float(*nors_src)[3]; blender::Span<blender::float3> nors_src;
float best_nor_dot = -2.0f; float best_nor_dot = -2.0f;
float best_sqdist_fallback = FLT_MAX; float best_sqdist_fallback = FLT_MAX;
int best_index_src = -1; int best_index_src = -1;
if (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) { if (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) {
copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + mp_dst->loopstart]); copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + mp_dst->loopstart]);
if (space_transform) { if (space_transform) {
BLI_space_transform_apply_normal(space_transform, tmp_no); BLI_space_transform_apply_normal(space_transform, tmp_no);
} }
nor_dst = &tmp_no; nor_dst = &tmp_no;
nors_src = loop_nors_src; nors_src = loop_normals_src;
vert_to_refelem_map_src = vert_to_loop_map_src; vert_to_refelem_map_src = vert_to_loop_map_src;
} }
else { /* if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) { */ else { /* if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) { */
nor_dst = &pnor_dst; nor_dst = &pnor_dst;
nors_src = poly_nors_src; nors_src = poly_normals_src;
vert_to_refelem_map_src = vert_to_poly_map_src; vert_to_refelem_map_src = vert_to_poly_map_src;
} }
@ -1717,7 +1720,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
float w = 1.0f; float w = 1.0f;
copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]);
copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + mp_dst->loopstart]); copy_v3_v3(tmp_no, loop_normals_dst[plidx_dst + mp_dst->loopstart]);
/* We do our transform here, since we may do several raycast/nearest queries. */ /* We do our transform here, since we may do several raycast/nearest queries. */
if (space_transform) { if (space_transform) {
@ -2167,14 +2170,14 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
{ {
const float full_weight = 1.0f; const float full_weight = 1.0f;
const float max_dist_sq = max_dist * max_dist; const float max_dist_sq = max_dist * max_dist;
const float(*poly_nors_dst)[3] = nullptr; blender::Span<blender::float3> poly_normals_dst;
blender::float3 tmp_co, tmp_no; blender::float3 tmp_co, tmp_no;
int i; int i;
BLI_assert(mode & MREMAP_MODE_POLY); BLI_assert(mode & MREMAP_MODE_POLY);
if (mode & (MREMAP_USE_NORMAL | MREMAP_USE_NORPROJ)) { if (mode & (MREMAP_USE_NORMAL | MREMAP_USE_NORPROJ)) {
poly_nors_dst = BKE_mesh_poly_normals_ensure(mesh_dst); poly_normals_dst = mesh_dst->poly_normals();
} }
BKE_mesh_remap_init(r_map, numpolys_dst); BKE_mesh_remap_init(r_map, numpolys_dst);
@ -2220,15 +2223,13 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
} }
} }
else if (mode == MREMAP_MODE_POLY_NOR) { else if (mode == MREMAP_MODE_POLY_NOR) {
BLI_assert(poly_nors_dst);
for (i = 0; i < numpolys_dst; i++) { for (i = 0; i < numpolys_dst; i++) {
const MPoly &poly = polys_dst[i]; const MPoly &poly = polys_dst[i];
tmp_co = blender::bke::mesh::poly_center_calc( tmp_co = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst}, {reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&loops_dst[poly.loopstart], poly.totloop}); {&loops_dst[poly.loopstart], poly.totloop});
copy_v3_v3(tmp_no, poly_nors_dst[i]); copy_v3_v3(tmp_no, poly_normals_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */ /* Convert the vertex to tree coordinates, if needed. */
if (space_transform) { if (space_transform) {
@ -2294,7 +2295,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst}, {reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&loops_dst[poly.loopstart], poly.totloop}); {&loops_dst[poly.loopstart], poly.totloop});
copy_v3_v3(tmp_no, poly_nors_dst[i]); copy_v3_v3(tmp_no, poly_normals_dst[i]);
/* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */ /* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */
if (space_transform) { if (space_transform) {

View File

@ -591,8 +591,8 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
calc_active_tangent, calc_active_tangent,
tangent_names, tangent_names,
tangent_names_len, tangent_names_len,
BKE_mesh_vert_normals_ensure(me_eval), reinterpret_cast<const float(*)[3]>(me_eval->vert_normals().data()),
BKE_mesh_poly_normals_ensure(me_eval), reinterpret_cast<const float(*)[3]>(me_eval->poly_normals().data()),
static_cast<const float(*)[3]>(CustomData_get_layer(&me_eval->ldata, CD_NORMAL)), static_cast<const float(*)[3]>(CustomData_get_layer(&me_eval->ldata, CD_NORMAL)),
/* may be nullptr */ /* may be nullptr */
static_cast<const float(*)[3]>(CustomData_get_layer(&me_eval->vdata, CD_ORCO)), static_cast<const float(*)[3]>(CustomData_get_layer(&me_eval->vdata, CD_ORCO)),

View File

@ -554,7 +554,7 @@ struct VertexDupliData_Mesh {
int totvert; int totvert;
Span<float3> vert_positions; Span<float3> vert_positions;
const float (*vert_normals)[3]; Span<float3> vert_normals;
const float (*orco)[3]; const float (*orco)[3];
}; };
@ -735,7 +735,7 @@ static void make_duplis_verts(const DupliContext *ctx)
vdd.params = vdd_params; vdd.params = vdd_params;
vdd.totvert = me_eval->totvert; vdd.totvert = me_eval->totvert;
vdd.vert_positions = me_eval->vert_positions(); vdd.vert_positions = me_eval->vert_positions();
vdd.vert_normals = BKE_mesh_vert_normals_ensure(me_eval); vdd.vert_normals = me_eval->vert_normals();
vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO); vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
make_child_duplis(ctx, &vdd, make_child_duplis_verts_from_mesh); make_child_duplis(ctx, &vdd, make_child_duplis_verts_from_mesh);

View File

@ -2160,7 +2160,7 @@ void psys_particle_on_dm(Mesh *mesh_final,
} }
orcodata = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh_final->vdata, CD_ORCO)); orcodata = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh_final->vdata, CD_ORCO));
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh_final); const blender::Span<blender::float3> vert_normals = mesh_final->vert_normals();
if (from == PART_FROM_VERT) { if (from == PART_FROM_VERT) {
const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final); const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final);
@ -2203,7 +2203,7 @@ void psys_particle_on_dm(Mesh *mesh_final,
if (from == PART_FROM_VOLUME) { if (from == PART_FROM_VOLUME) {
psys_interpolate_face(mesh_final, psys_interpolate_face(mesh_final,
vert_positions, vert_positions,
vert_normals, reinterpret_cast<const float(*)[3]>(vert_normals.data()),
mface, mface,
mtface, mtface,
orcodata, orcodata,
@ -2226,7 +2226,7 @@ void psys_particle_on_dm(Mesh *mesh_final,
else { else {
psys_interpolate_face(mesh_final, psys_interpolate_face(mesh_final,
vert_positions, vert_positions,
vert_normals, reinterpret_cast<const float(*)[3]>(vert_normals.data()),
mface, mface,
mtface, mtface,
orcodata, orcodata,

View File

@ -845,7 +845,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
pbvh->mloop = mloop; pbvh->mloop = mloop;
pbvh->looptri = looptri; pbvh->looptri = looptri;
pbvh->vert_positions = vert_positions; pbvh->vert_positions = vert_positions;
BKE_mesh_vert_normals_ensure(mesh); /* Make sure cached normals start out calculated. */
mesh->vert_normals();
pbvh->vert_normals = BKE_mesh_vert_normals_for_write(mesh); pbvh->vert_normals = BKE_mesh_vert_normals_for_write(mesh);
pbvh->hide_vert = static_cast<bool *>(CustomData_get_layer_named_for_write( pbvh->hide_vert = static_cast<bool *>(CustomData_get_layer_named_for_write(
&mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert)); &mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert));

View File

@ -60,7 +60,7 @@ struct ShrinkwrapCalcData {
Object *ob; /* object we are applying shrinkwrap to */ Object *ob; /* object we are applying shrinkwrap to */
float (*vert_positions)[3]; /* Array of verts being projected. */ float (*vert_positions)[3]; /* Array of verts being projected. */
const float (*vert_normals)[3]; blender::Span<blender::float3> vert_normals;
/* Vertices being shrink-wrapped. */ /* Vertices being shrink-wrapped. */
float (*vertexCos)[3]; float (*vertexCos)[3];
int numVerts; int numVerts;
@ -115,7 +115,7 @@ bool BKE_shrinkwrap_init_tree(
data->mesh = mesh; data->mesh = mesh;
data->polys = mesh->polys().data(); data->polys = mesh->polys().data();
data->vert_normals = BKE_mesh_vert_normals_ensure(mesh); data->vert_normals = reinterpret_cast<const float(*)[3]>(mesh->vert_normals().data()),
data->sharp_faces = static_cast<const bool *>( data->sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_face")); CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_face"));
@ -136,7 +136,7 @@ bool BKE_shrinkwrap_init_tree(
} }
if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) { if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) {
data->poly_normals = BKE_mesh_poly_normals_ensure(mesh); data->poly_normals = reinterpret_cast<const float(*)[3]>(mesh->poly_normals().data());
if ((mesh->flag & ME_AUTOSMOOTH) != 0) { if ((mesh->flag & ME_AUTOSMOOTH) != 0) {
data->clnors = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); data->clnors = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
} }
@ -297,7 +297,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
MEM_freeN(vert_status); MEM_freeN(vert_status);
/* Finalize average direction and compute normal. */ /* Finalize average direction and compute normal. */
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
for (int i = 0; i < mesh->totvert; i++) { for (int i = 0; i < mesh->totvert; i++) {
int bidx = vert_boundary_id[i]; int bidx = vert_boundary_id[i];
@ -1409,7 +1409,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
if (mesh != nullptr && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { if (mesh != nullptr && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
/* Setup arrays to get vertex positions, normals and deform weights */ /* Setup arrays to get vertex positions, normals and deform weights */
calc.vert_positions = BKE_mesh_vert_positions_for_write(mesh); calc.vert_positions = BKE_mesh_vert_positions_for_write(mesh);
calc.vert_normals = BKE_mesh_vert_normals_ensure(mesh); calc.vert_normals = mesh->vert_normals();
/* Using vertices positions/normals as if a subsurface was applied */ /* Using vertices positions/normals as if a subsurface was applied */
if (smd->subsurfLevels) { if (smd->subsurfLevels) {
@ -1570,7 +1570,7 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
calc.smd = &ssmd; calc.smd = &ssmd;
calc.numVerts = src_me->totvert; calc.numVerts = src_me->totvert;
calc.vertexCos = vertexCos; calc.vertexCos = vertexCos;
calc.vert_normals = BKE_mesh_vert_normals_ensure(src_me); calc.vert_normals = src_me->vert_normals();
calc.vgroup = -1; calc.vgroup = -1;
calc.target = target_me; calc.target = target_me;
calc.keepDist = ssmd.keepDist; calc.keepDist = ssmd.keepDist;

View File

@ -277,9 +277,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
return; return;
} }
const float(*vert_normals)[3] = nullptr; blender::Span<blender::float3> vert_normals;
if (params->calc_vert_normal) { if (params->calc_vert_normal) {
vert_normals = BKE_mesh_vert_normals_ensure(me); vert_normals = me->vert_normals();
} }
if (is_new) { if (is_new) {
@ -433,7 +433,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_vert_select_set(bm, v, true); BM_vert_select_set(bm, v, true);
} }
if (vert_normals) { if (!vert_normals.is_empty()) {
copy_v3_v3(v->no, vert_normals[i]); copy_v3_v3(v->no, vert_normals[i]);
} }

View File

@ -928,7 +928,7 @@ typedef struct MeshDeformBind {
blender::Span<MPoly> polys; blender::Span<MPoly> polys;
blender::Span<MLoop> loops; blender::Span<MLoop> loops;
blender::Span<MLoopTri> looptris; blender::Span<MLoopTri> looptris;
const float (*poly_nors)[3]; blender::Span<blender::float3> poly_normals;
} cagemesh_cache; } cagemesh_cache;
} MeshDeformBind; } MeshDeformBind;
@ -958,7 +958,7 @@ static void harmonic_ray_callback(void *userdata,
MeshRayCallbackData *data = static_cast<MeshRayCallbackData *>(userdata); MeshRayCallbackData *data = static_cast<MeshRayCallbackData *>(userdata);
MeshDeformBind *mdb = data->mdb; MeshDeformBind *mdb = data->mdb;
const blender::Span<MLoop> loops = mdb->cagemesh_cache.loops; const blender::Span<MLoop> loops = mdb->cagemesh_cache.loops;
const float(*poly_nors)[3] = mdb->cagemesh_cache.poly_nors; const blender::Span<blender::float3> poly_normals = mdb->cagemesh_cache.poly_normals;
MeshDeformIsect *isec = data->isec; MeshDeformIsect *isec = data->isec;
float no[3], co[3], dist; float no[3], co[3], dist;
float *face[3]; float *face[3];
@ -976,8 +976,8 @@ static void harmonic_ray_callback(void *userdata,
return; return;
} }
if (poly_nors) { if (!poly_normals.is_empty()) {
copy_v3_v3(no, poly_nors[lt->poly]); copy_v3_v3(no, poly_normals[lt->poly]);
} }
else { else {
normal_tri_v3(no, UNPACK3(face)); normal_tri_v3(no, UNPACK3(face));
@ -1631,7 +1631,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
mdb->cagemesh_cache.polys = me->polys(); mdb->cagemesh_cache.polys = me->polys();
mdb->cagemesh_cache.loops = me->loops(); mdb->cagemesh_cache.loops = me->loops();
mdb->cagemesh_cache.looptris = me->looptris(); mdb->cagemesh_cache.looptris = me->looptris();
mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me); mdb->cagemesh_cache.poly_normals = me->poly_normals();
} }
/* make bounding box equal size in all directions, add padding, and compute /* make bounding box equal size in all directions, add padding, and compute

View File

@ -411,7 +411,7 @@ struct ProjPaintState {
int totvert_eval; int totvert_eval;
const float (*vert_positions_eval)[3]; const float (*vert_positions_eval)[3];
const float (*vert_normals)[3]; blender::Span<blender::float3> vert_normals;
blender::Span<MEdge> edges_eval; blender::Span<MEdge> edges_eval;
blender::Span<MPoly> polys_eval; blender::Span<MPoly> polys_eval;
blender::Span<MLoop> loops_eval; blender::Span<MLoop> loops_eval;
@ -4069,7 +4069,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
ps->mat_array[totmat - 1] = nullptr; ps->mat_array[totmat - 1] = nullptr;
ps->vert_positions_eval = BKE_mesh_vert_positions(ps->me_eval); ps->vert_positions_eval = BKE_mesh_vert_positions(ps->me_eval);
ps->vert_normals = BKE_mesh_vert_normals_ensure(ps->me_eval); ps->vert_normals = ps->me_eval->vert_normals();
ps->edges_eval = ps->me_eval->edges(); ps->edges_eval = ps->me_eval->edges();
ps->polys_eval = ps->me_eval->polys(); ps->polys_eval = ps->me_eval->polys();
ps->loops_eval = ps->me_eval->loops(); ps->loops_eval = ps->me_eval->loops();

View File

@ -680,8 +680,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
break; break;
} }
case SCULPT_FACE_SETS_FROM_NORMALS: { case SCULPT_FACE_SETS_FROM_NORMALS: {
const Span<float3> poly_normals( const Span<float3> poly_normals = mesh->poly_normals();
reinterpret_cast<const float3 *>(BKE_mesh_poly_normals_ensure(mesh)), mesh->totpoly);
sculpt_face_sets_init_flood_fill( sculpt_face_sets_init_flood_fill(
ob, [&](const int from_face, const int /*edge*/, const int to_face) -> bool { ob, [&](const int from_face, const int /*edge*/, const int to_face) -> bool {
return std::abs(math::dot(poly_normals[from_face], poly_normals[to_face])) > threshold; return std::abs(math::dot(poly_normals[from_face], poly_normals[to_face])) > threshold;

View File

@ -1427,7 +1427,7 @@ struct Nearest2dUserData {
}; };
struct { struct {
const float (*vert_positions)[3]; const float (*vert_positions)[3];
const float (*vert_normals)[3]; const blender::float3 *vert_normals;
const MEdge *edges; /* only used for #BVHTreeFromMeshEdges */ const MEdge *edges; /* only used for #BVHTreeFromMeshEdges */
const MLoop *loop; const MLoop *loop;
const MLoopTri *looptris; const MLoopTri *looptris;
@ -1716,7 +1716,7 @@ static void nearest2d_data_init_mesh(const Mesh *mesh,
r_nearest2d->get_tri_edges_index = cb_mlooptri_edges_get; r_nearest2d->get_tri_edges_index = cb_mlooptri_edges_get;
r_nearest2d->vert_positions = BKE_mesh_vert_positions(mesh); r_nearest2d->vert_positions = BKE_mesh_vert_positions(mesh);
r_nearest2d->vert_normals = BKE_mesh_vert_normals_ensure(mesh); r_nearest2d->vert_normals = mesh->vert_normals().data();
r_nearest2d->edges = mesh->edges().data(); r_nearest2d->edges = mesh->edges().data();
r_nearest2d->loop = mesh->loops().data(); r_nearest2d->loop = mesh->loops().data();
r_nearest2d->looptris = mesh->looptris().data(); r_nearest2d->looptris = mesh->looptris().data();

View File

@ -124,7 +124,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
&mesh->fdata, CD_MTFACE, mesh->totface); &mesh->fdata, CD_MTFACE, mesh->totface);
const MFace *mface = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); const MFace *mface = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const Span<float3> vert_normals = mesh->vert_normals();
if ((!mtface || !mface) && !uv_warning_shown_) { if ((!mtface || !mface) && !uv_warning_shown_) {
std::fprintf(stderr, std::fprintf(stderr,
@ -165,7 +165,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
psys_interpolate_face(mesh, psys_interpolate_face(mesh,
positions, positions,
vert_normals, reinterpret_cast<const float(*)[3]>(vert_normals.data()),
face, face,
tface, tface,
nullptr, nullptr,
@ -249,7 +249,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
MTFace *mtface = (MTFace *)CustomData_get_layer_for_write( MTFace *mtface = (MTFace *)CustomData_get_layer_for_write(
&mesh->fdata, CD_MTFACE, mesh->totface); &mesh->fdata, CD_MTFACE, mesh->totface);
const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const Span<float3> vert_normals = mesh->vert_normals();
ParticleSystem *psys = context.particle_system; ParticleSystem *psys = context.particle_system;
ParticleSettings *part = psys->part; ParticleSettings *part = psys->part;
@ -283,7 +283,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
psys_interpolate_face(mesh, psys_interpolate_face(mesh,
positions, positions,
vert_normals, reinterpret_cast<const float(*)[3]>(vert_normals.data()),
face, face,
tface, tface,
nullptr, nullptr,

View File

@ -441,8 +441,8 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
else { else {
/* Compute the loop normals based on the 'smooth' flag. */ /* Compute the loop normals based on the 'smooth' flag. */
bke::AttributeAccessor attributes = mesh->attributes(); bke::AttributeAccessor attributes = mesh->attributes();
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const Span<float3> vert_normals = mesh->vert_normals();
const float(*face_normals)[3] = BKE_mesh_poly_normals_ensure(mesh); const Span<float3> poly_normals = mesh->poly_normals();
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>( const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
"sharp_face", ATTR_DOMAIN_FACE, false); "sharp_face", ATTR_DOMAIN_FACE, false);
for (const int i : polys.index_range()) { for (const int i : polys.index_range()) {
@ -450,7 +450,7 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
if (sharp_faces[i]) { if (sharp_faces[i]) {
/* Flat shaded, use common normal for all verts. */ /* Flat shaded, use common normal for all verts. */
pxr::GfVec3f pxr_normal(face_normals[i]); pxr::GfVec3f pxr_normal(&poly_normals[i].x);
for (int loop_idx = 0; loop_idx < poly.totloop; ++loop_idx) { for (int loop_idx = 0; loop_idx < poly.totloop; ++loop_idx) {
loop_normals.push_back(pxr_normal); loop_normals.push_back(pxr_normal);
} }
@ -458,7 +458,7 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
else { else {
/* Smooth shaded, use individual vert normals. */ /* Smooth shaded, use individual vert normals. */
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
loop_normals.push_back(pxr::GfVec3f(vert_normals[loop.v])); loop_normals.push_back(pxr::GfVec3f(&vert_normals[loop.v].x));
} }
} }
} }

View File

@ -576,10 +576,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
first_chunk_nverts = chunk_nverts; first_chunk_nverts = chunk_nverts;
unit_m4(current_offset); unit_m4(current_offset);
const float(*src_vert_normals)[3] = nullptr; blender::Span<blender::float3> src_vert_normals;
float(*dst_vert_normals)[3] = nullptr; float(*dst_vert_normals)[3] = nullptr;
if (!use_recalc_normals) { if (!use_recalc_normals) {
src_vert_normals = BKE_mesh_vert_normals_ensure(mesh); src_vert_normals = mesh->vert_normals();
dst_vert_normals = BKE_mesh_vert_normals_for_write(result); dst_vert_normals = BKE_mesh_vert_normals_for_write(result);
BKE_mesh_vert_normals_clear_dirty(result); BKE_mesh_vert_normals_clear_dirty(result);
} }

View File

@ -155,7 +155,7 @@ struct DisplaceUserdata {
float (*tex_co)[3]; float (*tex_co)[3];
float (*vertexCos)[3]; float (*vertexCos)[3];
float local_mat[4][4]; float local_mat[4][4];
const float (*vert_normals)[3]; blender::Span<blender::float3> vert_normals;
float (*vert_clnors)[3]; float (*vert_clnors)[3];
}; };
@ -336,7 +336,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
data.vertexCos = vertexCos; data.vertexCos = vertexCos;
copy_m4_m4(data.local_mat, local_mat); copy_m4_m4(data.local_mat, local_mat);
if (direction == MOD_DISP_DIR_NOR) { if (direction == MOD_DISP_DIR_NOR) {
data.vert_normals = BKE_mesh_vert_normals_ensure(mesh); data.vert_normals = mesh->vert_normals();
} }
data.vert_clnors = vert_clnors; data.vert_clnors = vert_clnors;
if (tex_target != nullptr) { if (tex_target != nullptr) {

View File

@ -50,11 +50,11 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
/** /**
* \param mesh: Mesh to calculate normals for. * \param mesh: Mesh to calculate normals for.
* \param poly_nors: Precalculated face normals. * \param poly_normals: Precalculated face normals.
* \param r_vert_nors: Return vert normals. * \param r_vert_nors: Return vert normals.
*/ */
static void mesh_calc_hq_normal(Mesh *mesh, static void mesh_calc_hq_normal(Mesh *mesh,
const float (*poly_nors)[3], const blender::Span<blender::float3> poly_normals,
float (*r_vert_nors)[3], float (*r_vert_nors)[3],
#ifdef USE_NONMANIFOLD_WORKAROUND #ifdef USE_NONMANIFOLD_WORKAROUND
BLI_bitmap *edge_tmp_tag BLI_bitmap *edge_tmp_tag
@ -115,13 +115,13 @@ static void mesh_calc_hq_normal(Mesh *mesh,
angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
#else #else
mid_v3_v3v3_angle_weighted( mid_v3_v3v3_angle_weighted(
edge_normal, poly_nors[edge_ref->p1], poly_nors[edge_ref->p2]); edge_normal, poly_normals[edge_ref->p1], poly_normals[edge_ref->p2]);
#endif #endif
} }
else { else {
/* only one face attached to that edge */ /* only one face attached to that edge */
/* an edge without another attached- the weight on this is undefined */ /* an edge without another attached- the weight on this is undefined */
copy_v3_v3(edge_normal, poly_nors[edge_ref->p1]); copy_v3_v3(edge_normal, poly_normals[edge_ref->p1]);
} }
add_v3_v3(r_vert_nors[edge->v1], edge_normal); add_v3_v3(r_vert_nors[edge->v1], edge_normal);
add_v3_v3(r_vert_nors[edge->v2], edge_normal); add_v3_v3(r_vert_nors[edge->v2], edge_normal);
@ -131,7 +131,7 @@ static void mesh_calc_hq_normal(Mesh *mesh,
} }
/* normalize vertex normals and assign */ /* normalize vertex normals and assign */
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
for (int i = 0; i < verts_num; i++) { for (int i = 0; i < verts_num; i++) {
if (normalize_v3(r_vert_nors[i]) == 0.0f) { if (normalize_v3(r_vert_nors[i]) == 0.0f) {
copy_v3_v3(r_vert_nors[i], vert_normals[i]); copy_v3_v3(r_vert_nors[i], vert_normals[i]);
@ -176,7 +176,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
int *edge_order = nullptr; int *edge_order = nullptr;
float(*vert_nors)[3] = nullptr; float(*vert_nors)[3] = nullptr;
const float(*poly_nors)[3] = nullptr; blender::Span<blender::float3> poly_normals;
const bool need_poly_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || const bool need_poly_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) ||
(smd->flag & MOD_SOLIDIFY_EVEN) || (smd->flag & MOD_SOLIDIFY_EVEN) ||
@ -205,7 +205,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
/* array size is doubled in case of using a shell */ /* array size is doubled in case of using a shell */
const uint stride = do_shell ? 2 : 1; const uint stride = do_shell ? 2 : 1;
const float(*mesh_vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh); const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);
@ -216,7 +216,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (need_poly_normals) { if (need_poly_normals) {
/* calculate only face normals */ /* calculate only face normals */
poly_nors = BKE_mesh_poly_normals_ensure(mesh); poly_normals = mesh->poly_normals();
} }
STACK_INIT(new_vert_arr, verts_num * 2); STACK_INIT(new_vert_arr, verts_num * 2);
@ -315,7 +315,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
vert_nors = static_cast<float(*)[3]>(MEM_calloc_arrayN(verts_num, sizeof(float[3]), __func__)); vert_nors = static_cast<float(*)[3]>(MEM_calloc_arrayN(verts_num, sizeof(float[3]), __func__));
mesh_calc_hq_normal(mesh, mesh_calc_hq_normal(mesh,
poly_nors, poly_normals,
vert_nors vert_nors
#ifdef USE_NONMANIFOLD_WORKAROUND #ifdef USE_NONMANIFOLD_WORKAROUND
, ,
@ -540,8 +540,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
for (uint i = 0; i < edges_num; i++, edge++) { for (uint i = 0; i < edges_num; i++, edge++) {
if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) &&
!ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) {
const float *n0 = poly_nors[edge_user_pairs[i][0]]; const float *n0 = poly_normals[edge_user_pairs[i][0]];
const float *n1 = poly_nors[edge_user_pairs[i][1]]; const float *n1 = poly_normals[edge_user_pairs[i][1]];
sub_v3_v3v3(e, orig_vert_positions[edge->v1], orig_vert_positions[edge->v2]); sub_v3_v3v3(e, orig_vert_positions[edge->v1], orig_vert_positions[edge->v2]);
normalize_v3(e); normalize_v3(e);
const float angle = angle_signed_on_axis_v3v3_v3(n0, n1, e); const float angle = angle_signed_on_axis_v3v3_v3(n0, n1, e);
@ -606,7 +606,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
madd_v3_v3fl(vert_positions[vert_index], vert_nors[i], ofs_new_vgroup); madd_v3_v3fl(vert_positions[vert_index], vert_nors[i], ofs_new_vgroup);
} }
else { else {
madd_v3_v3fl(vert_positions[vert_index], mesh_vert_normals[i], ofs_new_vgroup); madd_v3_v3fl(vert_positions[vert_index], vert_normals[i], ofs_new_vgroup);
} }
} }
} }
@ -658,7 +658,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
madd_v3_v3fl(vert_positions[vert_index], vert_nors[i], ofs_new_vgroup); madd_v3_v3fl(vert_positions[vert_index], vert_nors[i], ofs_new_vgroup);
} }
else { else {
madd_v3_v3fl(vert_positions[vert_index], mesh_vert_normals[i], ofs_new_vgroup); madd_v3_v3fl(vert_positions[vert_index], vert_normals[i], ofs_new_vgroup);
} }
} }
} }
@ -710,7 +710,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
vert_nors = static_cast<float(*)[3]>( vert_nors = static_cast<float(*)[3]>(
MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno")); MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno"));
for (i = 0; i < verts_num; i++) { for (i = 0; i < verts_num; i++) {
copy_v3_v3(vert_nors[i], mesh_vert_normals[i]); copy_v3_v3(vert_nors[i], vert_normals[i]);
} }
} }
@ -746,14 +746,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if ((check_non_manifold == false) || if ((check_non_manifold == false) ||
LIKELY(!BLI_BITMAP_TEST(edge_tmp_tag, ml[i_curr].e) && LIKELY(!BLI_BITMAP_TEST(edge_tmp_tag, ml[i_curr].e) &&
!BLI_BITMAP_TEST(edge_tmp_tag, ml[i_next].e))) { !BLI_BITMAP_TEST(edge_tmp_tag, ml[i_next].e))) {
vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_nors[i]) * vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_normals[i]) *
angle; angle;
} }
else { else {
vert_angles[vidx] += angle; vert_angles[vidx] += angle;
} }
#else #else
vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_nors[i]) * angle; vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_normals[i]) *
angle;
#endif #endif
/* --- end non-angle-calc section --- */ /* --- end non-angle-calc section --- */
@ -837,8 +838,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
for (i = 0; i < edges_num; i++, edge++) { for (i = 0; i < edges_num; i++, edge++) {
if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) &&
!ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) {
const float *n0 = poly_nors[edge_user_pairs[i][0]]; const float *n0 = poly_normals[edge_user_pairs[i][0]];
const float *n1 = poly_nors[edge_user_pairs[i][1]]; const float *n1 = poly_normals[edge_user_pairs[i][1]];
if (do_angle_clamp) { if (do_angle_clamp) {
const float angle = M_PI - angle_normalized_v3v3(n0, n1); const float angle = M_PI - angle_normalized_v3v3(n0, n1);
vert_angs[edge->v1] = max_ff(vert_angs[edge->v1], angle); vert_angs[edge->v1] = max_ff(vert_angs[edge->v1], angle);
@ -976,7 +977,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
uint i; uint i;
/* flip vertex normals for copied verts */ /* flip vertex normals for copied verts */
for (i = 0; i < verts_num; i++) { for (i = 0; i < verts_num; i++) {
negate_v3((float *)mesh_vert_normals[i]); negate_v3((float *)&vert_normals[i].x);
} }
} }
@ -1183,10 +1184,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
normalize_v3_v3(nor_cpy, edge_vert_nos[edge_orig.v1]); normalize_v3_v3(nor_cpy, edge_vert_nos[edge_orig.v1]);
for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ for (k = 0; k < 2; k++) { /* loop over both verts of the edge */
copy_v3_v3(nor, mesh_vert_normals[*(&edge.v1 + k)]); copy_v3_v3(nor, vert_normals[*(&edge.v1 + k)]);
add_v3_v3(nor, nor_cpy); add_v3_v3(nor, nor_cpy);
normalize_v3(nor); normalize_v3(nor);
copy_v3_v3((float *)mesh_vert_normals[*(&edge.v1 + k)], nor); copy_v3_v3((float *)&vert_normals[*(&edge.v1 + k)].x, nor);
} }
} }

View File

@ -207,9 +207,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
#define MOD_SOLIDIFY_EMPTY_TAG uint(-1) #define MOD_SOLIDIFY_EMPTY_TAG uint(-1)
/* Calculate only face normals. Copied because they are modified directly below. */ /* Calculate only face normals. Copied because they are modified directly below. */
float(*poly_nors)[3] = static_cast<float(*)[3]>( blender::Array<blender::float3> poly_nors = mesh->poly_normals();
MEM_malloc_arrayN(polys_num, sizeof(float[3]), __func__));
memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * polys_num);
NewFaceRef *face_sides_arr = static_cast<NewFaceRef *>( NewFaceRef *face_sides_arr = static_cast<NewFaceRef *>(
MEM_malloc_arrayN(polys_num * 2, sizeof(*face_sides_arr), __func__)); MEM_malloc_arrayN(polys_num * 2, sizeof(*face_sides_arr), __func__));
@ -2671,7 +2669,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(p->link_edges); MEM_freeN(p->link_edges);
} }
MEM_freeN(face_sides_arr); MEM_freeN(face_sides_arr);
MEM_freeN(poly_nors);
} }
#undef MOD_SOLIDIFY_EMPTY_TAG #undef MOD_SOLIDIFY_EMPTY_TAG

View File

@ -144,9 +144,9 @@ static void waveModifier_do(WaveModifierData *md,
float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */ float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */
const bool invert_group = (wmd->flag & MOD_WAVE_INVERT_VGROUP) != 0; const bool invert_group = (wmd->flag & MOD_WAVE_INVERT_VGROUP) != 0;
const float(*vert_normals)[3] = nullptr; blender::Span<blender::float3> vert_normals;
if ((wmd->flag & MOD_WAVE_NORM) && (mesh != nullptr)) { if ((wmd->flag & MOD_WAVE_NORM) && (mesh != nullptr)) {
vert_normals = BKE_mesh_vert_normals_ensure(mesh); vert_normals = mesh->vert_normals();
} }
if (wmd->objectcenter != nullptr) { if (wmd->objectcenter != nullptr) {
@ -266,7 +266,7 @@ static void waveModifier_do(WaveModifierData *md,
/* Apply weight & falloff. */ /* Apply weight & falloff. */
amplit *= def_weight * falloff_fac; amplit *= def_weight * falloff_fac;
if (vert_normals) { if (!vert_normals.is_empty()) {
/* move along normals */ /* move along normals */
if (wmd->flag & MOD_WAVE_NORM_X) { if (wmd->flag & MOD_WAVE_NORM_X) {
co[0] += (lifefac * amplit) * vert_normals[i][0]; co[0] += (lifefac * amplit) * vert_normals[i][0];

View File

@ -1161,14 +1161,17 @@ static PyObject *C_BVHTree_FromObject(PyObject * /*cls*/, PyObject *args, PyObje
uint i; uint i;
int *orig_index = nullptr; int *orig_index = nullptr;
float(*orig_normal)[3] = nullptr; blender::float3 *orig_normal = nullptr;
tree = BLI_bvhtree_new(int(tris_len), epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT); tree = BLI_bvhtree_new(int(tris_len), epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
if (tree) { if (tree) {
orig_index = static_cast<int *>( orig_index = static_cast<int *>(
MEM_mallocN(sizeof(*orig_index) * size_t(tris_len), __func__)); MEM_mallocN(sizeof(*orig_index) * size_t(tris_len), __func__));
if (!BKE_mesh_poly_normals_are_dirty(mesh)) { if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
orig_normal = static_cast<float(*)[3]>(MEM_dupallocN(BKE_mesh_poly_normals_ensure(mesh))); const blender::Span<blender::float3> poly_normals = mesh->poly_normals();
orig_normal = static_cast<blender::float3 *>(
MEM_malloc_arrayN(size_t(mesh->totpoly), sizeof(blender::float3), __func__));
blender::MutableSpan(orig_normal, poly_normals.size()).copy_from(poly_normals);
} }
for (i = 0; i < tris_len; i++, lt++) { for (i = 0; i < tris_len; i++, lt++) {
@ -1193,8 +1196,14 @@ static PyObject *C_BVHTree_FromObject(PyObject * /*cls*/, PyObject *args, PyObje
BKE_id_free(nullptr, mesh); BKE_id_free(nullptr, mesh);
} }
return bvhtree_CreatePyObject( return bvhtree_CreatePyObject(tree,
tree, epsilon, coords, coords_len, tris, tris_len, orig_index, orig_normal); epsilon,
coords,
coords_len,
tris,
tris_len,
orig_index,
reinterpret_cast<float(*)[3]>(orig_normal));
} }
} }
#endif /* MATH_STANDALONE */ #endif /* MATH_STANDALONE */

View File

@ -500,7 +500,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval
CustomData_get_layer(&me_eval->ldata, CD_NORMAL)); CustomData_get_layer(&me_eval->ldata, CD_NORMAL));
} }
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me); const blender::Span<blender::float3> vert_normals = me->vert_normals();
for (i = 0; i < tottri; i++) { for (i = 0; i < tottri; i++) {
const MLoopTri *lt = &looptri[i]; const MLoopTri *lt = &looptri[i];
const MPoly &poly = polys[lt->poly]; const MPoly &poly = polys[lt->poly];

View File

@ -61,7 +61,7 @@ struct MultiresBakeResult {
struct MResolvePixelData { struct MResolvePixelData {
const float (*vert_positions)[3]; const float (*vert_positions)[3];
const float (*vert_normals)[3]; const blender::float3 *vert_normals;
int verts_num; int verts_num;
const MPoly *polys; const MPoly *polys;
const int *material_indices; const int *material_indices;
@ -71,7 +71,7 @@ struct MResolvePixelData {
float uv_offset[2]; float uv_offset[2];
const MLoopTri *mlooptri; const MLoopTri *mlooptri;
float *pvtangent; float *pvtangent;
const float (*precomputed_normals)[3]; const blender::float3 *poly_normals;
int w, h; int w, h;
int tri_index; int tri_index;
DerivedMesh *lores_dm, *hires_dm; DerivedMesh *lores_dm, *hires_dm;
@ -123,8 +123,8 @@ static void multiresbake_get_normal(const MResolvePixelData *data,
copy_v3_v3(r_normal, data->vert_normals[vi]); copy_v3_v3(r_normal, data->vert_normals[vi]);
} }
else { else {
if (data->precomputed_normals) { if (data->poly_normals) {
copy_v3_v3(r_normal, data->precomputed_normals[poly_index]); copy_v3_v3(r_normal, data->poly_normals[poly_index]);
} }
else { else {
copy_v3_v3( copy_v3_v3(
@ -497,8 +497,8 @@ static void do_multires_bake(MultiresBakeRender *bkr,
temp_mesh->edges_for_write().copy_from({dm->getEdgeArray(dm), temp_mesh->totedge}); temp_mesh->edges_for_write().copy_from({dm->getEdgeArray(dm), temp_mesh->totedge});
temp_mesh->polys_for_write().copy_from({dm->getPolyArray(dm), temp_mesh->totpoly}); temp_mesh->polys_for_write().copy_from({dm->getPolyArray(dm), temp_mesh->totpoly});
temp_mesh->loops_for_write().copy_from({dm->getLoopArray(dm), temp_mesh->totloop}); temp_mesh->loops_for_write().copy_from({dm->getLoopArray(dm), temp_mesh->totloop});
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(temp_mesh); const blender::Span<blender::float3> vert_normals = temp_mesh->vert_normals();
const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(temp_mesh); const blender::Span<blender::float3> poly_normals = temp_mesh->poly_normals();
if (require_tangent) { if (require_tangent) {
if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) { if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
@ -515,8 +515,8 @@ static void do_multires_bake(MultiresBakeRender *bkr,
true, true,
nullptr, nullptr,
0, 0,
vert_normals, reinterpret_cast<const float(*)[3]>(vert_normals.data()),
poly_normals, reinterpret_cast<const float(*)[3]>(poly_normals.data()),
(const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL), (const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL),
(const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* May be nullptr. */ (const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* May be nullptr. */
/* result */ /* result */
@ -560,14 +560,14 @@ static void do_multires_bake(MultiresBakeRender *bkr,
handle->data.sharp_faces = static_cast<const bool *>( handle->data.sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face")); CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face"));
handle->data.vert_positions = positions; handle->data.vert_positions = positions;
handle->data.vert_normals = vert_normals; handle->data.vert_normals = vert_normals.data();
handle->data.verts_num = dm->getNumVerts(dm); handle->data.verts_num = dm->getNumVerts(dm);
handle->data.mloopuv = mloopuv; handle->data.mloopuv = mloopuv;
BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset);
handle->data.mlooptri = mlooptri; handle->data.mlooptri = mlooptri;
handle->data.mloop = mloop; handle->data.mloop = mloop;
handle->data.pvtangent = pvtangent; handle->data.pvtangent = pvtangent;
handle->data.precomputed_normals = poly_normals; /* don't strictly need this */ handle->data.poly_normals = poly_normals.data(); /* don't strictly need this */
handle->data.w = ibuf->x; handle->data.w = ibuf->x;
handle->data.h = ibuf->y; handle->data.h = ibuf->y;
handle->data.lores_dm = dm; handle->data.lores_dm = dm;