Mesh: Replace auto smooth with node group #108014

Merged
Hans Goudey merged 149 commits from HooglyBoogly/blender:refactor-mesh-corner-normals-lazy into main 2023-10-20 16:54:20 +02:00
38 changed files with 138 additions and 165 deletions
Showing only changes of commit 55dd8b2db5 - Show all commits

View File

@ -985,7 +985,7 @@ static void create_mesh(Scene *scene,
const int polys_num = b_mesh.polygons.length(); const int polys_num = b_mesh.polygons.length();
int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length(); int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
const int numcorners = b_mesh.loops.length(); const int numcorners = b_mesh.loops.length();
bool use_loop_normals = b_mesh.use_auto_smooth() && bool use_loop_normals = b_mesh.normal_domain_all_info()== BL::Mesh::normal_domain_all_info_POINT &&
(mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK); (mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK);
/* If no faces, create empty mesh. */ /* If no faces, create empty mesh. */

View File

@ -87,8 +87,8 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
/* Make a copy to split faces if we use autosmooth, otherwise not needed. /* Make a copy to split faces if we use autosmooth, otherwise not needed.
* Also in edit mode do we need to make a copy, to ensure data layers like * Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */ * UV are not empty. */
if (mesh.is_editmode() || if (mesh.is_editmode() || (mesh.normal_domain_all_info()== BL::Mesh::normal_domain_all_info_POINT &&
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) { subdivision_type == Mesh::SUBDIVISION_NONE)) {
BL::Depsgraph depsgraph(PointerRNA_NULL); BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph); mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
} }
@ -112,7 +112,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
#endif #endif
if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) { if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
if (mesh.use_auto_smooth()) { if (mesh.normal_domain_all_info()== BL::Mesh::normal_domain_all_info_POINT) {
mesh.calc_normals_split(); mesh.calc_normals_split();
mesh.split_faces(false); mesh.split_faces(false);
} }

View File

@ -186,28 +186,6 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
layout.template_ID(space, "pin_id") layout.template_ID(space, "pin_id")
class DATA_PT_normals(MeshButtonsPanel, Panel):
bl_label = "Normals"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
mesh = context.mesh
col = layout.column(align=False, heading="Auto Smooth")
col.use_property_decorate = False
row = col.row(align=True)
sub = row.row(align=True)
sub.prop(mesh, "use_auto_smooth", text="")
sub = sub.row(align=True)
sub.active = mesh.use_auto_smooth and not mesh.has_custom_normals
sub.prop(mesh, "auto_smooth_angle", text="")
row.prop_decorator(mesh, "auto_smooth_angle")
class DATA_PT_texture_space(MeshButtonsPanel, Panel): class DATA_PT_texture_space(MeshButtonsPanel, Panel):
bl_label = "Texture Space" bl_label = "Texture Space"
bl_options = {'DEFAULT_CLOSED'} bl_options = {'DEFAULT_CLOSED'}
@ -738,7 +716,6 @@ classes = (
DATA_PT_vertex_colors, DATA_PT_vertex_colors,
DATA_PT_face_maps, DATA_PT_face_maps,
DATA_PT_mesh_attributes, DATA_PT_mesh_attributes,
DATA_PT_normals,
DATA_PT_texture_space, DATA_PT_texture_space,
DATA_PT_remesh, DATA_PT_remesh,
DATA_PT_customdata, DATA_PT_customdata,

View File

@ -118,7 +118,7 @@ const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph
int *r_vert_len, int *r_vert_len,
bool *r_is_alloc))[3]; bool *r_is_alloc))[3];
void BKE_editmesh_lnorspace_update(BMEditMesh *em, struct Mesh *me); void BKE_editmesh_lnorspace_update(BMEditMesh *em);
struct BoundBox *BKE_editmesh_cage_boundbox_get(struct Object *object, BMEditMesh *em); struct BoundBox *BKE_editmesh_cage_boundbox_get(struct Object *object, BMEditMesh *em);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -364,11 +364,6 @@ void BKE_mesh_calc_poly_normal(const int *poly_verts,
int verts_num, int verts_num,
float r_no[3]); float r_no[3]);
/**
* Called after calculating all modifiers.
*/
void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh);
/** /**
* References a contiguous loop-fan with normal offset vars. * References a contiguous loop-fan with normal offset vars.
*/ */
@ -710,8 +705,7 @@ void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, bool selec
void BKE_mesh_calc_edges_tessface(struct Mesh *mesh); void BKE_mesh_calc_edges_tessface(struct Mesh *mesh);
/* In DerivedMesh.cc */ /* In DerivedMesh.cc */
void BKE_mesh_wrapper_deferred_finalize_mdata(struct Mesh *me_eval, void BKE_mesh_wrapper_deferred_finalize_mdata(struct Mesh *me_eval);
const struct CustomData_MeshMasks *cd_mask_finalize);
/* **** Depsgraph evaluation **** */ /* **** Depsgraph evaluation **** */

View File

