Mesh: Move functions to C++ header #105416

Merged
Hans Goudey merged 18 commits from HooglyBoogly/blender:mesh-header-cleanup into main 2023-03-12 22:29:27 +01:00
295 changed files with 1385 additions and 1607 deletions

View File

@ -316,24 +316,10 @@ 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 *polys,
const float (*vert_positions)[3],
int totvert,
int totloop,
int totpoly,
struct MLoopTri *mlooptri);
/**
* A version of #BKE_mesh_recalc_looptri which takes pre-calculated polygon normals
* (used to avoid having to calculate the face normal for NGON tessellation).
*
* \note Only use this function if normals have already been calculated, there is no need
* to calculate normals just to use this function as it will cause the normals for triangles
* to be calculated which aren't needed for tessellation.
*/
void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
const struct MPoly *polys,
const float (*vert_positions)[3],
int totloop,
int totpoly,
struct MLoopTri *mlooptri,
const float (*poly_normals)[3]);
/* *** mesh_normals.cc *** */
@ -409,63 +395,17 @@ bool BKE_mesh_vert_normals_are_dirty(const struct Mesh *mesh);
*/
bool BKE_mesh_poly_normals_are_dirty(const struct Mesh *mesh);
void BKE_mesh_calc_poly_normal(const struct MPoly *polys,
const struct MLoop *loopstart,
void BKE_mesh_calc_poly_normal(const struct MLoop *poly_loops,
int poly_size,
const float (*vert_positions)[3],
int verts_num,
float r_no[3]);
/**
* Calculate face normals directly into a result array.
*
* \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 float (*vert_positions)[3],
int mvert_len,
const struct MLoop *mloop,
int mloop_len,
const struct MPoly *polys,
int polys_len,
float (*r_poly_normals)[3]);
/**
* Calculate face and vertex normals directly into result arrays.
*
* \note Usually #BKE_mesh_vert_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 float (*vert_positions)[3],
int mvert_len,
const struct MLoop *mloop,
int mloop_len,
const struct MPoly *polys,
int polys_len,
float (*r_poly_normals)[3],
float (*r_vert_normals)[3]);
/**
* Called after calculating all modifiers.
*/
void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh);
/**
* Define sharp edges as needed to mimic 'autosmooth' from angle threshold.
*
* Used when defining an empty custom loop normals data layer,
* to keep same shading as with auto-smooth!
*
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void BKE_edges_sharp_from_angle_set(int numEdges,
const struct MLoop *mloops,
int numLoops,
const struct MPoly *polys,
const float (*poly_normals)[3],
const bool *sharp_faces,
int numPolys,
float split_angle,
bool *sharp_edges);
/**
* References a contiguous loop-fan with normal offset vars.
*/
@ -569,66 +509,6 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space,
const float custom_lnor[3],
short r_clnor_data[2]);
/* Medium-level custom normals functions. */
/**
* Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry
* (splitting edges).
*
* \param loop_to_poly_map: Optional pre-created map from loops to their polygon.
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
* \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on
* each side of the edge.
*/
void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
const float (*vert_normals)[3],
int numVerts,
const struct MEdge *edges,
int numEdges,
const struct MLoop *mloops,
float (*r_loop_normals)[3],
int numLoops,
const struct MPoly *polys,
const float (*poly_normals)[3],
int numPolys,
bool use_split_normals,
float split_angle,
const bool *sharp_edges,
const bool *sharp_faces,
const int *loop_to_poly_map,
MLoopNorSpaceArray *r_lnors_spacearr,
short (*clnors_data)[2]);
void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3],
const float (*vert_normals)[3],
int numVerts,
const struct MEdge *edges,
int numEdges,
const struct MLoop *mloops,
float (*r_custom_loop_normals)[3],
int numLoops,
const struct MPoly *polys,
const float (*poly_normals)[3],
const bool *sharp_faces,
int numPolys,
bool *sharp_edges,
short (*r_clnors_data)[2]);
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,
const struct MEdge *edges,
int numEdges,
const struct MLoop *mloops,
int numLoops,
const struct MPoly *polys,
const float (*poly_normals)[3],
const bool *sharp_faces,
int numPolys,
bool *sharp_edges,
short (*r_clnors_data)[2]);
/**
* Computes average per-vertex normals from given custom loop normals.
*
@ -660,7 +540,7 @@ void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh,
/**
* Higher level functions hiding most of the code needed around call to
* #BKE_mesh_normals_loop_custom_set().
* #normals_loop_custom_set().
*
* \param r_custom_loop_normals: is not const, since code will replace zero_v3 normals there
* with automatically computed vectors.
@ -668,7 +548,7 @@ void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh,
void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loop_normals)[3]);
/**
* Higher level functions hiding most of the code needed around call to
* #BKE_mesh_normals_loop_custom_from_verts_set().
* #normals_loop_custom_set_from_verts().
*
* \param r_custom_vert_normals: is not const, since code will replace zero_v3 normals there
* with automatically computed vectors.
@ -677,25 +557,22 @@ void BKE_mesh_set_custom_normals_from_verts(struct Mesh *mesh, float (*r_custom_
/* *** mesh_evaluate.cc *** */
void BKE_mesh_calc_poly_center(const struct MPoly *poly,
const struct MLoop *loopstart,
void BKE_mesh_calc_poly_center(const struct MLoop *poly_loops,
int poly_size,
const float (*vert_positions)[3],
int verts_num,
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 *poly,
const struct MLoop *loopstart,
const float (*vert_positions)[3]);
float BKE_mesh_calc_poly_area(const struct MLoop *poly_loops,
int poly_size,
const float (*vert_positions)[3],
int verts_num);
float BKE_mesh_calc_area(const struct Mesh *me);
void BKE_mesh_calc_poly_angles(const struct MPoly *poly,
const struct MLoop *loopstart,
const float (*vert_positions)[3],
float angles[]);
void BKE_mesh_poly_edgehash_insert(struct EdgeHash *ehash,
const struct MPoly *mp,
const struct MPoly *poly,
const struct MLoop *mloop);
void BKE_mesh_poly_edgebitmap_insert(unsigned int *edge_bitmap,
const struct MPoly *mp,
const struct MPoly *poly,
const struct MLoop *mloop);
bool BKE_mesh_center_median(const struct Mesh *me, float r_cent[3]);
@ -988,73 +865,4 @@ BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh)
}
#endif
#ifdef __cplusplus
# include "BLI_math_vector_types.hh"
# include "BLI_span.hh"
inline blender::Span<blender::float3> Mesh::vert_positions() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vert_positions(this)), this->totvert};
}
inline blender::MutableSpan<blender::float3> Mesh::vert_positions_for_write()
{
return {reinterpret_cast<blender::float3 *>(BKE_mesh_vert_positions_for_write(this)),
this->totvert};
}
inline blender::Span<MEdge> Mesh::edges() const
{
return {BKE_mesh_edges(this), this->totedge};
}
inline blender::MutableSpan<MEdge> Mesh::edges_for_write()
{
return {BKE_mesh_edges_for_write(this), this->totedge};
}
inline blender::Span<MPoly> Mesh::polys() const
{
return {BKE_mesh_polys(this), this->totpoly};
}
inline blender::MutableSpan<MPoly> Mesh::polys_for_write()
{
return {BKE_mesh_polys_for_write(this), this->totpoly};
}
inline blender::Span<MLoop> Mesh::loops() const
{
return {BKE_mesh_loops(this), this->totloop};
}
inline blender::MutableSpan<MLoop> Mesh::loops_for_write()
{
return {BKE_mesh_loops_for_write(this), this->totloop};
}
inline blender::Span<MDeformVert> Mesh::deform_verts() const
{
const MDeformVert *dverts = BKE_mesh_deform_verts(this);
if (!dverts) {
return {};
}
return {dverts, this->totvert};
}
inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
{
return {BKE_mesh_deform_verts_for_write(this), this->totvert};
}
inline blender::Span<blender::float3> Mesh::poly_normals() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_poly_normals_ensure(this)),
this->totpoly};
}
inline blender::Span<blender::float3> Mesh::vert_normals() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vert_normals_ensure(this)),
this->totvert};
}
#endif
/** \} */

View File

@ -0,0 +1,211 @@
/* SPDX-License-Identifier: GPL-2.0-or-later. */
#pragma once
/** \file
* \ingroup bke
*/
#include "BKE_mesh.h"
namespace blender::bke::mesh {
/* -------------------------------------------------------------------- */
/** \name Polygon Data Evaluation
* \{ */
/** Calculate the up direction for the polygon, depending on its winding direction. */
float3 poly_normal_calc(Span<float3> vert_positions, Span<MLoop> poly_loops);
/**
* Calculate tessellation into #MLoopTri which exist only for this purpose.
*/
void looptris_calc(Span<float3> vert_positions,
Span<MPoly> polys,
Span<MLoop> loops,
MutableSpan<MLoopTri> looptris);
/**
* A version of #looptris_calc which takes pre-calculated polygon normals
* (used to avoid having to calculate the face normal for NGON tessellation).
*
* \note Only use this function if normals have already been calculated, there is no need
* to calculate normals just to use this function.
*/
void looptris_calc_with_normals(Span<float3> vert_positions,
Span<MPoly> polys,
Span<MLoop> loops,
Span<float3> poly_normals,
MutableSpan<MLoopTri> looptris);
/** Calculate the average position of the vertices in the polygon. */
HooglyBoogly marked this conversation as resolved
Review

typo (poligon)

typo (poligon)
float3 poly_center_calc(Span<float3> vert_positions, Span<MLoop> poly_loops);
/** Calculate the surface area of the polygon described by the indexed vertices. */
float poly_area_calc(Span<float3> vert_positions, Span<MLoop> poly_loops);
/** Calculate the angles at each of the polygons's corners. */
void poly_angles_calc(Span<float3> vert_positions,
Span<MLoop> poly_loops,
MutableSpan<float> angles);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Medium-Level Normals Calculation
* \{ */
/**
* Calculate face normals directly into a result array.
*
* \note Usually #Mesh::poly_normals() is the preferred way to access face normals,
* since they may already be calculated and cached on the mesh.
*/
void normals_calc_polys(Span<float3> vert_positions,
Span<MPoly> polys,
Span<MLoop> loops,
MutableSpan<float3> poly_normals);
/**
* Calculate face and vertex normals directly into result arrays.
*
* \note Usually #Mesh::vert_normals() is the preferred way to access vertex normals,
* since they may already be calculated and cached on the mesh.
*/
void normals_calc_poly_vert(Span<float3> vert_positions,
Span<MPoly> polys,
Span<MLoop> loops,
MutableSpan<float3> poly_normals,
MutableSpan<float3> vert_normals);
/**
* Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry
* (splitting edges).
*
* \param loop_to_poly_map: Optional pre-created map from loops to their polygon.
* \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on
* each side of the edge.
*/
void normals_calc_loop(Span<float3> vert_positions,
Span<MEdge> edges,
Span<MPoly> polys,
Span<MLoop> loops,
Span<int> loop_to_poly_map,
Span<float3> vert_normals,
Span<float3> poly_normals,
const bool *sharp_edges,
const bool *sharp_faces,
bool use_split_normals,
float split_angle,
short (*clnors_data)[2],
MLoopNorSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals);
void normals_loop_custom_set(Span<float3> vert_positions,
Span<MEdge> edges,
Span<MPoly> polys,
Span<MLoop> loops,
Span<float3> vert_normals,
Span<float3> poly_normals,
const bool *sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals,
short (*r_clnors_data)[2]);
void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
Span<MEdge> edges,
Span<MPoly> polys,
Span<MLoop> loops,
Span<float3> vert_normals,
Span<float3> poly_normals,
const bool *sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
short (*r_clnors_data)[2]);
/**
* Define sharp edges as needed to mimic 'autosmooth' from angle threshold.
*
* Used when defining an empty custom loop normals data layer,
* to keep same shading as with auto-smooth!
*
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void edges_sharp_from_angle_set(Span<MPoly> polys,
Span<MLoop> loops,
Span<float3> poly_normals,
const bool *sharp_faces,
const float split_angle,
MutableSpan<bool> sharp_edges);
} // namespace blender::bke::mesh
/** \} */
/* -------------------------------------------------------------------- */
/** \name Inline Mesh Data Access
* \{ */
inline blender::Span<blender::float3> Mesh::vert_positions() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vert_positions(this)), this->totvert};
}
inline blender::MutableSpan<blender::float3> Mesh::vert_positions_for_write()
{
return {reinterpret_cast<blender::float3 *>(BKE_mesh_vert_positions_for_write(this)),
this->totvert};
}
inline blender::Span<MEdge> Mesh::edges() const
{
return {BKE_mesh_edges(this), this->totedge};
}
inline blender::MutableSpan<MEdge> Mesh::edges_for_write()
{
return {BKE_mesh_edges_for_write(this), this->totedge};
}
inline blender::Span<MPoly> Mesh::polys() const
{
return {BKE_mesh_polys(this), this->totpoly};
}
inline blender::MutableSpan<MPoly> Mesh::polys_for_write()
{
return {BKE_mesh_polys_for_write(this), this->totpoly};
}
inline blender::Span<MLoop> Mesh::loops() const
{
return {BKE_mesh_loops(this), this->totloop};
}
inline blender::MutableSpan<MLoop> Mesh::loops_for_write()
{
return {BKE_mesh_loops_for_write(this), this->totloop};
}
inline blender::Span<MDeformVert> Mesh::deform_verts() const
{
const MDeformVert *dverts = BKE_mesh_deform_verts(this);
if (!dverts) {
return {};
}
return {dverts, this->totvert};
}
inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
{
return {BKE_mesh_deform_verts_for_write(this), this->totvert};
}
inline blender::Span<blender::float3> Mesh::poly_normals() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_poly_normals_ensure(this)),
this->totpoly};
}
inline blender::Span<blender::float3> Mesh::vert_normals() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vert_normals_ensure(this)),
this->totvert};
}
/** \} */

