forked from blender/blender
main sync #3
@ -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
|
||||
|
||||
/** \} */
|
||||
|
211
source/blender/blenkernel/BKE_mesh.hh
Normal file
211
source/blender/blenkernel/BKE_mesh.hh
Normal 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. */
|
||||
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};
|
||||
}
|
||||
|
||||
/** \} */
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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(
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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"
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
# include "BKE_customdata.h"
|
||||
|
||||
# include "BKE_mesh.h"
|
||||
# include "BKE_mesh.hh"
|
||||
|
||||
# include "BLI_dynstr.h"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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! */
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)});
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -5,7 +5,7 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
|
@ -90,7 +90,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"
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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]) {
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user