@ -98,7 +98,7 @@ void normals_calc_loop(Span<float3> vert_positions,
Span<float3> poly_normals, Span<float3> poly_normals,
const VArray<bool> &sharp_edges, const VArray<bool> &sharp_edges,
const VArray<bool> &sharp_faces, const VArray<bool> &sharp_faces,
short (*clnors_data)[2], const short2 *custom_normals_data,
MLoopNorSpaceArray *r_lnors_spacearr, MLoopNorSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals); MutableSpan<float3> r_loop_normals);
@ -112,7 +112,7 @@ void normals_loop_custom_set(Span<float3> vert_positions,
const VArray<bool> &sharp_faces, const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges, MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals, MutableSpan<float3> r_custom_loop_normals,
short (*r_clnors_data)[2]); short2 *r_clnors_data);
void normals_loop_custom_set_from_verts(Span<float3> vert_positions, void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
Span<MEdge> edges, Span<MEdge> edges,
@ -124,7 +124,7 @@ void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
const VArray<bool> &sharp_faces, const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges, MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals, MutableSpan<float3> r_custom_vert_normals,
short (*r_clnors_data)[2]); short2 *r_clnors_data);
/** /**
* Define sharp edges as needed to mimic 'autosmooth' from angle threshold. * Define sharp edges as needed to mimic 'autosmooth' from angle threshold.

View File

@ -201,8 +201,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode,
const struct Mesh *mesh_dst, const struct Mesh *mesh_dst,
const float (*vert_positions_dst)[3], const float (*vert_positions_dst)[3],
int numverts_dst, int numverts_dst,
const struct MEdge *edges_dst,
int numedges_dst,
const int *corner_verts_dst, const int *corner_verts_dst,
int numloops_dst, int numloops_dst,
const blender::OffsetIndices<int> polys_dst, const blender::OffsetIndices<int> polys_dst,

View File

@ -83,10 +83,8 @@ using blender::VArray;
#endif #endif
static void mesh_init_origspace(Mesh *mesh); static void mesh_init_origspace(Mesh *mesh);
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final, static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final);
const CustomData_MeshMasks *final_datamask); static void editbmesh_calc_modifier_final_normals_or_defer(Mesh *mesh_final);
static void editbmesh_calc_modifier_final_normals_or_defer(
Mesh *mesh_final, const CustomData_MeshMasks *final_datamask);
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@ -440,21 +438,17 @@ static void add_orco_mesh(
} }
} }
static void mesh_calc_modifier_final_normals(const Mesh *mesh_input, static void mesh_calc_modifier_final_normals(const bool sculpt_dyntopo, Mesh *mesh_final)
const CustomData_MeshMasks *final_datamask,
const bool sculpt_dyntopo,
Mesh *mesh_final)
{ {
/* Compute normals. */ const eAttrDomain domain = mesh_final->normal_domain_all_info();
const bool calc_loop_normals = mesh_final->normal_domain_all_info() == ATTR_DOMAIN_CORNER;
/* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */ /* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data; SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
if (subsurf_runtime_data) { if (subsurf_runtime_data) {
subsurf_runtime_data->calc_loop_normals = calc_loop_normals; subsurf_runtime_data->calc_loop_normals = domain == ATTR_DOMAIN_CORNER;
} }
if (calc_loop_normals) { if (domain == ATTR_DOMAIN_CORNER) {
/* Compute loop normals (NOTE: will compute poly and vert normals as well, if needed!). In case /* Compute loop normals (NOTE: will compute poly and vert normals as well, if needed!). In case
* of deferred CPU subdivision, this will be computed when the wrapper is generated. */ * of deferred CPU subdivision, this will be computed when the wrapper is generated. */
if (!subsurf_runtime_data || subsurf_runtime_data->resolution == 0) { if (!subsurf_runtime_data || subsurf_runtime_data->resolution == 0) {
@ -468,7 +462,12 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
* this where possible since calculating polygon normals isn't fast, * this where possible since calculating polygon normals isn't fast,
* note that this isn't a problem for subsurf (only quads) or edit-mode * note that this isn't a problem for subsurf (only quads) or edit-mode
* which deals with drawing differently. */ * which deals with drawing differently. */
BKE_mesh_ensure_normals_for_display(mesh_final); if (domain == ATTR_DOMAIN_FACE) {
mesh_final->poly_normals();
}
else if (domain == ATTR_DOMAIN_FACE) {
mesh_final->vert_normals();
}
} }
} }
} }
@ -487,11 +486,10 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
mesh_eval->edit_mesh = mesh_input->edit_mesh; mesh_eval->edit_mesh = mesh_input->edit_mesh;
} }
void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval, void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval)
const CustomData_MeshMasks *cd_mask_finalize)
{ {
if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) { if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize); editbmesh_calc_modifier_final_normals(me_eval);
me_eval->runtime->wrapper_type_finalize = eMeshWrapperType( me_eval->runtime->wrapper_type_finalize = eMeshWrapperType(
me_eval->runtime->wrapper_type_finalize & ~(1 << ME_WRAPPER_TYPE_BMESH)); me_eval->runtime->wrapper_type_finalize & ~(1 << ME_WRAPPER_TYPE_BMESH));
} }
@ -970,7 +968,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Compute normals. */ /* Compute normals. */
if (is_own_mesh) { if (is_own_mesh) {
mesh_calc_modifier_final_normals(mesh_input, &final_datamask, sculpt_dyntopo, mesh_final); mesh_calc_modifier_final_normals(sculpt_dyntopo, mesh_final);
mesh_calc_finalize(mesh_input, mesh_final); mesh_calc_finalize(mesh_input, mesh_final);
} }
else { else {
@ -982,8 +980,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
* Isolate since computing normals is multithreaded and we are holding a lock. */ * Isolate since computing normals is multithreaded and we are holding a lock. */
blender::threading::isolate_task([&] { blender::threading::isolate_task([&] {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true); mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_calc_modifier_final_normals( mesh_calc_modifier_final_normals(sculpt_dyntopo, mesh_final);
mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
mesh_calc_finalize(mesh_input, mesh_final); mesh_calc_finalize(mesh_input, mesh_final);
runtime->mesh_eval = mesh_final; runtime->mesh_eval = mesh_final;
}); });
@ -1047,17 +1044,16 @@ bool editbmesh_modifier_is_enabled(const Scene *scene,
return true; return true;
} }
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final, static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final)
const CustomData_MeshMasks *final_datamask)
{ {
const bool calc_loop_normals = mesh_final->normal_domain_all_info() == ATTR_DOMAIN_CORNER; const eAttrDomain domain = mesh_final->normal_domain_all_info();
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data; SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
if (subsurf_runtime_data) { if (subsurf_runtime_data) {
subsurf_runtime_data->calc_loop_normals = calc_loop_normals; subsurf_runtime_data->calc_loop_normals = domain == ATTR_DOMAIN_CORNER;
} }
if (calc_loop_normals) { if (domain == ATTR_DOMAIN_CORNER) {
/* Compute loop normals. In case of deferred CPU subdivision, this will be computed when the /* Compute loop normals. In case of deferred CPU subdivision, this will be computed when the
* wrapper is generated. */ * wrapper is generated. */
if (!subsurf_runtime_data || subsurf_runtime_data->resolution == 0) { if (!subsurf_runtime_data || subsurf_runtime_data->resolution == 0) {
@ -1065,14 +1061,32 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
} }
} }
else { else {
/* Same as #mesh_calc_modifiers. switch (mesh_final->runtime->wrapper_type) {
* If using loop normals, poly normals have already been computed. */ case ME_WRAPPER_TYPE_SUBD:
BKE_mesh_ensure_normals_for_display(mesh_final); break;
case ME_WRAPPER_TYPE_MDATA:
/* Same as #mesh_calc_modifiers. */
if (domain == ATTR_DOMAIN_FACE) {
mesh_final->poly_normals();
}
else if (domain == ATTR_DOMAIN_FACE) {
mesh_final->vert_normals();
}
break;
case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh *em = mesh_final->edit_mesh;
EditMeshData *emd = mesh_final->runtime->edit_data;
if (emd->vertexCos) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
BKE_editmesh_cache_ensure_poly_normals(em, emd);
}
return;
}
}
} }
} }
static void editbmesh_calc_modifier_final_normals_or_defer( static void editbmesh_calc_modifier_final_normals_or_defer(Mesh *mesh_final)
Mesh *mesh_final, const CustomData_MeshMasks *final_datamask)
{ {
if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) { if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) {
/* Generated at draw time. */ /* Generated at draw time. */
@ -1081,7 +1095,7 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
return; return;
} }
editbmesh_calc_modifier_final_normals(mesh_final, final_datamask); editbmesh_calc_modifier_final_normals(mesh_final);
} }
static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
@ -1362,9 +1376,9 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
} }
/* Compute normals. */ /* Compute normals. */
editbmesh_calc_modifier_final_normals_or_defer(mesh_final, &final_datamask); editbmesh_calc_modifier_final_normals_or_defer(mesh_final);
if (mesh_cage && (mesh_cage != mesh_final)) { if (mesh_cage && (mesh_cage != mesh_final)) {
editbmesh_calc_modifier_final_normals_or_defer(mesh_cage, &final_datamask); editbmesh_calc_modifier_final_normals_or_defer(mesh_cage);
} }
/* Return final mesh. */ /* Return final mesh. */