View File

@ -221,6 +221,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode,
float ray_radius,
const struct Mesh *mesh_dst,
const float (*vert_positions_dst)[3],
int numverts_dst,
const struct MLoop *loops_dst,
const struct MPoly *polys_dst,
int numpolys_dst,

View File

@ -420,6 +420,7 @@ set(SRC
BKE_mball.h
BKE_mball_tessellate.h
BKE_mesh.h
BKE_mesh.hh
BKE_mesh_boolean_convert.hh
BKE_mesh_fair.h
BKE_mesh_iterators.h

View File

@ -42,7 +42,7 @@
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
@ -1914,14 +1914,15 @@ static void mesh_init_origspace(Mesh *mesh)
}
else {
const MLoop *l = &loops[poly.loopstart];
float p_nor[3], co[3];
float co[3];
float mat[3][3];
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
BKE_mesh_calc_poly_normal(
&poly, l, reinterpret_cast<const float(*)[3]>(positions.data()), p_nor);
const float3 p_nor = blender::bke::mesh::poly_normal_calc(
positions, loops.slice(poly.loopstart, poly.totloop));
axis_dominant_v3_to_m3(mat, p_nor);
vcos_2d.resize(poly.totloop);

View File

@ -31,7 +31,7 @@
#include "BKE_curves.hh"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_report.h"

View File

@ -6,7 +6,7 @@
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_geometry_set.hh"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_type_conversions.hh"

View File

@ -24,7 +24,7 @@
#include "BKE_attribute.hh"
#include "BKE_bvhutils.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "MEM_guardedalloc.h"

View File

@ -20,7 +20,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_curve.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@ -121,12 +121,11 @@ 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->vert_positions,
totloop,
totpoly,
cddm->dm.looptris.array_wip);
blender::bke::mesh::looptris_calc(
{reinterpret_cast<const blender::float3 *>(cddm->vert_positions), dm->numVertData},
{cddm->mpoly, totpoly},
{cddm->mloop, totloop},
{dm->looptris.array_wip, dm->looptris.num});
BLI_assert(cddm->dm.looptris.array == NULL);
atomic_cas_ptr(

View File

@ -27,7 +27,7 @@
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_pointcache.h"

View File

@ -24,7 +24,7 @@
#include "BKE_editmesh.h"
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"

View File

@ -12,7 +12,7 @@
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_curve_to_mesh.hh"

View File

@ -24,7 +24,7 @@
#include "BKE_customdata.h"
#include "BKE_data_transfer.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
@ -351,12 +351,6 @@ 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 float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
const blender::Span<MEdge> edges_dst = me_dst->edges();
const blender::Span<MPoly> polys_dst = me_dst->polys();
const blender::Span<MLoop> loops_dst = me_dst->loops();
CustomData *ldata_dst = &me_dst->ldata;
const bool use_split_nors_dst = (me_dst->flag & ME_AUTOSMOOTH) != 0;
@ -366,17 +360,16 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
BLI_assert(CustomData_get_layer(&me_src->ldata, CD_NORMAL) != nullptr);
(void)me_src;
float(*loop_nors_dst)[3];
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>(
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop));
/* Cache loop nors into a temp CDLayer. */
loop_nors_dst = static_cast<float(*)[3]>(
blender::float3 *loop_nors_dst = static_cast<blender::float3 *>(
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop));
const bool do_loop_nors_dst = (loop_nors_dst == nullptr);
if (do_loop_nors_dst) {
loop_nors_dst = static_cast<float(*)[3]>(
CustomData_add_layer(ldata_dst, CD_NORMAL, CD_SET_DEFAULT, nullptr, loops_dst.size()));
loop_nors_dst = static_cast<blender::float3 *>(
CustomData_add_layer(ldata_dst, CD_NORMAL, CD_SET_DEFAULT, nullptr, me_dst->totloop));
CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
}
if (dirty_nors_dst || do_loop_nors_dst) {
@ -384,24 +377,20 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face"));
BKE_mesh_normals_loop_split(positions_dst,
BKE_mesh_vert_normals_ensure(me_dst),
num_verts_dst,
edges_dst.data(),
edges_dst.size(),
loops_dst.data(),
loop_nors_dst,
loops_dst.size(),
polys_dst.data(),
BKE_mesh_poly_normals_ensure(me_dst),
polys_dst.size(),
use_split_nors_dst,
split_angle_dst,
sharp_edges,
sharp_faces,
nullptr,
nullptr,
custom_nors_dst);
blender::bke::mesh::normals_calc_loop(me_dst->vert_positions(),
me_dst->edges(),
me_dst->polys(),
me_dst->loops(),
{},
me_dst->vert_normals(),
me_dst->poly_normals(),
sharp_edges,
sharp_faces,
use_split_nors_dst,
split_angle_dst,
custom_nors_dst,
nullptr,
{loop_nors_dst, me_dst->totloop});
}
}
}
@ -418,47 +407,35 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/,
if (!changed) {
return;
}
/* Bake edited destination loop normals into custom normals again. */
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert;
const blender::Span<MEdge> edges_dst = me_dst->edges();
blender::MutableSpan<MPoly> polys_dst = me_dst->polys_for_write();
blender::MutableSpan<MLoop> loops_dst = me_dst->loops_for_write();
CustomData *ldata_dst = &me_dst->ldata;
const float(*poly_nors_dst)[3] = BKE_mesh_poly_normals_ensure(me_dst);
float(*loop_nors_dst)[3] = static_cast<float(*)[3]>(
blender::float3 *loop_nors_dst = static_cast<blender::float3 *>(
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop));
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>(
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop));
if (!custom_nors_dst) {
custom_nors_dst = static_cast<short(*)[2]>(CustomData_add_layer(
ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, loops_dst.size()));
ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, me_dst->totloop));
}
bke::MutableAttributeAccessor attributes = me_dst->attributes_for_write();
bke::SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE);
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face"));
/* Note loop_nors_dst contains our custom normals as transferred from source... */
BKE_mesh_normals_loop_custom_set(positions_dst,
BKE_mesh_vert_normals_ensure(me_dst),
num_verts_dst,
edges_dst.data(),
edges_dst.size(),
loops_dst.data(),
loop_nors_dst,
loops_dst.size(),
polys_dst.data(),
poly_nors_dst,
static_cast<const bool *>(CustomData_get_layer_named(
&me_dst->pdata, CD_PROP_BOOL, "sharp_face")),
polys_dst.size(),
sharp_edges.span.data(),
custom_nors_dst);
blender::bke::mesh::normals_loop_custom_set(me_dst->vert_positions(),
me_dst->edges(),
me_dst->polys(),
me_dst->loops(),
me_dst->vert_normals(),
me_dst->poly_normals(),
sharp_faces,
sharp_edges.span,
{loop_nors_dst, me_dst->totloop},
custom_nors_dst);
sharp_edges.finish();
}
}
@ -1715,6 +1692,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
ray_radius,
me_dst,
positions_dst,
num_verts_dst,
loops_dst.data(),
polys_dst.data(),
polys_dst.size(),

View File

@ -31,7 +31,7 @@
#include "BKE_customdata.h"
#include "BKE_data_transfer.h"
#include "BKE_deform.h" /* own include */
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"

View File

@ -36,7 +36,7 @@
#include "BKE_key.h"
#include "BKE_lib_id.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_vfont.h"

View File

@ -48,7 +48,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"

View File

@ -19,7 +19,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_object.h"

View File

@ -14,7 +14,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_tangent.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_tangent.h" /* for utility functions */
#include "MEM_guardedalloc.h"

View File

@ -56,7 +56,7 @@
# include "BKE_colortools.h"
# include "BKE_customdata.h"
# include "BKE_deform.h"
# include "BKE_mesh.h"
# include "BKE_mesh.hh"
# include "BKE_mesh_runtime.h"
# include "BKE_object.h"
# include "BKE_particle.h"

View File

@ -12,7 +12,7 @@
#include "BKE_geometry_fields.hh"
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "FN_multi_function_builder.hh"

View File

@ -7,7 +7,7 @@
#include "BKE_geometry_fields.hh"
#include "BKE_geometry_set.hh"
#include "BKE_instances.hh"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_type_conversions.hh"

View File

@ -11,7 +11,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_pointcloud.h"

View File

@ -4,7 +4,7 @@
#include "BKE_geometry_set_instances.hh"
#include "BKE_instances.hh"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_pointcloud.h"

View File

@ -43,7 +43,7 @@
#include "BKE_gpencil_geom.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_object.h"
#include "DEG_depsgraph_query.h"

View File