View File

@ -361,11 +361,11 @@ static void data_transfer_dtdata_type_postprocess(Mesh *me_dst,
blender::float3 *loop_nors_dst = static_cast<blender::float3 *>( blender::float3 *loop_nors_dst = static_cast<blender::float3 *>(
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop)); CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop));
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>( blender::short2 *custom_nors_dst = static_cast<blender::short2 *>(
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop)); CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop));
if (!custom_nors_dst) { if (!custom_nors_dst) {
custom_nors_dst = static_cast<short(*)[2]>( custom_nors_dst = static_cast<blender::short2 *>(
CustomData_add_layer(ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, me_dst->totloop)); CustomData_add_layer(ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, me_dst->totloop));
} }
@ -1503,7 +1503,6 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (DT_DATATYPE_IS_LOOP(dtdata_type)) { if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst); const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst);
const int num_verts_dst = me_dst->totvert; const int num_verts_dst = me_dst->totvert;
const blender::Span<MEdge> edges_dst = me_dst->edges();
const blender::OffsetIndices polys_dst = me_dst->polys(); const blender::OffsetIndices polys_dst = me_dst->polys();
const blender::Span<int> corner_verts_dst = me_dst->corner_verts(); const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
@ -1542,8 +1541,6 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
me_dst, me_dst,
positions_dst, positions_dst,
num_verts_dst, num_verts_dst,
edges_dst.data(),
edges_dst.size(),
corner_verts_dst.data(), corner_verts_dst.data(),
corner_verts_dst.size(), corner_verts_dst.size(),
polys_dst, polys_dst,

View File

@ -758,7 +758,6 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
if (geometry_set.has_mesh()) { if (geometry_set.has_mesh()) {
Mesh *final_mesh = geometry_set.get_mesh_for_write(); Mesh *final_mesh = geometry_set.get_mesh_for_write();
BKE_mesh_ensure_normals_for_display(final_mesh);
BLI_strncpy(final_mesh->id.name, cu->id.name, sizeof(final_mesh->id.name)); BLI_strncpy(final_mesh->id.name, cu->id.name, sizeof(final_mesh->id.name));
*((short *)final_mesh->id.name) = ID_ME; *((short *)final_mesh->id.name) = ID_ME;

View File

@ -250,7 +250,7 @@ float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3]
return BM_mesh_vert_coords_alloc(em->bm, r_vert_len); return BM_mesh_vert_coords_alloc(em->bm, r_vert_len);
} }
void BKE_editmesh_lnorspace_update(BMEditMesh *em, Mesh *me) void BKE_editmesh_lnorspace_update(BMEditMesh *em)
{ {
BM_lnorspace_update(em->bm); BM_lnorspace_update(em->bm);
} }

View File

@ -2280,7 +2280,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
"sharp_edge", ATTR_DOMAIN_EDGE, false); "sharp_edge", ATTR_DOMAIN_EDGE, false);
const blender::VArray<bool> sharp_faces = attributes.lookup_or_default<bool>( const blender::VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
"sharp_face", ATTR_DOMAIN_FACE, false); "sharp_face", ATTR_DOMAIN_FACE, false);
const short(*custom_normals)[2] = static_cast<const short(*)[2]>( const blender::short2 *custom_normals = static_cast<const blender::short2 *>(
CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL));
blender::bke::mesh::normals_calc_loop( blender::bke::mesh::normals_calc_loop(
{reinterpret_cast<const blender::float3 *>(positions), mesh->totvert}, {reinterpret_cast<const blender::float3 *>(positions), mesh->totvert},

View File

@ -380,7 +380,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
result->totpoly > 0) { result->totpoly > 0) {
blender::Array<blender::float3> loop_normals(result_corner_verts.size()); blender::Array<blender::float3> loop_normals(result_corner_verts.size());
CustomData *ldata = &result->ldata; CustomData *ldata = &result->ldata;
short(*clnors)[2] = static_cast<short(*)[2]>( blender::short2 *clnors = static_cast<blender::short2 *>(
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, result->totloop)); CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, result->totloop));
MLoopNorSpaceArray lnors_spacearr = {nullptr}; MLoopNorSpaceArray lnors_spacearr = {nullptr};

View File