@ -42,7 +42,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_scene.h"
#include "RNA_access.h"
@ -2258,23 +2258,19 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
}
if (poly_normals_needed) {
BKE_mesh_calc_normals_poly(positions,
mesh->totvert,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
poly_normals);
blender::bke::mesh::normals_calc_polys(
{reinterpret_cast<const blender::float3 *>(positions), mesh->totvert},
polys,
loops,
{reinterpret_cast<blender::float3 *>(poly_normals), polys.size()});
}
if (vert_normals_needed) {
BKE_mesh_calc_normals_poly_and_vertex(positions,
mesh->totvert,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
poly_normals,
vert_normals);
blender::bke::mesh::normals_calc_poly_vert(
{reinterpret_cast<const blender::float3 *>(positions), mesh->totvert},
polys,
loops,
{reinterpret_cast<blender::float3 *>(poly_normals), polys.size()},
{reinterpret_cast<blender::float3 *>(vert_normals), mesh->totvert});
}
if (loop_normals_needed) {
short(*clnors)[2] = static_cast<short(*)[2]>(CustomData_get_layer_for_write(
@ -2283,24 +2279,21 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
BKE_mesh_normals_loop_split(positions,
vert_normals,
mesh->totvert,
edges.data(),
mesh->totedge,
loops.data(),
r_loop_normals,
loops.size(),
polys.data(),
poly_normals,
polys.size(),
(mesh->flag & ME_AUTOSMOOTH) != 0,
mesh->smoothresh,
sharp_edges,
sharp_faces,
nullptr,
nullptr,
clnors);
blender::bke::mesh::normals_calc_loop(
{reinterpret_cast<const blender::float3 *>(positions), mesh->totvert},
edges,
polys,
loops,
{},
{reinterpret_cast<blender::float3 *>(vert_normals), mesh->totvert},
{reinterpret_cast<blender::float3 *>(poly_normals), polys.size()},
sharp_edges,
sharp_faces,
(mesh->flag & ME_AUTOSMOOTH) != 0,
mesh->smoothresh,
clnors,
nullptr,
{reinterpret_cast<blender::float3 *>(r_loop_normals), loops.size()});
}
if (free_vert_normals) {

View File

@ -20,7 +20,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"

View File

@ -56,7 +56,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_object.h"

View File

@ -48,7 +48,7 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mball_tessellate.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_object.h"
#include "BKE_scene.h"

View File

@ -30,7 +30,7 @@
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_mball_tessellate.h" /* own include */
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_object.h"
#include "BKE_scene.h"

View File

@ -50,7 +50,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_legacy_convert.h"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
@ -1854,29 +1854,22 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
const Span<float3> positions = mesh->vert_positions();
const Span<MEdge> edges = mesh->edges();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(positions.data()),
BKE_mesh_vert_normals_ensure(mesh),
positions.size(),
edges.data(),
edges.size(),
loops.data(),
r_corner_normals,
loops.size(),
polys.data(),
BKE_mesh_poly_normals_ensure(mesh),
polys.size(),
use_split_normals,
split_angle,
sharp_edges,
sharp_faces,
nullptr,
r_lnors_spacearr,
clnors);
blender::bke::mesh::normals_calc_loop(
mesh->vert_positions(),
mesh->edges(),
mesh->polys(),
mesh->loops(),
{},
mesh->vert_normals(),
mesh->poly_normals(),
sharp_edges,
sharp_faces,
use_split_normals,
split_angle,
clnors,
nullptr,
{reinterpret_cast<float3 *>(r_corner_normals), mesh->totloop});
}
void BKE_mesh_calc_normals_split(Mesh *mesh)

View File

@ -12,7 +12,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_boolean_convert.hh"
#include "BLI_alloca.h"
@ -547,11 +547,7 @@ static void get_poly2d_cos(const Mesh *me,
const Span<MLoop> poly_loops = loops.slice(poly->loopstart, poly->totloop);
/* Project coordinates to 2d in cos_2d, using normal as projection axis. */
float axis_dominant[3];
BKE_mesh_calc_poly_normal(poly,
&loops[poly->loopstart],
reinterpret_cast<const float(*)[3]>(positions.data()),
axis_dominant);
const float3 axis_dominant = bke::mesh::poly_normal_calc(positions, poly_loops);
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
for (const int i : poly_loops.index_range()) {
float3 co = positions[poly_loops[i].v];

View File

@ -15,7 +15,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
namespace blender::bke::calc_edges {

View File

@ -40,7 +40,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"

View File

@ -23,7 +23,7 @@
# include "BKE_customdata.h"
# include "BKE_mesh.h"
# include "BKE_mesh.hh"
# include "BLI_dynstr.h"

View File

@ -24,10 +24,9 @@
#include "BLI_utildefines.h"
#include "BLI_virtual_array.hh"
#include "BKE_customdata.h"
#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "BKE_customdata.h"
#include "BKE_mesh.hh"
#include "BKE_multires.h"
using blender::float3;
@ -39,65 +38,81 @@ using blender::VArray;
/** \name Polygon Calculations
* \{ */
static void mesh_calc_ngon_center(const MPoly *poly,
const MLoop *loopstart,
const float (*positions)[3],
float cent[3])
namespace blender::bke::mesh {
static float3 poly_center_calc_ngon(const Span<float3> vert_positions,
const Span<MLoop> poly_loops)
{
const float w = 1.0f / float(poly->totloop);
const float w = 1.0f / float(poly_loops.size());
zero_v3(cent);
for (int i = 0; i < poly->totloop; i++) {
madd_v3_v3fl(cent, positions[(loopstart++)->v], w);
float3 center(0);
for (const int i : poly_loops.index_range()) {
center += vert_positions[poly_loops[i].v] * w;
}
return center;
}
void BKE_mesh_calc_poly_center(const MPoly *poly,
const MLoop *loopstart,
float3 poly_center_calc(const Span<float3> vert_positions, const Span<MLoop> poly_loops)
{
if (poly_loops.size() == 3) {
float3 center;
mid_v3_v3v3v3(center,
vert_positions[poly_loops[0].v],
vert_positions[poly_loops[1].v],
vert_positions[poly_loops[2].v]);
return center;
}
if (poly_loops.size() == 4) {
float3 center;
mid_v3_v3v3v3v3(center,
vert_positions[poly_loops[0].v],
vert_positions[poly_loops[1].v],
vert_positions[poly_loops[2].v],
vert_positions[poly_loops[3].v]);
return center;
}
return poly_center_calc_ngon(vert_positions, poly_loops);
}
} // namespace blender::bke::mesh
void BKE_mesh_calc_poly_center(const MLoop *poly_loops,
const int poly_size,
const float (*vert_positions)[3],
const int verts_num,
float r_cent[3])
{
if (poly->totloop == 3) {
mid_v3_v3v3v3(r_cent,
vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v]);
}
else if (poly->totloop == 4) {
mid_v3_v3v3v3v3(r_cent,
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(poly, loopstart, vert_positions, r_cent);
}
copy_v3_v3(r_cent,
blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions), verts_num},
{poly_loops, poly_size}));
}
float BKE_mesh_calc_poly_area(const MPoly *poly,
const MLoop *loopstart,
const float (*vert_positions)[3])
namespace blender::bke::mesh {
float poly_area_calc(const Span<float3> vert_positions, const Span<MLoop> poly_loops)
{
if (poly->totloop == 3) {
return area_tri_v3(vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v]);
if (poly_loops.size() == 3) {
return area_tri_v3(vert_positions[poly_loops[0].v],
vert_positions[poly_loops[1].v],
vert_positions[poly_loops[2].v]);
}
const MLoop *l_iter = loopstart;
float(*vertexcos)[3] = (float(*)[3])BLI_array_alloca(vertexcos, size_t(poly->totloop));
/* pack vertex cos into an array for area_poly_v3 */
for (int i = 0; i < poly->totloop; i++, l_iter++) {
copy_v3_v3(vertexcos[i], vert_positions[l_iter->v]);
Array<float3, 32> poly_coords(poly_loops.size());
for (const int i : poly_loops.index_range()) {
poly_coords[i] = vert_positions[poly_loops[i].v];
}
return area_poly_v3((const float(*)[3])poly_coords.data(), poly_loops.size());
}
/* finally calculate the area */
float area = area_poly_v3((const float(*)[3])vertexcos, uint(poly->totloop));
} // namespace blender::bke::mesh
return area;
float BKE_mesh_calc_poly_area(const MLoop *poly_loops,
const int poly_size,
const float (*vert_positions)[3],
const int verts_num)
{
return blender::bke::mesh::poly_area_calc(
{reinterpret_cast<const float3 *>(vert_positions), verts_num}, {poly_loops, poly_size});
}
float BKE_mesh_calc_area(const Mesh *me)
@ -108,14 +123,14 @@ float BKE_mesh_calc_area(const Mesh *me)
float total_area = 0.0f;
for (const MPoly &poly : polys) {
total_area += BKE_mesh_calc_poly_area(
&poly, &loops[poly.loopstart], reinterpret_cast<const float(*)[3]>(positions.data()));
total_area += blender::bke::mesh::poly_area_calc(positions,
loops.slice(poly.loopstart, poly.totloop));
}
return total_area;
}
static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *poly,
const MLoop *loopstart,
static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MLoop *poly_loops,
const int poly_size,
const float (*positions)[3],
float r_cent[3])
{
@ -124,11 +139,11 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *poly,
zero_v3(r_cent);
v_pivot = positions[loopstart[0].v];
v_step1 = positions[loopstart[1].v];
v_pivot = positions[poly_loops[0].v];
v_step1 = positions[poly_loops[1].v];
for (int i = 2; i < poly->totloop; i++) {
const float *v_step2 = positions[loopstart[i].v];
for (int i = 2; i < poly_size; i++) {
const float *v_step2 = positions[poly_loops[i].v];
/* Calculate the 6x volume of the tetrahedron formed by the 3 vertices
* of the triangle and the origin as the fourth vertex */
@ -151,26 +166,27 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *poly,
return total_volume;
}
namespace blender::bke::mesh {
/**
* A version of mesh_calc_poly_volume_centroid that takes an initial reference center,
* use this to increase numeric stability as the quality of the result becomes
* very low quality as the value moves away from 0.0, see: #65986.
*/
static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *poly,
const MLoop *loopstart,
const Span<float3> positions,
const float reference_center[3],
static float mesh_calc_poly_volume_centroid_with_reference_center(const Span<float3> positions,
const Span<MLoop> poly_loops,
const float3 &reference_center,
float r_cent[3])
{
/* See: mesh_calc_poly_volume_centroid for comments. */
float v_pivot[3], v_step1[3];
float total_volume = 0.0f;
zero_v3(r_cent);
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 < poly->totloop; i++) {
sub_v3_v3v3(v_pivot, positions[poly_loops[0].v], reference_center);
sub_v3_v3v3(v_step1, positions[poly_loops[1].v], reference_center);
for (int i = 2; i < poly_loops.size(); i++) {
float v_step2[3];
sub_v3_v3v3(v_step2, positions[loopstart[i].v], reference_center);
sub_v3_v3v3(v_step2, positions[poly_loops[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++) {
@ -187,21 +203,22 @@ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *p
* - This has the advantage over #mesh_calc_poly_volume_centroid
* that it doesn't depend on solid geometry, instead it weights the surface by volume.
*/
static float mesh_calc_poly_area_centroid(const MPoly *poly,
const MLoop *loopstart,
const float (*positions)[3],
float r_cent[3])
static float poly_area_centroid_calc(const Span<float3> positions,
const Span<MLoop> poly_loops,
float r_cent[3])
{
float total_area = 0.0f;
float v1[3], v2[3], v3[3], normal[3], tri_cent[3];
float v1[3], v2[3], v3[3], tri_cent[3];
const float3 normal = blender::bke::mesh::poly_normal_calc(positions, poly_loops);
copy_v3_v3(v1, positions[poly_loops[0].v]);
copy_v3_v3(v2, positions[poly_loops[1].v]);
BKE_mesh_calc_poly_normal(poly, 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 < poly->totloop; i++) {
copy_v3_v3(v3, positions[loopstart[i].v]);
for (int i = 2; i < poly_loops.size(); i++) {
copy_v3_v3(v3, positions[poly_loops[i].v]);
float tri_area = area_tri_signed_v3(v1, v2, v3, normal);
total_area += tri_area;
@ -217,24 +234,23 @@ static float mesh_calc_poly_area_centroid(const MPoly *poly,
return total_area;
}
void BKE_mesh_calc_poly_angles(const MPoly *poly,
const MLoop *loopstart,
const float (*vert_positions)[3],
float angles[])
void poly_angles_calc(const Span<float3> vert_positions,
const Span<MLoop> poly_loops,
MutableSpan<float> angles)
{
float nor_prev[3];
float nor_next[3];
int i_this = poly->totloop - 1;
int i_this = poly_loops.size() - 1;
int i_next = 0;
sub_v3_v3v3(
nor_prev, vert_positions[loopstart[i_this - 1].v], vert_positions[loopstart[i_this].v]);
nor_prev, vert_positions[poly_loops[i_this - 1].v], vert_positions[poly_loops[i_this].v]);
normalize_v3(nor_prev);
while (i_next < poly->totloop) {
while (i_next < poly_loops.size()) {
sub_v3_v3v3(
nor_next, vert_positions[loopstart[i_this].v], vert_positions[loopstart[i_next].v]);
nor_next, vert_positions[poly_loops[i_this].v], vert_positions[poly_loops[i_next].v]);
normalize_v3(nor_next);
angles[i_this] = angle_normalized_v3v3(nor_prev, nor_next);
@ -245,6 +261,8 @@ void BKE_mesh_calc_poly_angles(const MPoly *poly,
}
}
} // namespace blender::bke::mesh
void BKE_mesh_poly_edgehash_insert(EdgeHash *ehash, const MPoly *poly, const MLoop *mloop)
{
const MLoop *ml, *ml_next;
@ -332,7 +350,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 float(*positions)[3] = BKE_mesh_vert_positions(me);
const Span<float3> positions = me->vert_positions();
const blender::Span<MPoly> polys = me->polys();
const blender::Span<MLoop> loops = me->loops();
@ -340,8 +358,8 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
/* calculate a weighted average of polygon centroids */
for (const int i : polys.index_range()) {
poly_area = mesh_calc_poly_area_centroid(
&polys[i], &loops[polys[i].loopstart], positions, poly_cent);
poly_area = blender::bke::mesh::poly_area_centroid_calc(
positions, loops.slice(polys[i].loopstart, polys[i].totloop), poly_cent);
madd_v3_v3fl(r_cent, poly_cent, poly_area);
total_area += poly_area;
@ -376,8 +394,8 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
/* calculate a weighted average of polyhedron centroids */
for (const int i : polys.index_range()) {
poly_volume = mesh_calc_poly_volume_centroid_with_reference_center(
&polys[i], &loops[polys[i].loopstart], positions, init_cent, poly_cent);
poly_volume = blender::bke::mesh::mesh_calc_poly_volume_centroid_with_reference_center(
positions, loops.slice(polys[i].loopstart, polys[i].totloop), 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);

View File

@ -16,7 +16,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_fair.h"
#include "BKE_mesh_mapping.h"

View File

@ -12,7 +12,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_iterators.h"
#include "BLI_bitmap.h"
@ -233,6 +233,7 @@ void BKE_mesh_foreach_mapped_face_center(
void *userData,
MeshForeachFlag flag)
{
using namespace blender;
if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) {
BMEditMesh *em = mesh->edit_mesh;
BMesh *bm = em->bm;
@ -267,11 +268,9 @@ void BKE_mesh_foreach_mapped_face_center(
}
}
else {
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const blender::Span<float3> positions = mesh->vert_positions();
const blender::Span<MPoly> polys = mesh->polys();
const blender::Span<MLoop> loops = mesh->loops();
float _no_buf[3];
float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : nullptr;
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
if (index) {
@ -280,22 +279,28 @@ void BKE_mesh_foreach_mapped_face_center(
if (orig == ORIGINDEX_NONE) {
continue;
}
float cent[3];
BKE_mesh_calc_poly_center(&polys[i], &loops[polys[i].loopstart], positions, cent);
const Span<MLoop> poly_loops = loops.slice(polys[i].loopstart, polys[i].totloop);
const float3 center = bke::mesh::poly_center_calc(positions, poly_loops);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(&polys[i], &loops[polys[i].loopstart], positions, no);
const float3 normal = bke::mesh::poly_normal_calc(positions, poly_loops);
func(userData, orig, center, normal);
}
else {
func(userData, orig, center, nullptr);
}
func(userData, orig, cent, no);
}
}
else {
for (const int i : polys.index_range()) {
float cent[3];
BKE_mesh_calc_poly_center(&polys[i], &loops[polys[i].loopstart], positions, cent);
const Span<MLoop> poly_loops = loops.slice(polys[i].loopstart, polys[i].totloop);
const float3 center = bke::mesh::poly_center_calc(positions, poly_loops);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(&polys[i], &loops[polys[i].loopstart], positions, no);
const float3 normal = bke::mesh::poly_normal_calc(positions, poly_loops);
func(userData, i, center, normal);
}
else {
func(userData, i, center, nullptr);
}
func(userData, i, cent, no);
}
}
}

View File

@ -27,7 +27,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_legacy_convert.h"
#include "BKE_multires.h"

View File

@ -15,7 +15,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BLI_memarena.h"

View File

@ -5,6 +5,7 @@
* \ingroup bke
*/
#include "BLI_array.hh"
#include "BLI_math.h"
#include "DNA_mesh_types.h"
@ -14,7 +15,7 @@
#include "BKE_deform.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mirror.h"
#include "BKE_modifier.h"
@ -372,8 +373,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* handle custom split normals */
if (ob->type == OB_MESH && (((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) &&
CustomData_has_layer(&result->ldata, CD_CUSTOMLOOPNORMAL) && result->totpoly > 0) {
float(*loop_normals)[3] = static_cast<float(*)[3]>(
MEM_calloc_arrayN(size_t(result->totloop), sizeof(*loop_normals), __func__));
blender::Array<blender::float3> loop_normals(result_loops.size());
CustomData *ldata = &result->ldata;
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, result->totloop));
@ -391,24 +391,20 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
CustomData_get_layer_named(&result->edata, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&result->pdata, CD_PROP_BOOL, "sharp_face"));
BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result),
BKE_mesh_vert_normals_ensure(result),
result->totvert,
result_edges.data(),
result_edges.size(),
result_loops.data(),
loop_normals,
result_loops.size(),
result_polys.data(),
BKE_mesh_poly_normals_ensure(result),
result_polys.size(),
true,
result->smoothresh,
sharp_edges,
sharp_faces,
nullptr,
&lnors_spacearr,
clnors);
blender::bke::mesh::normals_calc_loop(result->vert_positions(),
result_edges,
result_polys,
result_loops,
{},
result->vert_normals(),
result->poly_normals(),
sharp_edges,
sharp_faces,
true,
result->smoothresh,
clnors,
&lnors_spacearr,
loop_normals);
/* mirroring has to account for loops being reversed in polys in second half */
for (const int i : src_polys.index_range()) {
@ -427,7 +423,6 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
}
MEM_freeN(loop_normals);
BKE_lnor_spacearr_free(&lnors_spacearr);
}

View File

@ -21,7 +21,7 @@
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_math_vector_types.hh"
#include "BLI_math_vector.hh"
#include "BLI_memarena.h"
#include "BLI_span.hh"
#include "BLI_stack.h"
@ -34,7 +34,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "atomic_ops.h"
@ -158,6 +158,8 @@ bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh)
/** \name Mesh Normal Calculation (Polygons)
* \{ */
namespace blender::bke::mesh {
/*
* COMPUTE POLY NORMAL
*
@ -165,88 +167,77 @@ bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh)
* polygon See Graphics Gems for
* computing newell normal.
*/
static void mesh_calc_ngon_normal(const MPoly *poly,
const MLoop *loopstart,
const float (*positions)[3],
float r_normal[3])
static float3 normal_calc_ngon(const Span<float3> vert_positions, const Span<MLoop> poly_loops)
{
const int nverts = poly->totloop;
const float *v_prev = positions[loopstart[nverts - 1].v];
const float *v_curr;
zero_v3(r_normal);
float3 normal(0);
/* Newell's Method */
for (int i = 0; i < nverts; i++) {
v_curr = positions[loopstart[i].v];
add_newell_cross_v3_v3v3(r_normal, v_prev, v_curr);
const float *v_prev = vert_positions[poly_loops.last().v];
for (const int i : poly_loops.index_range()) {
const float *v_curr = vert_positions[poly_loops[i].v];
add_newell_cross_v3_v3v3(normal, v_prev, v_curr);
v_prev = v_curr;
}
if (UNLIKELY(normalize_v3(r_normal) == 0.0f)) {
r_normal[2] = 1.0f; /* other axis set to 0.0 */
if (UNLIKELY(normalize_v3(normal) == 0.0f)) {
normal[2] = 1.0f; /* other axis set to 0.0 */
}
return normal;
}
void BKE_mesh_calc_poly_normal(const MPoly *poly,
const MLoop *loopstart,
float3 poly_normal_calc(const Span<float3> vert_positions, const Span<MLoop> poly_loops)
{
if (poly_loops.size() > 4) {
return normal_calc_ngon(vert_positions, poly_loops);
}
if (poly_loops.size() == 3) {
return math::normal_tri(vert_positions[poly_loops[0].v],
vert_positions[poly_loops[1].v],
vert_positions[poly_loops[2].v]);
}
if (poly_loops.size() == 4) {
float3 normal;
normal_quad_v3(normal,
vert_positions[poly_loops[0].v],
vert_positions[poly_loops[1].v],
vert_positions[poly_loops[2].v],
vert_positions[poly_loops[3].v]);
return normal;
}
/* horrible, two sided face! */
return float3(0);
}
} // namespace blender::bke::mesh
void BKE_mesh_calc_poly_normal(const MLoop *poly_loops,
const int poly_size,
const float (*vert_positions)[3],
const int verts_num,
float r_no[3])
{
if (poly->totloop > 4) {
mesh_calc_ngon_normal(poly, loopstart, vert_positions, r_no);
}
else if (poly->totloop == 3) {
normal_tri_v3(r_no,
vert_positions[loopstart[0].v],
vert_positions[loopstart[1].v],
vert_positions[loopstart[2].v]);
}
else if (poly->totloop == 4) {
normal_quad_v3(r_no,
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;
r_no[1] = 0.0;
r_no[2] = 1.0;
}
copy_v3_v3(r_no,
blender::bke::mesh::poly_normal_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions), verts_num},
{poly_loops, poly_size}));
}
static void calculate_normals_poly(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<float3> poly_normals)
namespace blender::bke::mesh {
void normals_calc_polys(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<float3> poly_normals)
{
using namespace blender;
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],
reinterpret_cast<const float(*)[3]>(positions.data()),
poly_normals[poly_i]);
for (const int i : range) {
const MPoly &poly = polys[i];
poly_normals[i] = poly_normal_calc(positions, loops.slice(poly.loopstart, poly.totloop));
}
});
}
void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3],
const int verts_num,
const MLoop *mloop,
const int mloop_len,
const MPoly *polys,
int polys_len,
float (*r_poly_normals)[3])
{
calculate_normals_poly({reinterpret_cast<const float3 *>(vert_positions), verts_num},
{polys, polys_len},
{mloop, mloop_len},
{reinterpret_cast<float3 *>(r_poly_normals), polys_len});
}
/** \} */
/* -------------------------------------------------------------------- */
@ -256,13 +247,12 @@ void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3],
* meshes can slow down high-poly meshes. For details on performance, see D11993.
* \{ */
static void calculate_normals_poly_and_vert(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<float3> poly_normals,
MutableSpan<float3> vert_normals)
void normals_calc_poly_vert(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<float3> poly_normals,
MutableSpan<float3> vert_normals)
{
using namespace blender;
/* Zero the vertex normal array for accumulation. */
{
@ -281,7 +271,7 @@ static void calculate_normals_poly_and_vert(const Span<float3> positions,
const int i_end = poly.totloop - 1;
/* Polygon Normal and edge-vector. */
/* Inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors. */
/* Inline version of #poly_normal_calc, also does edge-vectors. */
{
zero_v3(pnor);
/* Newell's Method */
@ -346,21 +336,7 @@ static void calculate_normals_poly_and_vert(const Span<float3> positions,
}
}
void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3],
const int mvert_len,
const MLoop *mloop,
const int mloop_len,
const MPoly *polys,
const int polys_len,
float (*r_poly_normals)[3],
float (*r_vert_normals)[3])
{
calculate_normals_poly_and_vert({reinterpret_cast<const float3 *>(vert_positions), mvert_len},
{polys, polys_len},
{mloop, mloop_len},
{reinterpret_cast<float3 *>(r_poly_normals), polys_len},
{reinterpret_cast<float3 *>(r_vert_normals), mvert_len});
}
} // namespace blender::bke::mesh
/** \} */
@ -397,15 +373,12 @@ const float (*BKE_mesh_vert_normals_ensure(const Mesh *mesh))[3]
vert_normals = BKE_mesh_vert_normals_for_write(&mesh_mutable);
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_calc_normals_poly_and_vertex(reinterpret_cast<const float(*)[3]>(positions.data()),
positions.size(),
loops.data(),
loops.size(),
polys.data(),
polys.size(),
poly_normals,
vert_normals);
blender::bke::mesh::normals_calc_poly_vert(
positions,
polys,
loops,
{reinterpret_cast<float3 *>(poly_normals), mesh->totpoly},
{reinterpret_cast<float3 *>(vert_normals), mesh->totvert});
BKE_mesh_vert_normals_clear_dirty(&mesh_mutable);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
@ -441,14 +414,8 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
const Span<MLoop> loops = mesh_mutable.loops();
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_calc_normals_poly(reinterpret_cast<const float(*)[3]>(positions.data()),
positions.size(),
loops.data(),
loops.size(),
polys.data(),
polys.size(),
poly_normals);
blender::bke::mesh::normals_calc_polys(
positions, polys, loops, {reinterpret_cast<float3 *>(poly_normals), mesh->totvert});
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
});
@ -788,6 +755,8 @@ struct LoopSplitTaskDataCommon {
/* See comment about edge_to_loops below. */
#define IS_EDGE_SHARP(_e2l) ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID)
namespace blender::bke::mesh {
static void mesh_edges_sharp_tag(const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<int> loop_to_poly_map,
@ -799,7 +768,6 @@ static void mesh_edges_sharp_tag(const Span<MPoly> polys,
MutableSpan<int2> edge_to_loops,
MutableSpan<bool> r_sharp_edges)
{
using namespace blender;
const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
auto poly_is_smooth = [&](const int poly_i) {
return sharp_faces.is_empty() || !sharp_faces[poly_i];
@ -860,40 +828,34 @@ static void mesh_edges_sharp_tag(const Span<MPoly> polys,
}
}
void BKE_edges_sharp_from_angle_set(const int numEdges,
const MLoop *mloops,
const int numLoops,
const MPoly *polys,
const float (*poly_normals)[3],
const bool *sharp_faces,
const int numPolys,
const float split_angle,
bool *sharp_edges)
void edges_sharp_from_angle_set(const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<float3> poly_normals,
const bool *sharp_faces,
const float split_angle,
MutableSpan<bool> sharp_edges)
{
using namespace blender;
using namespace blender::bke;
if (split_angle >= float(M_PI)) {
/* Nothing to do! */
return;
}
/* Mapping edge -> loops. See #BKE_mesh_normals_loop_split for details. */
Array<int2> edge_to_loops(numEdges, int2(0));
/* Mapping edge -> loops. See #bke::mesh::normals_calc_loop for details. */
Array<int2> edge_to_loops(sharp_edges.size(), int2(0));
/* Simple mapping from a loop to its polygon index. */
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map({polys, numPolys},
numLoops);
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map(polys, loops.size());
mesh_edges_sharp_tag({polys, numPolys},
{mloops, numLoops},
mesh_edges_sharp_tag(polys,
loops,
loop_to_poly,
{reinterpret_cast<const float3 *>(poly_normals), numPolys},
Span<bool>(sharp_faces, sharp_faces ? numPolys : 0),
Span<bool>(sharp_edges, numEdges),
poly_normals,
Span<bool>(sharp_faces, sharp_faces ? polys.size() : 0),
sharp_edges,
true,
split_angle,
edge_to_loops,
{sharp_edges, numEdges});
sharp_edges);
}
static void loop_manifold_fan_around_vert_next(const Span<MLoop> loops,
@ -1304,8 +1266,6 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span<MLoop> mloop
static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data)
{
using namespace blender;
using namespace blender::bke;
MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
const Span<MLoop> loops = common_data->loops;
@ -1440,27 +1400,21 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
}
}
void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
const float (*vert_normals)[3],
const int numVerts,
const MEdge *edges,
const int numEdges,
const MLoop *mloops,
float (*r_loop_normals)[3],
const int numLoops,
const MPoly *polys,
const float (*poly_normals)[3],
const int numPolys,
const bool use_split_normals,
const float split_angle,
const bool *sharp_edges,
const bool *sharp_faces,
const int *loop_to_poly_map,
MLoopNorSpaceArray *r_lnors_spacearr,
short (*clnors_data)[2])
void normals_calc_loop(const Span<float3> vert_positions,
const Span<MEdge> edges,
const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<int> loop_to_poly_map,
const Span<float3> vert_normals,
const Span<float3> poly_normals,
const bool *sharp_edges,
const bool *sharp_faces,
bool use_split_normals,
float split_angle,
short (*clnors_data)[2],
MLoopNorSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals)
{
using namespace blender;
using namespace blender::bke;
/* For now this is not supported.
* If we do not use split normals, we do not generate anything fancy! */
BLI_assert(use_split_normals || !(r_lnors_spacearr));
@ -1472,12 +1426,10 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
* since we may want to use loop_normals even when mesh's 'autosmooth' is disabled
* (see e.g. mesh mapping code). As usual, we could handle that on case-by-case basis,
* but simpler to keep it well confined here. */
int poly_index;
for (poly_index = 0; poly_index < numPolys; poly_index++) {
const MPoly &poly = polys[poly_index];
int ml_index = poly.loopstart;
const int ml_index_end = ml_index + poly.totloop;
for (const int poly_index : polys.index_range()) {
const MPoly *poly = &polys[poly_index];
int ml_index = poly->loopstart;
const int ml_index_end = ml_index + poly->totloop;
const bool is_poly_flat = sharp_faces && sharp_faces[poly_index];
for (; ml_index < ml_index_end; ml_index++) {
@ -1485,7 +1437,7 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
copy_v3_v3(r_loop_normals[ml_index], poly_normals[poly_index]);
}
else {
copy_v3_v3(r_loop_normals[ml_index], vert_normals[mloops[ml_index].v]);
copy_v3_v3(r_loop_normals[ml_index], vert_normals[loops[ml_index].v]);
}
}
}
@ -1506,17 +1458,17 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
* However, if needed, we can store the negated value of loop index instead of INDEX_INVALID
* to retrieve the real value later in code).
* Note also that loose edges always have both values set to 0! */
Array<int2> edge_to_loops(numEdges, int2(0));
Array<int2> edge_to_loops(edges.size(), int2(0));
/* Simple mapping from a loop to its polygon index. */
Span<int> loop_to_poly;
Array<int> local_loop_to_poly_map;
if (loop_to_poly_map) {
loop_to_poly = {loop_to_poly_map, numLoops};
if (loop_to_poly_map.is_empty()) {
local_loop_to_poly_map = mesh_topology::build_loop_to_poly_map(polys, loops.size());
loop_to_poly = local_loop_to_poly_map;
}
else {
local_loop_to_poly_map = mesh_topology::build_loop_to_poly_map({polys, numPolys}, numLoops);
loop_to_poly = local_loop_to_poly_map;
loop_to_poly = loop_to_poly_map;
}
/* When using custom loop normals, disable the angle feature! */
@ -1533,28 +1485,27 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
r_lnors_spacearr = &_lnors_spacearr;
}
if (r_lnors_spacearr) {
BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops, MLNOR_SPACEARR_LOOP_INDEX);
BKE_lnor_spacearr_init(r_lnors_spacearr, loops.size(), MLNOR_SPACEARR_LOOP_INDEX);
}
const Span<MLoop> loops(mloops, numLoops);
/* Init data common to all tasks. */
LoopSplitTaskDataCommon common_data;
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.positions = {reinterpret_cast<const float3 *>(vert_positions), numVerts};
common_data.edges = {edges, numEdges};
common_data.polys = {polys, numPolys};
common_data.loop_normals = r_loop_normals;
common_data.clnors_data = {reinterpret_cast<short2 *>(clnors_data),
clnors_data ? loops.size() : 0};
common_data.positions = vert_positions;
common_data.edges = edges;
common_data.polys = polys;
common_data.loops = loops;
common_data.edge_to_loops = edge_to_loops;
common_data.loop_to_poly = loop_to_poly;
common_data.poly_normals = {reinterpret_cast<const float3 *>(poly_normals), numPolys};
common_data.vert_normals = {reinterpret_cast<const float3 *>(vert_normals), numVerts};
common_data.poly_normals = poly_normals;
common_data.vert_normals = vert_normals;
/* Pre-populate all loop normals as if their verts were all smooth.
* This way we don't have to compute those later! */
threading::parallel_for(IndexRange(numPolys), 1024, [&](const IndexRange range) {
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
for (const int poly_i : range) {
const MPoly &poly = polys[poly_i];
for (const int loop_i : IndexRange(poly.loopstart, poly.totloop)) {
@ -1564,18 +1515,18 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
});
/* This first loop check which edges are actually smooth, and compute edge vectors. */
mesh_edges_sharp_tag({polys, numPolys},
mesh_edges_sharp_tag(polys,
loops,
loop_to_poly,
{reinterpret_cast<const float3 *>(poly_normals), numPolys},
Span<bool>(sharp_faces, sharp_faces ? numPolys : 0),
Span<bool>(sharp_edges, sharp_edges ? numEdges : 0),
poly_normals,
Span<bool>(sharp_faces, sharp_faces ? polys.size() : 0),
Span<bool>(sharp_edges, sharp_edges ? edges.size() : 0),
check_angle,
split_angle,
edge_to_loops,
{});
if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) {
if (loops.size() < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) {
/* Not enough loops to be worth the whole threading overhead. */
loop_split_generator(nullptr, &common_data);
}
@ -1609,36 +1560,28 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3],
* 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 float (*positions)[3],
const float (*vert_normals)[3],
const int numVerts,
const MEdge *edges,
const int numEdges,
const MLoop *mloops,
float (*r_custom_loop_normals)[3],
const int numLoops,
const MPoly *polys,
const float (*poly_normals)[3],
static void mesh_normals_loop_custom_set(Span<float3> positions,
Span<MEdge> edges,
Span<MPoly> polys,
Span<MLoop> loops,
Span<float3> vert_normals,
Span<float3> poly_normals,
const bool *sharp_faces,
const int numPolys,
const bool use_vertices,
MutableSpan<float3> r_custom_loop_normals,
MutableSpan<bool> sharp_edges,
short (*r_clnors_data)[2],
const bool use_vertices)
short (*r_clnors_data)[2])
{
using namespace blender;
using namespace blender::bke;
/* We *may* make that poor #BKE_mesh_normals_loop_split() even more complex by making it handling
* that feature too, would probably be more efficient in absolute.
* However, this function *is not* performance-critical, since it is mostly expected to be called
* by io add-ons when importing custom normals, and modifier
* (and perhaps from some editing tools later?).
* So better to keep some simplicity here, and just call #BKE_mesh_normals_loop_split() twice! */
/* We *may* make that poor #bke::mesh::normals_calc_loop() even more complex by making it
* handling that feature too, would probably be more efficient in absolute. However, this
* function *is not* performance-critical, since it is mostly expected to be called by io add-ons
* when importing custom normals, and modifier (and perhaps from some editing tools later?). So
* better to keep some simplicity here, and just call #bke::mesh::normals_calc_loop() twice! */
MLoopNorSpaceArray lnors_spacearr = {nullptr};
BitVector<> done_loops(numLoops, false);
float(*loop_normals)[3] = (float(*)[3])MEM_calloc_arrayN(
size_t(numLoops), sizeof(*loop_normals), __func__);
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map({polys, numPolys},
numLoops);
BitVector<> done_loops(loops.size(), false);
Array<float3> loop_normals(loops.size());
const Array<int> loop_to_poly = mesh_topology::build_loop_to_poly_map(polys, loops.size());
/* In this case we always consider split nors as ON,
* and do not want to use angle to define smooth fans! */
const bool use_split_normals = true;
@ -1647,35 +1590,31 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
BLI_SMALLSTACK_DECLARE(clnors_data, short *);
/* Compute current lnor spacearr. */
BKE_mesh_normals_loop_split(positions,
vert_normals,
numVerts,
edges,
numEdges,
mloops,
loop_normals,
numLoops,
polys,
poly_normals,
numPolys,
use_split_normals,
split_angle,
sharp_edges.data(),
sharp_faces,
loop_to_poly.data(),
&lnors_spacearr,
nullptr);
normals_calc_loop(positions,
edges,
polys,
loops,
loop_to_poly,
vert_normals,
poly_normals,
sharp_edges.data(),
sharp_faces,
use_split_normals,
split_angle,
r_clnors_data,
&lnors_spacearr,
loop_normals);
/* Set all given zero vectors to their default value. */
if (use_vertices) {
for (int i = 0; i < numVerts; i++) {
for (const int i : positions.index_range()) {
if (is_zero_v3(r_custom_loop_normals[i])) {
copy_v3_v3(r_custom_loop_normals[i], vert_normals[i]);
}
}
}
else {
for (int i = 0; i < numLoops; i++) {
for (const int i : loops.index_range()) {
if (is_zero_v3(r_custom_loop_normals[i])) {
copy_v3_v3(r_custom_loop_normals[i], loop_normals[i]);
}
@ -1686,7 +1625,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
/* Now, check each current smooth fan (one lnor space per smooth fan!),
* and if all its matching custom loop_normals are not (enough) equal, add sharp edges as needed.
* This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans
* This way, next time we run bke::mesh::normals_calc_loop(), we'll get lnor spacearr/smooth fans
* matching given custom loop_normals.
* Note this code *will never* unsharp edges! And quite obviously,
* when we set custom normals per vertices, running this is absolutely useless. */
@ -1694,7 +1633,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
done_loops.fill(true);
}
else {
for (int i = 0; i < numLoops; i++) {
for (const int i : loops.index_range()) {
if (!lnors_spacearr.lspacearr[i]) {
/* This should not happen in theory, but in some rare case (probably ugly geometry)
* we can get some nullptr loopspacearr at this point. :/
@ -1712,7 +1651,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
/* Notes:
* - In case of mono-loop smooth fan, we have nothing to do.
* - Loops in this linklist are ordered (in reversed order compared to how they were
* discovered by BKE_mesh_normals_loop_split(), but this is not a problem).
* discovered by bke::mesh::normals_calc_loop(), but this is not a problem).
* Which means if we find a mismatching clnor,
* we know all remaining loops will have to be in a new, different smooth fan/lnor space.
* - In smooth fan case, we compare each clnor against a ref one,
@ -1723,13 +1662,13 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
continue;
}
LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
LinkNode *loop_link = lnors_spacearr.lspacearr[i]->loops;
const MLoop *prev_ml = nullptr;
const float *org_nor = nullptr;
while (loops) {
const int lidx = POINTER_AS_INT(loops->link);
const MLoop *ml = &mloops[lidx];
while (loop_link) {
const int lidx = POINTER_AS_INT(loop_link->link);
const MLoop *ml = &loops[lidx];
const int nidx = lidx;
float *nor = r_custom_loop_normals[nidx];
@ -1743,14 +1682,14 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
* since we do not allow reversed winding in a same smooth fan. */
const MPoly &poly = polys[loop_to_poly[lidx]];
const MLoop *mlp =
&mloops[(lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1];
&loops[(lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1];
sharp_edges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e] = true;
org_nor = nor;
}
prev_ml = ml;
loops = loops->next;
loop_link = loop_link->next;
done_loops[lidx].set();
}
@ -1758,17 +1697,17 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
* otherwise we may miss some sharp edges here!
* This is just a simplified version of above while loop.
* See #45984. */
loops = lnors_spacearr.lspacearr[i]->loops;
if (loops && org_nor) {
const int lidx = POINTER_AS_INT(loops->link);
const MLoop *ml = &mloops[lidx];
loop_link = lnors_spacearr.lspacearr[i]->loops;
if (loop_link && org_nor) {
const int lidx = POINTER_AS_INT(loop_link->link);
const MLoop *ml = &loops[lidx];
const int nidx = lidx;
float *nor = r_custom_loop_normals[nidx];
if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) {
const MPoly &poly = polys[loop_to_poly[lidx]];
const MLoop *mlp =
&mloops[(lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1];
&loops[(lidx == poly.loopstart) ? poly.loopstart + poly.totloop - 1 : lidx - 1];
sharp_edges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e] = true;
}
}
@ -1776,29 +1715,25 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
/* And now, recompute our new auto `loop_normals` and lnor spacearr! */
BKE_lnor_spacearr_clear(&lnors_spacearr);
BKE_mesh_normals_loop_split(positions,
vert_normals,
numVerts,
edges,
numEdges,
mloops,
loop_normals,
numLoops,
polys,
poly_normals,
numPolys,
use_split_normals,
split_angle,
sharp_edges.data(),
sharp_faces,
loop_to_poly.data(),
&lnors_spacearr,
nullptr);
normals_calc_loop(positions,
edges,
polys,
loops,
loop_to_poly,
vert_normals,
poly_normals,
sharp_edges.data(),
sharp_faces,
use_split_normals,
split_angle,
r_clnors_data,
&lnors_spacearr,
loop_normals);
}
/* And we just have to convert plain object-space custom normals to our
* lnor space-encoded ones. */
for (int i = 0; i < numLoops; i++) {
for (const int i : loops.index_range()) {
if (!lnors_spacearr.lspacearr[i]) {
done_loops[i].reset();
if (G.debug & G_DEBUG) {
@ -1812,10 +1747,10 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
/* Note we accumulate and average all custom normals in current smooth fan,
* to avoid getting different clnors data (tiny differences in plain custom normals can
* give rather huge differences in computed 2D factors). */
LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
LinkNode *loop_link = lnors_spacearr.lspacearr[i]->loops;
if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) {
BLI_assert(POINTER_AS_INT(loops) == i);
const int nidx = use_vertices ? int(mloops[i].v) : i;
BLI_assert(POINTER_AS_INT(loop_link) == i);
const int nidx = use_vertices ? int(loops[i].v) : i;
float *nor = r_custom_loop_normals[nidx];
BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]);
@ -1827,16 +1762,16 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
short clnor_data_tmp[2], *clnor_data;
zero_v3(avg_nor);
while (loops) {
const int lidx = POINTER_AS_INT(loops->link);
const int nidx = use_vertices ? int(mloops[lidx].v) : lidx;
while (loop_link) {
const int lidx = POINTER_AS_INT(loop_link->link);
const int nidx = use_vertices ? int(loops[lidx].v) : lidx;
float *nor = r_custom_loop_normals[nidx];
avg_nor_count++;
add_v3_v3(avg_nor, nor);
BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]);
loops = loops->next;
loop_link = loop_link->next;
done_loops[lidx].reset();
}
@ -1851,78 +1786,59 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3],
}
}
MEM_freeN(loop_normals);
BKE_lnor_spacearr_free(&lnors_spacearr);
}
void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3],
const float (*vert_normals)[3],
const int numVerts,
const MEdge *edges,
const int numEdges,
const MLoop *mloops,
float (*r_custom_loop_normals)[3],
const int numLoops,
const MPoly *polys,
const float (*poly_normals)[3],
const bool *sharp_faces,
const int numPolys,
bool *sharp_edges,
short (*r_clnors_data)[2])
void normals_loop_custom_set(const Span<float3> vert_positions,
const Span<MEdge> edges,
const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<float3> vert_normals,
const Span<float3> poly_normals,
const bool *sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals,
short (*r_clnors_data)[2])
{
mesh_normals_loop_custom_set(vert_positions,
vert_normals,
numVerts,
edges,
numEdges,
mloops,
r_custom_loop_normals,
numLoops,
polys,
loops,
vert_normals,
poly_normals,
sharp_faces,
numPolys,
{sharp_edges, numEdges},
r_clnors_data,
false);
false,
r_custom_loop_normals,
sharp_edges,
r_clnors_data);
}
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,
const MEdge *edges,
const int numEdges,
const MLoop *mloops,
const int numLoops,
const MPoly *polys,
const float (*poly_normals)[3],
const bool *sharp_faces,
const int numPolys,
bool *sharp_edges,
short (*r_clnors_data)[2])
void normals_loop_custom_set_from_verts(const Span<float3> vert_positions,
const Span<MEdge> edges,
const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<float3> vert_normals,
const Span<float3> poly_normals,
const bool *sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
short (*r_clnors_data)[2])
{
mesh_normals_loop_custom_set(vert_positions,
vert_normals,
numVerts,
edges,
numEdges,
mloops,
r_custom_vert_normals,
numLoops,
polys,
loops,
vert_normals,
poly_normals,
sharp_faces,
numPolys,
{sharp_edges, numEdges},
r_clnors_data,
true);
true,
r_custom_vert_normals,
sharp_edges,
r_clnors_data);
}
static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices)
{
using namespace blender;
using namespace blender::bke;
short(*clnors)[2];
const int numloops = mesh->totloop;
@ -1935,41 +1851,38 @@ 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<float3> positions = mesh->vert_positions();
MutableSpan<MEdge> edges = mesh->edges_for_write();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
MutableAttributeAccessor attributes = mesh->attributes_for_write();
SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE);
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
mesh_normals_loop_custom_set(reinterpret_cast<const float(*)[3]>(positions.data()),
BKE_mesh_vert_normals_ensure(mesh),
positions.size(),
edges.data(),
edges.size(),
loops.data(),
r_custom_nors,
loops.size(),
polys.data(),
BKE_mesh_poly_normals_ensure(mesh),
mesh_normals_loop_custom_set(mesh->vert_positions(),
mesh->edges(),
mesh->polys(),
mesh->loops(),
mesh->vert_normals(),
mesh->poly_normals(),
sharp_faces,
polys.size(),
use_vertices,
{reinterpret_cast<blender::float3 *>(r_custom_nors),
use_vertices ? mesh->totvert : mesh->totloop},
sharp_edges.span,
clnors,
use_vertices);
clnors);
sharp_edges.finish();
}
} // namespace blender::bke::mesh
void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loop_normals)[3])
{
mesh_set_custom_normals(mesh, r_custom_loop_normals, false);
blender::bke::mesh::mesh_set_custom_normals(mesh, r_custom_loop_normals, false);
}
void BKE_mesh_set_custom_normals_from_verts(Mesh *mesh, float (*r_custom_vert_normals)[3])
{
mesh_set_custom_normals(mesh, r_custom_vert_normals, true);
blender::bke::mesh::mesh_set_custom_normals(mesh, r_custom_vert_normals, true);
}
void BKE_mesh_normals_loop_to_vertex(const int numVerts,

View File

@ -26,7 +26,7 @@
#include "BKE_bvhutils.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h" /* own include */
#include "BKE_mesh_runtime.h"
@ -1043,9 +1043,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
const int island_index,
BLI_AStarGraph *as_graph,
const float (*positions)[3],
const MPoly *polys,
const MLoop *loops,
const blender::Span<blender::float3> positions,
const blender::Span<MPoly> polys,
const blender::Span<MLoop> loops,
const int edge_idx,
BLI_bitmap *done_edges,
MeshElemMap *edge_to_poly_map,
@ -1075,7 +1075,9 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
}
if (poly_status[pidx_isld] == POLY_UNSET) {
BKE_mesh_calc_poly_center(&poly, &loops[poly.loopstart], positions, poly_centers[pidx_isld]);
copy_v3_v3(poly_centers[pidx_isld],
blender::bke::mesh::poly_center_calc(positions,
loops.slice(poly.loopstart, poly.totloop)));
BLI_astar_node_init(as_graph, pidx_isld, poly_centers[pidx_isld]);
poly_status[pidx_isld] = POLY_CENTER_INIT;
}
@ -1100,11 +1102,11 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
static void mesh_island_to_astar_graph(MeshIslandStore *islands,
const int island_index,
const float (*positions)[3],
const blender::Span<blender::float3> positions,
MeshElemMap *edge_to_poly_map,
const int numedges,
const MLoop *loops,
const MPoly *polys,
const blender::Span<MPoly> polys,
const blender::Span<MLoop> loops,
const int numpolys,
BLI_AStarGraph *r_as_graph)
{
@ -1289,7 +1291,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const float(*poly_nors_dst)[3] = nullptr;
float(*loop_nors_dst)[3] = nullptr;
float(*poly_cents_src)[3] = nullptr;
blender::Array<blender::float3> poly_cents_src;
MeshElemMap *vert_to_loop_map_src = nullptr;
int *vert_to_loop_map_src_buff = nullptr;
@ -1303,7 +1305,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 float(*positions_src)[3] = BKE_mesh_vert_positions(me_src);
const blender::Span<blender::float3> positions_src = me_src->vert_positions();
const int num_verts_src = me_src->totvert;
float(*vcos_src)[3] = nullptr;
const blender::Span<MEdge> edges_src = me_src->edges();
@ -1363,24 +1365,21 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
CustomData_get_layer_named(&mesh_dst->edata, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh_dst->pdata, CD_PROP_BOOL, "sharp_face"));
BKE_mesh_normals_loop_split(vert_positions_dst,
BKE_mesh_vert_normals_ensure(mesh_dst),
numverts_dst,
edges_dst,
numedges_dst,
loops_dst,
loop_nors_dst,
numloops_dst,
polys_dst,
poly_nors_dst,
numpolys_dst,
use_split_nors_dst,
split_angle_dst,
sharp_edges,
sharp_faces,
nullptr,
nullptr,
custom_nors_dst);
blender::bke::mesh::normals_calc_loop(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{edges_dst, numedges_dst},
{polys_dst, numpolys_dst},
{loops_dst, numloops_dst},
{},
mesh_dst->vert_normals(),
mesh_dst->poly_normals(),
sharp_edges,
sharp_faces,
use_split_nors_dst,
split_angle_dst,
custom_nors_dst,
nullptr,
{reinterpret_cast<blender::float3 *>(loop_nors_dst), numloops_dst});
}
}
if (need_pnors_src || need_lnors_src) {
@ -1425,8 +1424,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (use_from_vert) {
loop_to_poly_map_src = static_cast<int *>(
MEM_mallocN(sizeof(*loop_to_poly_map_src) * size_t(loops_src.size()), __func__));
poly_cents_src = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*poly_cents_src) * size_t(polys_src.size()), __func__));
poly_cents_src.reinitialize(polys_src.size());
for (pidx_src = 0; pidx_src < polys_src.size(); pidx_src++) {
const MPoly &poly = polys_src[pidx_src];
ml_src = &loops_src[poly.loopstart];
@ -1434,7 +1432,8 @@ 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(&poly, ml_src, positions_src, poly_cents_src[pidx_src]);
poly_cents_src[pidx_src] = blender::bke::mesh::poly_center_calc(
positions_src, loops_src.slice(poly.loopstart, poly.totloop));
}
}
@ -1449,7 +1448,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (gen_islands_src) {
const bool *uv_seams = static_cast<const bool *>(
CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, ".uv_seam"));
use_islands = gen_islands_src(positions_src,
use_islands = gen_islands_src(reinterpret_cast<const float(*)[3]>(positions_src.data()),
num_verts_src,
edges_src.data(),
int(edges_src.size()),
@ -1493,8 +1492,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
positions_src,
edge_to_poly_map_src,
int(edges_src.size()),
loops_src.data(),
polys_src.data(),
polys_src,
loops_src,
int(polys_src.size()),
&as_graphdata[tindex]);
}
@ -1520,7 +1519,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
}
bvhtree_from_mesh_verts_ex(&treedata[tindex],
positions_src,
reinterpret_cast<const float(*)[3]>(positions_src.data()),
num_verts_src,
verts_active,
num_verts_active,
@ -1550,7 +1549,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
}
bvhtree_from_mesh_looptri_ex(&treedata[tindex],
positions_src,
reinterpret_cast<const float(*)[3]>(positions_src.data()),
loops_src.data(),
looptris_src.data(),
int(looptris_src.size()),
@ -1580,7 +1579,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
/* Only in use_from_vert case, we may need polys' centers as fallback
* in case we cannot decide which corner to use from normals only. */
float pcent_dst[3];
blender::float3 pcent_dst;
bool pcent_dst_valid = false;
if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) {
@ -1668,8 +1667,10 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
ml_src = &loops_src[poly.loopstart];
if (!pcent_dst_valid) {
BKE_mesh_calc_poly_center(
mp_dst, &loops_dst[mp_dst->loopstart], vert_positions_dst, pcent_dst);
pcent_dst = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst),
numverts_dst},
{&loops_dst[mp_dst->loopstart], mp_dst->totloop});
pcent_dst_valid = true;
}
pcent_src = poly_cents_src[pidx_src];
@ -2139,9 +2140,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
if (loop_to_poly_map_src) {
MEM_freeN(loop_to_poly_map_src);
}
if (poly_cents_src) {
MEM_freeN(poly_cents_src);
}
if (vcos_interp) {
MEM_freeN(vcos_interp);
}
@ -2160,6 +2158,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const float ray_radius,
const Mesh *mesh_dst,
const float (*vert_positions_dst)[3],
const int numverts_dst,
const MLoop *loops_dst,
const MPoly *polys_dst,
const int numpolys_dst,
@ -2169,7 +2168,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const float full_weight = 1.0f;
const float max_dist_sq = max_dist * max_dist;
const float(*poly_nors_dst)[3] = nullptr;
float tmp_co[3], tmp_no[3];
blender::float3 tmp_co, tmp_no;
int i;
BLI_assert(mode & MREMAP_MODE_POLY);
@ -2199,8 +2198,9 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
for (i = 0; i < numpolys_dst; i++) {
const MPoly &poly = polys_dst[i];
BKE_mesh_calc_poly_center(&poly, &loops_dst[poly.loopstart], vert_positions_dst, tmp_co);
tmp_co = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&loops_dst[poly.loopstart], poly.totloop});
/* Convert the vertex to tree coordinates, if needed. */
if (space_transform) {
@ -2225,7 +2225,9 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
for (i = 0; i < numpolys_dst; i++) {
const MPoly &poly = polys_dst[i];
BKE_mesh_calc_poly_center(&poly, &loops_dst[poly.loopstart], vert_positions_dst, tmp_co);
tmp_co = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&loops_dst[poly.loopstart], poly.totloop});
copy_v3_v3(tmp_no, poly_nors_dst[i]);
/* Convert the vertex to tree coordinates, if needed. */
@ -2277,7 +2279,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
int tot_rays, done_rays = 0;
float poly_area_2d_inv, done_area = 0.0f;
float pcent_dst[3];
blender::float3 pcent_dst;
float to_pnor_2d_mat[3][3], from_pnor_2d_mat[3][3];
float poly_dst_2d_min[2], poly_dst_2d_max[2], poly_dst_2d_z;
float poly_dst_2d_size[2];
@ -2288,8 +2290,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const int tris_num = poly.totloop - 2;
int j;
BKE_mesh_calc_poly_center(
&poly, &loops_dst[poly.loopstart], vert_positions_dst, pcent_dst);
pcent_dst = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
{&loops_dst[poly.loopstart], poly.totloop});
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! */