@ -319,8 +319,8 @@ enum class BoolArrayMix {
AllTrue, AllTrue,
Mixed, Mixed,
}; };
BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray, static BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray,
const blender::IndexRange range_to_check) const blender::IndexRange range_to_check)
{ {
using namespace blender; using namespace blender;
if (varray.is_empty()) { if (varray.is_empty()) {
@ -372,7 +372,7 @@ BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray,
[&](BoolArrayMix a, BoolArrayMix b) { return (a == b) ? a : BoolArrayMix::Mixed; }); [&](BoolArrayMix a, BoolArrayMix b) { return (a == b) ? a : BoolArrayMix::Mixed; });
} }
BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray) static BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray)
{ {
return bool_array_mix_calc(varray, varray.index_range()); return bool_array_mix_calc(varray, varray.index_range());
} }
@ -381,9 +381,11 @@ eAttrDomain Mesh::normal_domain_all_info() const
{ {
using namespace blender; using namespace blender;
using namespace blender::bke; using namespace blender::bke;
const short(*custom_normals)[2] = static_cast<const short(*)[2]>( if (this->totpoly == 0) {
CustomData_get_layer(&this->ldata, CD_CUSTOMLOOPNORMAL)); return ATTR_DOMAIN_POINT;
if (custom_normals) { }
if (CustomData_has_layer(&this->ldata, CD_CUSTOMLOOPNORMAL)) {
return ATTR_DOMAIN_CORNER; return ATTR_DOMAIN_CORNER;
} }
@ -520,7 +522,7 @@ blender::Span<blender::float3> Mesh::corner_normals() const
"sharp_edge", ATTR_DOMAIN_EDGE, false); "sharp_edge", ATTR_DOMAIN_EDGE, false);
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>( const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
"sharp_face", ATTR_DOMAIN_FACE, false); "sharp_face", ATTR_DOMAIN_FACE, false);
const short(*custom_normals)[2] = static_cast<const short(*)[2]>( const short2 *custom_normals = static_cast<const short2 *>(
CustomData_get_layer(&this->ldata, CD_CUSTOMLOOPNORMAL)); CustomData_get_layer(&this->ldata, CD_CUSTOMLOOPNORMAL));
bke::mesh::normals_calc_loop(this->vert_positions(), bke::mesh::normals_calc_loop(this->vert_positions(),
@ -553,26 +555,6 @@ const float (*BKE_mesh_corner_normals_ensure(const Mesh *mesh))[3]
return reinterpret_cast<const float(*)[3]>(mesh->corner_normals().data()); return reinterpret_cast<const float(*)[3]>(mesh->corner_normals().data());
} }
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA:
mesh->vert_normals();
mesh->poly_normals();
break;
case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh *em = mesh->edit_mesh;
EditMeshData *emd = mesh->runtime->edit_data;
if (emd->vertexCos) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
BKE_editmesh_cache_ensure_poly_normals(em, emd);
}
return;
}
}
}
void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
const int numLoops, const int numLoops,
const char data_type) const char data_type)
@ -1589,7 +1571,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
const Span<float3> poly_normals, const Span<float3> poly_normals,
const VArray<bool> &sharp_edges, const VArray<bool> &sharp_edges,
const VArray<bool> &sharp_faces, const VArray<bool> &sharp_faces,
short (*clnors_data)[2], const short2 *custom_normals_data,
MLoopNorSpaceArray *r_lnors_spacearr, MLoopNorSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals) MutableSpan<float3> r_loop_normals)
{ {
@ -1626,7 +1608,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
SCOPED_TIMER_AVERAGED(__func__); SCOPED_TIMER_AVERAGED(__func__);
#endif #endif
if (!r_lnors_spacearr && clnors_data) { if (!r_lnors_spacearr && custom_normals_data) {
/* We need to compute lnor spacearr if some custom lnor data are given to us! */ /* We need to compute lnor spacearr if some custom lnor data are given to us! */
r_lnors_spacearr = &_lnors_spacearr; r_lnors_spacearr = &_lnors_spacearr;
} }
@ -1638,8 +1620,8 @@ void normals_calc_loop(const Span<float3> vert_positions,
LoopSplitTaskDataCommon common_data; LoopSplitTaskDataCommon common_data;
common_data.lnors_spacearr = r_lnors_spacearr; common_data.lnors_spacearr = r_lnors_spacearr;
common_data.loop_normals = r_loop_normals; common_data.loop_normals = r_loop_normals;
common_data.clnors_data = {reinterpret_cast<short2 *>(clnors_data), common_data.clnors_data = {const_cast<short2 *>(custom_normals_data),
clnors_data ? corner_verts.size() : 0}; custom_normals_data ? corner_verts.size() : 0};
common_data.positions = vert_positions; common_data.positions = vert_positions;
common_data.edges = edges; common_data.edges = edges;
common_data.polys = polys; common_data.polys = polys;
@ -1704,7 +1686,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
const bool use_vertices, const bool use_vertices,
MutableSpan<float3> r_custom_loop_normals, MutableSpan<float3> r_custom_loop_normals,
MutableSpan<bool> sharp_edges, MutableSpan<bool> sharp_edges,
short (*r_clnors_data)[2]) short2 *r_clnors_data)
{ {
/* We *may* make that poor #bke::mesh::normals_calc_loop() even more complex by making it /* 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 * handling that feature too, would probably be more efficient in absolute. However, this
@ -1926,7 +1908,7 @@ void normals_loop_custom_set(const Span<float3> vert_positions,
const VArray<bool> &sharp_faces, const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges, MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals, MutableSpan<float3> r_custom_loop_normals,
short (*r_clnors_data)[2]) short2 *r_clnors_data)
{ {
mesh_normals_loop_custom_set(vert_positions, mesh_normals_loop_custom_set(vert_positions,
edges, edges,
@ -1952,7 +1934,7 @@ void normals_loop_custom_set_from_verts(const Span<float3> vert_positions,
const VArray<bool> &sharp_faces, const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges, MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals, MutableSpan<float3> r_custom_vert_normals,
short (*r_clnors_data)[2]) short2 *r_clnors_data)
{ {
mesh_normals_loop_custom_set(vert_positions, mesh_normals_loop_custom_set(vert_positions,
edges, edges,
@ -1970,16 +1952,16 @@ void normals_loop_custom_set_from_verts(const Span<float3> vert_positions,
static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices) static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices)
{ {
short(*clnors)[2]; short2 *clnors;
const int numloops = mesh->totloop; const int numloops = mesh->totloop;
clnors = (short(*)[2])CustomData_get_layer_for_write( clnors = (short2 *)CustomData_get_layer_for_write(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop); &mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop);
if (clnors != nullptr) { if (clnors != nullptr) {
memset(clnors, 0, sizeof(*clnors) * size_t(numloops)); memset(clnors, 0, sizeof(*clnors) * size_t(numloops));
} }
else { else {
clnors = (short(*)[2])CustomData_add_layer( clnors = (short2 *)CustomData_add_layer(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, numloops); &mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, numloops);
} }
MutableAttributeAccessor attributes = mesh->attributes_for_write(); MutableAttributeAccessor attributes = mesh->attributes_for_write();

View File

@ -1206,8 +1206,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const Mesh *mesh_dst, const Mesh *mesh_dst,
const float (*vert_positions_dst)[3], const float (*vert_positions_dst)[3],
const int numverts_dst, const int numverts_dst,
const MEdge *edges_dst,
const int numedges_dst,
const int *corner_verts_dst, const int *corner_verts_dst,
const int numloops_dst, const int numloops_dst,
const blender::OffsetIndices<int> polys_dst, const blender::OffsetIndices<int> polys_dst,

View File

@ -247,12 +247,14 @@ void BKE_mesh_tag_face_winding_changed(Mesh *mesh)
{ {
mesh->runtime->vert_normals_dirty = true; mesh->runtime->vert_normals_dirty = true;
mesh->runtime->poly_normals_dirty = true; mesh->runtime->poly_normals_dirty = true;
mesh->runtime->corner_normals_dirty = true;
} }
void BKE_mesh_tag_positions_changed(Mesh *mesh) void BKE_mesh_tag_positions_changed(Mesh *mesh)
{ {
mesh->runtime->vert_normals_dirty = true; mesh->runtime->vert_normals_dirty = true;
mesh->runtime->poly_normals_dirty = true; mesh->runtime->poly_normals_dirty = true;
mesh->runtime->corner_normals_dirty = true;
free_bvh_cache(*mesh->runtime); free_bvh_cache(*mesh->runtime);
mesh->runtime->looptris_cache.tag_dirty(); mesh->runtime->looptris_cache.tag_dirty();
mesh->runtime->bounds_cache.tag_dirty(); mesh->runtime->bounds_cache.tag_dirty();

View File

@ -140,7 +140,7 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
} }
if (me->runtime->wrapper_type_finalize) { if (me->runtime->wrapper_type_finalize) {
BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime->cd_mask_extra); BKE_mesh_wrapper_deferred_finalize_mdata(me);
} }
/* Keep type assignment last, so that read-only access only uses the mdata code paths after all /* Keep type assignment last, so that read-only access only uses the mdata code paths after all
@ -338,8 +338,9 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
Mesh *subdiv_mesh = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me); Mesh *subdiv_mesh = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me);
if (use_clnors) { if (use_clnors) {
BKE_mesh_set_custom_normals( BKE_mesh_set_custom_normals(subdiv_mesh,
subdiv_mesh, reinterpret_cast<const float(*)[3]>(subdiv_mesh->corner_normals().data())); const_cast<float(*)[3]>(reinterpret_cast<const float(*)[3]>(
subdiv_mesh->corner_normals().data())));
} }
if (!ELEM(subdiv, runtime_data->subdiv_cpu, runtime_data->subdiv_gpu)) { if (!ELEM(subdiv, runtime_data->subdiv_cpu, runtime_data->subdiv_gpu)) {

View File

@ -11,6 +11,8 @@
* To update preference defaults see `userdef_default.c`. * To update preference defaults see `userdef_default.c`.
*/ */
#define DNA_DEPRECATED_ALLOW
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"

View File

@ -1796,7 +1796,6 @@ static BMOpDefine bmo_bevel_def = {
{"miter_inner", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, {"miter_inner", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
bmo_enum_bevel_miter_type}, /* outer miter kind */ bmo_enum_bevel_miter_type}, /* outer miter kind */
{"spread", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */ {"spread", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
{"smoothresh", BMO_OP_SLOT_FLT}, /* for passing mesh's smoothresh, used in hardening */
{"custom_profile", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_STRUCT}}, /* CurveProfile, if None ignored */ {"custom_profile", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_STRUCT}}, /* CurveProfile, if None ignored */
{"vmesh_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, {"vmesh_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
bmo_enum_bevel_vmesh_method}, /* The method to use to create meshes at intersections. */ bmo_enum_bevel_vmesh_method}, /* The method to use to create meshes at intersections. */

View File

@ -33,7 +33,6 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
const int miter_outer = BMO_slot_int_get(op->slots_in, "miter_outer"); const int miter_outer = BMO_slot_int_get(op->slots_in, "miter_outer");
const int miter_inner = BMO_slot_int_get(op->slots_in, "miter_inner"); const int miter_inner = BMO_slot_int_get(op->slots_in, "miter_inner");
const float spread = BMO_slot_float_get(op->slots_in, "spread"); const float spread = BMO_slot_float_get(op->slots_in, "spread");
const float smoothresh = BMO_slot_float_get(op->slots_in, "smoothresh");
const CurveProfile *custom_profile = BMO_slot_ptr_get(op->slots_in, "custom_profile"); const CurveProfile *custom_profile = BMO_slot_ptr_get(op->slots_in, "custom_profile");
const int vmesh_method = BMO_slot_int_get(op->slots_in, "vmesh_method"); const int vmesh_method = BMO_slot_int_get(op->slots_in, "vmesh_method");
@ -79,7 +78,6 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
miter_outer, miter_outer,
miter_inner, miter_inner,
spread, spread,
smoothresh,
custom_profile, custom_profile,
vmesh_method); vmesh_method);

View File

@ -367,8 +367,6 @@ typedef struct BevelParams {
int vmesh_method; int vmesh_method;
/** Amount to spread when doing inside miter. */ /** Amount to spread when doing inside miter. */
float spread; float spread;
/** Mesh's smoothresh, used if hardening. */
float smoothresh;
} BevelParams; } BevelParams;
// #pragma GCC diagnostic ignored "-Wpadded" // #pragma GCC diagnostic ignored "-Wpadded"
@ -2476,7 +2474,6 @@ static void bevel_harden_normals(BevelParams *bp, BMesh *bm)
* to mark the sharpen the edges that are only sharp because of the angle test -- otherwise would * to mark the sharpen the edges that are only sharp because of the angle test -- otherwise would
* be smooth. */ * be smooth. */
if (cd_clnors_offset == -1) { if (cd_clnors_offset == -1) {
BM_edges_sharp_from_angle_set(bm, bp->smoothresh);
bevel_edges_sharp_boundary(bm, bp); bevel_edges_sharp_boundary(bm, bp);
} }
@ -7724,7 +7721,6 @@ void BM_mesh_bevel(BMesh *bm,
const int miter_outer, const int miter_outer,
const int miter_inner, const int miter_inner,
const float spread, const float spread,
const float smoothresh,
const struct CurveProfile *custom_profile, const struct CurveProfile *custom_profile,
const int vmesh_method) const int vmesh_method)
{ {
@ -7757,7 +7753,6 @@ void BM_mesh_bevel(BMesh *bm,
.miter_outer = miter_outer, .miter_outer = miter_outer,
.miter_inner = miter_inner, .miter_inner = miter_inner,
.spread = spread, .spread = spread,
.smoothresh = smoothresh,
.face_hash = NULL, .face_hash = NULL,
.profile_type = profile_type, .profile_type = profile_type,
.custom_profile = custom_profile, .custom_profile = custom_profile,

View File

@ -41,6 +41,5 @@ void BM_mesh_bevel(BMesh *bm,
int miter_outer, int miter_outer,
int miter_inner, int miter_inner,
float spread, float spread,
float smoothresh,
const struct CurveProfile *custom_profile, const struct CurveProfile *custom_profile,
int vmesh_method); int vmesh_method);

View File

@ -573,6 +573,7 @@ const bool *ED_mesh_uv_map_edge_select_layer_get(const struct Mesh *mesh, int uv
const bool *ED_mesh_uv_map_pin_layer_get(const struct Mesh *mesh, int uv_map_index); const bool *ED_mesh_uv_map_pin_layer_get(const struct Mesh *mesh, int uv_map_index);
bool ED_mesh_edge_is_loose(const struct Mesh *mesh, int index); bool ED_mesh_edge_is_loose(const struct Mesh *mesh, int index);
int ED_mesh_normal_domain_all_info_get(const struct Mesh *mesh);
void ED_mesh_uv_ensure(struct Mesh *me, const char *name); void ED_mesh_uv_ensure(struct Mesh *me, const char *name);
int ED_mesh_uv_add( int ED_mesh_uv_add(

View File

@ -341,7 +341,7 @@ static bool edbm_bevel_calc(wmOperator *op)
"bevel geom=%hev offset=%f segments=%i affect=%i offset_type=%i " "bevel geom=%hev offset=%f segments=%i affect=%i offset_type=%i "
"profile_type=%i profile=%f clamp_overlap=%b material=%i loop_slide=%b " "profile_type=%i profile=%f clamp_overlap=%b material=%i loop_slide=%b "
"mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i " "mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i "
"miter_outer=%i miter_inner=%i spread=%f smoothresh=%f custom_profile=%p " "miter_outer=%i miter_inner=%i spread=%f custom_profile=%p "
"vmesh_method=%i", "vmesh_method=%i",
BM_ELEM_SELECT, BM_ELEM_SELECT,
offset, offset,
@ -360,7 +360,6 @@ static bool edbm_bevel_calc(wmOperator *op)
miter_outer, miter_outer,
miter_inner, miter_inner,
spread, spread,
me->smoothresh,
opdata->custom_profile, opdata->custom_profile,
vmesh_method); vmesh_method);

View File

@ -8392,7 +8392,7 @@ static bool point_normals_init(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit); BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm; BMesh *bm = em->bm;
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false); BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
op->customdata = lnors_ed_arr; op->customdata = lnors_ed_arr;
@ -9018,7 +9018,7 @@ static int normals_split_merge(bContext *C, const bool do_merge)
BMEdge *e; BMEdge *e;
BMIter eiter; BMIter eiter;
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
/* Note that we need temp lnor editing data for all loops of all affected vertices, since by /* Note that we need temp lnor editing data for all loops of all affected vertices, since by
* setting some faces/edges as smooth we are going to change clnors spaces... See also #65809. * setting some faces/edges as smooth we are going to change clnors spaces... See also #65809.
@ -9036,7 +9036,7 @@ static int normals_split_merge(bContext *C, const bool do_merge)
} }
bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
if (do_merge) { if (do_merge) {
normals_merge(bm, lnors_ed_arr); normals_merge(bm, lnors_ed_arr);
@ -9157,7 +9157,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op)
BMIter fiter; BMIter fiter;
bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
@ -9404,7 +9404,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
continue; continue;
} }
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false); BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
@ -9628,7 +9628,7 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp"); const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp");
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
float(*vert_normals)[3] = static_cast<float(*)[3]>( float(*vert_normals)[3] = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*vert_normals) * bm->totvert, __func__)); MEM_mallocN(sizeof(*vert_normals) * bm->totvert, __func__));
@ -9735,7 +9735,7 @@ static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
BMLoop *l; BMLoop *l;
BMIter fiter, liter; BMIter fiter, liter;
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data)); BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false); BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
float(*smooth_normal)[3] = static_cast<float(*)[3]>( float(*smooth_normal)[3] = static_cast<float(*)[3]>(

View File

@ -1110,6 +1110,11 @@ bool ED_mesh_edge_is_loose(const Mesh *mesh, const int index)
return loose_edges.count > 0 && loose_edges.is_loose_bits[index]; return loose_edges.count > 0 && loose_edges.is_loose_bits[index];
} }
int ED_mesh_normal_domain_all_info_get(const Mesh *mesh)
{
return mesh->normal_domain_all_info();
}
static void mesh_add_verts(Mesh *mesh, int len) static void mesh_add_verts(Mesh *mesh, int len)
{ {
using namespace blender; using namespace blender;
@ -1450,7 +1455,6 @@ void ED_mesh_split_faces(Mesh *mesh)
{ {
using namespace blender; using namespace blender;
const OffsetIndices polys = mesh->polys(); const OffsetIndices polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
const Span<int> corner_edges = mesh->corner_edges(); const Span<int> corner_edges = mesh->corner_edges();
const bke::AttributeAccessor attributes = mesh->attributes(); const bke::AttributeAccessor attributes = mesh->attributes();
const VArray<bool> mesh_sharp_edges = attributes.lookup_or_default<bool>( const VArray<bool> mesh_sharp_edges = attributes.lookup_or_default<bool>(

View File

@ -2016,7 +2016,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
else if (!do_skip) { else if (!do_skip) {
const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop); const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop);
if (preserve_clnor) { if (preserve_clnor) {
BKE_editmesh_lnorspace_update(em, tc->obedit->data); BKE_editmesh_lnorspace_update(em);
t->flag |= T_CLNOR_REBUILD; t->flag |= T_CLNOR_REBUILD;
} }
BM_lnorspace_invalidate(em->bm, true); BM_lnorspace_invalidate(em->bm, true);

View File

@ -128,7 +128,7 @@ void initNormalRotation(TransInfo *t)
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm; BMesh *bm = em->bm;
BKE_editmesh_lnorspace_update(em, tc->obedit->data); BKE_editmesh_lnorspace_update(em);
storeCustomLNorValue(tc, bm); storeCustomLNorValue(tc, bm);
} }

View File

@ -70,7 +70,7 @@ static void get_edge_creases(struct Mesh *mesh,
static void get_vert_creases(struct Mesh *mesh, static void get_vert_creases(struct Mesh *mesh,
std::vector<int32_t> &indices, std::vector<int32_t> &indices,
std::vector<float> &sharpnesses); std::vector<float> &sharpnesses);
static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals); static void get_loop_normals(const Mesh *mesh, std::vector<Imath::V3f> &normals);
ABCGenericMeshWriter::ABCGenericMeshWriter(const ABCWriterConstructorArgs &args) ABCGenericMeshWriter::ABCGenericMeshWriter(const ABCWriterConstructorArgs &args)
: ABCAbstractWriter(args), is_subd_(false) : ABCAbstractWriter(args), is_subd_(false)
@ -277,10 +277,9 @@ void ABCGenericMeshWriter::write_subd(HierarchyContext &context, struct Mesh *me
std::vector<Imath::V3f> points; std::vector<Imath::V3f> points;
std::vector<int32_t> poly_verts, loop_counts; std::vector<int32_t> poly_verts, loop_counts;
std::vector<int32_t> edge_crease_indices, edge_crease_lengths, vert_crease_indices; std::vector<int32_t> edge_crease_indices, edge_crease_lengths, vert_crease_indices;
bool has_flat_poly = false;
get_vertices(mesh, points); get_vertices(mesh, points);
get_topology(mesh, poly_verts, loop_counts, has_flat_poly); get_topology(mesh, poly_verts, loop_counts);
get_edge_creases(mesh, edge_crease_indices, edge_crease_lengths, edge_crease_sharpness); get_edge_creases(mesh, edge_crease_indices, edge_crease_lengths, edge_crease_sharpness);
get_vert_creases(mesh, vert_crease_indices, vert_crease_sharpness); get_vert_creases(mesh, vert_crease_indices, vert_crease_sharpness);

View File

@ -16,7 +16,6 @@
#define _DNA_DEFAULT_Mesh \ #define _DNA_DEFAULT_Mesh \
{ \ { \
.texspace_size = {1.0f, 1.0f, 1.0f}, \ .texspace_size = {1.0f, 1.0f, 1.0f}, \
.smoothresh = DEG2RADF(30), \
.texspace_flag = ME_TEXSPACE_FLAG_AUTO, \ .texspace_flag = ME_TEXSPACE_FLAG_AUTO, \
.remesh_voxel_size = 0.1f, \ .remesh_voxel_size = 0.1f, \
.remesh_voxel_adaptivity = 0.0f, \ .remesh_voxel_adaptivity = 0.0f, \

View File

@ -148,7 +148,7 @@ typedef struct Mesh {
/** /**
* The angle for auto smooth in radians. `M_PI` (180 degrees) causes all edges to be smooth. * The angle for auto smooth in radians. `M_PI` (180 degrees) causes all edges to be smooth.
*/ */
float smoothresh; float smoothresh DNA_DEPRECATED;
/** Per-mesh settings for voxel remesh. */ /** Per-mesh settings for voxel remesh. */
float remesh_voxel_size; float remesh_voxel_size;

View File

@ -213,6 +213,7 @@ DEF_ENUM(rna_enum_color_attribute_type_items)
DEF_ENUM(rna_enum_attribute_type_with_auto_items) DEF_ENUM(rna_enum_attribute_type_with_auto_items)
DEF_ENUM(rna_enum_attribute_domain_items) DEF_ENUM(rna_enum_attribute_domain_items)
DEF_ENUM(rna_enum_attribute_domain_only_mesh_items) DEF_ENUM(rna_enum_attribute_domain_only_mesh_items)
DEF_ENUM(rna_enum_attribute_domain_only_mesh_no_edge_items)
DEF_ENUM(rna_enum_attribute_curves_domain_items) DEF_ENUM(rna_enum_attribute_curves_domain_items)
DEF_ENUM(rna_enum_color_attribute_domain_items) DEF_ENUM(rna_enum_color_attribute_domain_items)
DEF_ENUM(rna_enum_attribute_domain_without_corner_items) DEF_ENUM(rna_enum_attribute_domain_without_corner_items)

View File

@ -91,6 +91,13 @@ const EnumPropertyItem rna_enum_attribute_domain_only_mesh_items[] = {
{0, NULL, 0, NULL, NULL}, {0, NULL, 0, NULL, NULL},
}; };
const EnumPropertyItem rna_enum_attribute_domain_only_mesh_no_edge_items[] = {
{ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"},
{ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
{ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_attribute_domain_without_corner_items[] = { const EnumPropertyItem rna_enum_attribute_domain_without_corner_items[] = {
{ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"}, {ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"},
{ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"}, {ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"},

View File

@ -620,10 +620,10 @@ static void rna_MeshLoop_bitangent_get(PointerRNA *ptr, float *values)
Mesh *me = rna_mesh(ptr); Mesh *me = rna_mesh(ptr);
const int index = rna_MeshLoop_index_get(ptr); const int index = rna_MeshLoop_index_get(ptr);
const float(*loop_normals)[3] = BKE_mesh_corner_normals_ensure(me); const float(*loop_normals)[3] = BKE_mesh_corner_normals_ensure(me);
const float(*vec)[4] = CustomData_get(&me->ldata, index, CD_MLOOPTANGENT); const float(*vec)[4] = CustomData_get_layer(&me->ldata, CD_MLOOPTANGENT);
if (vec) { if (vec) {
cross_v3_v3v3(values, loop_normals[index][index], vec[index]); cross_v3_v3v3(values, loop_normals[index], vec[index]);
mul_v3_fl(values, vec[index][3]); mul_v3_fl(values, vec[index][3]);
} }
else { else {
@ -2043,6 +2043,12 @@ int rna_Mesh_loops_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
return true; return true;
} }
static int rna_Mesh_normal_domain_all_info_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
return ED_mesh_normal_domain_all_info_get(mesh);
}
static void rna_Mesh_vertex_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) static void rna_Mesh_vertex_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{ {
const Mesh *mesh = rna_mesh(ptr); const Mesh *mesh = rna_mesh(ptr);
@ -4217,6 +4223,12 @@ static void rna_def_mesh(BlenderRNA *brna)
rna_def_normal_layer_value(brna); rna_def_normal_layer_value(brna);
prop = RNA_def_property(srna, "normal_domain_all_info", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_domain_only_mesh_no_edge_items);
RNA_def_property_ui_text(prop, "Normal Domain ALl Info", "");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_funcs(prop, "rna_Mesh_normal_domain_all_info_get", NULL, NULL);
prop = RNA_def_property(srna, "vertex_normals", PROP_COLLECTION, PROP_NONE); prop = RNA_def_property(srna, "vertex_normals", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshNormalValue"); RNA_def_property_struct_type(prop, "MeshNormalValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);

View File

@ -48,7 +48,7 @@ static void rna_Mesh_create_normals_split(Mesh *mesh)
BKE_mesh_corner_normals_ensure(mesh); BKE_mesh_corner_normals_ensure(mesh);
} }
static void rna_Mesh_free_normals_split(Mesh *mesh) static void rna_Mesh_free_normals_split(Mesh *UNUSED(mesh))
{ {
/* TODO: Deprecation? */ /* TODO: Deprecation? */
} }

View File

@ -192,8 +192,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
} }
} }
Object *ob = ctx->object;
BM_mesh_bevel(bm, BM_mesh_bevel(bm,
value, value,
offset_type, offset_type,
@ -214,7 +212,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
miter_outer, miter_outer,
miter_inner, miter_inner,
spread, spread,
mesh->smoothresh,
bmd->custom_profile, bmd->custom_profile,
bmd->vmesh_method); bmd->vmesh_method);

View File

@ -222,7 +222,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
const ModifierEvalContext * /*ctx*/, const ModifierEvalContext * /*ctx*/,
Object *ob, Object *ob,
Mesh *mesh, Mesh *mesh,
short (*clnors)[2], blender::short2 *clnors,
blender::MutableSpan<blender::float3> loop_normals, blender::MutableSpan<blender::float3> loop_normals,
const short mix_mode, const short mix_mode,
const float mix_factor, const float mix_factor,
@ -353,7 +353,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
const ModifierEvalContext * /*ctx*/, const ModifierEvalContext * /*ctx*/,
Object *ob, Object *ob,
Mesh *mesh, Mesh *mesh,
short (*clnors)[2], blender::short2 *clnors,
blender::MutableSpan<blender::float3> loop_normals, blender::MutableSpan<blender::float3> loop_normals,
const short mix_mode, const short mix_mode,
const float mix_factor, const float mix_factor,
@ -519,10 +519,10 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
bke::SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>( bke::SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE); "sharp_edge", ATTR_DOMAIN_EDGE);
short(*clnors)[2] = static_cast<short(*)[2]>( blender::short2 *clnors = static_cast<blender::short2 *>(
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size()));
if (use_current_clnors) { if (use_current_clnors) {
clnors = static_cast<short(*)[2]>( clnors = static_cast<blender::short2 *>(
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size()));
loop_normals.reinitialize(corner_verts.size()); loop_normals.reinitialize(corner_verts.size());
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>( const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
@ -543,7 +543,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
} }
if (clnors == nullptr) { if (clnors == nullptr) {
clnors = static_cast<short(*)[2]>( clnors = static_cast<blender::short2 *>(
CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size())); CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size()));
} }

View File

@ -78,7 +78,7 @@ struct WeightedNormalData {
blender::Span<int> corner_verts; blender::Span<int> corner_verts;
blender::Span<int> corner_edges; blender::Span<int> corner_edges;
blender::Span<int> loop_to_poly; blender::Span<int> loop_to_poly;
short (*clnors)[2]; blender::short2 *clnors;
bool has_clnors; /* True if clnors already existed, false if we had to create them. */ bool has_clnors; /* True if clnors already existed, false if we had to create them. */
blender::OffsetIndices<int> polys; blender::OffsetIndices<int> polys;
@ -190,7 +190,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
const blender::Span<int> corner_verts = wn_data->corner_verts; const blender::Span<int> corner_verts = wn_data->corner_verts;
const blender::Span<int> corner_edges = wn_data->corner_edges; const blender::Span<int> corner_edges = wn_data->corner_edges;
short(*clnors)[2] = wn_data->clnors; blender::short2 *clnors = wn_data->clnors;
const blender::Span<int> loop_to_poly = wn_data->loop_to_poly; const blender::Span<int> loop_to_poly = wn_data->loop_to_poly;
const blender::Span<blender::float3> poly_normals = wn_data->poly_normals; const blender::Span<blender::float3> poly_normals = wn_data->poly_normals;
@ -513,7 +513,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{ {
using namespace blender; using namespace blender;
WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md; WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
Object *ob = ctx->object;
Mesh *result = (Mesh *)BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE); Mesh *result = (Mesh *)BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE);
@ -541,14 +540,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
weight = (weight - 1) * 25; weight = (weight - 1) * 25;
} }
short(*clnors)[2] = static_cast<short(*)[2]>( blender::short2 *clnors = static_cast<blender::short2 *>(
CustomData_get_layer_for_write(&result->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop)); CustomData_get_layer_for_write(&result->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop));
/* Keep info whether we had clnors, /* Keep info whether we had clnors,
* it helps when generating clnor spaces and default normals. */ * it helps when generating clnor spaces and default normals. */
const bool has_clnors = clnors != nullptr; const bool has_clnors = clnors != nullptr;
if (!clnors) { if (!clnors) {
clnors = static_cast<short(*)[2]>(CustomData_add_layer( clnors = static_cast<blender::short2 *>(CustomData_add_layer(
&result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size())); &result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size()));
} }