View File

@ -30,7 +30,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remesh_voxel.h" /* own include */
#include "BKE_mesh_runtime.h"
@ -338,15 +338,12 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
blender::threading::parallel_for(IndexRange(target->totpoly), 2048, [&](const IndexRange range) {
for (const int i : range) {
float from_co[3];
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],
reinterpret_cast<const float(*)[3]>(target_positions.data()),
from_co);
const float3 from_co = mesh::poly_center_calc(
target_positions, target_loops.slice(poly.loopstart, poly.totloop));
BLI_bvhtree_find_nearest(
bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {

View File

@ -20,7 +20,7 @@
#include "BKE_bvhutils.h"
#include "BKE_editmesh_cache.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_shrinkwrap.h"
#include "BKE_subdiv_ccg.h"
@ -152,21 +152,11 @@ blender::Span<MLoopTri> Mesh::looptris() const
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(),
reinterpret_cast<const float(*)[3]>(positions.data()),
loops.size(),
polys.size(),
r_data.data());
blender::bke::mesh::looptris_calc(positions, polys, loops, r_data);
}
else {
BKE_mesh_recalc_looptri_with_normals(loops.data(),
polys.data(),
reinterpret_cast<const float(*)[3]>(positions.data()),
loops.size(),
polys.size(),
r_data.data(),
BKE_mesh_poly_normals_ensure(this));
blender::bke::mesh::looptris_calc_with_normals(
positions, polys, loops, this->poly_normals(), r_data);
}
});

View File

@ -2,7 +2,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_sample.hh"

View File

@ -20,7 +20,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_tangent.h"
#include "BKE_report.h"

View File

@ -10,24 +10,18 @@
* \see bmesh_mesh_tessellate.c for the #BMesh equivalent of this file.
*/
#include <climits>
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_enumerable_thread_specific.hh"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h" /* Own include. */
#include "BKE_mesh.hh"
#include "BLI_strict_flags.h"
namespace blender::bke::mesh {
/** Compared against total loops. */
#define MESH_FACE_TESSELLATE_THREADED_LIMIT 4096
@ -40,9 +34,9 @@
/**
* \param face_normal: This will be optimized out as a constant.
*/
BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
const MPoly *polys,
const float (*positions)[3],
BLI_INLINE void mesh_calc_tessellation_for_face_impl(const Span<MLoop> mloop,
const Span<MPoly> polys,
const Span<float3> positions,
uint poly_index,
MLoopTri *mlt,
MemArena **pf_arena_p,
@ -101,7 +95,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
zero_v3(normal);
/* Calc normal, flipped: to get a positive 2D cross product. */
ml = mloop + mp_loopstart;
ml = mloop.data() + mp_loopstart;
co_prev = positions[ml[mp_totloop - 1].v];
for (uint j = 0; j < mp_totloop; j++, ml++) {
co_curr = positions[ml->v];
@ -129,7 +123,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
float(*projverts)[2] = static_cast<float(*)[2]>(
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(mp_totloop)));
ml = mloop + mp_loopstart;
ml = mloop.data() + mp_loopstart;
for (uint j = 0; j < mp_totloop; j++, ml++) {
mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]);
}
@ -150,9 +144,9 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
#undef ML_TO_MLT
}
static void mesh_calc_tessellation_for_face(const MLoop *mloop,
const MPoly *polys,
const float (*positions)[3],
static void mesh_calc_tessellation_for_face(const Span<MLoop> mloop,
const Span<MPoly> polys,
const Span<float3> positions,
uint poly_index,
MLoopTri *mlt,
MemArena **pf_arena_p)
@ -161,9 +155,9 @@ static void mesh_calc_tessellation_for_face(const MLoop *mloop,
mloop, polys, positions, poly_index, mlt, pf_arena_p, false, nullptr);
}
static void mesh_calc_tessellation_for_face_with_normal(const MLoop *mloop,
const MPoly *polys,
const float (*positions)[3],
static void mesh_calc_tessellation_for_face_with_normal(const Span<MLoop> mloop,
const Span<MPoly> polys,
const Span<float3> positions,
uint poly_index,
MLoopTri *mlt,
MemArena **pf_arena_p,
@ -173,16 +167,16 @@ static void mesh_calc_tessellation_for_face_with_normal(const MLoop *mloop,
mloop, polys, positions, poly_index, mlt, pf_arena_p, true, normal_precalc);
}
static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
const MPoly *polys,
const float (*positions)[3],
static void mesh_recalc_looptri__single_threaded(const Span<MLoop> mloop,
const Span<MPoly> polys,
const Span<float3> positions,
int totloop,
int totpoly,
MLoopTri *mlooptri,
const float (*poly_normals)[3])
{
MemArena *pf_arena = nullptr;
const MPoly *poly = polys;
const MPoly *poly = polys.data();
uint tri_index = 0;
if (poly_normals != nullptr) {
@ -214,12 +208,12 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
}
struct TessellationUserData {
const MLoop *mloop;
const MPoly *polys;
const float (*positions)[3];
Span<MLoop> mloop;
Span<MPoly> polys;
Span<float3> positions;
/** Output array. */
MLoopTri *mlooptri;
MutableSpan<MLoopTri> mlooptri;
/** Optional pre-calculated polygon normals array. */
const float (*poly_normals)[3];
@ -272,23 +266,31 @@ 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 *polys,
const float (*positions)[3],
int /*totloop*/,
int totpoly,
MLoopTri *mlooptri,
const float (*poly_normals)[3])
static void looptris_calc_all(const Span<float3> positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<float3> poly_normals,
MutableSpan<MLoopTri> looptris)
{
if (loops.size() < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
mesh_recalc_looptri__single_threaded(loops,
polys,
positions,
int(loops.size()),
int(polys.size()),
looptris.data(),
reinterpret_cast<const float(*)[3]>(poly_normals.data()));
return;
}
struct TessellationUserTLS tls_data_dummy = {nullptr};
struct TessellationUserData data {
};
data.mloop = mloop;
data.mloop = loops;
data.polys = polys;
data.positions = positions;
data.mlooptri = mlooptri;
data.poly_normals = poly_normals;
data.mlooptri = looptris;
data.poly_normals = reinterpret_cast<const float(*)[3]>(poly_normals.data());
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
@ -299,47 +301,46 @@ static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop,
settings.func_free = mesh_calc_tessellation_for_face_free_fn;
BLI_task_parallel_range(0,
totpoly,
int(polys.size()),
&data,
poly_normals ? mesh_calc_tessellation_for_face_with_normal_fn :
mesh_calc_tessellation_for_face_fn,
data.poly_normals ? mesh_calc_tessellation_for_face_with_normal_fn :
mesh_calc_tessellation_for_face_fn,
&settings);
}
void looptris_calc(const Span<float3> vert_positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
MutableSpan<MLoopTri> looptris)
{
looptris_calc_all(vert_positions, polys, loops, {}, looptris);
}
void looptris_calc_with_normals(const Span<float3> vert_positions,
const Span<MPoly> polys,
const Span<MLoop> loops,
const Span<float3> poly_normals,
MutableSpan<MLoopTri> looptris)
{
BLI_assert(!poly_normals.is_empty());
looptris_calc_all(vert_positions, polys, loops, poly_normals, looptris);
}
} // namespace blender::bke::mesh
void BKE_mesh_recalc_looptri(const MLoop *mloop,
const MPoly *polys,
const float (*vert_positions)[3],
int totvert,
int totloop,
int totpoly,
MLoopTri *mlooptri)
{
if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
mesh_recalc_looptri__single_threaded(
mloop, polys, vert_positions, totloop, totpoly, mlooptri, nullptr);
}
else {
mesh_recalc_looptri__multi_threaded(
mloop, polys, vert_positions, totloop, totpoly, mlooptri, nullptr);
}
}
void BKE_mesh_recalc_looptri_with_normals(const MLoop *mloop,
const MPoly *polys,
const float (*vert_positions)[3],
int totloop,
int totpoly,
MLoopTri *mlooptri,
const float (*poly_normals)[3])
{
BLI_assert(poly_normals != nullptr);
if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) {
mesh_recalc_looptri__single_threaded(
mloop, polys, vert_positions, totloop, totpoly, mlooptri, poly_normals);
}
else {
mesh_recalc_looptri__multi_threaded(
mloop, polys, vert_positions, totloop, totpoly, mlooptri, poly_normals);
}
blender::bke::mesh::looptris_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions), totvert},
{polys, totpoly},
{mloop, totloop},
{mlooptri, poly_to_tri_count(totpoly, totloop)});
}
/** \} */

View File

@ -27,7 +27,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "DEG_depsgraph.h"

View File

@ -34,7 +34,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"

View File

@ -54,7 +54,7 @@
#include "BKE_key.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_multires.h"
#include "BKE_object.h"

View File

@ -24,7 +24,7 @@
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"

View File

@ -14,7 +14,7 @@
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"

View File

@ -19,7 +19,7 @@
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"
@ -114,16 +114,10 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find normal. */
for (int j = 0; j < pmap[i].count; j++) {
const MPoly &poly = reshape_context->base_polys[pmap[i].indices[j]];
MPoly fake_poly;
float no[3];
/* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */
fake_poly.totloop = poly.totloop;
fake_poly.loopstart = 0;
MLoop *fake_loops = static_cast<MLoop *>(
MEM_malloc_arrayN(poly.totloop, sizeof(MLoop), __func__));
float(*fake_co)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(poly.totloop, sizeof(float[3]), __func__));
/* Set up poly, loops, and coords in order to call #bke::mesh::poly_normal_calc(). */
blender::Array<MLoop> fake_loops(poly.totloop);
blender::Array<blender::float3> fake_co(poly.totloop);
for (int k = 0; k < poly.totloop; k++) {
const int vndx = reshape_context->base_loops[poly.loopstart + k].v;
@ -138,10 +132,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
}
}
BKE_mesh_calc_poly_normal(&fake_poly, fake_loops, (const float(*)[3])fake_co, no);
MEM_freeN(fake_loops);
MEM_freeN(fake_co);
const blender::float3 no = blender::bke::mesh::poly_normal_calc(fake_co, fake_loops);
add_v3_v3(avg_no, no);
}
normalize_v3(avg_no);

View File

@ -14,7 +14,7 @@
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
@ -28,7 +28,9 @@
static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
{
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
using namespace blender;
using namespace blender::bke;
const Span<float3> positions = mesh->vert_positions();
const blender::Span<MPoly> polys = mesh->polys();
const blender::Span<MLoop> loops = mesh->loops();
@ -36,8 +38,8 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop));
for (const int p : polys.index_range()) {
const MPoly &poly = polys[p];
float poly_center[3];
BKE_mesh_calc_poly_center(&poly, &loops[poly.loopstart], positions, poly_center);
const float3 poly_center = mesh::poly_center_calc(positions,
loops.slice(poly.loopstart, poly.totloop));
for (int l = 0; l < poly.totloop; l++) {
const int loop_index = poly.loopstart + l;

View File

@ -18,7 +18,7 @@
#include "BLI_task.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"
#include "BKE_subdiv.h"

View File

@ -12,7 +12,7 @@
#include "BLI_utildefines.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_subdiv.h"

View File

@ -20,7 +20,7 @@
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"

View File

@ -105,7 +105,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"

View File

@ -44,7 +44,7 @@
#include "BKE_instances.hh"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"

View File

@ -38,7 +38,7 @@
#include "BKE_light.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"

View File

@ -46,7 +46,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
@ -2188,12 +2188,7 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
MLoopTri *looptri = static_cast<MLoopTri *>(
MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__));
BKE_mesh_recalc_looptri(loops.data(),
polys.data(),
reinterpret_cast<const float(*)[3]>(positions.data()),
me->totloop,
me->totpoly,
looptri);
blender::bke::mesh::looptris_calc(positions, polys, loops, {looptri, looptris_num});
BKE_pbvh_build_mesh(pbvh,
me,

View File

@ -58,7 +58,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_legacy_convert.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"

View File

@ -20,7 +20,7 @@
#include "BKE_attribute.h"
#include "BKE_ccg.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@ -1409,7 +1409,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
if (node->flag & PBVH_UpdateNormals) {
uint mpoly_prev = UINT_MAX;
float fn[3];
blender::float3 fn;
const int *faces = node->prim_indices;
const int totface = node->totprim;
@ -1426,7 +1426,9 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
/* Face normal and mask */
if (lt->poly != mpoly_prev) {
const MPoly &poly = pbvh->polys[lt->poly];
BKE_mesh_calc_poly_normal(&poly, &pbvh->mloop[poly.loopstart], pbvh->vert_positions, fn);
fn = blender::bke::mesh::poly_normal_calc(
{reinterpret_cast<const blender::float3 *>(pbvh->vert_positions), pbvh->totvert},
{&pbvh->mloop[poly.loopstart], poly.totloop});
mpoly_prev = lt->poly;
}

View File

@ -21,7 +21,7 @@
#include "BKE_attribute.h"
#include "BKE_ccg.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"

View File

@ -3,7 +3,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_pbvh.h"
#include "BKE_pbvh_pixels.hh"

View File

@ -33,7 +33,7 @@
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h" /* for OMP limits. */
#include "BKE_mesh.hh" /* for OMP limits. */
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_subsurf.h"

View File

@ -2759,7 +2759,8 @@ 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, vert_positions, me->totloop, me->totpoly, looptri);
BKE_mesh_recalc_looptri(
loops, polys, vert_positions, me->totvert, me->totloop, me->totpoly, looptri);
bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface,
"SB_body_Faces");

View File

@ -20,7 +20,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_subdiv.h"
#include "BKE_subdiv_eval.h"

View File

@ -17,7 +17,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_subdiv.h"
#include "MEM_guardedalloc.h"

View File

@ -5,7 +5,7 @@
* \ingroup bke
*/
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_subdiv_ccg.h"
#include "MEM_guardedalloc.h"

View File

@ -16,7 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_subdiv.h"

View File

@ -18,7 +18,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_multires.h"
#include "BKE_subdiv_eval.h"

View File

@ -16,7 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_subdiv.h"
#include "MEM_guardedalloc.h"

View File

@ -18,7 +18,7 @@
#include "BKE_customdata.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_subdiv.h"
#include "BKE_subdiv_mesh.hh"

View File

@ -21,7 +21,7 @@
#include "BKE_customdata.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_subdiv.h"
#include "BKE_subdiv_eval.h"

View File

@ -11,7 +11,7 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_subdiv.h"

View File

@ -33,7 +33,7 @@
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"

View File

@ -10,7 +10,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_volume_types.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_volume.h"
#ifdef WITH_OPENVDB

View File

@ -75,7 +75,7 @@
#include "BKE_main.h" /* for Main */
#include "BKE_main_idmap.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_node.h" /* for tree type defines */
#include "BKE_object.h"

View File

@ -48,7 +48,7 @@
#include "BKE_gpencil.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_multires.h"
#include "BKE_node.h"

View File

@ -63,7 +63,7 @@
#include "BKE_lib_override.h"
#include "BKE_main.h"
#include "BKE_main_namemap.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_screen.h"

View File

@ -49,7 +49,7 @@
#include "BKE_main.h"
#include "BKE_main_namemap.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"

View File

@ -16,7 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "bmesh.h"

View File

@ -89,7 +89,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"

View File

@ -22,7 +22,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "intern/bmesh_private.h"
@ -1053,7 +1053,7 @@ static void bm_mesh_loops_calc_normals_for_vert_without_clnors(
}
/**
* BMesh version of BKE_mesh_normals_loop_split() in `mesh_evaluate.cc`
* BMesh version of bke::mesh::normals_calc_loop() in `mesh_evaluate.cc`
* Will use first clnors_data array, and fallback to cd_loop_clnors_offset
* (use nullptr and -1 to not use clnors).
*
@ -1404,7 +1404,7 @@ static bool bm_mesh_loops_split_lnor_fans(BMesh *bm,
/* Notes:
* * In case of mono-loop smooth fan, we have nothing to do.
* * Loops in this linklist are ordered (in reversed order compared to how they were
* discovered by BKE_mesh_normals_loop_split(), but this is not a problem).
* discovered by bke::mesh::normals_calc_loop(), but this is not a problem).
* Which means if we find a mismatching clnor,
* we know all remaining loops will have to be in a new, different smooth fan/lnor space.
* * In smooth fan case, we compare each clnor against a ref one,

View File

@ -75,7 +75,7 @@
#include "BKE_mask.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_movieclip.h"
#include "BKE_node.h"

View File

@ -15,7 +15,7 @@
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_movieclip.h"
#include "BKE_object.h"

View File

@ -17,7 +17,7 @@
#include "BKE_attribute.hh"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "GPU_batch.h"
@ -363,30 +363,25 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
mr->poly_normals = mr->me->poly_normals();
}
if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
mr->loop_normals = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__));
mr->loop_normals.reinitialize(mr->loops.size());
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer_for_write(&mr->me->ldata, CD_CUSTOMLOOPNORMAL, mr->me->totloop));
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mr->me->edata, CD_PROP_BOOL, "sharp_edge"));
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(mr->vert_positions.data()),
reinterpret_cast<const float(*)[3]>(mr->vert_normals.data()),
mr->vert_positions.size(),
mr->edges.data(),
mr->edges.size(),
mr->loops.data(),
mr->loop_normals,
mr->loops.size(),
mr->polys.data(),
reinterpret_cast<const float(*)[3]>(mr->poly_normals.data()),
mr->polys.size(),
is_auto_smooth,
split_angle,
sharp_edges,
mr->sharp_faces,
nullptr,
nullptr,
clnors);
blender::bke::mesh::normals_calc_loop(mr->vert_positions,
mr->edges,
mr->polys,
mr->loops,
{},
mr->vert_normals,
mr->poly_normals,
sharp_edges,
mr->sharp_faces,
is_auto_smooth,
split_angle,
clnors,
nullptr,
mr->loop_normals);
}
}
else {
@ -406,8 +401,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
poly_normals = mr->bm_poly_normals;
}
mr->loop_normals = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__));
mr->loop_normals.reinitialize(mr->loop_len);
const int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
BM_loops_calc_normal_vcos(mr->bm,
vert_coords,
@ -415,7 +409,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
poly_normals,
is_auto_smooth,
split_angle,
mr->loop_normals,
reinterpret_cast<float(*)[3]>(mr->loop_normals.data()),
nullptr,
nullptr,
clnors_offset,
@ -443,7 +437,7 @@ MeshRenderData *mesh_render_data_create(Object *object,
const bool do_uvedit,
const ToolSettings *ts)
{
MeshRenderData *mr = static_cast<MeshRenderData *>(MEM_callocN(sizeof(*mr), __func__));
MeshRenderData *mr = MEM_new<MeshRenderData>(__func__);
mr->toolsettings = ts;
mr->mat_len = mesh_render_mat_len_get(object, me);
@ -596,13 +590,12 @@ MeshRenderData *mesh_render_data_create(Object *object,
void mesh_render_data_free(MeshRenderData *mr)
{
MEM_SAFE_FREE(mr->loop_normals);
/* Loose geometry are owned by #MeshBufferCache. */
mr->ledges = nullptr;
mr->lverts = nullptr;
MEM_freeN(mr);
MEM_delete(mr);
}
/** \} */

View File

@ -36,7 +36,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_editmesh_tangent.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_tangent.h"
#include "BKE_modifier.h"

View File

@ -9,7 +9,7 @@
#include "BKE_attribute.hh"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_object.h"

View File

@ -15,7 +15,7 @@
#include "BKE_duplilist.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"

View File

@ -15,7 +15,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_unit.h"
#include "DNA_mesh_types.h"

View File

@ -36,7 +36,7 @@
#include "BKE_attribute.h"
#include "BKE_ccg.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
#include "BKE_subdiv_ccg.h"
@ -345,9 +345,9 @@ struct PBVHBatches {
flat = sharp_faces && sharp_faces[tri->poly];
if (flat) {
const MPoly &poly = args->polys[tri->poly];
float fno[3];
BKE_mesh_calc_poly_normal(
&poly, args->mloop + poly.loopstart, args->vert_positions, fno);
const float3 fno = blender::bke::mesh::poly_normal_calc(
{reinterpret_cast<const float3 *>(args->vert_positions), args->mesh_verts_num},
{&args->mloop[poly.loopstart], poly.totloop});
normal_float_to_short_v3(no, fno);
}
}

View File

@ -15,7 +15,7 @@
#include "BKE_fluid.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_modifier.h"
#include "BKE_volume.h"
#include "BKE_volume_render.h"

View File

@ -95,7 +95,7 @@ struct MeshRenderData {
const bool *select_edge;
const bool *select_poly;
const bool *sharp_faces;
float (*loop_normals)[3];
blender::Array<blender::float3> loop_normals;
int *lverts, *ledges;
const char *active_color_name;

View File

@ -15,7 +15,7 @@
#include "BKE_attribute.h"
#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "draw_attributes.hh"
#include "draw_subdivision.h"

View File

@ -7,7 +7,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BLI_math_vector_types.hh"

View File

@ -9,7 +9,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "extract_mesh.hh"
@ -77,10 +77,8 @@ static void compute_area_ratio(const MeshRenderData *mr,
const float2 *uv_data = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2);
for (int poly_index = 0; poly_index < mr->poly_len; poly_index++) {
const MPoly &poly = mr->polys[poly_index];
float area = BKE_mesh_calc_poly_area(
&poly,
&mr->loops[poly.loopstart],
reinterpret_cast<const float(*)[3]>(mr->vert_positions.data()));
const float area = bke::mesh::poly_area_calc(mr->vert_positions,
mr->loops.slice(poly.loopstart, poly.totloop));
float uvarea = area_poly_v2(reinterpret_cast<const float(*)[2]>(&uv_data[poly.loopstart]),
poly.totloop);
tot_area += area;

View File

@ -41,7 +41,7 @@ static void extract_lnor_iter_poly_bm(const MeshRenderData *mr,
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const int l_index = BM_elem_index_get(l_iter);
if (mr->loop_normals) {
if (!mr->loop_normals.is_empty()) {
(*(GPUPackedNormal **)data)[l_index] = GPU_normal_convert_i10_v3(mr->loop_normals[l_index]);
}
else {
@ -68,7 +68,7 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mr->loops[ml_index];
GPUPackedNormal *lnor_data = &(*(GPUPackedNormal **)data)[ml_index];
if (mr->loop_normals) {
if (!mr->loop_normals.is_empty()) {
*lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[ml_index]);
}
else if (mr->sharp_faces && mr->sharp_faces[poly_index]) {
@ -167,7 +167,7 @@ static void extract_lnor_hq_iter_poly_bm(const MeshRenderData *mr,
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const int l_index = BM_elem_index_get(l_iter);
if (mr->loop_normals) {
if (!mr->loop_normals.is_empty()) {
normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, mr->loop_normals[l_index]);
}
else {
@ -192,7 +192,7 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
for (int ml_index = poly->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mr->loops[ml_index];
gpuHQNor *lnor_data = &(*(gpuHQNor **)data)[ml_index];
if (mr->loop_normals) {
if (!mr->loop_normals.is_empty()) {
normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[ml_index]);
}
else if (mr->sharp_faces && mr->sharp_faces[poly_index]) {

View File

@ -9,7 +9,7 @@
#include "BLI_string.h"
#include "BKE_mesh.h"
#include "BKE_mesh.hh"
#include "BKE_paint.h"
#include "draw_subdivision.h"

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